diff --git a/.gitignore b/.gitignore index a61e4778d011cf706e6784818a1357f392f3a669..6839cf84acda0d2d3c236a2e42b0cb0fe1b14965 100644 --- a/.gitignore +++ b/.gitignore @@ -129,6 +129,7 @@ series # ctags files tags +!tags/ TAGS # cscope files diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc index 4feb692c4c1d37190c04cff86ace614648e3db03..b6720768d63d23634804ef799371325040ae00a9 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uvc +++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc @@ -342,6 +342,70 @@ Description: Specific uncompressed frame descriptors support ========================= ===================================== +What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased +Date: Sept 2024 +KernelVersion: 5.15 +Description: Framebased format descriptors + +What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name +Date: Sept 2024 +KernelVersion: 5.15 +Description: Specific framebased format descriptors + + ================== ======================================= + bFormatIndex unique id for this format descriptor; + only defined after parent header is + linked into the streaming class; + read-only + bmaControls this format's data for bmaControls in + the streaming header + bmInterlaceFlags specifies interlace information, + read-only + bAspectRatioY the X dimension of the picture aspect + ratio, read-only + bAspectRatioX the Y dimension of the picture aspect + ratio, read-only + bDefaultFrameIndex optimum frame index for this stream + bBitsPerPixel number of bits per pixel used to + specify color in the decoded video + frame + guidFormat globally unique id used to identify + stream-encoding format + ================== ======================================= + +What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name/name +Date: Sept 2024 +KernelVersion: 5.15 +Description: Specific framebased frame descriptors + + ========================= ===================================== + bFrameIndex unique id for this framedescriptor; + only defined after parent format is + linked into the streaming header; + read-only + dwFrameInterval indicates how frame interval can be + programmed; a number of values + separated by newline can be specified + dwDefaultFrameInterval the frame interval the device would + like to use as default + dwBytesPerLine Specifies the number of bytes per line + of video for packed fixed frame size + formats, allowing the receiver to + perform stride alignment of the video. + If the bVariableSize value (above) is + TRUE (1), or if the format does not + permit such alignment, this value shall + be set to zero (0). + dwMaxBitRate the maximum bit rate at the shortest + frame interval in bps + dwMinBitRate the minimum bit rate at the longest + frame interval in bps + wHeight height of decoded bitmap frame in px + wWidth width of decoded bitmam frame in px + bmCapabilities still image support, fixed frame-rate + support + ========================= ===================================== + What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header Date: Dec 2014 KernelVersion: 4.0 diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-vpa-pmu b/Documentation/ABI/testing/sysfs-bus-event_source-devices-vpa-pmu index 8285263ff78dc00a0b2d3d30bad966b0557045de..a116aee9709aa8891fad00a8b5fadfb184e00531 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-vpa-pmu +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-vpa-pmu @@ -8,17 +8,18 @@ Description: Read-only. Attribute group to describe the magic bits Each attribute under this group defines a bit range of the perf_event_attr.config. Supported attribute are listed below:: - event = "config:0-31" - event ID - For example:: + event = "config:0-31" - event ID - l1_to_l2_lat = "event=0x1" + For example:: + + l1_to_l2_lat = "event=0x1" What: /sys/bus/event_source/devices/vpa_pmu/events Date: November 2024 Contact: Linux on PowerPC Developer List -Description: Read-only. Attribute group to describe performance monitoring +Description: Read-only. Attribute group to describe performance monitoring events for the Virtual Processor Area events. Each attribute - in this group describes a single performance monitoring event - supported by vpa_pmu. The name of the file is the name of - the event (See ABI/testing/sysfs-bus-event_source-devices-events). + in this group describes a single performance monitoring event + supported by vpa_pmu. The name of the file is the name of + the event (See ABI/testing/sysfs-bus-event_source-devices-events). diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 89943c2d54e8a85a8bbc0354fd6b11342f6b2cc7..f83bd6829285cd507c493cfff088158228388b67 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -2268,6 +2268,30 @@ Description: An example format is 16-bytes, 2-digits-per-byte, HEX-string representing the sensor unique ID number. +What: /sys/bus/iio/devices/iio:deviceX/filter_type_available +What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_filter_mode_available +KernelVersion: 6.1 +Contact: linux-iio@vger.kernel.org +Description: + Reading returns a list with the possible filter modes. Options + for the attribute: + + * "sinc3" - The digital sinc3 filter. Moderate 1st + conversion time. Good noise performance. + * "sinc4" - Sinc 4. Excellent noise performance. Long + 1st conversion time. + * "sinc5" - The digital sinc5 filter. Excellent noise + performance + * "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion + time. + * "sinc3+rej60" - Sinc3 + 60Hz rejection. + * "sinc3+sinc1" - Sinc3 + averaging by 8. Low 1st conversion + time. + * "sinc3+pf1" - Sinc3 + device specific Post Filter 1. + * "sinc3+pf2" - Sinc3 + device specific Post Filter 2. + * "sinc3+pf3" - Sinc3 + device specific Post Filter 3. + * "sinc3+pf4" - Sinc3 + device specific Post Filter 4. + What: /sys/.../events/in_proximity_thresh_either_runningperiod KernelVersion: 6.6 Contact: linux-iio@vger.kernel.org @@ -2339,3 +2363,11 @@ KernelVersion: 6.10 Contact: linux-iio@vger.kernel.org Description: The value of current sense resistor in Ohms. + +What: /sys/.../iio:deviceX/in_attention_input +KernelVersion: 6.13 +Contact: linux-iio@vger.kernel.org +Description: + Value representing the user's attention to the system expressed + in units as percentage. This usually means if the user is + looking at the screen or not. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 deleted file mode 100644 index f24ed6687e900ec5213cf0769ebdf65a0b65ae3d..0000000000000000000000000000000000000000 --- a/Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 +++ /dev/null @@ -1,46 +0,0 @@ -What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_filter_mode_available -KernelVersion: 6.2 -Contact: linux-iio@vger.kernel.org -Description: - Reading returns a list with the possible filter modes. - - * "sinc4" - Sinc 4. Excellent noise performance. Long - 1st conversion time. No natural 50/60Hz rejection. - - * "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion - time. - - * "sinc3" - Sinc3. Moderate 1st conversion time. - Good noise performance. - - * "sinc3+rej60" - Sinc3 + 60Hz rejection. At a sampling - frequency of 50Hz, achieves simultaneous 50Hz and 60Hz - rejection. - - * "sinc3+sinc1" - Sinc3 + averaging by 8. Low 1st conversion - time. Best used with a sampling frequency of at least - 216.19Hz. - - * "sinc3+pf1" - Sinc3 + Post Filter 1. 53dB rejection @ - 50Hz, 58dB rejection @ 60Hz. - - * "sinc3+pf2" - Sinc3 + Post Filter 2. 70dB rejection @ - 50Hz, 70dB rejection @ 60Hz. - - * "sinc3+pf3" - Sinc3 + Post Filter 3. 99dB rejection @ - 50Hz, 103dB rejection @ 60Hz. - - * "sinc3+pf4" - Sinc3 + Post Filter 4. 103dB rejection @ - 50Hz, 109dB rejection @ 60Hz. - -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_filter_mode -KernelVersion: 6.2 -Contact: linux-iio@vger.kernel.org -Description: - Set the filter mode of the differential channel. When the filter - mode changes, the in_voltageY-voltageZ_sampling_frequency and - in_voltageY-voltageZ_sampling_frequency_available attributes - might also change to accommodate the new filter mode. - If the current sampling frequency is out of range for the new - filter mode, the sampling frequency will be changed to the - closest valid one. diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec index 281b995beb05ae62106d6a4037a235dcfc7087c9..38e101c17a0048d9daeec4e12896a11f85ba1e9d 100644 --- a/Documentation/ABI/testing/sysfs-class-typec +++ b/Documentation/ABI/testing/sysfs-class-typec @@ -149,6 +149,19 @@ Description: advertise to the partner. The currently used capabilities are in brackets. Selection happens by writing to the file. +What: /sys/class/typec//usb_capability +Date: November 2024 +Contact: Heikki Krogerus +Description: Lists the supported USB Modes. The default USB mode that is used + next time with the Enter_USB Message is in brackets. The default + mode can be changed by writing to the file when supported by the + driver. + + Valid values: + - usb2 (USB 2.0) + - usb3 (USB 3.2) + - usb4 (USB4) + USB Type-C partner devices (eg. /sys/class/typec/port0-partner/) What: /sys/class/typec/-partner/accessory_mode @@ -220,6 +233,20 @@ Description: directory exists, it will have an attribute file for every VDO in Discover Identity command result. +What: /sys/class/typec/-partner/usb_mode +Date: November 2024 +Contact: Heikki Krogerus +Description: The USB Modes that the partner device supports. The active mode + is displayed in brackets. The active USB mode can be changed by + writing to this file when the port driver is able to send Data + Reset Message to the partner. That requires USB Power Delivery + contract between the partner and the port. + + Valid values: + - usb2 (USB 2.0) + - usb3 (USB 3.2) + - usb4 (USB4) + USB Type-C cable devices (eg. /sys/class/typec/port0-cable/) Note: Electronically Marked Cables will have a device also for one cable plug diff --git a/Documentation/ABI/testing/sysfs-class-watchdog b/Documentation/ABI/testing/sysfs-class-watchdog index 94fb7461595123733b524b7c43ace4c31ab4c339..70eabccf055786c7d300986c83bc162c9b9aff3e 100644 --- a/Documentation/ABI/testing/sysfs-class-watchdog +++ b/Documentation/ABI/testing/sysfs-class-watchdog @@ -76,7 +76,7 @@ Description: timeout when the pretimeout interrupt is delivered. Pretimeout is an optional feature. -What: /sys/class/watchdog/watchdogn/pretimeout_avaialable_governors +What: /sys/class/watchdog/watchdogn/pretimeout_available_governors Date: February 2017 Contact: Wim Van Sebroeck Description: diff --git a/Documentation/admin-guide/LSM/apparmor.rst b/Documentation/admin-guide/LSM/apparmor.rst index 6cf81bbd7ce8b86bfcc740abe4e0bde49e239700..47939ee89d7462830c94eb8f683deeb6b3d44be2 100644 --- a/Documentation/admin-guide/LSM/apparmor.rst +++ b/Documentation/admin-guide/LSM/apparmor.rst @@ -18,8 +18,11 @@ set ``CONFIG_SECURITY_APPARMOR=y`` If AppArmor should be selected as the default security module then set:: - CONFIG_DEFAULT_SECURITY="apparmor" - CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 + CONFIG_DEFAULT_SECURITY_APPARMOR=y + +The CONFIG_LSM parameter manages the order and selection of LSMs. +Specify apparmor as the first "major" module (e.g. AppArmor, SELinux, Smack) +in the list. Build the kernel diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index 65bfab1b1861467358d201619018b1a327de4ad8..77db10e944f039a8920a3e8dd9cfff7757b56f32 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -258,6 +258,8 @@ stable kernels. | Hisilicon | Hip{08,09,10,10C| #162001900 | N/A | | | ,11} SMMU PMCG | | | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/Documentation/arch/x86/boot.rst b/Documentation/arch/x86/boot.rst index 4fd492cb49704fa21fd368fe0832f332e952c83d..ad2d8ddad27fe43119f8f7f389687317e5da6571 100644 --- a/Documentation/arch/x86/boot.rst +++ b/Documentation/arch/x86/boot.rst @@ -896,10 +896,19 @@ Offset/size: 0x260/4 The kernel runtime start address is determined by the following algorithm:: - if (relocatable_kernel) - runtime_start = align_up(load_address, kernel_alignment) - else - runtime_start = pref_address + if (relocatable_kernel) { + if (load_address < pref_address) + load_address = pref_address; + runtime_start = align_up(load_address, kernel_alignment); + } else { + runtime_start = pref_address; + } + +Hence the necessary memory window location and size can be estimated by +a boot loader as:: + + memory_window_start = runtime_start; + memory_window_size = init_size; ============ =============== Field name: handover_offset diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst index 12e4aecdae94522c30929c427410505bef6f3c4b..27a9cccc792c1eb4e72776a8b0e673012f5bfdf5 100644 --- a/Documentation/core-api/symbol-namespaces.rst +++ b/Documentation/core-api/symbol-namespaces.rst @@ -46,7 +46,7 @@ Please note that due to macro expansion that argument needs to be a preprocessor symbol. E.g. to export the symbol ``usb_stor_suspend`` into the namespace ``USB_STORAGE``, use:: - EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); + EXPORT_SYMBOL_NS(usb_stor_suspend, "USB_STORAGE"); The corresponding ksymtab entry struct ``kernel_symbol`` will have the member ``namespace`` set accordingly. A symbol that is exported without a namespace will @@ -68,7 +68,7 @@ is to define the default namespace in the ``Makefile`` of the subsystem. E.g. to export all symbols defined in usb-common into the namespace USB_COMMON, add a line like this to drivers/usb/common/Makefile:: - ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON + ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"USB_COMMON"' That will affect all EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() statements. A symbol exported with EXPORT_SYMBOL_NS() while this definition is present, will @@ -79,7 +79,7 @@ A second option to define the default namespace is directly in the compilation unit as preprocessor statement. The above example would then read:: #undef DEFAULT_SYMBOL_NAMESPACE - #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON + #define DEFAULT_SYMBOL_NAMESPACE "USB_COMMON" within the corresponding compilation unit before any EXPORT_SYMBOL macro is used. @@ -94,7 +94,7 @@ for the namespaces it uses symbols from. E.g. a module using the usb_stor_suspend symbol from above, needs to import the namespace USB_STORAGE using a statement like:: - MODULE_IMPORT_NS(USB_STORAGE); + MODULE_IMPORT_NS("USB_STORAGE"); This will create a ``modinfo`` tag in the module for each imported namespace. This has the side effect, that the imported namespaces of a module can be diff --git a/Documentation/dev-tools/autofdo.rst b/Documentation/dev-tools/autofdo.rst new file mode 100644 index 0000000000000000000000000000000000000000..1f0a451e9ccd329b0930dca6be5b13bfbfb78823 --- /dev/null +++ b/Documentation/dev-tools/autofdo.rst @@ -0,0 +1,168 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=================================== +Using AutoFDO with the Linux kernel +=================================== + +This enables AutoFDO build support for the kernel when using +the Clang compiler. AutoFDO (Auto-Feedback-Directed Optimization) +is a type of profile-guided optimization (PGO) used to enhance the +performance of binary executables. It gathers information about the +frequency of execution of various code paths within a binary using +hardware sampling. This data is then used to guide the compiler's +optimization decisions, resulting in a more efficient binary. AutoFDO +is a powerful optimization technique, and data indicates that it can +significantly improve kernel performance. It's especially beneficial +for workloads affected by front-end stalls. + +For AutoFDO builds, unlike non-FDO builds, the user must supply a +profile. Acquiring an AutoFDO profile can be done in several ways. +AutoFDO profiles are created by converting hardware sampling using +the "perf" tool. It is crucial that the workload used to create these +perf files is representative; they must exhibit runtime +characteristics similar to the workloads that are intended to be +optimized. Failure to do so will result in the compiler optimizing +for the wrong objective. + +The AutoFDO profile often encapsulates the program's behavior. If the +performance-critical codes are architecture-independent, the profile +can be applied across platforms to achieve performance gains. For +instance, using the profile generated on Intel architecture to build +a kernel for AMD architecture can also yield performance improvements. + +There are two methods for acquiring a representative profile: +(1) Sample real workloads using a production environment. +(2) Generate the profile using a representative load test. +When enabling the AutoFDO build configuration without providing an +AutoFDO profile, the compiler only modifies the dwarf information in +the kernel without impacting runtime performance. It's advisable to +use a kernel binary built with the same AutoFDO configuration to +collect the perf profile. While it's possible to use a kernel built +with different options, it may result in inferior performance. + +One can collect profiles using AutoFDO build for the previous kernel. +AutoFDO employs relative line numbers to match the profiles, offering +some tolerance for source changes. This mode is commonly used in a +production environment for profile collection. + +In a profile collection based on a load test, the AutoFDO collection +process consists of the following steps: + +#. Initial build: The kernel is built with AutoFDO options + without a profile. + +#. Profiling: The above kernel is then run with a representative + workload to gather execution frequency data. This data is + collected using hardware sampling, via perf. AutoFDO is most + effective on platforms supporting advanced PMU features like + LBR on Intel machines. + +#. AutoFDO profile generation: Perf output file is converted to + the AutoFDO profile via offline tools. + +The support requires a Clang compiler LLVM 17 or later. + +Preparation +=========== + +Configure the kernel with:: + + CONFIG_AUTOFDO_CLANG=y + +Customization +============= + +The default CONFIG_AUTOFDO_CLANG setting covers kernel space objects for +AutoFDO builds. One can, however, enable or disable AutoFDO build for +individual files and directories by adding a line similar to the following +to the respective kernel Makefile: + +- For enabling a single file (e.g. foo.o) :: + + AUTOFDO_PROFILE_foo.o := y + +- For enabling all files in one directory :: + + AUTOFDO_PROFILE := y + +- For disabling one file :: + + AUTOFDO_PROFILE_foo.o := n + +- For disabling all files in one directory :: + + AUTOFDO_PROFILE := n + +Workflow +======== + +Here is an example workflow for AutoFDO kernel: + +1) Build the kernel on the host machine with LLVM enabled, + for example, :: + + $ make menuconfig LLVM=1 + + Turn on AutoFDO build config:: + + CONFIG_AUTOFDO_CLANG=y + + With a configuration that with LLVM enabled, use the following command:: + + $ scripts/config -e AUTOFDO_CLANG + + After getting the config, build with :: + + $ make LLVM=1 + +2) Install the kernel on the test machine. + +3) Run the load tests. The '-c' option in perf specifies the sample + event period. We suggest using a suitable prime number, like 500009, + for this purpose. + + - For Intel platforms:: + + $ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c -o -- + + - For AMD platforms: + + The supported systems are: Zen3 with BRS, or Zen4 with amd_lbr_v2. To check, + + For Zen3:: + + $ cat proc/cpuinfo | grep " brs" + + For Zen4:: + + $ cat proc/cpuinfo | grep amd_lbr_v2 + + The following command generated the perf data file:: + + $ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c -o -- + +4) (Optional) Download the raw perf file to the host machine. + +5) To generate an AutoFDO profile, two offline tools are available: + create_llvm_prof and llvm_profgen. The create_llvm_prof tool is part + of the AutoFDO project and can be found on GitHub + (https://github.com/google/autofdo), version v0.30.1 or later. + The llvm_profgen tool is included in the LLVM compiler itself. It's + important to note that the version of llvm_profgen doesn't need to match + the version of Clang. It needs to be the LLVM 19 release of Clang + or later, or just from the LLVM trunk. :: + + $ llvm-profgen --kernel --binary= --perfdata= -o + + or :: + + $ create_llvm_prof --binary= --profile= --format=extbinary --out= + + Note that multiple AutoFDO profile files can be merged into one via:: + + $ llvm-profdata merge -o ... + +6) Rebuild the kernel using the AutoFDO profile file with the same config as step 1, + (Note CONFIG_AUTOFDO_CLANG needs to be enabled):: + + $ make LLVM=1 CLANG_AUTOFDO_PROFILE= diff --git a/Documentation/dev-tools/coccinelle.rst b/Documentation/dev-tools/coccinelle.rst index 535ce126fb4fa2da45799aee610bc2aadf77df17..6e70a1e9a3c0e9ac68972a4d22b4bea97fb7fe19 100644 --- a/Documentation/dev-tools/coccinelle.rst +++ b/Documentation/dev-tools/coccinelle.rst @@ -250,25 +250,17 @@ variables for .cocciconfig is as follows: - Your directory from which spatch is called is processed next - The directory provided with the ``--dir`` option is processed last, if used -Since coccicheck runs through make, it naturally runs from the kernel -proper dir; as such the second rule above would be implied for picking up a -.cocciconfig when using ``make coccicheck``. - ``make coccicheck`` also supports using M= targets. If you do not supply any M= target, it is assumed you want to target the entire kernel. The kernel coccicheck script has:: - if [ "$KBUILD_EXTMOD" = "" ] ; then - OPTIONS="--dir $srctree $COCCIINCLUDE" - else - OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" - fi - -KBUILD_EXTMOD is set when an explicit target with M= is used. For both cases -the spatch ``--dir`` argument is used, as such third rule applies when whether -M= is used or not, and when M= is used the target directory can have its own -.cocciconfig file. When M= is not passed as an argument to coccicheck the -target directory is the same as the directory from where spatch was called. + OPTIONS="--dir $srcroot $COCCIINCLUDE" + +Here, $srcroot refers to the source directory of the target: it points to the +external module's source directory when M= used, and otherwise, to the kernel +source directory. The third rule ensures the spatch reads the .cocciconfig from +the target directory, allowing external modules to have their own .cocciconfig +file. If not using the kernel's coccicheck target, keep the above precedence order logic of .cocciconfig reading. If using the kernel's coccicheck target, diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst index 53d4d124f9c52f37a77cfce8c488307321b5a608..3c0ac08b2709119f283ed8ca57c1c42c9f640c36 100644 --- a/Documentation/dev-tools/index.rst +++ b/Documentation/dev-tools/index.rst @@ -34,6 +34,8 @@ Documentation/dev-tools/testing-overview.rst ktap checkuapi gpio-sloppy-logic-analyzer + autofdo + propeller .. only:: subproject and html diff --git a/Documentation/dev-tools/propeller.rst b/Documentation/dev-tools/propeller.rst new file mode 100644 index 0000000000000000000000000000000000000000..92195958e3dbcaff594f1bfb603fc9187cf3bb9c --- /dev/null +++ b/Documentation/dev-tools/propeller.rst @@ -0,0 +1,162 @@ +.. SPDX-License-Identifier: GPL-2.0 + +===================================== +Using Propeller with the Linux kernel +===================================== + +This enables Propeller build support for the kernel when using Clang +compiler. Propeller is a profile-guided optimization (PGO) method used +to optimize binary executables. Like AutoFDO, it utilizes hardware +sampling to gather information about the frequency of execution of +different code paths within a binary. Unlike AutoFDO, this information +is then used right before linking phase to optimize (among others) +block layout within and across functions. + +A few important notes about adopting Propeller optimization: + +#. Although it can be used as a standalone optimization step, it is + strongly recommended to apply Propeller on top of AutoFDO, + AutoFDO+ThinLTO or Instrument FDO. The rest of this document + assumes this paradigm. + +#. Propeller uses another round of profiling on top of + AutoFDO/AutoFDO+ThinLTO/iFDO. The whole build process involves + "build-afdo - train-afdo - build-propeller - train-propeller - + build-optimized". + +#. Propeller requires LLVM 19 release or later for Clang/Clang++ + and the linker(ld.lld). + +#. In addition to LLVM toolchain, Propeller requires a profiling + conversion tool: https://github.com/google/autofdo with a release + after v0.30.1: https://github.com/google/autofdo/releases/tag/v0.30.1. + +The Propeller optimization process involves the following steps: + +#. Initial building: Build the AutoFDO or AutoFDO+ThinLTO binary as + you would normally do, but with a set of compile-time / link-time + flags, so that a special metadata section is created within the + kernel binary. The special section is only intend to be used by the + profiling tool, it is not part of the runtime image, nor does it + change kernel run time text sections. + +#. Profiling: The above kernel is then run with a representative + workload to gather execution frequency data. This data is collected + using hardware sampling, via perf. Propeller is most effective on + platforms supporting advanced PMU features like LBR on Intel + machines. This step is the same as profiling the kernel for AutoFDO + (the exact perf parameters can be different). + +#. Propeller profile generation: Perf output file is converted to a + pair of Propeller profiles via an offline tool. + +#. Optimized build: Build the AutoFDO or AutoFDO+ThinLTO optimized + binary as you would normally do, but with a compile-time / + link-time flag to pick up the Propeller compile time and link time + profiles. This build step uses 3 profiles - the AutoFDO profile, + the Propeller compile-time profile and the Propeller link-time + profile. + +#. Deployment: The optimized kernel binary is deployed and used + in production environments, providing improved performance + and reduced latency. + +Preparation +=========== + +Configure the kernel with:: + + CONFIG_AUTOFDO_CLANG=y + CONFIG_PROPELLER_CLANG=y + +Customization +============= + +The default CONFIG_PROPELLER_CLANG setting covers kernel space objects +for Propeller builds. One can, however, enable or disable Propeller build +for individual files and directories by adding a line similar to the +following to the respective kernel Makefile: + +- For enabling a single file (e.g. foo.o):: + + PROPELLER_PROFILE_foo.o := y + +- For enabling all files in one directory:: + + PROPELLER_PROFILE := y + +- For disabling one file:: + + PROPELLER_PROFILE_foo.o := n + +- For disabling all files in one directory:: + + PROPELLER__PROFILE := n + + +Workflow +======== + +Here is an example workflow for building an AutoFDO+Propeller kernel: + +1) Assuming an AutoFDO profile is already collected following + instructions in the AutoFDO document, build the kernel on the host + machine, with AutoFDO and Propeller build configs :: + + CONFIG_AUTOFDO_CLANG=y + CONFIG_PROPELLER_CLANG=y + + and :: + + $ make LLVM=1 CLANG_AUTOFDO_PROFILE= + +2) Install the kernel on the test machine. + +3) Run the load tests. The '-c' option in perf specifies the sample + event period. We suggest using a suitable prime number, like 500009, + for this purpose. + + - For Intel platforms:: + + $ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c -o -- + + - For AMD platforms:: + + $ perf record --pfm-event RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c -o -- + + Note you can repeat the above steps to collect multiple s. + +4) (Optional) Download the raw perf file(s) to the host machine. + +5) Use the create_llvm_prof tool (https://github.com/google/autofdo) to + generate Propeller profile. :: + + $ create_llvm_prof --binary= --profile= + --format=propeller --propeller_output_module_name + --out=_cc_profile.txt + --propeller_symorder=_ld_profile.txt + + "" can be something like "/home/user/dir/any_string". + + This command generates a pair of Propeller profiles: + "_cc_profile.txt" and + "_ld_profile.txt". + + If there are more than 1 perf_file collected in the previous step, + you can create a temp list file "" with each line + containing one perf file name and run:: + + $ create_llvm_prof --binary= --profile=@ + --format=propeller --propeller_output_module_name + --out=_cc_profile.txt + --propeller_symorder=_ld_profile.txt + +6) Rebuild the kernel using the AutoFDO and Propeller + profiles. :: + + CONFIG_AUTOFDO_CLANG=y + CONFIG_PROPELLER_CLANG=y + + and :: + + $ make LLVM=1 CLANG_AUTOFDO_PROFILE= CLANG_PROPELLER_PROFILE_PREFIX= diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml index fb216ce68bb3579f5646b5eff39ebf524cd26a7e..67700440e23b5b7ca0db2c395c8a455bcf650864 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml @@ -253,6 +253,46 @@ properties: additionalProperties: false + sink-wait-cap-time-ms: + description: Represents the max time in ms that USB Type-C port (in sink + role) should wait for the port partner (source role) to send source caps. + SinkWaitCap timer starts when port in sink role attaches to the source. + This timer will stop when sink receives PD source cap advertisement before + timeout in which case it'll move to capability negotiation stage. A + timeout leads to a hard reset message by the port. + minimum: 310 + maximum: 620 + default: 310 + + ps-source-off-time-ms: + description: Represents the max time in ms that a DRP in source role should + take to turn off power after the PsSourceOff timer starts. PsSourceOff + timer starts when a sink's PHY layer receives EOP of the GoodCRC message + (corresponding to an Accept message sent in response to a PR_Swap or a + FR_Swap request). This timer stops when last bit of GoodCRC EOP + corresponding to the received PS_RDY message is transmitted by the PHY + layer. A timeout shall lead to error recovery in the type-c port. + minimum: 750 + maximum: 920 + default: 920 + + cc-debounce-time-ms: + description: Represents the max time in ms that a port shall wait to + determine if it's attached to a partner. + minimum: 100 + maximum: 200 + default: 200 + + sink-bc12-completion-time-ms: + description: Represents the max time in ms that a port in sink role takes + to complete Battery Charger (BC1.2) Detection. BC1.2 detection is a + hardware mechanism, which in some TCPC implementations, can run in + parallel once the Type-C connection state machine reaches the "potential + connect as sink" state. In TCPCs where this causes delays to respond to + the incoming PD messages, sink-bc12-completion-time-ms is used to delay + PD negotiation till BC1.2 detection completes. + default: 0 + dependencies: sink-vdos-v1: [ sink-vdos ] sink-vdos: [ sink-vdos-v1 ] @@ -380,7 +420,7 @@ examples: }; # USB-C connector attached to a typec port controller(ptn5110), which has - # power delivery support and enables drp. + # power delivery support, explicitly defines time properties and enables drp. - | #include typec: ptn5110 { @@ -393,6 +433,10 @@ examples: sink-pdos = ; op-sink-microwatt = <10000000>; + sink-wait-cap-time-ms = <465>; + ps-source-off-time-ms = <835>; + cc-debounce-time-ms = <101>; + sink-bc12-completion-time-ms = <500>; }; }; diff --git a/Documentation/devicetree/bindings/iio/adc/adc.yaml b/Documentation/devicetree/bindings/iio/adc/adc.yaml index 8e7835cf36fd23b5a779ee34e7fe43db6c096171..b9bc02b5b07a4c7d9bf86825a7fb551a8c43097d 100644 --- a/Documentation/devicetree/bindings/iio/adc/adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adc.yaml @@ -37,6 +37,10 @@ properties: to both the positive and negative inputs of a differential ADC. The first value specifies the positive input pin, the second specifies the negative input pin. + There are also some ADCs, where the differential channel has dedicated + positive and negative inputs which can be used to measure differential + voltage levels. For those setups, this property can be configured with + the 'reg' property for both inputs (i.e. diff-channels = ). single-channel: $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml index 17c5d39cc2c17d7f4a093bc9420794d701613731..ad15cf9bc2ffd162d14930342b560000f9c412d1 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml @@ -28,6 +28,7 @@ description: | Datasheets for supported chips: https://www.analog.com/media/en/technical-documentation/data-sheets/AD4111.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD4112.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/AD4114.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD4115.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD4116.pdf @@ -44,6 +45,7 @@ properties: enum: - adi,ad4111 - adi,ad4112 + - adi,ad4113 - adi,ad4114 - adi,ad4115 - adi,ad4116 @@ -331,6 +333,7 @@ allOf: enum: - adi,ad4111 - adi,ad4112 + - adi,ad4113 - adi,ad4114 - adi,ad4115 - adi,ad4116 diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml index 0065d650882489e21b952bb9fb25f1e3a070ee68..ada08005b3cd1ce7ba13f96484a33fdee0e83a1c 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml @@ -25,6 +25,8 @@ description: | * https://www.analog.com/en/products/ad7386-4.html * https://www.analog.com/en/products/ad7387-4.html * https://www.analog.com/en/products/ad7388-4.html + * https://www.analog.com/en/products/adaq4370-4.html + * https://www.analog.com/en/products/adaq4380-4.html $ref: /schemas/spi/spi-peripheral-props.yaml# @@ -46,6 +48,8 @@ properties: - adi,ad7386-4 - adi,ad7387-4 - adi,ad7388-4 + - adi,adaq4370-4 + - adi,adaq4380-4 reg: maxItems: 1 @@ -70,6 +74,20 @@ properties: refin-supply: description: A 2.5V to 3.3V supply for external reference voltage, for ad7380-4 only. + For adaq devices, a 5V supply voltage. A 3.3V internal reference is + derived from it. Connect to vs-p-supply for normal operation. + + vs-p-supply: + description: + Amplifiers positive supply. + + vs-n-supply: + description: + Amplifiers negative supply. + + ldo-supply: + description: + LDO supply. Connect to vs-p-supply or a 3.6 to 5.5 V supply. aina-supply: description: @@ -97,12 +115,45 @@ properties: specify the ALERT interrupt. maxItems: 1 + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + required: - compatible - reg - vcc-supply - vlogic-supply +patternProperties: + "^channel@[0-3]$": + $ref: adc.yaml + type: object + + properties: + reg: + description: + The channel number. From 0 to 3 corresponding to channels A,B,C,D + minimum: 0 + maximum: 3 + + adi,gain-milli: + description: + The hardware gain applied to the ADC input (in milli units). + If not present, default to 1000 (no actual gain applied). + Refer to the typical connection diagrams section of the datasheet for + pin wiring. + $ref: /schemas/types.yaml#/definitions/uint16 + enum: [300, 600, 1000, 1600] + default: 1000 + + required: + - reg + + additionalProperties: false + unevaluatedProperties: false allOf: @@ -140,6 +191,7 @@ allOf: aind-supply: false # ad7380-4 uses refin-supply as external reference. + # adaq devices use internal reference only, derived from refin-supply # All other chips from ad738x family use refio as optional external reference. # When refio-supply is omitted, internal reference is used. - if: @@ -147,6 +199,8 @@ allOf: compatible: enum: - adi,ad7380-4 + - adi,adaq4370-4 + - adi,adaq4380-4 then: properties: refio-supply: false @@ -156,6 +210,27 @@ allOf: properties: refin-supply: false + # adaq devices need more supplies and using channel to declare gain property + # only applies to adaq devices + - if: + properties: + compatible: + enum: + - adi,adaq4370-4 + - adi,adaq4380-4 + then: + required: + - vs-p-supply + - vs-n-supply + - ldo-supply + else: + properties: + vs-p-supply: false + vs-n-supply: false + ldo-supply: false + patternProperties: + "^channel@[0-3]$": false + examples: - | #include @@ -180,3 +255,48 @@ examples: refio-supply = <&supply_2_5V>; }; }; + + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,adaq4380-4"; + reg = <0>; + + spi-cpol; + spi-cpha; + spi-max-frequency = <80000000>; + + interrupts = <27 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent = <&gpio0>; + + vcc-supply = <&supply_3_3V>; + vlogic-supply = <&supply_3_3V>; + refin-supply = <&supply_5V>; + vs-p-supply = <&supply_5V>; + vs-n-supply = <&supply_0V>; + ldo-supply = <&supply_5V>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + adi,gain-milli = /bits/ 16 <300>; + }; + + channel@2 { + reg = <2>; + adi,gain-milli = /bits/ 16 <600>; + }; + + channel@3 { + reg = <3>; + adi,gain-milli = /bits/ 16 <1000>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml index 69408cae3db9603b27c7c4d1b93f548d5a9dd40c..ab5881d0d017f565cf79cfc4a2f2f8c8ba84dc76 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml @@ -14,6 +14,11 @@ description: | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7605-4.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/ad7606_7606-6_7606-4.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD7606B.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7606c-16.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7606c-18.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7607.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7608.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7609.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD7616.pdf properties: @@ -24,11 +29,27 @@ properties: - adi,ad7606-6 - adi,ad7606-8 # Referred to as AD7606 (without -8) in the datasheet - adi,ad7606b + - adi,ad7606c-16 + - adi,ad7606c-18 + - adi,ad7607 + - adi,ad7608 + - adi,ad7609 - adi,ad7616 reg: maxItems: 1 + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + # According to the datasheet, "Data is clocked in from SDI on the falling + # edge of SCLK, while data is clocked out on DOUTA on the rising edge of + # SCLK". Also, even if not stated textually in the datasheet, it is made + # clear on the diagrams that sclk idles at high. Subsequently, in case SPI + # interface is used, the correct way is to only set spi-cpol. spi-cpha: true spi-cpol: true @@ -114,18 +135,91 @@ properties: assumed that the pins are hardwired to VDD. type: boolean + pwms: + description: + In case the conversion is triggered by a PWM instead of a GPIO plugged to + the CONVST pin, the PWM must be referenced. + The first is the PWM connected to CONVST or CONVST1 for the chips with the + 2nd PWM connected to CONVST2, if CONVST2 is available and not shorted to + CONVST1. + minItems: 1 + maxItems: 2 + + pwm-names: + items: + - const: convst1 + - const: convst2 + + io-backends: + description: + A reference to the iio-backend, which is responsible handling the BUSY + pin's falling edge and communication. + An example of backend can be found at + http://analogdevicesinc.github.io/hdl/library/axi_ad7606x/index.html + + +patternProperties: + "^channel@[1-8]$": + type: object + $ref: adc.yaml + unevaluatedProperties: false + + properties: + reg: + description: + The channel number, as specified in the datasheet (from 1 to 8). + minimum: 1 + maximum: 8 + + diff-channels: + description: + Each channel can be configured as a bipolar differential channel. + The ADC uses the same positive and negative inputs for this. + This property must be specified as 'reg' (or the channel number) for + both positive and negative inputs (i.e. diff-channels = ). + Since the configuration is bipolar differential, the 'bipolar' + property is required. + items: + minimum: 1 + maximum: 8 + + bipolar: + description: + The ADC channels can be configured as + * Bipolar single-ended + * Unipolar single-ended + * Bipolar differential + Therefore in the DT, if no channel node is specified, it is considered + 'unipolar single-ended'. So for the other configurations the 'bipolar' + property must be specified. If 'diff-channels' is specified, it is + considered a bipolar differential channel. Otherwise it is bipolar + single-ended. + + required: + - reg + - bipolar + required: - compatible - reg - - spi-cpha - avcc-supply - vdrive-supply - - interrupts - - adi,conversion-start-gpios allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# + - oneOf: + - required: + - adi,conversion-start-gpios + - required: + - pwms + + - oneOf: + - required: + - interrupts + - required: + - io-backends + - if: properties: compatible: @@ -162,17 +256,66 @@ allOf: - adi,ad7606-4 - adi,ad7606-6 - adi,ad7606-8 + - adi,ad7607 + - adi,ad7608 + - adi,ad7609 then: properties: adi,sw-mode: false else: properties: + pwms: + maxItems: 1 + pwm-names: + maxItems: 1 adi,conversion-start-gpios: maxItems: 1 + - if: + not: + required: + - adi,sw-mode + then: + patternProperties: + "^channel@[1-8]$": false + + - if: + not: + properties: + compatible: + enum: + - adi,ad7606c-16 + - adi,ad7606c-18 + then: + patternProperties: + "^channel@[1-8]$": false + unevaluatedProperties: false examples: + - | + #include + iio-backend { + #address-cells = <1>; + #size-cells = <0>; + adi_adc@0 { + compatible = "adi,ad7606b"; + reg = <0>; + pwms = <&axi_pwm_gen 0 0>; + + avcc-supply = <&adc_vref>; + vdrive-supply = <&vdd_supply>; + + reset-gpios = <&gpio0 91 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpio0 90 GPIO_ACTIVE_LOW>; + adi,range-gpios = <&gpio0 89 GPIO_ACTIVE_HIGH>; + adi,oversampling-ratio-gpios = <&gpio0 88 GPIO_ACTIVE_HIGH + &gpio0 87 GPIO_ACTIVE_HIGH + &gpio0 86 GPIO_ACTIVE_HIGH>; + io-backends = <&iio_backend>; + }; + }; + - | #include #include @@ -185,7 +328,6 @@ examples: reg = <0>; spi-max-frequency = <1000000>; spi-cpol; - spi-cpha; avcc-supply = <&adc_vref>; vdrive-supply = <&vdd_supply>; @@ -202,4 +344,53 @@ examples: standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>; }; }; + - | + #include + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad7606c-18"; + reg = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + spi-max-frequency = <1000000>; + spi-cpol; + + avcc-supply = <&adc_vref>; + vdrive-supply = <&vdd_supply>; + + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent = <&gpio>; + + adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; + adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>; + + adi,sw-mode; + + channel@1 { + reg = <1>; + diff-channels = <1 1>; + bipolar; + }; + + channel@3 { + reg = <3>; + bipolar; + }; + + channel@8 { + reg = <8>; + diff-channels = <8 8>; + bipolar; + }; + + }; + }; ... diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7625.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7625.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8848562af28f20fe9cfb1484fd664bd89bc776f1 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7625.yaml @@ -0,0 +1,176 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7625.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices Fast PulSAR Analog to Digital Converters + +maintainers: + - Michael Hennerich + - Nuno Sá + +description: | + A family of single channel differential analog to digital converters. + + * https://www.analog.com/en/products/ad7625.html + * https://www.analog.com/en/products/ad7626.html + * https://www.analog.com/en/products/ad7960.html + * https://www.analog.com/en/products/ad7961.html + +properties: + compatible: + enum: + - adi,ad7625 + - adi,ad7626 + - adi,ad7960 + - adi,ad7961 + + vdd1-supply: true + vdd2-supply: true + vio-supply: true + + ref-supply: + description: + Voltage regulator for the external reference voltage (REF). + + refin-supply: + description: + Voltage regulator for the reference buffer input (REFIN). + + clocks: + description: + The clock connected to the CLK pins, gated by the clk_gate PWM. + maxItems: 1 + + pwms: + items: + - description: PWM connected to the CNV input on the ADC. + - description: PWM that gates the clock connected to the ADC's CLK input. + + pwm-names: + items: + - const: cnv + - const: clk_gate + + io-backends: + description: + The AXI ADC IP block connected to the D+/- and DCO+/- lines of the + ADC. An example backend can be found at + http://analogdevicesinc.github.io/hdl/projects/pulsar_lvds/index.html. + maxItems: 1 + + adi,no-dco: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicates the wiring of the DCO+/- lines. If true, then they are + grounded and the device is in self-clocked mode. If this is not + present, then the device is in echoed clock mode. + + adi,en0-always-on: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicates if EN0 is hard-wired to the high state. If neither this + nor en0-gpios are present, then EN0 is hard-wired low. + + adi,en1-always-on: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicates if EN1 is hard-wired to the high state. If neither this + nor en1-gpios are present, then EN1 is hard-wired low. + + adi,en2-always-on: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicates if EN2 is hard-wired to the high state. If neither this + nor en2-gpios are present, then EN2 is hard-wired low. + + adi,en3-always-on: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicates if EN3 is hard-wired to the high state. If neither this + nor en3-gpios are present, then EN3 is hard-wired low. + + en0-gpios: + description: + Configurable EN0 pin. + + en1-gpios: + description: + Configurable EN1 pin. + + en2-gpios: + description: + Configurable EN2 pin. + + en3-gpios: + description: + Configurable EN3 pin. + +required: + - compatible + - vdd1-supply + - vdd2-supply + - vio-supply + - clocks + - pwms + - pwm-names + - io-backends + +allOf: + - if: + required: + - ref-supply + then: + properties: + refin-supply: false + - if: + required: + - refin-supply + then: + properties: + ref-supply: false + - if: + properties: + compatible: + contains: + enum: + - adi,ad7625 + - adi,ad7626 + then: + properties: + en2-gpios: false + en3-gpios: false + adi,en2-always-on: false + adi,en3-always-on: false + + - if: + properties: + compatible: + contains: + enum: + - adi,ad7960 + - adi,ad7961 + then: + # ad796x parts must have one of the two supplies + oneOf: + - required: [ref-supply] + - required: [refin-supply] + +additionalProperties: false + +examples: + - | + #include + adc { + compatible = "adi,ad7625"; + vdd1-supply = <&supply_5V>; + vdd2-supply = <&supply_2_5V>; + vio-supply = <&supply_2_5V>; + io-backends = <&axi_adc>; + clocks = <&ref_clk>; + pwms = <&axi_pwm_gen 0 0>, <&axi_pwm_gen 1 0>; + pwm-names = "cnv", "clk_gate"; + en0-gpios = <&gpio0 86 GPIO_ACTIVE_HIGH>; + en1-gpios = <&gpio0 87 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7779.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7779.yaml new file mode 100644 index 0000000000000000000000000000000000000000..044f92f39cfa767ef89a5e0a6ae396486836e010 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7779.yaml @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7779.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD777X family 8-Channel, 24-Bit, Simultaneous Sampling ADCs + +maintainers: + - Ramona Nechita + +description: | + The AD777X family consist of 8-channel, simultaneous sampling analog-to- + digital converter (ADC). Eight full Σ-Δ ADCs are on-chip. The + AD7771 provides an ultralow input current to allow direct sensor + connection. Each input channel has a programmable gain stage + allowing gains of 1, 2, 4, and 8 to map lower amplitude sensor + outputs into the full-scale ADC input range, maximizing the + dynamic range of the signal chain. + + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7770.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7771.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7779.pdf + +$ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + enum: + - adi,ad7770 + - adi,ad7771 + - adi,ad7779 + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + clocks: + maxItems: 1 + + avdd1-supply: + description: Front-End analog supply AVDD1. Can be used as conversion ref. + + avdd2-supply: + description: AVDD2 Analog Supply from 2.2 V to 3.6 V. + + avdd4-supply: + description: AVDD4 SAR Analog Supply and Reference Source. + + interrupts: + minItems: 1 + items: + - description: | + adc_rdy: Interrupt line for DRDY signal which indicates the end of + conversion independently of the interface selected to read back the + Σ-∆ conversion. + - description: | + Alert: The chip includes self diagnostic features to guarantee the + correct operation. If an error is detected, the ALERT pin is pulled + high to generate an external interruption to the controller. + + interrupt-names: + minItems: 1 + maxItems: 2 + items: + enum: + - adc_rdy + - alert + + start-gpios: + description: + Pin that controls start synchronization pulse. + maxItems: 1 + + reset-gpios: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - interrupts + +unevaluatedProperties: false + +examples: + - | + #include + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad7779"; + reg = <0>; + start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>; + interrupt-parent = <&intc>; + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "adc_rdy"; + clocks = <&adc_clk>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml index f748f3a60b35289de1769068e602acb3e96c8015..b0962a4583ac716edc0cd4e15bbbc6a331efd1a0 100644 --- a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml @@ -98,6 +98,7 @@ allOf: compatible: contains: enum: + - amlogic,meson8-saradc - amlogic,meson8b-saradc - amlogic,meson8m2-saradc then: diff --git a/Documentation/devicetree/bindings/iio/adc/gehc,pmc-adc.yaml b/Documentation/devicetree/bindings/iio/adc/gehc,pmc-adc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2cea7c104a269c652375db0d66a60d002aba9af1 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/gehc,pmc-adc.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/gehc,pmc-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: GE HealthCare PMC Analog to Digital Converter (ADC) + +maintainers: + - Herve Codina + +description: + The GE HealthCare PMC ADC is a 16-Channel (voltage and current), 16-Bit ADC + with an I2C Interface. + +properties: + compatible: + const: gehc,pmc-adc + + reg: + maxItems: 1 + + vdd-supply: + description: + Regulator for the VDD power supply. + + vdda-supply: + description: + Regulator for the VDD analog (VDDA) power supply. + + vddio-supply: + description: + Regulator for the VDD IO (VDDIO) power supply. + + vref-supply: + description: + Regulator for the voltage reference power supply. + + clocks: + maxItems: 1 + description: + The component uses an external oscillator (osc) if an external oscillator + is connected to its clock pins. Otherwise, it uses an internal reference + clock. + + clock-names: + items: + - const: osc + + "#io-channel-cells": + const: 2 + description: | + The first cell is the channel type (dt-bindings/iio/adc/gehc,pmc-adc.h + defines these values): + - 0: voltage + - 1: current + The second cell is the channel number from 0 to 15. + +required: + - compatible + - reg + - vdd-supply + - vdda-supply + - vddio-supply + - vref-supply + - '#io-channel-cells' + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@14 { + compatible = "gehc,pmc-adc"; + reg = <0x14>; + vdd-supply = <®_vdd>; + vdda-supply = <®_vdda>; + vddio-supply = <®_vddio>; + vref-supply = <®_vref>; + #io-channel-cells = <2>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml index fc8b97f820775b8563675543508eb55001da3989..2d2561a526838db1a02be625b4a431dfc13e9f73 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml @@ -30,7 +30,7 @@ properties: maxItems: 1 spi-max-frequency: - maximum: 30000000 + maximum: 66000000 reset-gpios: maxItems: 1 @@ -60,6 +60,12 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1, 2, 3] + io-backends: + description: The iio backend reference. + Device can be optionally connected to the "axi-ad3552r IP" fpga-based + QSPI + DDR (Double Data Rate) controller to reach high speed transfers. + maxItems: 1 + '#address-cells': const: 1 @@ -128,6 +134,7 @@ patternProperties: - custom-output-range-config allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml index c81285d84db7a206d0633995072053ea208c0f55..79cb4b78a88a97c812e32d2f225556c1aafbbbf0 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml @@ -26,16 +26,47 @@ properties: vdd-supply: true vss-supply: true + vcc-supply: + description: + Supply that powers the chip. + + iovcc-supply: + description: + Supply for the digital interface. + + vrefp-supply: + description: + Positive referance input voltage range. From 5v to (vdd - 2.5) + + vrefn-supply: + description: + Negative referance input voltage range. From (vss + 2.5) to 0. + adi,rbuf-gain2-en: description: Specify to allow an external amplifier to be connected in a gain of two configuration. type: boolean + reset-gpios: + maxItems: 1 + + clear-gpios: + maxItems: 1 + + ldac-gpios: + description: + LDAC pin to be used as a hardware trigger to update the DAC channels. + maxItems: 1 + required: - compatible - reg - vdd-supply - vss-supply + - vcc-supply + - iovcc-supply + - vrefp-supply + - vrefn-supply allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# @@ -44,6 +75,7 @@ unevaluatedProperties: false examples: - | + #include spi { #address-cells = <1>; #size-cells = <0>; @@ -53,6 +85,13 @@ examples: reg = <0>; vss-supply = <&dac_vss>; vdd-supply = <&dac_vdd>; + vcc-supply = <&dac_vcc>; + iovcc-supply = <&dac_iovcc>; + vrefp-supply = <&dac_vrefp>; + vrefn-supply = <&dac_vrefn>; + reset-gpios = <&gpio_bd 16 GPIO_ACTIVE_LOW>; + clear-gpios = <&gpio_bd 17 GPIO_ACTIVE_LOW>; + ldac-gpios = <&gpio_bd 18 GPIO_ACTIVE_HIGH>; }; }; ... diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad8460.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad8460.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b65928024e12febf4f84c117dc9feb9807d0cbee --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad8460.yaml @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2024 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/dac/adi,ad8460.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD8460 DAC + +maintainers: + - Mariel Tinaco + +description: | + Analog Devices AD8460 110 V High Voltage, 1 A High Current, + Arbitrary Waveform Generator with Integrated 14-Bit High Speed DAC + https://www.analog.com/media/en/technical-documentation/data-sheets/ad8460.pdf + +properties: + compatible: + enum: + - adi,ad8460 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + dmas: + maxItems: 1 + + dma-names: + items: + - const: tx + + spi-max-frequency: + maximum: 20000000 + + hvcc-supply: + description: Positive high voltage power supply line + + hvee-supply: + description: Negative high voltage power supply line + + vcc-5v-supply: + description: Low voltage power supply + + vref-5v-supply: + description: Reference voltage for analog low voltage + + dvdd-3p3v-supply: + description: Digital supply bypass + + avdd-3p3v-supply: + description: Analog supply bypass + + refio-1p2v-supply: + description: Drive voltage in the range of 1.2V maximum to as low as + low as 0.12V through the REF_IO pin to adjust full scale output span + + adi,external-resistor-ohms: + description: Specify value of external resistor connected to FS_ADJ pin + to establish internal HVDAC's reference current I_REF + minimum: 2000 + maximum: 20000 + default: 2000 + + adi,range-microvolt: + description: Voltage output range specified as + items: + - minimum: -55000000 + maximum: 0 + default: 0 + - minimum: 0 + maximum: 55000000 + default: 0 + + adi,range-microamp: + description: Current output range specified as + items: + - minimum: -1000000 + maximum: 0 + default: 0 + - minimum: 0 + maximum: 1000000 + default: 0 + + adi,max-millicelsius: + description: Overtemperature threshold + minimum: 0 + maximum: 150000 + default: 0 + + shutdown-reset-gpios: + description: Corresponds to SDN_RESET pin. To exit shutdown + or sleep mode, pulse SDN_RESET HIGH, then leave LOW. + maxItems: 1 + + reset-gpios: + description: Manual Power On Reset (POR). Pull this GPIO pin + LOW and then HIGH to reset all digital registers to default + maxItems: 1 + + shutdown-gpios: + description: Corresponds to SDN_IO pin. Shutdown may be + initiated by the user, by pulsing SDN_IO high. To exit shutdown, + pulse SDN_IO low, then float. + maxItems: 1 + +required: + - compatible + - reg + - clocks + - hvcc-supply + - hvee-supply + - vcc-5v-supply + - vref-5v-supply + - dvdd-3p3v-supply + - avdd-3p3v-supply + - refio-1p2v-supply + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + dac@0 { + compatible = "adi,ad8460"; + reg = <0>; + spi-max-frequency = <8000000>; + + dmas = <&tx_dma 0>; + dma-names = "tx"; + + shutdown-reset-gpios = <&gpio 86 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 91 GPIO_ACTIVE_LOW>; + shutdown-gpios = <&gpio 88 GPIO_ACTIVE_HIGH>; + + clocks = <&sync_ext_clk>; + + hvcc-supply = <&hvcc>; + hvee-supply = <&hvee>; + vcc-5v-supply = <&vcc_5>; + vref-5v-supply = <&vref_5>; + dvdd-3p3v-supply = <&dvdd_3_3>; + avdd-3p3v-supply = <&avdd_3_3>; + refio-1p2v-supply = <&refio_1_2>; + + adi,external-resistor-ohms = <2000>; + adi,range-microvolt = <(-40000000) 40000000>; + adi,range-microamp = <0 50000>; + adi,max-millicelsius = <50000>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml index a55e9bfc66d746f064c11dc6d823d78470703a1b..1adba9aceeb1130f45f48198ee8c5f4121bbf17c 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml @@ -19,11 +19,13 @@ description: | memory via DMA into the DAC. https://wiki.analog.com/resources/fpga/docs/axi_dac_ip + https://analogdevicesinc.github.io/hdl/library/axi_ad3552r/index.html properties: compatible: enum: - adi,axi-dac-9.1.b + - adi,axi-ad3552r reg: maxItems: 1 @@ -36,7 +38,14 @@ properties: - const: tx clocks: - maxItems: 1 + minItems: 1 + maxItems: 2 + + clock-names: + items: + - const: s_axi_aclk + - const: dac_clk + minItems: 1 '#io-backend-cells': const: 0 @@ -47,7 +56,29 @@ required: - reg - clocks -additionalProperties: false +allOf: + - if: + properties: + compatible: + contains: + const: adi,axi-ad3552r + then: + $ref: /schemas/spi/spi-controller.yaml# + properties: + clocks: + minItems: 2 + clock-names: + minItems: 2 + required: + - clock-names + else: + properties: + clocks: + maxItems: 1 + clock-names: + maxItems: 1 + +unevaluatedProperties: false examples: - | @@ -57,6 +88,38 @@ examples: dmas = <&tx_dma 0>; dma-names = "tx"; #io-backend-cells = <0>; - clocks = <&axi_clk>; + clocks = <&clkc 15>; + clock-names = "s_axi_aclk"; + }; + + - | + #include + axi_dac: spi@44a70000 { + compatible = "adi,axi-ad3552r"; + reg = <0x44a70000 0x1000>; + dmas = <&dac_tx_dma 0>; + dma-names = "tx"; + #io-backend-cells = <0>; + clocks = <&clkc 15>, <&ref_clk>; + clock-names = "s_axi_aclk", "dac_clk"; + + #address-cells = <1>; + #size-cells = <0>; + + dac@0 { + compatible = "adi,ad3552r"; + reg = <0>; + reset-gpios = <&gpio0 92 GPIO_ACTIVE_HIGH>; + io-backends = <&axi_dac>; + spi-max-frequency = <20000000>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + adi,output-range-microvolt = <(-10000000) (10000000)>; + }; + }; }; ... diff --git a/Documentation/devicetree/bindings/iio/imu/bosch,bmi270.yaml b/Documentation/devicetree/bindings/iio/imu/bosch,bmi270.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7b0cde1c9b0a418c7bf3cda01411a00067c58a2c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/bosch,bmi270.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/bosch,bmi270.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bosch BMI270 6-Axis IMU + +maintainers: + - Alex Lanzano + +description: | + BMI270 is a 6-axis inertial measurement unit that can measure acceleration and + angular velocity. The sensor also supports configurable interrupt events such + as motion, step counter, and wrist motion gestures. The sensor can communicate + I2C or SPI. + https://www.bosch-sensortec.com/products/motion-sensors/imus/bmi270/ + +properties: + compatible: + enum: + - bosch,bmi260 + - bosch,bmi270 + + reg: + maxItems: 1 + + vdd-supply: true + vddio-supply: true + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + maxItems: 2 + items: + enum: + - INT1 + - INT2 + + drive-open-drain: + description: + set if the specified interrupt pins should be configured as + open drain. If not set, defaults to push-pull. + + mount-matrix: + description: + an optional 3x3 mounting rotation matrix. + +required: + - compatible + - reg + - vdd-supply + - vddio-supply + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + imu@68 { + compatible = "bosch,bmi270"; + reg = <0x68>; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + interrupt-parent = <&gpio1>; + interrupts = <16 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "INT1"; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/imu/bosch,smi240.yaml b/Documentation/devicetree/bindings/iio/imu/bosch,smi240.yaml new file mode 100644 index 0000000000000000000000000000000000000000..58f1411728f63c5e6e01a0bf3f74743cc72c5141 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/bosch,smi240.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/bosch,smi240.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bosch smi240 imu + +maintainers: + - Jianping Shen + +description: + Inertial Measurement Unit with Accelerometer and Gyroscope + with a measurement range of +/-300°/s and up to 16g. + https://www.bosch-semiconductors.com/mems-sensors/highly-automated-driving/smi240/ + +properties: + compatible: + const: bosch,smi240 + + reg: + maxItems: 1 + + vdd-supply: true + vddio-supply: true + +required: + - compatible + - reg + - vdd-supply + - vddio-supply + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + imu@0 { + compatible = "bosch,smi240"; + reg = <0>; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + spi-max-frequency = <10000000>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml index 3769f8e8e98cee3db61cc0138f485c488d55a63e..7e4492bbd0278a336587dc5ac04da7153453da29 100644 --- a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: InvenSense ICM-426xx Inertial Measurement Unit maintainers: - - Jean-Baptiste Maneyrol + - Jean-Baptiste Maneyrol description: | 6-axis MotionTracking device that combines a 3-axis gyroscope and a 3-axis diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml index 587ff2bced2ddd42e767f72b8e84c334d0e90481..f91954870a44c60cadc76b5bc3917ee6f23e30a2 100644 --- a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml +++ b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: InvenSense MPU-6050 Six-Axis (Gyro + Accelerometer) MEMS MotionTracking Device maintainers: - - Jean-Baptiste Maneyrol + - Jean-Baptiste Maneyrol description: | These devices support both I2C and SPI bus interfaces. @@ -36,6 +36,11 @@ properties: - items: - const: invensense,icm20608d - const: invensense,icm20608 + - items: + - enum: + - invensense,iam20680hp + - invensense,iam20680ht + - const: invensense,iam20680 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/light/ti,opt3001.yaml b/Documentation/devicetree/bindings/iio/light/ti,opt3001.yaml index 441e9343fc975f6a6255562c514843d81d960b87..67ca8d08256a52c42cdec65a6eac6df87d594cdb 100644 --- a/Documentation/devicetree/bindings/iio/light/ti,opt3001.yaml +++ b/Documentation/devicetree/bindings/iio/light/ti,opt3001.yaml @@ -15,7 +15,9 @@ description: | properties: compatible: - const: ti,opt3001 + enum: + - ti,opt3001 + - ti,opt3002 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/light/veml6030.yaml b/Documentation/devicetree/bindings/iio/light/veml6030.yaml deleted file mode 100644 index fb19a2d7a849708a6a89a6a69768ca3683b0f8d2..0000000000000000000000000000000000000000 --- a/Documentation/devicetree/bindings/iio/light/veml6030.yaml +++ /dev/null @@ -1,64 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/iio/light/veml6030.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: VEML6030 Ambient Light Sensor (ALS) - -maintainers: - - Rishi Gupta - -description: | - Bindings for the ambient light sensor veml6030 from Vishay - Semiconductors over an i2c interface. - - Irrespective of whether interrupt is used or not, application - can get the ALS and White channel reading from IIO raw interface. - - If the interrupts are used, application will receive an IIO event - whenever configured threshold is crossed. - - Specifications about the sensor can be found at: - https://www.vishay.com/docs/84366/veml6030.pdf - -properties: - compatible: - enum: - - vishay,veml6030 - - reg: - description: - I2C address of the device. - enum: - - 0x10 # ADDR pin pulled down - - 0x48 # ADDR pin pulled up - - interrupts: - description: - interrupt mapping for IRQ. Configure with IRQ_TYPE_LEVEL_LOW. - Refer to interrupt-controller/interrupts.txt for generic - interrupt client node bindings. - maxItems: 1 - -required: - - compatible - - reg - -additionalProperties: false - -examples: - - | - #include - - i2c { - #address-cells = <1>; - #size-cells = <0>; - - light-sensor@10 { - compatible = "vishay,veml6030"; - reg = <0x10>; - interrupts = <12 IRQ_TYPE_LEVEL_LOW>; - }; - }; -... diff --git a/Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml b/Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4ea69f1fdd63aea263c0c8c1b310ebdf075af015 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: GPL-2.0+ +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/light/vishay,veml6030.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: VEML3235, VEML6030, VEML6035 and VEML7700 Ambient Light Sensors (ALS) + +maintainers: + - Rishi Gupta + +description: | + Bindings for the ambient light sensors veml6030 and veml6035 from + Vishay Semiconductors over an i2c interface. + + Irrespective of whether interrupt is used or not, application + can get the ALS and White channel reading from IIO raw interface. + + If the interrupts are used, application will receive an IIO event + whenever configured threshold is crossed. + + Specifications about the sensors can be found at: + https://www.vishay.com/docs/80131/veml3235.pdf + https://www.vishay.com/docs/84366/veml6030.pdf + https://www.vishay.com/docs/84889/veml6035.pdf + https://www.vishay.com/docs/84286/veml7700.pdf + +properties: + compatible: + enum: + - vishay,veml3235 + - vishay,veml6030 + - vishay,veml6035 + - vishay,veml7700 + + reg: + maxItems: 1 + + interrupts: + description: + interrupt mapping for IRQ. Configure with IRQ_TYPE_LEVEL_LOW. + Refer to interrupt-controller/interrupts.txt for generic + interrupt client node bindings. + maxItems: 1 + + vdd-supply: true + +required: + - compatible + - reg + - vdd-supply + +allOf: + - if: + properties: + compatible: + enum: + - vishay,veml6030 + then: + properties: + reg: + enum: + - 0x10 # ADDR pin pulled down + - 0x48 # ADDR pin pulled up + + - if: + properties: + compatible: + enum: + - vishay,veml6035 + then: + properties: + reg: + enum: + - 0x29 + + - if: + properties: + compatible: + enum: + - vishay,veml3235 + - vishay,veml7700 + then: + properties: + reg: + enum: + - 0x10 + interrupts: false + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + light-sensor@10 { + compatible = "vishay,veml6030"; + reg = <0x10>; + interrupts = <12 IRQ_TYPE_LEVEL_LOW>; + vdd-supply = <&vdd>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml b/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml index ecf2339e02f65c0649914334a7e4936993a195e3..d2effccbfb563f4e332e64b84fea8e1c96b52d22 100644 --- a/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml +++ b/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/iio/light/vishay,veml6075.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Vishay VEML6075 UVA/B and VEML6040 RGBW sensors +title: Vishay VEML6070 UVA, VEML6075 UVA/B and VEML6040 RGBW sensors maintainers: - Javier Carrasco @@ -16,11 +16,19 @@ properties: compatible: enum: - vishay,veml6040 + - vishay,veml6070 - vishay,veml6075 reg: maxItems: 1 + vishay,rset-ohms: + description: + Resistor used to select the integration time. + default: 270000 + minimum: 75000 + maximum: 1200000 + vdd-supply: true required: @@ -28,6 +36,17 @@ required: - reg - vdd-supply +allOf: + - if: + properties: + compatible: + enum: + - vishay,veml6040 + - vishay,veml6075 + then: + properties: + vishay,rset-ohms: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/iio/magnetometer/allegromicro,als31300.yaml b/Documentation/devicetree/bindings/iio/magnetometer/allegromicro,als31300.yaml new file mode 100644 index 0000000000000000000000000000000000000000..52e3781834ee9d98aa84c5d340ae75ffbf76f925 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/magnetometer/allegromicro,als31300.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/magnetometer/allegromicro,als31300.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Allegro MicroSystems ALS31300 3-D Linear Hall Effect sensor + +maintainers: + - Neil Armstrong + +properties: + $nodename: + pattern: '^magnetometer@[0-9a-f]+$' + + compatible: + enum: + - allegromicro,als31300-500 # Factory configured at 500 Gauss input range + - allegromicro,als31300-1000 # Factory configured at 1000 Gauss input range + - allegromicro,als31300-2000 # Factory configured at 2000 Gauss input range + + reg: + maxItems: 1 + + vcc-supply: + description: 5.5V supply + + interrupts: + maxItems: 1 + +required: + - compatible + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + magnetometer@61 { + compatible = "allegromicro,als31300-500"; + reg = <0x61>; + vcc-supply = <&hall_vcc>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml b/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml index 6fda887ee9d42e79cbc35c8571eca2e9d6715df8..cb201cecfa1a3e1d813ba242006543ae94c72e7d 100644 --- a/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml @@ -47,15 +47,33 @@ properties: maxItems: 1 interrupts: - description: - interrupt mapping for IRQ (BMP085 only) maxItems: 1 + drive-open-drain: + description: + set if the interrupt pin should be configured as open drain. + If not set, defaults to push-pull configuration. + type: boolean + required: - compatible - vddd-supply - vdda-supply +allOf: + - if: + properties: + compatible: + not: + contains: + enum: + - bosch,bmp085 + - bosch,bmp380 + - bosch,bmp580 + then: + properties: + interrupts: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/iio/temperature/ti,tmp006.yaml b/Documentation/devicetree/bindings/iio/temperature/ti,tmp006.yaml index d43002b9bfdc0239772b735bd560ace8ad9d94c3..590f50ba3a3150baa781b71f874f55c8cd225d36 100644 --- a/Documentation/devicetree/bindings/iio/temperature/ti,tmp006.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/ti,tmp006.yaml @@ -23,6 +23,9 @@ properties: vdd-supply: description: provide VDD power to the sensor. + interrupts: + maxItems: 1 + required: - compatible - reg @@ -31,6 +34,7 @@ additionalProperties: false examples: - | + #include i2c { #address-cells = <1>; #size-cells = <0>; @@ -38,5 +42,7 @@ examples: compatible = "ti,tmp006"; reg = <0x40>; vdd-supply = <&ldo4_reg>; + interrupt-parent = <&gpio1>; + interrupts = <4 IRQ_TYPE_EDGE_FALLING>; }; }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml index 189f5900ee50d6e7ed742893e78de9cb2930c67b..251410aabf38be28003ccb93c0ee1aa94c742d1b 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -26,6 +26,7 @@ properties: - items: - enum: - qcom,qcm2290-cpu-bwmon + - qcom,qcs8300-cpu-bwmon - qcom,sa8775p-cpu-bwmon - qcom,sc7180-cpu-bwmon - qcom,sc7280-cpu-bwmon @@ -40,6 +41,7 @@ properties: - const: qcom,sdm845-bwmon # BWMON v4, unified register space - items: - enum: + - qcom,qcs8300-llcc-bwmon - qcom,sa8775p-llcc-bwmon - qcom,sc7180-llcc-bwmon - qcom,sc8280xp-llcc-bwmon diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9d762b2a1fcf87b638a0b9060e7b90579e329cef --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,qcs615-rpmh.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm RPMh Network-On-Chip Interconnect on QCS615 + +maintainers: + - Raviteja Laggyshetty + +description: | + RPMh interconnect providers support system bandwidth requirements through + RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is + able to communicate with the BCM through the Resource State Coordinator (RSC) + associated with each execution environment. Provider nodes must point to at + least one RPMh device child node pertaining to their RSC and each provider + can map to multiple RPMh resources. + + See also: include/dt-bindings/interconnect/qcom,qcs615-rpmh.h + +properties: + compatible: + enum: + - qcom,qcs615-aggre1-noc + - qcom,qcs615-camnoc-virt + - qcom,qcs615-config-noc + - qcom,qcs615-dc-noc + - qcom,qcs615-gem-noc + - qcom,qcs615-ipa-virt + - qcom,qcs615-mc-virt + - qcom,qcs615-mmss-noc + - qcom,qcs615-system-noc + + reg: + maxItems: 1 + +required: + - compatible + +allOf: + - $ref: qcom,rpmh-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,qcs615-camnoc-virt + - qcom,qcs615-ipa-virt + - qcom,qcs615-mc-virt + then: + properties: + reg: false + else: + required: + - reg + +unevaluatedProperties: false + +examples: + - | + gem_noc: interconnect@9680000 { + compatible = "qcom,qcs615-gem-noc"; + reg = <0x9680000 0x3e200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect-2 { + compatible = "qcom,qcs615-mc-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e9f528d6d9a8cbfa12d3bbf52cada8c188f9c340 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,qcs8300-rpmh.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm RPMh Network-On-Chip Interconnect on QCS8300 + +maintainers: + - Raviteja Laggyshetty + +description: | + RPMh interconnect providers support system bandwidth requirements through + RPMh hardware accelerators known as Bus Clock Manager (BCM). + + See also: include/dt-bindings/interconnect/qcom,qcs8300-rpmh.h + +properties: + compatible: + enum: + - qcom,qcs8300-aggre1-noc + - qcom,qcs8300-aggre2-noc + - qcom,qcs8300-clk-virt + - qcom,qcs8300-config-noc + - qcom,qcs8300-dc-noc + - qcom,qcs8300-gem-noc + - qcom,qcs8300-gpdsp-anoc + - qcom,qcs8300-lpass-ag-noc + - qcom,qcs8300-mc-virt + - qcom,qcs8300-mmss-noc + - qcom,qcs8300-nspa-noc + - qcom,qcs8300-pcie-anoc + - qcom,qcs8300-system-noc + + reg: + maxItems: 1 + +required: + - compatible + +allOf: + - $ref: qcom,rpmh-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,qcs8300-clk-virt + - qcom,qcs8300-mc-virt + then: + properties: + reg: false + else: + required: + - reg + +unevaluatedProperties: false + +examples: + - | + gem_noc: interconnect@9100000 { + compatible = "qcom,qcs8300-gem-noc"; + reg = <0x9100000 0xf7080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + clk_virt: interconnect-0 { + compatible = "qcom,qcs8300-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sar2130p-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sar2130p-rpmh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4647dac740e9b8bf308470255ba92066fb2903c0 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sar2130p-rpmh.yaml @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,sar2130p-rpmh.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm RPMh Network-On-Chip Interconnect on SAR2130P + +maintainers: + - Dmitry Baryshkov + - Georgi Djakov + +description: | + RPMh interconnect providers support system bandwidth requirements through + RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is + able to communicate with the BCM through the Resource State Coordinator (RSC) + associated with each execution environment. Provider nodes must point to at + least one RPMh device child node pertaining to their RSC and each provider + can map to multiple RPMh resources. + + See also:: include/dt-bindings/interconnect/qcom,sar2130p-rpmh.h + +properties: + compatible: + enum: + - qcom,sar2130p-clk-virt + - qcom,sar2130p-config-noc + - qcom,sar2130p-gem-noc + - qcom,sar2130p-lpass-ag-noc + - qcom,sar2130p-mc-virt + - qcom,sar2130p-mmss-noc + - qcom,sar2130p-nsp-noc + - qcom,sar2130p-pcie-anoc + - qcom,sar2130p-system-noc + + reg: + maxItems: 1 + + clocks: + minItems: 1 + maxItems: 2 + +required: + - compatible + +allOf: + - $ref: qcom,rpmh-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,sar2130p-clk-virt + - qcom,sar2130p-mc-virt + then: + properties: + reg: false + else: + required: + - reg + + - if: + properties: + compatible: + contains: + enum: + - qcom,sar2130p-pcie-anoc + then: + properties: + clocks: + items: + - description: aggre-NOC PCIe AXI clock + - description: cfg-NOC PCIe a-NOC AHB clock + + - if: + properties: + compatible: + contains: + enum: + - qcom,sar2130p-system-noc + then: + properties: + clocks: + items: + - description: aggre USB3 PRIM AXI clock + + - if: + properties: + compatible: + contains: + enum: + - qcom,sar2130p-system-noc + - qcom,sar2130p-pcie-anoc + then: + required: + - clocks + else: + properties: + clocks: false + +unevaluatedProperties: false + +examples: + - | + clk_virt: interconnect-0 { + compatible = "qcom,sar2130p-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre1_noc: interconnect@1680000 { + compatible = "qcom,sar2130p-system-noc"; + reg = <0x01680000 0x29080>; + #interconnect-cells = <2>; + clocks = <&gcc_prim_axi_clk>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; diff --git a/Documentation/devicetree/bindings/fuse/renesas,rcar-efuse.yaml b/Documentation/devicetree/bindings/nvmem/renesas,rcar-efuse.yaml similarity index 54% rename from Documentation/devicetree/bindings/fuse/renesas,rcar-efuse.yaml rename to Documentation/devicetree/bindings/nvmem/renesas,rcar-efuse.yaml index d7e289244e72cce1e4e1d57dbc00a22bf3685bc6..ce7d65afa46025373a18167729505ca179fd84b4 100644 --- a/Documentation/devicetree/bindings/fuse/renesas,rcar-efuse.yaml +++ b/Documentation/devicetree/bindings/nvmem/renesas,rcar-efuse.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/fuse/renesas,rcar-efuse.yaml# +$id: http://devicetree.org/schemas/nvmem/renesas,rcar-efuse.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: R-Car E-FUSE connected to PFC @@ -13,6 +13,9 @@ description: The E-FUSE is a type of non-volatile memory, which is accessible through the Pin Function Controller (PFC) on some R-Car Gen4 SoCs. +allOf: + - $ref: nvmem.yaml# + properties: compatible: enum: @@ -39,17 +42,27 @@ required: - power-domains - resets -additionalProperties: false +unevaluatedProperties: false examples: - | - #include - #include - - fuse: fuse@e6078800 { - compatible = "renesas,r8a779a0-efuse"; - reg = <0xe6078800 0x100>; - clocks = <&cpg CPG_MOD 916>; - power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; - resets = <&cpg 916>; + #include + #include + + fuse@e6078800 { + compatible = "renesas,r8a779f0-efuse"; + reg = <0xe6078800 0x200>; + clocks = <&cpg CPG_MOD 915>; + power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>; + resets = <&cpg 915>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + calib@144 { + reg = <0x144 0x08>; + }; + }; }; diff --git a/Documentation/devicetree/bindings/fuse/renesas,rcar-otp.yaml b/Documentation/devicetree/bindings/nvmem/renesas,rcar-otp.yaml similarity index 60% rename from Documentation/devicetree/bindings/fuse/renesas,rcar-otp.yaml rename to Documentation/devicetree/bindings/nvmem/renesas,rcar-otp.yaml index d74872ae9ff378f9d59587ed6fe1bfb6a4f67782..3313c03ea68dfd57766ffedaf152f432c4a2dabc 100644 --- a/Documentation/devicetree/bindings/fuse/renesas,rcar-otp.yaml +++ b/Documentation/devicetree/bindings/nvmem/renesas,rcar-otp.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/fuse/renesas,rcar-otp.yaml# +$id: http://devicetree.org/schemas/nvmem/renesas,rcar-otp.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: R-Car E-FUSE connected to OTP_MEM @@ -13,6 +13,9 @@ description: The E-FUSE is a type of non-volatile memory, which is accessible through the One-Time Programmable Memory (OTP_MEM) module on some R-Car Gen4 SoCs. +allOf: + - $ref: nvmem.yaml# + properties: compatible: enum: @@ -22,17 +25,19 @@ properties: reg: items: - description: OTP_MEM_0 - - description: OTP_MEM_1 + - description: OTP_MEM_1. + The addresses of cells defined under the optional nvmem-layout + subnode are relative to this register bank. required: - compatible - reg -additionalProperties: false +unevaluatedProperties: false examples: - | - otp: otp@e61be000 { - compatible = "renesas,r8a779g0-otp"; - reg = <0xe61be000 0x1000>, <0xe61bf000 0x1000>; + otp@e61be000 { + compatible = "renesas,r8a779g0-otp"; + reg = <0xe61be000 0x1000>, <0xe61bf000 0x1000>; }; diff --git a/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt b/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt deleted file mode 100644 index 586c08286aa9afeb7f1a882ddf85942b39860bac..0000000000000000000000000000000000000000 --- a/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt +++ /dev/null @@ -1,52 +0,0 @@ -= Spreadtrum SC27XX PMIC eFuse device tree bindings = - -Required properties: -- compatible: Should be one of the following. - "sprd,sc2720-efuse" - "sprd,sc2721-efuse" - "sprd,sc2723-efuse" - "sprd,sc2730-efuse" - "sprd,sc2731-efuse" -- reg: Specify the address offset of efuse controller. -- hwlocks: Reference to a phandle of a hwlock provider node. - -= Data cells = -Are child nodes of eFuse, bindings of which as described in -bindings/nvmem/nvmem.txt - -Example: - - sc2731_pmic: pmic@0 { - compatible = "sprd,sc2731"; - reg = <0>; - spi-max-frequency = <26000000>; - interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; - #address-cells = <1>; - #size-cells = <0>; - - efuse@380 { - compatible = "sprd,sc2731-efuse"; - reg = <0x380>; - #address-cells = <1>; - #size-cells = <1>; - hwlocks = <&hwlock 12>; - - /* Data cells */ - thermal_calib: calib@10 { - reg = <0x10 0x2>; - }; - }; - }; - -= Data consumers = -Are device nodes which consume nvmem data cells. - -Example: - - thermal { - ... - nvmem-cells = <&thermal_calib>; - nvmem-cell-names = "calibration"; - }; diff --git a/Documentation/devicetree/bindings/nvmem/sprd,sc2731-efuse.yaml b/Documentation/devicetree/bindings/nvmem/sprd,sc2731-efuse.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dc25fe3d1841f5d72620cce16dfbee6d0ba9877a --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/sprd,sc2731-efuse.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/sprd,sc2731-efuse.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spreadtrum SC27XX PMIC eFuse + +maintainers: + - Orson Zhai + - Baolin Wang + - Chunyan Zhang + +properties: + compatible: + enum: + - sprd,sc2720-efuse + - sprd,sc2721-efuse + - sprd,sc2723-efuse + - sprd,sc2730-efuse + - sprd,sc2731-efuse + + reg: + maxItems: 1 + + hwlocks: + maxItems: 1 + +required: + - compatible + - reg + - hwlocks + +allOf: + - $ref: nvmem.yaml# + - $ref: nvmem-deprecated-cells.yaml# + +unevaluatedProperties: false + +examples: + - | + pmic { + #address-cells = <1>; + #size-cells = <0>; + + efuse@380 { + compatible = "sprd,sc2731-efuse"; + reg = <0x380>; + hwlocks = <&hwlock 12>; + #address-cells = <1>; + #size-cells = <1>; + + /* Data cells */ + fgu_calib: calib@6 { + reg = <0x6 0x2>; + bits = <0 9>; + }; + + adc_big_scale: calib@24 { + reg = <0x24 0x2>; + }; + + adc_small_scale: calib@26 { + reg = <0x26 0x2>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/nvmem/sprd,ums312-efuse.yaml b/Documentation/devicetree/bindings/nvmem/sprd,ums312-efuse.yaml new file mode 100644 index 0000000000000000000000000000000000000000..00e0fd1353a3f7dca6c66b167ee782ca14ce43b1 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/sprd,ums312-efuse.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/sprd,ums312-efuse.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spreadtrum UMS312 eFuse + +maintainers: + - Orson Zhai + - Baolin Wang + - Chunyan Zhang + +properties: + compatible: + const: sprd,ums312-efuse + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: enable + + hwlocks: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - hwlocks + +allOf: + - $ref: nvmem.yaml# + - $ref: nvmem-deprecated-cells.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + + efuse@32240000 { + compatible = "sprd,ums312-efuse"; + reg = <0x32240000 0x10000>; + clocks = <&aonapb_gate CLK_EFUSE_EB>; + clock-names = "enable"; + hwlocks = <&hwlock 8>; + #address-cells = <1>; + #size-cells = <1>; + + /* Data cells */ + thermal_calib: calib@10 { + reg = <0x10 0x2>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/nvmem/sprd-efuse.txt b/Documentation/devicetree/bindings/nvmem/sprd-efuse.txt deleted file mode 100644 index 96b6feec27f0b28834a3195bf31f2c50d9ace993..0000000000000000000000000000000000000000 --- a/Documentation/devicetree/bindings/nvmem/sprd-efuse.txt +++ /dev/null @@ -1,39 +0,0 @@ -= Spreadtrum eFuse device tree bindings = - -Required properties: -- compatible: Should be "sprd,ums312-efuse". -- reg: Specify the address offset of efuse controller. -- clock-names: Should be "enable". -- clocks: The phandle and specifier referencing the controller's clock. -- hwlocks: Reference to a phandle of a hwlock provider node. - -= Data cells = -Are child nodes of eFuse, bindings of which as described in -bindings/nvmem/nvmem.txt - -Example: - - ap_efuse: efuse@32240000 { - compatible = "sprd,ums312-efuse"; - reg = <0 0x32240000 0 0x10000>; - clock-names = "enable"; - hwlocks = <&hwlock 8>; - clocks = <&aonapb_gate CLK_EFUSE_EB>; - - /* Data cells */ - thermal_calib: calib@10 { - reg = <0x10 0x2>; - }; - }; - -= Data consumers = -Are device nodes which consume nvmem data cells. - -Example: - - thermal { - ... - - nvmem-cells = <&thermal_calib>; - nvmem-cell-names = "calibration"; - }; diff --git a/Documentation/devicetree/bindings/nvmem/zii,rave-sp-eeprom.txt b/Documentation/devicetree/bindings/nvmem/zii,rave-sp-eeprom.txt deleted file mode 100644 index 0df79d9e07ec22f50ef7c6641afea3ba6c311aa0..0000000000000000000000000000000000000000 --- a/Documentation/devicetree/bindings/nvmem/zii,rave-sp-eeprom.txt +++ /dev/null @@ -1,40 +0,0 @@ -Zodiac Inflight Innovations RAVE EEPROM Bindings - -RAVE SP EEPROM device is a "MFD cell" device exposing physical EEPROM -attached to RAVE Supervisory Processor. It is expected that its Device -Tree node is specified as a child of the node corresponding to the -parent RAVE SP device (as documented in -Documentation/devicetree/bindings/mfd/zii,rave-sp.txt) - -Required properties: - -- compatible: Should be "zii,rave-sp-eeprom" - -Optional properties: - -- zii,eeprom-name: Unique EEPROM identifier describing its function in the - system. Will be used as created NVMEM deivce's name. - -Data cells: - -Data cells are child nodes of eerpom node, bindings for which are -documented in Documentation/devicetree/bindings/nvmem/nvmem.txt - -Example: - - rave-sp { - compatible = "zii,rave-sp-rdu1"; - current-speed = <38400>; - - eeprom@a4 { - compatible = "zii,rave-sp-eeprom"; - reg = <0xa4 0x4000>; - #address-cells = <1>; - #size-cells = <1>; - zii,eeprom-name = "main-eeprom"; - - wdt_timeout: wdt-timeout@81 { - reg = <0x81 2>; - }; - }; - } diff --git a/Documentation/devicetree/bindings/nvmem/zii,rave-sp-eeprom.yaml b/Documentation/devicetree/bindings/nvmem/zii,rave-sp-eeprom.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d073c51c2b9a99888b023b4df732cd7cea6a0077 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/zii,rave-sp-eeprom.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/zii,rave-sp-eeprom.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Zodiac Inflight Innovations RAVE EEPROM + +maintainers: + - Frank Li + +description: + RAVE SP EEPROM device is a "MFD cell" device exposing physical EEPROM + attached to RAVE Supervisory Processor. It is expected that its Device + Tree node is specified as a child of the node corresponding to the + parent RAVE SP device (as documented in + Documentation/devicetree/bindings/mfd/zii,rave-sp.yaml) + +properties: + compatible: + const: zii,rave-sp-eeprom + + reg: + maxItems: 1 + + zii,eeprom-name: + $ref: /schemas/types.yaml#/definitions/string + description: + Unique EEPROM identifier describing its function in the + system. Will be used as created NVMEM deivce's name. + +required: + - compatible + +allOf: + - $ref: nvmem.yaml# + - $ref: nvmem-deprecated-cells.yaml# + +unevaluatedProperties: false + +examples: + - | + eeprom@a4 { + compatible = "zii,rave-sp-eeprom"; + reg = <0xa4 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + zii,eeprom-name = "main-eeprom"; + + wdt-timeout@81 { + reg = <0x81 2>; + }; + }; + diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml index dc3a3f709feaa693a05dc69fa718facada78461b..6d6d211883aee2fbd02f8afa65f75ac0b9f61377 100644 --- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml @@ -11,12 +11,17 @@ maintainers: properties: compatible: - enum: - - fsl,imx8mq-usb-phy - - fsl,imx8mp-usb-phy + oneOf: + - enum: + - fsl,imx8mq-usb-phy + - fsl,imx8mp-usb-phy + - items: + - const: fsl,imx95-usb-phy + - const: fsl,imx8mp-usb-phy reg: - maxItems: 1 + minItems: 1 + maxItems: 2 "#phy-cells": const: 0 @@ -89,7 +94,34 @@ required: - clocks - clock-names -additionalProperties: false +allOf: + - if: + properties: + compatible: + contains: + enum: + - fsl,imx95-usb-phy + then: + properties: + reg: + items: + - description: USB PHY Control range + - description: USB PHY TCA Block range + else: + properties: + reg: + maxItems: 1 + + - if: + properties: + compatible: + contains: + enum: + - fsl,imx95-usb-phy + then: + $ref: /schemas/usb/usb-switch.yaml# + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml index f1f4e4f83352d787b156bd4e2dd879be52005c57..1636285fbe535c430fdf792b33a5e9c523de323b 100644 --- a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml @@ -18,6 +18,7 @@ properties: enum: - qcom,msm8998-qmp-usb3-phy - qcom,qcm2290-qmp-usb3-phy + - qcom,qcs615-qmp-usb3-phy - qcom,sdm660-qmp-usb3-phy - qcom,sm6115-qmp-usb3-phy @@ -96,6 +97,7 @@ allOf: contains: enum: - qcom,msm8998-qmp-usb3-phy + - qcom,qcs615-qmp-usb3-phy - qcom,sdm660-qmp-usb3-phy then: properties: diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml index 95eecbaef05c0e410308a6c3ca2b360a8167a93c..4aed4b5d65ec5a3e8f95cbd1eac6f6dd4603ff5b 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml @@ -25,6 +25,7 @@ properties: - qcom,msm8996-qusb2-phy - qcom,msm8998-qusb2-phy - qcom,qcm2290-qusb2-phy + - qcom,qcs615-qusb2-phy - qcom,sdm660-qusb2-phy - qcom,sm4250-qusb2-phy - qcom,sm6115-qusb2-phy diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml index af7e5237b2c03085611daad9e1e39aa93cc8ae95..9c7dd7e75e0ca35f76eb666cdacfc297a7570958 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -171,6 +171,34 @@ properties: ratified at commit 3f9ed34 ("Add ability to manually trigger workflow. (#2)") of riscv-time-compare. + - const: svade + description: | + The standard Svade supervisor-level extension for SW-managed PTE A/D + bit updates as ratified in the 20240213 version of the privileged + ISA specification. + + Both Svade and Svadu extensions control the hardware behavior when + the PTE A/D bits need to be set. The default behavior for the four + possible combinations of these extensions in the device tree are: + 1) Neither Svade nor Svadu present in DT => It is technically + unknown whether the platform uses Svade or Svadu. Supervisor + software should be prepared to handle either hardware updating + of the PTE A/D bits or page faults when they need updated. + 2) Only Svade present in DT => Supervisor must assume Svade to be + always enabled. + 3) Only Svadu present in DT => Supervisor must assume Svadu to be + always enabled. + 4) Both Svade and Svadu present in DT => Supervisor must assume + Svadu turned-off at boot time. To use Svadu, supervisor must + explicitly enable it using the SBI FWFT extension. + + - const: svadu + description: | + The standard Svadu supervisor-level extension for hardware updating + of PTE A/D bits as ratified in the 20240528 version of the + privileged ISA specification. Please refer to Svade dt-binding + description for more details. + - const: svinval description: The standard Svinval supervisor-level extension for fine-grained diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml index 4531eec568a6578b19a85594e9ebb8458825bb47..9df5cdb6f63f2b8b9d8841c5acd6e9bbc351a9fb 100644 --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml @@ -30,7 +30,9 @@ properties: - const: allwinner,sun50i-a64-rtc - const: allwinner,sun8i-h3-rtc - items: - - const: allwinner,sun20i-d1-rtc + - enum: + - allwinner,sun20i-d1-rtc + - allwinner,sun55i-a523-rtc - const: allwinner,sun50i-r329-rtc reg: diff --git a/Documentation/devicetree/bindings/rtc/amlogic,a4-rtc.yaml b/Documentation/devicetree/bindings/rtc/amlogic,a4-rtc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5d3ac737abcbafc9fa81ce80e32e1f9973b6b9dc --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/amlogic,a4-rtc.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2024 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/amlogic,a4-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic A4 and A5 RTC + +maintainers: + - Yiting Deng + - Xianwei Zhao + +allOf: + - $ref: rtc.yaml# + +properties: + compatible: + enum: + - amlogic,a4-rtc + - amlogic,a5-rtc + + reg: + maxItems: 1 + + clocks: + items: + - description: RTC clock source, available 24M or 32K crystal + oscillator source. when using 24M, need to divide 24M into 32K. + - description: RTC module accesses the clock of the apb bus. + + clock-names: + items: + - const: osc + - const: sys + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + +additionalProperties: false + +examples: + - | + #include + apb { + #address-cells = <2>; + #size-cells = <2>; + + rtc@8e600 { + compatible = "amlogic,a4-rtc"; + reg = <0x0 0x8e600 0x0 0x38>; + clocks = <&xtal_32k>, <&clkc_periphs 1>; + clock-names = "osc", "sys"; + interrupts = ; + }; + }; diff --git a/Documentation/devicetree/bindings/rtc/microchip,mfps-rtc.yaml b/Documentation/devicetree/bindings/rtc/microchip,mpfs-rtc.yaml similarity index 87% rename from Documentation/devicetree/bindings/rtc/microchip,mfps-rtc.yaml rename to Documentation/devicetree/bindings/rtc/microchip,mpfs-rtc.yaml index 7742465b938398d7636b1de186f9954d777d3d90..a3e60d9f83993c2d1fb8388a0c4dc7ea0fbd773e 100644 --- a/Documentation/devicetree/bindings/rtc/microchip,mfps-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/microchip,mpfs-rtc.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/rtc/microchip,mfps-rtc.yaml# +$id: http://devicetree.org/schemas/rtc/microchip,mpfs-rtc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# @@ -12,12 +12,14 @@ allOf: maintainers: - Daire McNamara - - Lewis Hanly properties: compatible: - enum: - - microchip,mpfs-rtc + oneOf: + - items: + - const: microchip,pic64gx-rtc + - const: microchip,mpfs-rtc + - const: microchip,mpfs-rtc reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e70eeb66aa648ba90f4550e4d22de9e683142783 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/renesas,rz-rtca3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RTCA-3 Real Time Clock + +maintainers: + - Claudiu Beznea + +allOf: + - $ref: rtc.yaml# + +properties: + compatible: + items: + - enum: + - renesas,r9a08g045-rtca3 # RZ/G3S + - const: renesas,rz-rtca3 + + reg: + maxItems: 1 + + interrupts: + items: + - description: Alarm interrupt + - description: Periodic interrupt + - description: Carry interrupt + + interrupt-names: + items: + - const: alarm + - const: period + - const: carry + + clocks: + items: + - description: RTC bus clock + - description: RTC counter clock + + clock-names: + items: + - const: bus + - const: counter + + power-domains: + maxItems: 1 + + resets: + items: + - description: VBATTB module reset + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + - clock-names + - power-domains + - resets + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + rtc@1004ec00 { + compatible = "renesas,r9a08g045-rtca3", "renesas,rz-rtca3"; + reg = <0x1004ec00 0x400>; + interrupts = , + , + ; + interrupt-names = "alarm", "period", "carry"; + clocks = <&cpg CPG_MOD R9A08G045_VBAT_BCLK>, <&vbattclk VBATTB_VBATTCLK>; + clock-names = "bus", "counter"; + power-domains = <&cpg>; + resets = <&cpg R9A08G045_VBAT_BRESETN>; + }; diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml index 9418fd66a8e95a94066720be9e5f28c32b6e0665..b93254ad2a287ad496f791e3ee90eb9defa0609d 100644 --- a/Documentation/devicetree/bindings/serial/rs485.yaml +++ b/Documentation/devicetree/bindings/serial/rs485.yaml @@ -18,16 +18,15 @@ properties: description: prop-encoded-array $ref: /schemas/types.yaml#/definitions/uint32-array items: - items: - - description: Delay between rts signal and beginning of data sent in - milliseconds. It corresponds to the delay before sending data. - default: 0 - maximum: 100 - - description: Delay between end of data sent and rts signal in milliseconds. - It corresponds to the delay after sending data and actual release - of the line. - default: 0 - maximum: 100 + - description: Delay between rts signal and beginning of data sent in + milliseconds. It corresponds to the delay before sending data. + default: 0 + maximum: 100 + - description: Delay between end of data sent and rts signal in milliseconds. + It corresponds to the delay after sending data and actual release + of the line. + default: 0 + maximum: 100 rs485-rts-active-high: description: drive RTS high when sending (this is the default). diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml index 788c80e47831cb1db6a54b1c875387278b77064a..070eba9f19d3e039090c58a82f93d02eed58ab84 100644 --- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml +++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml @@ -27,6 +27,7 @@ properties: - samsung,exynos4210-uart - samsung,exynos5433-uart - samsung,exynos850-uart + - samsung,exynos8895-uart - items: - enum: - samsung,exynos7-uart @@ -160,18 +161,27 @@ allOf: contains: enum: - google,gs101-uart + - samsung,exynos8895-uart then: required: - samsung,uart-fifosize properties: - reg-io-width: false - clocks: maxItems: 2 clock-names: maxItems: 2 + - if: + properties: + compatible: + contains: + enum: + - google,gs101-uart + then: + properties: + reg-io-width: false + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml index 4cdb0dcaccf38886d161319c2489209d05b2718c..1c163cb5dff10576be417a0372d2f315d6284297 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml @@ -37,6 +37,8 @@ properties: - const: renesas,rzn1-uart - items: - enum: + - brcm,bcm11351-dw-apb-uart + - brcm,bcm21664-dw-apb-uart - rockchip,px30-uart - rockchip,rk1808-uart - rockchip,rk3036-uart @@ -48,18 +50,13 @@ properties: - rockchip,rk3328-uart - rockchip,rk3368-uart - rockchip,rk3399-uart + - rockchip,rk3528-uart - rockchip,rk3568-uart + - rockchip,rk3576-uart - rockchip,rk3588-uart - rockchip,rv1108-uart - rockchip,rv1126-uart - - const: snps,dw-apb-uart - - items: - - enum: - - brcm,bcm11351-dw-apb-uart - - brcm,bcm21664-dw-apb-uart - - const: snps,dw-apb-uart - - items: - - enum: + - sophgo,sg2044-uart - starfive,jh7100-hsuart - starfive,jh7100-uart - starfive,jh7110-uart diff --git a/Documentation/devicetree/bindings/serial/sprd-uart.yaml b/Documentation/devicetree/bindings/serial/sprd-uart.yaml index f4dbb6dc2b6ef2e1954f9268eca32ab49014c037..a2a5056eba048ebe9b9eaf2366a7c5fe9150a1c9 100644 --- a/Documentation/devicetree/bindings/serial/sprd-uart.yaml +++ b/Documentation/devicetree/bindings/serial/sprd-uart.yaml @@ -17,6 +17,7 @@ properties: oneOf: - items: - enum: + - sprd,sc9632-uart - sprd,sc9860-uart - sprd,sc9863a-uart - sprd,ums512-uart diff --git a/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml index ac99883a3f295ba6e8831a1af3463e261f7c1618..7f0be0ac644aa31d6c2a6be5981347473579ff70 100644 --- a/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml +++ b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml @@ -25,6 +25,7 @@ properties: - items: - enum: - mediatek,mt8186-spmi + - mediatek,mt8188-spmi - const: mediatek,mt8195-spmi reg: diff --git a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml index a28b70fb330a3a9831a24c0c5f5ab3251c184df2..7c3cc20a80d6cf8fe7c4614032cc4df6d8b54973 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml @@ -19,7 +19,11 @@ description: | properties: compatible: - const: qcom,x1e80100-spmi-pmic-arb + oneOf: + - items: + - const: qcom,sar2130p-spmi-pmic-arb + - const: qcom,x1e80100-spmi-pmic-arb + - const: qcom,x1e80100-spmi-pmic-arb reg: items: diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml index bb5010dcefe187ce7f0c4fd4674bbc3463b6ad59..7ffcd236d7bb45057b91a4daeeb83460601887a2 100644 --- a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml +++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.yaml @@ -25,6 +25,7 @@ properties: - allwinner,sun20i-d1-musb - allwinner,sun50i-a100-musb - allwinner,sun50i-h6-musb + - allwinner,sun55i-a523-musb - const: allwinner,sun8i-a33-musb - items: - const: allwinner,sun50i-h616-musb diff --git a/Documentation/devicetree/bindings/usb/cypress,cypd4226.yaml b/Documentation/devicetree/bindings/usb/cypress,cypd4226.yaml index 89fc9a434d05f413ea62c374c10c23f1df313b8a..0620d82508c17588e7e741711ecd4f97c3f6b673 100644 --- a/Documentation/devicetree/bindings/usb/cypress,cypd4226.yaml +++ b/Documentation/devicetree/bindings/usb/cypress,cypd4226.yaml @@ -61,18 +61,15 @@ additionalProperties: false examples: - | - #include #include i2c { #address-cells = <1>; #size-cells = <0>; - #interrupt-cells = <2>; typec@8 { compatible = "cypress,cypd4226"; reg = <0x08>; - interrupt-parent = <&gpio_aon>; - interrupts = ; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; firmware-name = "nvidia,jetson-agx-xavier"; #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml index 9ea1e4cd0709c9c0c349bf675170f8cf89353f75..baf130669c3877efb29aa0eaee237bf33004ba77 100644 --- a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml @@ -12,7 +12,11 @@ maintainers: properties: compatible: - const: fsl,imx8mp-dwc3 + oneOf: + - items: + - const: fsl,imx95-dwc3 + - const: fsl,imx8mp-dwc3 + - const: fsl,imx8mp-dwc3 reg: items: diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml index 0d797e01fc0b4419521fbbc1dd42e36000cfd97a..223f2abd5e592ff8cc3ad97f9a325356ea57044a 100644 --- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml @@ -32,6 +32,7 @@ properties: - allwinner,sun50i-a64-ehci - allwinner,sun50i-h6-ehci - allwinner,sun50i-h616-ehci + - allwinner,sun55i-a523-ehci - allwinner,sun5i-a13-ehci - allwinner,sun6i-a31-ehci - allwinner,sun7i-a20-ehci diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml index cf33764553fa7f095c2e28313594d9e0956025b6..3ee1586fc8b96866e0a96ea36a15d5a8d88bf8d8 100644 --- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml @@ -19,6 +19,7 @@ properties: - allwinner,sun50i-a64-ohci - allwinner,sun50i-h6-ohci - allwinner,sun50i-h616-ohci + - allwinner,sun55i-a523-ohci - allwinner,sun5i-a13-ohci - allwinner,sun6i-a31-ohci - allwinner,sun7i-a20-ohci diff --git a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml index fc833363cfb4925828ccfd7c136001ec15b7bf59..6fe2d356dcbdec20dd47e09c36174e1f0244e642 100644 --- a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml +++ b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml @@ -62,7 +62,14 @@ allOf: peer-hub: true vdd-supply: true -additionalProperties: false +patternProperties: + "^.*@[0-9a-f]{1,2}$": + description: The hard wired USB devices + type: object + $ref: /schemas/usb/usb-device.yaml + additionalProperties: true + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/usb/maxim,max33359.yaml b/Documentation/devicetree/bindings/usb/maxim,max33359.yaml index 276bf7554215e6ec8a71cb46faedf48d7b13087e..20b62228371bdedf2fe92767ffe443bec87babc5 100644 --- a/Documentation/devicetree/bindings/usb/maxim,max33359.yaml +++ b/Documentation/devicetree/bindings/usb/maxim,max33359.yaml @@ -69,6 +69,7 @@ examples: PDO_FIXED_DATA_SWAP | PDO_FIXED_DUAL_ROLE) PDO_FIXED(9000, 2000, 0)>; + sink-bc12-completion-time-ms = <500>; }; }; }; diff --git a/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml b/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml index 27b909de49922f76eb4dae5a558e8d35fbc01a85..a812317d808931d8f267da1d69841545300f8f40 100644 --- a/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml +++ b/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml @@ -14,8 +14,11 @@ maintainers: properties: compatible: - enum: - - microchip,mpfs-musb + oneOf: + - items: + - const: microchip,pic64gx-musb + - const: microchip,mpfs-musb + - const: microchip,mpfs-musb dr_mode: true diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index f7be056419307069c67b8f2d53bc88417a19b9ce..935e204b607bbd3bc9bfbdcd03519202197c9eb4 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -29,6 +29,7 @@ properties: - qcom,qcs8300-dwc3 - qcom,qdu1000-dwc3 - qcom,sa8775p-dwc3 + - qcom,sar2130p-dwc3 - qcom,sc7180-dwc3 - qcom,sc7280-dwc3 - qcom,sc8180x-dwc3 @@ -340,6 +341,7 @@ allOf: contains: enum: - qcom,qcm2290-dwc3 + - qcom,sar2130p-dwc3 - qcom,sc8180x-dwc3 - qcom,sc8180x-dwc3-mp - qcom,sm6115-dwc3 diff --git a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml index c63db3ebd07bd493bbc33345b553db39e8d47152..b23ef29bf7949ff972f6a83f1f0cfb6f99fe140a 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml @@ -76,6 +76,10 @@ properties: Integer to use BUSWAIT register. renesas,enable-gpio: + deprecated: true + maxItems: 1 + + renesas,enable-gpios: maxItems: 1 description: | gpio specifier to check GPIO determining if USB function should be diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml b/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml index c4924113f9bdec186d49c89a995c2b15a57e64d5..a21cc098542d7944093b2492026857a271a44167 100644 --- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml @@ -27,6 +27,7 @@ select: enum: - rockchip,rk3328-dwc3 - rockchip,rk3568-dwc3 + - rockchip,rk3576-dwc3 - rockchip,rk3588-dwc3 required: - compatible @@ -37,6 +38,7 @@ properties: - enum: - rockchip,rk3328-dwc3 - rockchip,rk3568-dwc3 + - rockchip,rk3576-dwc3 - rockchip,rk3588-dwc3 - const: snps,dwc3 @@ -113,7 +115,9 @@ allOf: properties: compatible: contains: - const: rockchip,rk3568-dwc3 + enum: + - rockchip,rk3568-dwc3 + - rockchip,rk3576-dwc3 then: properties: clocks: diff --git a/Documentation/devicetree/bindings/usb/ti,tusb1046.yaml b/Documentation/devicetree/bindings/usb/ti,tusb1046.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f713cac4a8ac8e89c017999bc11e4b3a38d3ac2e --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ti,tusb1046.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/ti,tusb1046.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TUSB1046-DCI Type-C crosspoint switch + +maintainers: + - Romain Gantois + +allOf: + - $ref: usb-switch.yaml# + +properties: + compatible: + const: ti,tusb1046 + + reg: + maxItems: 1 + +required: + - compatible + - reg + - port + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + typec-mux@44 { + compatible = "ti,tusb1046"; + reg = <0x44>; + + mode-switch; + orientation-switch; + + port { + endpoint { + remote-endpoint = <&typec_controller>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/usb/ti,tusb73x0-pci.yaml b/Documentation/devicetree/bindings/usb/ti,tusb73x0-pci.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ddda734f36fb2a3fd768d928783f33c4ce8c5b68 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ti,tusb73x0-pci.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/ti,tusb73x0-pci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TUSB73x0 USB 3.0 xHCI Host Controller (PCIe) + +maintainers: + - Francesco Dolcini + +description: + TUSB73x0 USB 3.0 xHCI Host Controller via PCIe x1 Gen2 interface. + The TUSB7320 supports up to two downstream ports, the TUSB7340 supports up + to four downstream ports, both variants share the same PCI device ID. + +properties: + compatible: + const: pci104c,8241 + + reg: + maxItems: 1 + + ti,pwron-active-high: + $ref: /schemas/types.yaml#/definitions/flag + description: + Configure the polarity of the PWRONx# signals. When this is present, the + PWRONx# pins are active high and their internal pull-down resistors are + disabled. When this is absent, the PWRONx# pins are active low (default) + and their internal pull-down resistors are enabled. + +required: + - compatible + - reg + +allOf: + - $ref: usb-xhci.yaml + +additionalProperties: false + +examples: + - | + pcie@0 { + reg = <0x0 0x1000>; + ranges = <0x02000000 0x0 0x100000 0x10000000 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + + usb@0 { + compatible = "pci104c,8241"; + reg = <0x0 0x0 0x0 0x0 0x0>; + ti,pwron-active-high; + }; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 715663b450f85bd13987dac722402c35ef7e7b8f..da01616802c76830a520594a69bd6a2e0231df0d 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -83,6 +83,8 @@ patternProperties: description: ALFA Network Inc. "^allegro,.*": description: Allegro DVT + "^allegromicro,.*": + description: Allegro MicroSystems, Inc. "^alliedvision,.*": description: Allied Vision Technologies GmbH "^allo,.*": @@ -565,6 +567,8 @@ patternProperties: description: GE Fanuc Intelligent Platforms Embedded Systems, Inc. "^GEFanuc,.*": description: GE Fanuc Intelligent Platforms Embedded Systems, Inc. + "^gehc,.*": + description: GE HealthCare "^gemei,.*": description: Gemei Digital Technology Co., Ltd. "^gemtek,.*": diff --git a/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml b/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6bbab3cb28e545013a091a828fe24d5d3121670d --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/airoha,en7581-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha EN7581 Watchdog Timer + +maintainers: + - Christian Marangi + +allOf: + - $ref: watchdog.yaml# + +properties: + compatible: + const: airoha,en7581-wdt + + reg: + maxItems: 1 + + clocks: + description: BUS clock (timer ticks at half the BUS clock) + maxItems: 1 + + clock-names: + const: bus + +required: + - compatible + - reg + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + #include + + watchdog@1fbf0100 { + compatible = "airoha,en7581-wdt"; + reg = <0x1fbf0100 0x3c>; + + clocks = <&scuclk EN7523_CLK_BUS>; + clock-names = "bus"; + }; diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml index 36b836d0620c9be49b3d5fbd39b08ad11600fb1c..0da953cb7127269c07b5eaef1374a94ec68ead60 100644 --- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml @@ -48,6 +48,8 @@ properties: clocks: maxItems: 1 + big-endian: true + fsl,ext-reset-output: $ref: /schemas/types.yaml#/definitions/flag description: | @@ -93,6 +95,18 @@ allOf: properties: fsl,suspend-in-wait: false + - if: + not: + properties: + compatible: + contains: + enum: + - fsl,ls1012a-wdt + - fsl,ls1043a-wdt + then: + properties: + big-endian: false + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 932393f8c649af238f459c48a263f06d777b819a..34896a39fa91f6b97c3412f94e0eb69bed6ad65f 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -26,6 +26,8 @@ properties: - qcom,apss-wdt-msm8994 - qcom,apss-wdt-qcm2290 - qcom,apss-wdt-qcs404 + - qcom,apss-wdt-qcs615 + - qcom,apss-wdt-qcs8300 - qcom,apss-wdt-sa8255p - qcom,apss-wdt-sa8775p - qcom,apss-wdt-sc7180 diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml index 77a5ddd0426ebc3d50adf6f3e195710f6790f988..d175ae9683366d33b1f9d9d820501d1e7c5964bd 100644 --- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml @@ -26,6 +26,7 @@ properties: - samsung,exynos7-wdt # for Exynos7 - samsung,exynos850-wdt # for Exynos850 - samsung,exynosautov9-wdt # for Exynosautov9 + - samsung,exynosautov920-wdt # for Exynosautov920 - items: - enum: - tesla,fsd-wdt @@ -77,6 +78,7 @@ allOf: - samsung,exynos7-wdt - samsung,exynos850-wdt - samsung,exynosautov9-wdt + - samsung,exynosautov920-wdt then: required: - samsung,syscon-phandle @@ -88,6 +90,7 @@ allOf: - google,gs101-wdt - samsung,exynos850-wdt - samsung,exynosautov9-wdt + - samsung,exynosautov920-wdt then: properties: clocks: diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst index cec84908fbc0d63b4d1edc46fa50f931be728867..b236de773e1d6cca9a4619ffac8b7e81a8c649f0 100644 --- a/Documentation/driver-api/auxiliary_bus.rst +++ b/Documentation/driver-api/auxiliary_bus.rst @@ -24,7 +24,6 @@ Auxiliary Device Creation .. kernel-doc:: drivers/base/auxiliary.c :identifiers: auxiliary_device_init __auxiliary_device_add - auxiliary_find_device Auxiliary Device Memory Model and Lifespan ------------------------------------------ diff --git a/Documentation/iio/ad7380.rst b/Documentation/iio/ad7380.rst index 6f70b49b9ef27c1ac32acaefecd1146e5c8bd6cc..c46127700e14ca9ec3cac0bd5776b6702f2659e2 100644 --- a/Documentation/iio/ad7380.rst +++ b/Documentation/iio/ad7380.rst @@ -27,6 +27,8 @@ The following chips are supported by this driver: * `AD7386-4 `_ * `AD7387-4 `_ * `AD7388-4 `_ +* `ADAQ4370-4 `_ +* `ADAQ4380-4 `_ Supported features @@ -47,6 +49,12 @@ ad7380-4 ad7380-4 supports only an external reference voltage (2.5V to 3.3V). It must be declared in the device tree as ``refin-supply``. +ADAQ devices +~~~~~~~~~~~~ + +adaq4370-4 and adaq4380-4 don't have an external reference, but use a 3.3V +internal reference derived from one of its supplies (``refin-supply``) + All other devices from ad738x family ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -121,6 +129,14 @@ Example for AD7386/7/8 (2 channels parts): When enabling sequencer mode, the effective sampling rate is divided by two. +Gain (ADAQ devices only) +~~~~~~~~~~~~~~~~~~~~~~~~ + +ADAQ devices have a pin selectable gain in front of each ADC. The appropriate +gain is selectable from device tree using the ``adi,gain-milli`` property. +Refer to the typical connection diagrams section of the datasheet for pin +wiring. + Unimplemented features ---------------------- diff --git a/Documentation/iio/ad7606.rst b/Documentation/iio/ad7606.rst new file mode 100644 index 0000000000000000000000000000000000000000..930199e03c67f68296ec83176f9e4f82741fb813 --- /dev/null +++ b/Documentation/iio/ad7606.rst @@ -0,0 +1,144 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +============= +AD7606 driver +============= + +ADC driver for Analog Devices Inc. AD7606 and similar devices. The module name +is ``ad7606``. + +Supported devices +================= + +The following chips are supported by this driver: + +* `AD7605 `_ +* `AD7606 `_ +* `AD7606B `_ +* `AD7616 `_ + +Supported features +================== + +SPI wiring modes +---------------- + +These ADCs can output data on several SDO lines (1/2/4/8). The driver +currently supports only 1 SDO line. + +Parallel wiring mode +-------------------- + +There is also a parallel interface, with 16 lines (that can be reduced to 8 in +byte mode). The parallel interface is selected by declaring the device as +platform in the device tree (with no io-backends node defined, see below). + +IIO-backend mode +---------------- + +This mode allows to reach the best sample rates, but it requires an external +hardware (eg HDL or APU) to handle the low level communication. +The backend mode is enabled when through the definition of the "io-backends" +property in the device tree. + +The reference configuration for the current implementation of IIO-backend mode +is the HDL reference provided by ADI: +https://wiki.analog.com/resources/eval/user-guides/ad7606x-fmc/hdl + +This implementation embeds an IIO-backend compatible IP (adi-axi-adc) and a PWM +connected to the conversion trigger pin. + +.. code-block:: + + +---+ +---------------------------- + | | +-------+ |AD76xx + | A | controls | | | + | D |-------------->| PWM |-------------->| cnvst + | 7 | | | | + | 6 | +-------+ | + | 0 | controls +-----------+-----------+ | + | 6 |---------->| | |<--| frstdata + | | | Backend | Backend |<--| busy + | D | | Driver | | | + | R | | | |-->| clk + | I | requests |+---------+| DMA | | + | V |----------->| Buffer ||<---- |<=>| DATA + | E | |+---------+| | | + | R | +-----------+-----------+ | + | |-------------------------------------->| reset/configuration gpios + +---+ +----------------------------- + + +Software and hardware modes +--------------------------- + +While all the AD7606/AD7616 series parts can be configured using GPIOs, some of +them can be configured using register. + +The chips that support software mode have more values available for configuring +the device, as well as more settings, and allow to control the range and +calibration per channel. + +The following settings are available per channel in software mode: + - Scale + +Also, there is a broader choice of oversampling ratios in software mode. + +Conversion triggering +--------------------- + +The conversion can be triggered by two distinct ways: + + - A GPIO is connected to the conversion trigger pin, and this GPIO is controlled + by the driver directly. In this configuration, the driver sets back the + conversion trigger pin to high as soon as it has read all the conversions. + + - An external source is connected to the conversion trigger pin. In the + current implementation, it must be a PWM. In this configuration, the driver + does not control directly the conversion trigger pin. Instead, it can + control the PWM's frequency. This trigger is enabled only for iio-backend. + +Reference voltage +----------------- + +2 possible reference voltage sources are supported: + + - Internal reference (2.5V) + - External reference (2.5V) + +The source is determined by the device tree. If ``refin-supply`` is present, +then the external reference is used, otherwise the internal reference is used. + +Oversampling +------------ + +This family supports oversampling to improve SNR. +In software mode, the following ratios are available: +1 (oversampling disabled)/2/4/8/16/32/64/128/256. + +Unimplemented features +---------------------- + +- 2/4/8 SDO lines +- CRC indication +- Calibration + +Device buffers +============== + +IIO triggered buffer +-------------------- + +This driver supports IIO triggered buffers, with a "built in" trigger, i.e the +trigger is allocated and linked by the driver, and a new conversion is triggered +as soon as the samples are transferred, and a timestamp channel is added to make +up for the potential jitter induced by the delays in the interrupt handling. + +IIO backend buffer +------------------ + +When IIO backend is used, the trigger is not needed, and the sample rate is +considered as stable. There is no timestamp channel. The communication is +delegated to an external logic, called a backend, and the backend's driver +handles the buffer. When this mode is enabled, the driver cannot control the +conversion pin, because the busy pin is bound to the backend. diff --git a/Documentation/iio/ad7625.rst b/Documentation/iio/ad7625.rst new file mode 100644 index 0000000000000000000000000000000000000000..61761e3b75c39db67648389eeb4b2326d64ebc11 --- /dev/null +++ b/Documentation/iio/ad7625.rst @@ -0,0 +1,91 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +==================== +AD7625 driver +==================== + +ADC driver for Analog Devices Inc. AD7625, AD7626, AD7960, and AD7961 +devices. The module name is ``ad7625``. + +Supported devices +================= + +The following chips are supported by this driver: + +* `AD7625 `_ +* `AD7626 `_ +* `AD7960 `_ +* `AD7961 `_ + +The driver requires use of the Pulsar LVDS HDL project: + +* `Pulsar LVDS HDL `_ + +To trigger conversions and enable subsequent data transfer, the devices +require coupled PWM signals with a phase offset. + +Supported features +================== + +Conversion control modes +------------------------ + +The driver currently supports one of two possible LVDS conversion control methods. + +Echoed-Clock interface mode +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: + + +----------------+ + +xxxxxxxxxxxxxxxxxxxxxxxxxx| CNV | + X | | + v | HOST | + +----------------------------+ | | + | CNV+/CNV- DCO+/DCO- |xxxxxxx>| CLK_IN | + | | | | + | | | | + | AD7625 D+/D- |xxxxxxx>| DATA_IN | + | | | | + | | | | + | CLK+/CLK- | "endchoice" -This defines a choice group and accepts any of the above attributes as -options. +This defines a choice group and accepts "prompt", "default", "depends on", and +"help" attributes as options. A choice only allows a single config entry to be selected. diff --git a/Documentation/kbuild/llvm.rst b/Documentation/kbuild/llvm.rst index 6dc66b4f31a7bb62ba5bb6174730dc0a69ee0bba..bc8a283bc44bbfa9948ad3c9fe8031269ce10be4 100644 --- a/Documentation/kbuild/llvm.rst +++ b/Documentation/kbuild/llvm.rst @@ -179,6 +179,9 @@ yet. Bug reports are always welcome at the issue tracker below! * - s390 - Maintained - ``LLVM=1`` (LLVM >= 18.1.0), ``CC=clang`` (LLVM < 18.1.0) + * - sparc (sparc64 only) + - Maintained + - ``CC=clang LLVM_IAS=0`` (LLVM >= 20) * - um (User Mode) - Maintained - ``LLVM=1`` diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 7964e0c245aebe71be607dfaefcb0f052ec86674..d36519f194dc0d18b72a6f3ce7f3649f7c1b5637 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -449,6 +449,20 @@ $(obj) to prerequisites are referenced with $(src) (because they are not generated files). +$(srcroot) + $(srcroot) refers to the root of the source you are building, which can be + either the kernel source or the external modules source, depending on whether + KBUILD_EXTMOD is set. This can be either a relative or an absolute path, but + if KBUILD_ABS_SRCTREE=1 is set, it is always an absolute path. + +$(srctree) + $(srctree) refers to the root of the kernel source tree. When building the + kernel, this is the same as $(srcroot). + +$(objtree) + $(objtree) refers to the root of the kernel object tree. It is ``.`` when + building the kernel, but it is different when building external modules. + $(kecho) echoing information to user in a rule is often a good practice but when execution ``make -s`` one does not expect to see any output diff --git a/Documentation/kbuild/modules.rst b/Documentation/kbuild/modules.rst index cd5a54d91e6d29b5eb62b6d5192650aad08ba8d8..101de236cd0c9abe1f5684d80063ff3f9a7fc673 100644 --- a/Documentation/kbuild/modules.rst +++ b/Documentation/kbuild/modules.rst @@ -59,6 +59,12 @@ Command Syntax $ make -C /lib/modules/`uname -r`/build M=$PWD modules_install + Starting from Linux 6.13, you can use the -f option instead of -C. This + will avoid unnecessary change of the working directory. The external + module will be output to the directory where you invoke make. + + $ make -f /lib/modules/`uname -r`/build/Makefile M=$PWD + Options ------- @@ -66,7 +72,10 @@ Options of the kernel output directory if the kernel was built in a separate build directory.) - make -C $KDIR M=$PWD + You can optionally pass MO= option if you want to build the modules in + a separate directory. + + make -C $KDIR M=$PWD [MO=$BUILD_DIR] -C $KDIR The directory that contains the kernel and relevant build @@ -80,6 +89,9 @@ Options directory where the external module (kbuild file) is located. + MO=$BUILD_DIR + Specifies a separate output directory for the external module. + Targets ------- @@ -215,6 +227,21 @@ Separate Kbuild File and Makefile consisting of several hundred lines, and here it really pays off to separate the kbuild part from the rest. + Linux 6.13 and later support another way. The external module Makefile + can include the kernel Makefile directly, rather than invoking sub Make. + + Example 3:: + + --> filename: Kbuild + obj-m := 8123.o + 8123-y := 8123_if.o 8123_pci.o + + --> filename: Makefile + KDIR ?= /lib/modules/$(shell uname -r)/build + export KBUILD_EXTMOD := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) + include $(KDIR)/Makefile + + Building Multiple Modules ------------------------- diff --git a/Documentation/networking/bareudp.rst b/Documentation/networking/bareudp.rst index b9d04ee6dac142c73a2eb7efce741e59da005726..621cb9575c8f7d8d80a75548927010831434bb50 100644 --- a/Documentation/networking/bareudp.rst +++ b/Documentation/networking/bareudp.rst @@ -6,16 +6,17 @@ Bare UDP Tunnelling Module Documentation There are various L3 encapsulation standards using UDP being discussed to leverage the UDP based load balancing capability of different networks. -MPLSoUDP (__ https://tools.ietf.org/html/rfc7510) is one among them. +MPLSoUDP (https://tools.ietf.org/html/rfc7510) is one among them. The Bareudp tunnel module provides a generic L3 encapsulation support for tunnelling different L3 protocols like MPLS, IP, NSH etc. inside a UDP tunnel. Special Handling ---------------- + The bareudp device supports special handling for MPLS & IP as they can have multiple ethertypes. -MPLS procotcol can have ethertypes ETH_P_MPLS_UC (unicast) & ETH_P_MPLS_MC (multicast). +The MPLS protocol can have ethertypes ETH_P_MPLS_UC (unicast) & ETH_P_MPLS_MC (multicast). IP protocol can have ethertypes ETH_P_IP (v4) & ETH_P_IPV6 (v6). This special handling can be enabled only for ethertypes ETH_P_IP & ETH_P_MPLS_UC with a flag called multiproto mode. @@ -52,7 +53,7 @@ be enabled explicitly with the "multiproto" flag. 3) Device Usage The bareudp device could be used along with OVS or flower filter in TC. -The OVS or TC flower layer must set the tunnel information in SKB dst field before -sending packet buffer to the bareudp device for transmission. On reception the -bareudp device extracts and stores the tunnel information in SKB dst field before +The OVS or TC flower layer must set the tunnel information in the SKB dst field before +sending the packet buffer to the bareudp device for transmission. On reception, the +bareUDP device extracts and stores the tunnel information in the SKB dst field before passing the packet buffer to the network stack. diff --git a/Documentation/sound/hd-audio/notes.rst b/Documentation/sound/hd-audio/notes.rst index e199131bf5abbb286336314a8887197daa3c35f7..f81e94d8f145b75d763921f3aa3c12f65a079359 100644 --- a/Documentation/sound/hd-audio/notes.rst +++ b/Documentation/sound/hd-audio/notes.rst @@ -42,7 +42,7 @@ If you are interested in the deep debugging of HD-audio, read the HD-audio specification at first. The specification is found on Intel's web page, for example: -* https://www.intel.com/standards/hdaudio/ +* https://www.intel.com/content/www/us/en/standards/high-definition-audio-specification.html HD-Audio Controller diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst index 14c4dc026e6bdaea450fe55a8e31a935c8571da5..73a42d5a9f30298bd01f61fcc8d06a80c62b424e 100644 --- a/Documentation/sound/soc/dapm.rst +++ b/Documentation/sound/soc/dapm.rst @@ -35,6 +35,9 @@ The graph for the STM32MP1-DK1 sound card is shown in picture: :alt: Example DAPM graph :align: center +You can also generate compatible graph for your sound card using +`tools/sound/dapm-graph` utility. + DAPM power domains ================== diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst index 74d5bd801b1a8e99513cd7a978dcea716c6496a9..272464bb7c60249fe93e84a4b81a65c85fe654ce 100644 --- a/Documentation/trace/ftrace.rst +++ b/Documentation/trace/ftrace.rst @@ -1033,9 +1033,13 @@ explains which is which. irqs-off: 'd' interrupts are disabled. '.' otherwise. need-resched: + - 'B' all, TIF_NEED_RESCHED, PREEMPT_NEED_RESCHED and TIF_RESCHED_LAZY is set, - 'N' both TIF_NEED_RESCHED and PREEMPT_NEED_RESCHED is set, - 'n' only TIF_NEED_RESCHED is set, - 'p' only PREEMPT_NEED_RESCHED is set, + - 'L' both PREEMPT_NEED_RESCHED and TIF_RESCHED_LAZY is set, + - 'b' both TIF_NEED_RESCHED and TIF_RESCHED_LAZY is set, + - 'l' only TIF_RESCHED_LAZY is set - '.' otherwise. hardirq/softirq: diff --git a/Documentation/translations/it_IT/core-api/symbol-namespaces.rst b/Documentation/translations/it_IT/core-api/symbol-namespaces.rst index 17abc25ee4c1e4ad581bb737cb70f3f20ec32b8e..6ee71398853167a5d51648318c85fd58d1af933a 100644 --- a/Documentation/translations/it_IT/core-api/symbol-namespaces.rst +++ b/Documentation/translations/it_IT/core-api/symbol-namespaces.rst @@ -43,7 +43,7 @@ Tenete presente che per via dell'espansione delle macro questo argomento deve essere un simbolo di preprocessore. Per esempio per esportare il simbolo ``usb_stor_suspend`` nello spazio dei nomi ``USB_STORAGE`` usate:: - EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); + EXPORT_SYMBOL_NS(usb_stor_suspend, "USB_STORAGE"); Di conseguenza, nella tabella dei simboli del kernel ci sarà una voce rappresentata dalla struttura ``kernel_symbol`` che avrà il campo @@ -69,7 +69,7 @@ Per esempio per esportare tutti i simboli definiti in usb-common nello spazio dei nomi USB_COMMON, si può aggiungere la seguente linea in drivers/usb/common/Makefile:: - ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON + ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"USB_COMMON"' Questo cambierà tutte le macro EXPORT_SYMBOL() ed EXPORT_SYMBOL_GPL(). Invece, un simbolo esportato con EXPORT_SYMBOL_NS() non verrà cambiato e il simbolo @@ -79,7 +79,7 @@ Una seconda possibilità è quella di definire il simbolo di preprocessore direttamente nei file da compilare. L'esempio precedente diventerebbe:: #undef DEFAULT_SYMBOL_NAMESPACE - #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON + #define DEFAULT_SYMBOL_NAMESPACE "USB_COMMON" Questo va messo prima di un qualsiasi uso di EXPORT_SYMBOL. @@ -94,7 +94,7 @@ dei nomi che contiene i simboli desiderati. Per esempio un modulo che usa il simbolo usb_stor_suspend deve importare lo spazio dei nomi USB_STORAGE usando la seguente dichiarazione:: - MODULE_IMPORT_NS(USB_STORAGE); + MODULE_IMPORT_NS("USB_STORAGE"); Questo creerà un'etichetta ``modinfo`` per ogni spazio dei nomi importato. Un risvolto di questo fatto è che gli spazi dei diff --git a/Documentation/translations/zh_CN/core-api/symbol-namespaces.rst b/Documentation/translations/zh_CN/core-api/symbol-namespaces.rst index bb16f0611046d3435b095ef8325bb2298291f05b..b1bec219912d5a2fcd6231e50437544175b1e298 100644 --- a/Documentation/translations/zh_CN/core-api/symbol-namespaces.rst +++ b/Documentation/translations/zh_CN/core-api/symbol-namespaces.rst @@ -48,7 +48,7 @@ 要是一个预处理器符号。例如,要把符号 ``usb_stor_suspend`` 导出到命名空间 ``USB_STORAGE``, 请使用:: - EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); + EXPORT_SYMBOL_NS(usb_stor_suspend, "USB_STORAGE"); 相应的 ksymtab 条目结构体 ``kernel_symbol`` 将有相应的成员 ``命名空间`` 集。 导出时未指明命名空间的符号将指向 ``NULL`` 。如果没有定义命名空间,则默认没有。 @@ -66,7 +66,7 @@ 子系统的 ``Makefile`` 中定义默认命名空间。例如,如果要将usb-common中定义的所有符号导 出到USB_COMMON命名空间,可以在drivers/usb/common/Makefile中添加这样一行:: - ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON + ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"USB_COMMON"' 这将影响所有 EXPORT_SYMBOL() 和 EXPORT_SYMBOL_GPL() 语句。当这个定义存在时, 用EXPORT_SYMBOL_NS()导出的符号仍然会被导出到作为命名空间参数传递的命名空间中, @@ -76,7 +76,7 @@ 成:: #undef DEFAULT_SYMBOL_NAMESPACE - #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON + #define DEFAULT_SYMBOL_NAMESPACE "USB_COMMON" 应置于相关编译单元中任何 EXPORT_SYMBOL 宏之前 @@ -88,7 +88,7 @@ 表示它所使用的命名空间的符号。例如,一个使用usb_stor_suspend符号的 模块,需要使用如下语句导入命名空间USB_STORAGE:: - MODULE_IMPORT_NS(USB_STORAGE); + MODULE_IMPORT_NS("USB_STORAGE"); 这将在模块中为每个导入的命名空间创建一个 ``modinfo`` 标签。这也顺带 使得可以用modinfo检查模块已导入的命名空间:: diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst index 29153eed6689006e4bb2262de1af7899c8da9fa8..0a0119edfa82d6b5d4ff1d687ef3787c5473b97b 100644 --- a/Documentation/watchdog/watchdog-parameters.rst +++ b/Documentation/watchdog/watchdog-parameters.rst @@ -120,16 +120,6 @@ coh901327_wdt: ------------------------------------------------- -cpu5wdt: - port: - base address of watchdog card, default is 0x91 - verbose: - be verbose, default is 0 (no) - ticks: - count down ticks, default is 10000 - -------------------------------------------------- - cpwd: wd0_timeout: Default watchdog0 timeout in 1/10secs diff --git a/MAINTAINERS b/MAINTAINERS index 0456a33ef65792bacb5d305a6384d245844fb743..686109008d8e0924e723f4bd71cbd909776f8bcb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1218,6 +1218,14 @@ F: Documentation/devicetree/bindings/perf/amlogic,g12-ddr-pmu.yaml F: drivers/perf/amlogic/ F: include/soc/amlogic/ +AMLOGIC RTC DRIVER +M: Yiting Deng +M: Xianwei Zhao +L: linux-amlogic@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/rtc/amlogic,a4-rtc.yaml +F: drivers/rtc/rtc-amlogic-a4.c + AMPHENOL CHIPCAP 2 HUMIDITY-TEMPERATURE IIO DRIVER M: Javier Carrasco L: linux-hwmon@vger.kernel.org @@ -1271,7 +1279,6 @@ M: Cosmin Tanislav L: linux-iio@vger.kernel.org S: Supported W: https://ez.analog.com/linux-software-drivers -F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml F: drivers/iio/adc/ad4130.c @@ -1336,6 +1343,17 @@ F: Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml F: drivers/iio/addac/ad74413r.c F: include/dt-bindings/iio/addac/adi,ad74413r.h +ANALOG DEVICES INC AD7625 DRIVER +M: Michael Hennerich +M: Nuno Sá +R: Trevor Gamblin +S: Supported +W: https://ez.analog.com/linux-software-drivers +W: http://analogdevicesinc.github.io/hdl/projects/pulsar_lvds/index.html +F: Documentation/devicetree/bindings/iio/adc/adi,ad7625.yaml +F: Documentation/iio/ad7625.rst +F: drivers/iio/adc/ad7625.c + ANALOG DEVICES INC AD7768-1 DRIVER M: Michael Hennerich L: linux-iio@vger.kernel.org @@ -1363,6 +1381,14 @@ F: Documentation/ABI/testing/debugfs-iio-ad9467 F: Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml F: drivers/iio/adc/ad9467.c +ANALOG DEVICES INC AD8460 DRIVER +M: Mariel Tinaco +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/dac/adi,ad8460.yaml +F: drivers/iio/dac/ad8460.c + ANALOG DEVICES INC AD9739a DRIVER M: Nuno Sa M: Dragos Bogdan @@ -1563,6 +1589,7 @@ F: Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 F: Documentation/devicetree/bindings/iio/*/adi,* F: Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml F: Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml +F: Documentation/iio/ad7606.rst F: drivers/iio/*/ad* F: drivers/iio/adc/ltc249* F: drivers/iio/amplifiers/hmc425a.c @@ -2924,6 +2951,7 @@ Q: http://patchwork.kernel.org/project/linux-renesas-soc/list/ C: irc://irc.libera.chat/renesas-soc T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next F: Documentation/devicetree/bindings/hwinfo/renesas,prr.yaml +F: Documentation/devicetree/bindings/nvmem/renesas,* F: Documentation/devicetree/bindings/soc/renesas/ F: arch/arm/boot/dts/renesas/ F: arch/arm/configs/shmobile_defconfig @@ -2931,6 +2959,7 @@ F: arch/arm/include/debug/renesas-scif.S F: arch/arm/mach-shmobile/ F: arch/arm64/boot/dts/renesas/ F: arch/riscv/boot/dts/renesas/ +F: drivers/nvmem/rcar-efuse.c F: drivers/pmdomain/renesas/ F: drivers/soc/renesas/ F: include/linux/soc/renesas/ @@ -3686,6 +3715,13 @@ F: kernel/audit* F: lib/*audit.c K: \baudit_[a-z_0-9]\+\b +AUTOFDO BUILD +M: Rong Xu +M: Han Shen +S: Supported +F: Documentation/dev-tools/autofdo.rst +F: scripts/Makefile.autofdo + AUXILIARY BUS DRIVER M: Greg Kroah-Hartman R: Dave Ertman @@ -4036,6 +4072,13 @@ S: Maintained F: Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml F: drivers/iio/accel/bma400* +BOSCH SENSORTEC BMI270 IMU IIO DRIVER +M: Alex Lanzano +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/imu/bosch,bmi270.yaml +F: drivers/iio/imu/bmi270/ + BOSCH SENSORTEC BMI323 IMU IIO DRIVER M: Jagath Jog J L: linux-iio@vger.kernel.org @@ -9483,6 +9526,14 @@ M: Kieran Bingham S: Supported F: scripts/gdb/ +GE HEALTHCARE PMC ADC DRIVER +M: Herve Codina +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/adc/gehc,pmc-adc.yaml +F: drivers/iio/adc/gehc-pmc-adc.c +F: include/dt-bindings/iio/adc/gehc,pmc-adc.h + GEMINI CRYPTO DRIVER M: Corentin Labbe L: linux-crypto@vger.kernel.org @@ -9718,6 +9769,11 @@ L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/gpd-pocket-fan.c +GPIB DRIVERS +M: Dave Penkler +S: Maintained +F: drivers/staging/gpib/ + GPIO ACPI SUPPORT M: Mika Westerberg M: Andy Shevchenko @@ -10702,6 +10758,14 @@ S: Maintained F: Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml F: drivers/i2c/busses/i2c-mv64xxx.c +I2C OF COMPONENT PROBER +M: Chen-Yu Tsai +L: linux-i2c@vger.kernel.org +L: devicetree@vger.kernel.org +S: Maintained +F: drivers/i2c/i2c-core-of-prober.c +F: include/linux/i2c-of-prober.h + I2C OVER PARALLEL PORT M: Jean Delvare L: linux-i2c@vger.kernel.org @@ -11641,7 +11705,7 @@ F: drivers/usb/misc/usb-ljca.c F: include/linux/usb/ljca.h INTEL MANAGEMENT ENGINE (mei) -M: Tomas Winkler +M: Alexander Usyskin L: linux-kernel@vger.kernel.org S: Supported F: Documentation/driver-api/mei/* @@ -11922,7 +11986,7 @@ F: Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml F: drivers/media/i2c/isl7998x.c INVENSENSE ICM-426xx IMU DRIVER -M: Jean-Baptiste Maneyrol +M: Jean-Baptiste Maneyrol L: linux-iio@vger.kernel.org S: Maintained W: https://invensense.tdk.com/ @@ -11937,6 +12001,14 @@ S: Maintained F: Documentation/devicetree/bindings/iio/gyroscope/invensense,mpu3050.yaml F: drivers/iio/gyro/mpu3050* +INVENSENSE MPU-6050 IMU DRIVER +M: Jean-Baptiste Maneyrol +L: linux-iio@vger.kernel.org +S: Maintained +W: https://invensense.tdk.com/ +F: Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml +F: drivers/iio/imu/inv_mpu6050/ + IOC3 ETHERNET DRIVER M: Thomas Bogendoerfer L: linux-mips@vger.kernel.org @@ -13745,6 +13817,7 @@ F: Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml F: drivers/input/misc/88pm886-onkey.c F: drivers/mfd/88pm886.c F: drivers/regulator/88pm886-regulator.c +F: drivers/rtc/rtc-88pm886.c F: include/linux/mfd/88pm886.h MARVELL ARMADA 3700 PHY DRIVERS @@ -16194,6 +16267,7 @@ F: Documentation/devicetree/bindings/net/ F: Documentation/networking/net_cachelines/net_device.rst F: drivers/connector/ F: drivers/net/ +F: drivers/ptp/ F: include/dt-bindings/net/ F: include/linux/cn_proc.h F: include/linux/etherdevice.h @@ -16304,6 +16378,7 @@ X: include/net/wext.h X: net/9p/ X: net/bluetooth/ X: net/can/ +X: net/ceph/ X: net/mac80211/ X: net/rfkill/ X: net/wireless/ @@ -18649,6 +18724,13 @@ S: Maintained F: include/linux/psi* F: kernel/sched/psi.c +PROPELLER BUILD +M: Rong Xu +M: Han Shen +S: Supported +F: Documentation/dev-tools/propeller.rst +F: scripts/Makefile.propeller + PRINTK M: Petr Mladek R: Steven Rostedt @@ -19865,6 +19947,14 @@ S: Supported F: Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml F: drivers/counter/rz-mtu3-cnt.c +RENESAS RTCA-3 RTC DRIVER +M: Claudiu Beznea +L: linux-rtc@vger.kernel.org +L: linux-renesas-soc@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml +F: drivers/rtc/rtc-renesas-rtca3.c + RENESAS RZ/N1 A5PSW SWITCH DRIVER M: Clément Léger L: linux-renesas-soc@vger.kernel.org @@ -22135,17 +22225,6 @@ L: linux-media@vger.kernel.org S: Maintained F: drivers/staging/media/atomisp/ -STAGING - FIELDBUS SUBSYSTEM -M: Sven Van Asbroeck -S: Maintained -F: drivers/staging/fieldbus/* -F: drivers/staging/fieldbus/Documentation/ - -STAGING - HMS ANYBUS-S BUS -M: Sven Van Asbroeck -S: Maintained -F: drivers/staging/fieldbus/anybuss/ - STAGING - INDUSTRIAL IO M: Jonathan Cameron L: linux-iio@vger.kernel.org @@ -22160,18 +22239,6 @@ L: linux-tegra@vger.kernel.org S: Maintained F: drivers/staging/nvec/ -STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) -M: Jens Frederich -M: Jon Nettleton -S: Maintained -W: http://wiki.laptop.org/go/DCON -F: drivers/staging/olpc_dcon/ - -STAGING - REALTEK RTL8712U DRIVERS -M: Florian Schilhabel . -S: Odd Fixes -F: drivers/staging/rtl8712/ - STAGING - SEPS525 LCD CONTROLLER DRIVERS M: Michael Hennerich L: linux-fbdev@vger.kernel.org @@ -22187,11 +22254,6 @@ L: linux-fbdev@vger.kernel.org S: Maintained F: drivers/staging/sm750fb/ -STAGING - VIA VT665X DRIVERS -M: Philipp Hortmann -S: Odd Fixes -F: drivers/staging/vt665?/ - STAGING SUBSYSTEM M: Greg Kroah-Hartman L: linux-staging@lists.linux.dev @@ -22346,7 +22408,7 @@ F: drivers/char/hw_random/jh7110-trng.c STARFIVE WATCHDOG DRIVER M: Xingyu Wu -M: Samin Guo +M: Ziv Xu S: Supported F: Documentation/devicetree/bindings/watchdog/starfive* F: drivers/watchdog/starfive-wdt.c @@ -24352,6 +24414,13 @@ L: linux-usb@vger.kernel.org S: Orphan F: drivers/usb/typec/tcpm/ +USB TYPEC TUSB1046 MUX DRIVER +M: Romain Gantois +L: linux-usb@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/usb/ti,tusb1046.yaml +F: drivers/usb/typec/mux/tusb1046.c + USB UHCI DRIVER M: Alan Stern L: linux-usb@vger.kernel.org @@ -24905,6 +24974,18 @@ S: Maintained F: drivers/input/serio/userio.c F: include/uapi/linux/userio.h +VISHAY VEML3235 AMBIENT LIGHT SENSOR DRIVER +M: Javier Carrasco +S: Maintained +F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml +F: drivers/iio/light/veml3235.c + +VISHAY VEML6030 AMBIENT LIGHT SENSOR DRIVER +M: Javier Carrasco +S: Maintained +F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml +F: drivers/iio/light/veml6030.c + VISHAY VEML6075 UVA AND UVB LIGHT SENSOR DRIVER M: Javier Carrasco S: Maintained diff --git a/Makefile b/Makefile index 8129de0b214f5b73a3b1cca0798041d74270836b..93ab62cef244ff99701e271bd23ef18c5b6b30ba 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 -PATCHLEVEL = 12 +PATCHLEVEL = 13 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = Baby Opossum Posse # *DOCUMENTATION* @@ -40,7 +40,7 @@ __all: this-makefile := $(lastword $(MAKEFILE_LIST)) abs_srctree := $(realpath $(dir $(this-makefile))) -abs_objtree := $(CURDIR) +abs_output := $(CURDIR) ifneq ($(sub_make_done),1) @@ -134,6 +134,10 @@ ifeq ("$(origin M)", "command line") KBUILD_EXTMOD := $(M) endif +ifeq ("$(origin MO)", "command line") + KBUILD_EXTMOD_OUTPUT := $(MO) +endif + $(if $(word 2, $(KBUILD_EXTMOD)), \ $(error building multiple external modules is not supported)) @@ -176,18 +180,41 @@ export KBUILD_EXTRA_WARN # The O= assignment takes precedence over the KBUILD_OUTPUT environment # variable. -# Do we want to change the working directory? ifeq ("$(origin O)", "command line") KBUILD_OUTPUT := $(O) endif -ifneq ($(KBUILD_OUTPUT),) +ifdef KBUILD_EXTMOD + ifdef KBUILD_OUTPUT + objtree := $(realpath $(KBUILD_OUTPUT)) + $(if $(objtree),,$(error specified kernel directory "$(KBUILD_OUTPUT)" does not exist)) + else + objtree := $(abs_srctree) + endif + # If Make is invoked from the kernel directory (either kernel + # source directory or kernel build directory), external modules + # are built in $(KBUILD_EXTMOD) for backward compatibility, + # otherwise, built in the current directory. + output := $(or $(KBUILD_EXTMOD_OUTPUT),$(if $(filter $(CURDIR),$(objtree) $(abs_srctree)),$(KBUILD_EXTMOD))) + # KBUILD_EXTMOD might be a relative path. Remember its absolute path before + # Make changes the working directory. + srcroot := $(realpath $(KBUILD_EXTMOD)) + $(if $(srcroot),,$(error specified external module directory "$(KBUILD_EXTMOD)" does not exist)) +else + objtree := . + output := $(KBUILD_OUTPUT) +endif + +export objtree srcroot + +# Do we want to change the working directory? +ifneq ($(output),) # $(realpath ...) gets empty if the path does not exist. Run 'mkdir -p' first. -$(shell mkdir -p "$(KBUILD_OUTPUT)") +$(shell mkdir -p "$(output)") # $(realpath ...) resolves symlinks -abs_objtree := $(realpath $(KBUILD_OUTPUT)) -$(if $(abs_objtree),,$(error failed to create output directory "$(KBUILD_OUTPUT)")) -endif # ifneq ($(KBUILD_OUTPUT),) +abs_output := $(realpath $(output)) +$(if $(abs_output),,$(error failed to create output directory "$(output)")) +endif ifneq ($(words $(subst :, ,$(abs_srctree))), 1) $(error source directory cannot contain spaces or colons) @@ -197,7 +224,7 @@ export sub_make_done := 1 endif # sub_make_done -ifeq ($(abs_objtree),$(CURDIR)) +ifeq ($(abs_output),$(CURDIR)) # Suppress "Entering directory ..." if we are at the final work directory. no-print-directory := --no-print-directory else @@ -221,43 +248,41 @@ $(filter-out $(this-makefile), $(MAKECMDGOALS)) __all: __sub-make # Invoke a second make in the output directory, passing relevant variables __sub-make: - $(Q)$(MAKE) $(no-print-directory) -C $(abs_objtree) \ + $(Q)$(MAKE) $(no-print-directory) -C $(abs_output) \ -f $(abs_srctree)/Makefile $(MAKECMDGOALS) else # need-sub-make # We process the rest of the Makefile if this is the final invocation of make -ifeq ($(abs_srctree),$(abs_objtree)) - # building in the source tree - srctree := . - building_out_of_srctree := -else - ifeq ($(abs_srctree)/,$(dir $(abs_objtree))) - # building in a subdirectory of the source tree - srctree := .. - else - srctree := $(abs_srctree) - endif - building_out_of_srctree := 1 +ifndef KBUILD_EXTMOD +srcroot := $(abs_srctree) endif -ifneq ($(KBUILD_ABS_SRCTREE),) -srctree := $(abs_srctree) +ifeq ($(srcroot),$(CURDIR)) +building_out_of_srctree := +else +export building_out_of_srctree := 1 endif -objtree := . +ifdef KBUILD_ABS_SRCTREE + # Do nothing. Use the absolute path. +else ifeq ($(srcroot),$(CURDIR)) + # Building in the source. + srcroot := . +else ifeq ($(srcroot)/,$(dir $(CURDIR))) + # Building in a subdirectory of the source. + srcroot := .. +endif -VPATH := +export srctree := $(if $(KBUILD_EXTMOD),$(abs_srctree),$(srcroot)) -ifeq ($(KBUILD_EXTMOD),) ifdef building_out_of_srctree -VPATH := $(srctree) -endif +export VPATH := $(srcroot) +else +VPATH := endif -export building_out_of_srctree srctree objtree VPATH - # To make sure we do not include .config for any of the *config targets # catch them early, and hand them over to scripts/kconfig/Makefile # It is allowed to specify more targets when calling make, including @@ -276,7 +301,7 @@ no-dot-config-targets := $(clean-targets) \ outputmakefile rustavailable rustfmt rustfmtcheck no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \ image_name -single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %.symtypes %/ +single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/ config-build := mixed-build := @@ -354,7 +379,7 @@ else # !mixed-build include $(srctree)/scripts/Kbuild.include # Read KERNELRELEASE from include/config/kernel.release (if it exists) -KERNELRELEASE = $(call read-file, include/config/kernel.release) +KERNELRELEASE = $(call read-file, $(objtree)/include/config/kernel.release) KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION @@ -513,7 +538,7 @@ KGZIP = gzip KBZIP2 = bzip2 KLZOP = lzop LZMA = lzma -LZ4 = lz4c +LZ4 = lz4 XZ = xz ZSTD = zstd @@ -543,7 +568,7 @@ USERINCLUDE := \ LINUXINCLUDE := \ -I$(srctree)/arch/$(SRCARCH)/include \ -I$(objtree)/arch/$(SRCARCH)/include/generated \ - $(if $(building_out_of_srctree),-I$(srctree)/include) \ + -I$(srctree)/include \ -I$(objtree)/include \ $(USERINCLUDE) @@ -629,13 +654,25 @@ ifdef building_out_of_srctree # At the same time when output Makefile generated, generate .gitignore to # ignore whole output directory +ifdef KBUILD_EXTMOD +print_env_for_makefile = \ + echo "export KBUILD_OUTPUT = $(objtree)"; \ + echo "export KBUILD_EXTMOD = $(realpath $(srcroot))" ; \ + echo "export KBUILD_EXTMOD_OUTPUT = $(CURDIR)" +else +print_env_for_makefile = \ + echo "export KBUILD_OUTPUT = $(CURDIR)" +endif + quiet_cmd_makefile = GEN Makefile cmd_makefile = { \ - echo "\# Automatically generated by $(srctree)/Makefile: don't edit"; \ - echo "include $(srctree)/Makefile"; \ + echo "\# Automatically generated by $(abs_srctree)/Makefile: don't edit"; \ + $(print_env_for_makefile); \ + echo "include $(abs_srctree)/Makefile"; \ } > Makefile outputmakefile: +ifeq ($(KBUILD_EXTMOD),) @if [ -f $(srctree)/.config -o \ -d $(srctree)/include/config -o \ -d $(srctree)/arch/$(SRCARCH)/include/generated ]; then \ @@ -645,7 +682,16 @@ outputmakefile: echo >&2 "***"; \ false; \ fi - $(Q)ln -fsn $(srctree) source +else + @if [ -f $(srcroot)/modules.order ]; then \ + echo >&2 "***"; \ + echo >&2 "*** The external module source tree is not clean."; \ + echo >&2 "*** Please run 'make -C $(abs_srctree) M=$(realpath $(srcroot)) clean'"; \ + echo >&2 "***"; \ + false; \ + fi +endif + $(Q)ln -fsn $(srcroot) source $(call cmd,makefile) $(Q)test -e .gitignore || \ { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore @@ -717,7 +763,7 @@ endif # in addition to whatever we do anyway. # Just "make" or "make all" shall build modules as well -ifneq ($(filter all modules nsdeps %compile_commands.json clang-%,$(MAKECMDGOALS)),) +ifneq ($(filter all modules nsdeps compile_commands.json clang-%,$(MAKECMDGOALS)),) KBUILD_MODULES := 1 endif @@ -728,7 +774,7 @@ endif export KBUILD_MODULES KBUILD_BUILTIN ifdef need-config -include include/config/auto.conf +include $(objtree)/include/config/auto.conf endif ifeq ($(KBUILD_EXTMOD),) @@ -789,17 +835,22 @@ $(KCONFIG_CONFIG): else # !may-sync-config # External modules and some install targets need include/generated/autoconf.h # and include/config/auto.conf but do not care if they are up-to-date. -# Use auto.conf to trigger the test -PHONY += include/config/auto.conf - -include/config/auto.conf: - @test -e include/generated/autoconf.h -a -e $@ || ( \ - echo >&2; \ - echo >&2 " ERROR: Kernel configuration is invalid."; \ - echo >&2 " include/generated/autoconf.h or $@ are missing.";\ - echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ - echo >&2 ; \ - /bin/false) +# Use auto.conf to show the error message + +checked-configs := $(addprefix $(objtree)/, include/generated/autoconf.h include/generated/rustc_cfg include/config/auto.conf) +missing-configs := $(filter-out $(wildcard $(checked-configs)), $(checked-configs)) + +ifdef missing-configs +PHONY += $(objtree)/include/config/auto.conf + +$(objtree)/include/config/auto.conf: + @echo >&2 '***' + @echo >&2 '*** ERROR: Kernel configuration is invalid. The following files are missing:' + @printf >&2 '*** - %s\n' $(missing-configs) + @echo >&2 '*** Run "make oldconfig && make prepare" on kernel source to fix it.' + @echo >&2 '***' + @/bin/false +endif endif # may-sync-config endif # need-config @@ -1013,8 +1064,10 @@ ifdef CONFIG_CC_IS_GCC KBUILD_CFLAGS += -fconserve-stack endif -# change __FILE__ to the relative path from the srctree -KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) +# change __FILE__ to the relative path to the source directory +ifdef building_out_of_srctree +KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) +endif # include additional Makefiles when needed include-y := scripts/Makefile.extrawarn @@ -1026,6 +1079,8 @@ include-$(CONFIG_KMSAN) += scripts/Makefile.kmsan include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan include-$(CONFIG_KCOV) += scripts/Makefile.kcov include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct +include-$(CONFIG_AUTOFDO_CLANG) += scripts/Makefile.autofdo +include-$(CONFIG_PROPELLER_CLANG) += scripts/Makefile.propeller include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins include $(addprefix $(srctree)/, $(include-y)) @@ -1106,10 +1161,6 @@ export MODLIB PHONY += prepare0 -export extmod_prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/) -export MODORDER := $(extmod_prefix)modules.order -export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps - ifeq ($(KBUILD_EXTMOD),) build-dir := . @@ -1204,7 +1255,8 @@ PHONY += prepare archprepare archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \ asm-generic $(version_h) include/generated/utsrelease.h \ - include/generated/compile.h include/generated/autoconf.h remove-stale-files + include/generated/compile.h include/generated/autoconf.h \ + include/generated/rustc_cfg remove-stale-files prepare0: archprepare $(Q)$(MAKE) $(build)=scripts/mod @@ -1435,6 +1487,10 @@ ifdef CONFIG_OF_EARLY_FLATTREE all: dtbs endif +ifdef CONFIG_GENERIC_BUILTIN_DTB +vmlinux: dtbs +endif + endif PHONY += scripts_dtc @@ -1502,7 +1558,8 @@ CLEAN_FILES += vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ modules.builtin.ranges vmlinux.o.map \ compile_commands.json rust/test \ - rust-project.json .vmlinux.objs .vmlinux.export.c + rust-project.json .vmlinux.objs .vmlinux.export.c \ + .builtin-dtbs-list .builtin-dtb.S # Directories & files removed with 'make mrproper' MRPROPER_FILES += include/config include/generated \ @@ -1750,18 +1807,9 @@ rusttest: prepare # Formatting targets PHONY += rustfmt rustfmtcheck -# We skip `rust/alloc` since we want to minimize the diff w.r.t. upstream. -# -# We match using absolute paths since `find` does not resolve them -# when matching, which is a problem when e.g. `srctree` is `..`. -# We `grep` afterwards in order to remove the directory entry itself. rustfmt: - $(Q)find $(abs_srctree) -type f -name '*.rs' \ - -o -path $(abs_srctree)/rust/alloc -prune \ - -o -path $(abs_objtree)/rust/test -prune \ - | grep -Fv $(abs_srctree)/rust/alloc \ - | grep -Fv $(abs_objtree)/rust/test \ - | grep -Fv generated \ + $(Q)find $(srctree) $(RCS_FIND_IGNORE) \ + -type f -a -name '*.rs' -a ! -name '*generated*' -print \ | xargs $(RUSTFMT) $(rustfmt_flags) rustfmtcheck: rustfmt_flags = --check @@ -1800,14 +1848,10 @@ filechk_kernel.release = echo $(KERNELRELEASE) KBUILD_BUILTIN := KBUILD_MODULES := 1 -build-dir := $(KBUILD_EXTMOD) +build-dir := . -compile_commands.json: $(extmod_prefix)compile_commands.json -PHONY += compile_commands.json - -clean-dirs := $(KBUILD_EXTMOD) -clean: private rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ - $(KBUILD_EXTMOD)/compile_commands.json +clean-dirs := . +clean: private rm-files := Module.symvers modules.nsdeps compile_commands.json PHONY += prepare # now expand this into a simple variable to reduce the cost of shell evaluations @@ -1866,7 +1910,7 @@ endif ifdef CONFIG_MODULES -$(MODORDER): $(build-dir) +modules.order: $(build-dir) @: # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. @@ -1877,7 +1921,7 @@ ifneq ($(KBUILD_MODPOST_NOFINAL),1) endif PHONY += modules_check -modules_check: $(MODORDER) +modules_check: modules.order $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh $< else # CONFIG_MODULES @@ -1918,15 +1962,15 @@ $(single-ko): single_modules $(single-no-ko): $(build-dir) @: -# Remove MODORDER when done because it is not the real one. +# Remove modules.order when done because it is not the real one. PHONY += single_modules single_modules: $(single-no-ko) modules_prepare - $(Q){ $(foreach m, $(single-ko), echo $(extmod_prefix)$(m:%.ko=%.o);) } > $(MODORDER) + $(Q){ $(foreach m, $(single-ko), echo $(m:%.ko=%.o);) } > modules.order $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost ifneq ($(KBUILD_MODPOST_NOFINAL),1) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal endif - $(Q)rm -f $(MODORDER) + $(Q)rm -f modules.order single-goals := $(addprefix $(build-dir)/, $(single-no-ko)) @@ -1934,6 +1978,8 @@ KBUILD_MODULES := 1 endif +prepare: outputmakefile + # Preset locale variables to speed up the build process. Limit locale # tweaks to this spot to avoid wrong language settings when running # make menuconfig etc. @@ -1949,7 +1995,7 @@ $(clean-dirs): clean: $(clean-dirs) $(call cmd,rmfiles) - @find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ + @find . $(RCS_FIND_IGNORE) \ \( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '*.ko.*' \ -o -name '*.dtb' -o -name '*.dtbo' \ @@ -1982,7 +2028,12 @@ tags TAGS cscope gtags: FORCE PHONY += rust-analyzer rust-analyzer: +$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh +ifdef KBUILD_EXTMOD +# FIXME: external modules must not descend into a sub-directory of the kernel + $(Q)$(MAKE) $(build)=$(objtree)/rust src=$(srctree)/rust $@ +else $(Q)$(MAKE) $(build)=rust $@ +endif # Script to generate missing namespace dependencies # --------------------------------------------------------------------------- @@ -1998,12 +2049,12 @@ nsdeps: modules quiet_cmd_gen_compile_commands = GEN $@ cmd_gen_compile_commands = $(PYTHON3) $< -a $(AR) -o $@ $(filter-out $<, $(real-prereqs)) -$(extmod_prefix)compile_commands.json: $(srctree)/scripts/clang-tools/gen_compile_commands.py \ +compile_commands.json: $(srctree)/scripts/clang-tools/gen_compile_commands.py \ $(if $(KBUILD_EXTMOD),, vmlinux.a $(KBUILD_VMLINUX_LIBS)) \ - $(if $(CONFIG_MODULES), $(MODORDER)) FORCE + $(if $(CONFIG_MODULES), modules.order) FORCE $(call if_changed,gen_compile_commands) -targets += $(extmod_prefix)compile_commands.json +targets += compile_commands.json PHONY += clang-tidy clang-analyzer @@ -2011,7 +2062,7 @@ ifdef CONFIG_CC_IS_CLANG quiet_cmd_clang_tools = CHECK $< cmd_clang_tools = $(PYTHON3) $(srctree)/scripts/clang-tools/run-clang-tools.py $@ $< -clang-tidy clang-analyzer: $(extmod_prefix)compile_commands.json +clang-tidy clang-analyzer: compile_commands.json $(call cmd,clang_tools) else clang-tidy clang-analyzer: diff --git a/arch/Kconfig b/arch/Kconfig index 832f68af7c7794f98788a1c7dcbd12985e8fd276..6682b2a53e342cbacc05b70ef99cb1c47efe55e8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -812,6 +812,45 @@ config LTO_CLANG_THIN If unsure, say Y. endchoice +config ARCH_SUPPORTS_AUTOFDO_CLANG + bool + +config AUTOFDO_CLANG + bool "Enable Clang's AutoFDO build (EXPERIMENTAL)" + depends on ARCH_SUPPORTS_AUTOFDO_CLANG + depends on CC_IS_CLANG && CLANG_VERSION >= 170000 + help + This option enables Clang’s AutoFDO build. When + an AutoFDO profile is specified in variable + CLANG_AUTOFDO_PROFILE during the build process, + Clang uses the profile to optimize the kernel. + + If no profile is specified, AutoFDO options are + still passed to Clang to facilitate the collection + of perf data for creating an AutoFDO profile in + subsequent builds. + + If unsure, say N. + +config ARCH_SUPPORTS_PROPELLER_CLANG + bool + +config PROPELLER_CLANG + bool "Enable Clang's Propeller build" + depends on ARCH_SUPPORTS_PROPELLER_CLANG + depends on CC_IS_CLANG && CLANG_VERSION >= 190000 + help + This option enables Clang’s Propeller build. When the Propeller + profiles is specified in variable CLANG_PROPELLER_PROFILE_PREFIX + during the build process, Clang uses the profiles to optimize + the kernel. + + If no profile is specified, Propeller options are still passed + to Clang to facilitate the collection of perf data for creating + the Propeller profiles in subsequent builds. + + If unsure, say N. + config ARCH_SUPPORTS_CFI_CLANG bool help diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 5808a66e2a81f7eba9a245fd6a343406a1ade87d..3048758304b57afa01ddeb6558c39bdb48c9a3f6 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -64,7 +64,7 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, * Return: %0 on success, negative error code otherwise */ static int pci_mmap_resource(struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma, int sparse) { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); @@ -93,14 +93,14 @@ static int pci_mmap_resource(struct kobject *kobj, } static int pci_mmap_resource_sparse(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 1); } static int pci_mmap_resource_dense(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 0); diff --git a/arch/arm/Makefile b/arch/arm/Makefile index aafebf145738ab1a443c116a1bf648953f7afed4..00ca7886b18efe2d01f33bc079eda2483ec807a7 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -264,13 +264,13 @@ stack_protector_prepare: prepare0 -mstack-protector-guard=tls \ -mstack-protector-guard-offset=$(shell \ awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\ - include/generated/asm-offsets.h)) + $(objtree)/include/generated/asm-offsets.h)) else stack_protector_prepare: prepare0 $(eval SSP_PLUGIN_CFLAGS := \ -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\ - include/generated/asm-offsets.h)) + $(objtree)/include/generated/asm-offsets.h)) $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) endif diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 06b0e5fd54a6d622efa85b8a03d563a381830d9b..cb6ef449b987ac53176b7650d416fe7252b5d74f 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -516,7 +516,7 @@ static void locomo_remove(struct platform_device *dev) */ static struct platform_driver locomo_device_driver = { .probe = locomo_probe, - .remove_new = locomo_remove, + .remove = locomo_remove, #ifdef CONFIG_PM .suspend = locomo_suspend, .resume = locomo_resume, diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 550978dc3c50ea69082ad941aa6ef57a15f0eb32..9846f30990f71122b20e04314ed522bb45069b35 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1154,7 +1154,7 @@ static struct dev_pm_ops sa1111_pm_ops = { */ static struct platform_driver sa1111_device_driver = { .probe = sa1111_probe, - .remove_new = sa1111_remove, + .remove = sa1111_remove, .driver = { .name = "sa1111", .pm = &sa1111_pm_ops, diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index 9018c72401665488dbe63943532ac8cf985242c7..0b08b6621878bfde0a2df3572be0cb668e189449 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -250,7 +250,7 @@ static void scoop_remove(struct platform_device *pdev) static struct platform_driver scoop_driver = { .probe = scoop_probe, - .remove_new = scoop_remove, + .remove = scoop_remove, .suspend = scoop_suspend, .resume = scoop_resume, .driver = { diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 1dfae1af8e31b0e8bed99947baaf0a43b86cf923..ef6a657c8d130663e68acd07226815ce8a3fff7d 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -25,6 +25,7 @@ #include #include #include +#include #include "entry-header.S" #include @@ -561,6 +562,13 @@ ENTRY(__switch_to) @ entries covering the vmalloc region. @ ldr r2, [ip] +#ifdef CONFIG_KASAN_VMALLOC + @ Also dummy read from the KASAN shadow memory for the new stack if we + @ are using KASAN + mov_l r2, KASAN_SHADOW_OFFSET + add r2, r2, ip, lsr #KASAN_SHADOW_SCALE_SHIFT + ldr r2, [r2] +#endif #endif @ When CONFIG_THREAD_INFO_IN_TASK=n, the update of SP itself is what diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index b68cb86dbe4cf9c8291c21504d861c172ba2f667..e898f7c2733efc74fd7c6d2743744f46d548256e 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -596,7 +596,7 @@ static struct platform_driver imx_mmdc_driver = { .of_match_table = imx_mmdc_dt_ids, }, .probe = imx_mmdc_probe, - .remove_new = imx_mmdc_remove, + .remove = imx_mmdc_remove, }; static int __init imx_mmdc_init(void) diff --git a/arch/arm/mach-omap1/omap-dma.c b/arch/arm/mach-omap1/omap-dma.c index f091f78631d0981969cd5e9ab019d2e2efd0a10e..aebe5e55ff60717429b87bddcb961b17db3d352f 100644 --- a/arch/arm/mach-omap1/omap-dma.c +++ b/arch/arm/mach-omap1/omap-dma.c @@ -832,7 +832,7 @@ static void omap_system_dma_remove(struct platform_device *pdev) static struct platform_driver omap_system_dma_driver = { .probe = omap_system_dma_probe, - .remove_new = omap_system_dma_remove, + .remove = omap_system_dma_remove, .driver = { .name = "omap_dma_system" }, diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 72fa2e3fd35318e5a63c121ed7990a56a56b134c..0c8d9000df5a6384d615cf231ff986c0c6b71681 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -919,7 +919,7 @@ static void sharpsl_pm_remove(struct platform_device *pdev) static struct platform_driver sharpsl_pm_driver = { .probe = sharpsl_pm_probe, - .remove_new = sharpsl_pm_remove, + .remove = sharpsl_pm_remove, .suspend = sharpsl_pm_suspend, .resume = sharpsl_pm_resume, .driver = { diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c index 1956b095e699d137ed398f795a00b10b5d65e8c7..d94810217095bd1eb7ebee16166047b085154d10 100644 --- a/arch/arm/mach-sa1100/jornada720_ssp.c +++ b/arch/arm/mach-sa1100/jornada720_ssp.c @@ -188,7 +188,7 @@ static void jornada_ssp_remove(struct platform_device *dev) struct platform_driver jornadassp_driver = { .probe = jornada_ssp_probe, - .remove_new = jornada_ssp_remove, + .remove = jornada_ssp_remove, .driver = { .name = "jornada_ssp", }, diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 0ef0ebbf31ac1f2a656809580158d191ad952d1c..88fe79f0a4ed36a3bcae349fd037b52d0f9964d9 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -423,7 +423,7 @@ static const struct dev_pm_ops neponset_pm_ops = { static struct platform_driver neponset_device_driver = { .probe = neponset_probe, - .remove_new = neponset_remove, + .remove = neponset_remove, .driver = { .name = "neponset", .pm = PM_OPS, diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 794cfea9f9d4c894d906d3032cac50cbbf0161ef..89f1c97f3079c11efbfd0112fe02f833ff1df9e3 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -23,6 +23,7 @@ */ #include #include +#include #include #include #include @@ -115,16 +116,40 @@ int ioremap_page(unsigned long virt, unsigned long phys, } EXPORT_SYMBOL(ioremap_page); +#ifdef CONFIG_KASAN +static unsigned long arm_kasan_mem_to_shadow(unsigned long addr) +{ + return (unsigned long)kasan_mem_to_shadow((void *)addr); +} +#else +static unsigned long arm_kasan_mem_to_shadow(unsigned long addr) +{ + return 0; +} +#endif + +static void memcpy_pgd(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + end = ALIGN(end, PGDIR_SIZE); + memcpy(pgd_offset(mm, start), pgd_offset_k(start), + sizeof(pgd_t) * (pgd_index(end) - pgd_index(start))); +} + void __check_vmalloc_seq(struct mm_struct *mm) { int seq; do { - seq = atomic_read(&init_mm.context.vmalloc_seq); - memcpy(pgd_offset(mm, VMALLOC_START), - pgd_offset_k(VMALLOC_START), - sizeof(pgd_t) * (pgd_index(VMALLOC_END) - - pgd_index(VMALLOC_START))); + seq = atomic_read_acquire(&init_mm.context.vmalloc_seq); + memcpy_pgd(mm, VMALLOC_START, VMALLOC_END); + if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { + unsigned long start = + arm_kasan_mem_to_shadow(VMALLOC_START); + unsigned long end = + arm_kasan_mem_to_shadow(VMALLOC_END); + memcpy_pgd(mm, start, end); + } /* * Use a store-release so that other CPUs that observe the * counter's new value are guaranteed to see the results of the diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index b68efe643a12ca3242e5f4c5b68acb187f9e0382..d44867fc0c5ee893a5a09edfa10cc6863f3677b7 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -55,6 +55,34 @@ extern unsigned int VFP_arch_feroceon __alias(VFP_arch); */ union vfp_state *vfp_current_hw_state[NR_CPUS]; +/* + * Claim ownership of the VFP unit. + * + * The caller may change VFP registers until vfp_state_release() is called. + * + * local_bh_disable() is used to disable preemption and to disable VFP + * processing in softirq context. On PREEMPT_RT kernels local_bh_disable() is + * not sufficient because it only serializes soft interrupt related sections + * via a local lock, but stays preemptible. Disabling preemption is the right + * choice here as bottom half processing is always in thread context on RT + * kernels so it implicitly prevents bottom half processing as well. + */ +static void vfp_state_hold(void) +{ + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_bh_disable(); + else + preempt_disable(); +} + +static void vfp_state_release(void) +{ + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_bh_enable(); + else + preempt_enable(); +} + /* * Is 'thread's most up to date state stored in this CPUs hardware? * Must be called from non-preemptible context. @@ -240,7 +268,7 @@ static void vfp_panic(char *reason, u32 inst) /* * Process bitmask of exception conditions. */ -static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_regs *regs) +static int vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr) { int si_code = 0; @@ -248,8 +276,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ if (exceptions == VFP_EXCEPTION_ERROR) { vfp_panic("unhandled bounce", inst); - vfp_raise_sigfpe(FPE_FLTINV, regs); - return; + return FPE_FLTINV; } /* @@ -277,8 +304,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF); RAISE(FPSCR_IOC, FPSCR_IOE, FPE_FLTINV); - if (si_code) - vfp_raise_sigfpe(si_code, regs); + return si_code; } /* @@ -324,6 +350,8 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) { u32 fpscr, orig_fpscr, fpsid, exceptions; + int si_code2 = 0; + int si_code = 0; pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); @@ -369,8 +397,8 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) * unallocated VFP instruction but with FPSCR.IXE set and not * on VFP subarch 1. */ - vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs); - return; + si_code = vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr); + goto exit; } /* @@ -394,14 +422,14 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) */ exceptions = vfp_emulate_instruction(trigger, fpscr, regs); if (exceptions) - vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); + si_code2 = vfp_raise_exceptions(exceptions, trigger, orig_fpscr); /* * If there isn't a second FP instruction, exit now. Note that * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1. */ if ((fpexc & (FPEXC_EX | FPEXC_FP2V)) != (FPEXC_EX | FPEXC_FP2V)) - return; + goto exit; /* * The barrier() here prevents fpinst2 being read @@ -413,7 +441,13 @@ static void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) emulate: exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs); if (exceptions) - vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); + si_code = vfp_raise_exceptions(exceptions, trigger, orig_fpscr); +exit: + vfp_state_release(); + if (si_code2) + vfp_raise_sigfpe(si_code2, regs); + if (si_code) + vfp_raise_sigfpe(si_code, regs); } static void vfp_enable(void *unused) @@ -512,11 +546,9 @@ static inline void vfp_pm_init(void) { } */ void vfp_sync_hwstate(struct thread_info *thread) { - unsigned int cpu = get_cpu(); + vfp_state_hold(); - local_bh_disable(); - - if (vfp_state_in_hw(cpu, thread)) { + if (vfp_state_in_hw(raw_smp_processor_id(), thread)) { u32 fpexc = fmrx(FPEXC); /* @@ -527,8 +559,7 @@ void vfp_sync_hwstate(struct thread_info *thread) fmxr(FPEXC, fpexc); } - local_bh_enable(); - put_cpu(); + vfp_state_release(); } /* Ensure that the thread reloads the hardware VFP state on the next use. */ @@ -683,7 +714,7 @@ static int vfp_support_entry(struct pt_regs *regs, u32 trigger) if (!user_mode(regs)) return vfp_kmode_exception(regs, trigger); - local_bh_disable(); + vfp_state_hold(); fpexc = fmrx(FPEXC); /* @@ -748,6 +779,7 @@ static int vfp_support_entry(struct pt_regs *regs, u32 trigger) * replay the instruction that trapped. */ fmxr(FPEXC, fpexc); + vfp_state_release(); } else { /* Check for synchronous or asynchronous exceptions */ if (!(fpexc & (FPEXC_EX | FPEXC_DEX))) { @@ -762,17 +794,17 @@ static int vfp_support_entry(struct pt_regs *regs, u32 trigger) if (!(fpscr & FPSCR_IXE)) { if (!(fpscr & FPSCR_LENGTH_MASK)) { pr_debug("not VFP\n"); - local_bh_enable(); + vfp_state_release(); return -ENOEXEC; } fpexc |= FPEXC_DEX; } } bounce: regs->ARM_pc += 4; + /* VFP_bounce() will invoke vfp_state_release() */ VFP_bounce(trigger, fpexc, regs); } - local_bh_enable(); return 0; } @@ -837,7 +869,7 @@ void kernel_neon_begin(void) unsigned int cpu; u32 fpexc; - local_bh_disable(); + vfp_state_hold(); /* * Kernel mode NEON is only allowed outside of hardirq context with @@ -868,7 +900,7 @@ void kernel_neon_end(void) { /* Disable the NEON/VFP unit. */ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); - local_bh_enable(); + vfp_state_release(); } EXPORT_SYMBOL(kernel_neon_end); diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index d743737bf9ce9d9813ca307fd8ab3477ee502911..100570a048c5e8892c0112704f9ca74c4fc55b27 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -14,7 +14,6 @@ config ARM64 select ARCH_HAS_DEBUG_WX select ARCH_BINFMT_ELF_EXTRA_PHDRS select ARCH_BINFMT_ELF_STATE - select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION select ARCH_ENABLE_MEMORY_HOTPLUG select ARCH_ENABLE_MEMORY_HOTREMOVE @@ -1236,6 +1235,17 @@ config HISILICON_ERRATUM_161600802 If unsure, say Y. +config HISILICON_ERRATUM_162100801 + bool "Hip09 162100801 erratum support" + default y + help + When enabling GICv4.1 in hip09, VMAPP will fail to clear some caches + during unmapping operation, which will cause some vSGIs lost. + To fix the issue, invalidate related vPE cache through GICR_INVALLR + after VMOVP. + + If unsure, say Y. + config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" default y diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 9efd3f37c2fd9de155019f69cee1a0bb09e9a6dd..358c68565bfd0633d8565187016e1003445208fc 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -71,7 +71,7 @@ stack_protector_prepare: prepare0 -mstack-protector-guard-reg=sp_el0 \ -mstack-protector-guard-offset=$(shell \ awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ - include/generated/asm-offsets.h)) + $(objtree)/include/generated/asm-offsets.h)) endif ifeq ($(CONFIG_ARM64_BTI_KERNEL),y) diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi index ae0379fd42a91ce5420f97553736649434d469aa..dfc5c2f0ddefd7bb0f2b989fe3214ba9a903100b 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi @@ -14,6 +14,7 @@ compatible = "melfas,mip4_ts"; reg = <0x34>; interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; /* @@ -26,6 +27,7 @@ reg = <0x20>; hid-descr-addr = <0x0020>; interrupts-extended = <&pio 88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; /* Lenovo Ideapad C330 uses G2Touch touchscreen as a 2nd source touchscreen */ @@ -35,6 +37,7 @@ hid-descr-addr = <0x0001>; interrupt-parent = <&pio>; interrupts = <88 IRQ_TYPE_LEVEL_LOW>; + status = "fail-needs-probe"; }; }; @@ -47,6 +50,8 @@ trackpad2: trackpad@2c { compatible = "hid-over-i2c"; interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&trackpad_irq>; reg = <0x2c>; hid-descr-addr = <0x0020>; /* @@ -58,6 +63,7 @@ */ vdd-supply = <&mt6397_vgp6_reg>; wakeup-source; + status = "fail-needs-probe"; }; }; @@ -82,3 +88,11 @@ }; }; }; + +&touchscreen { + status = "fail-needs-probe"; +}; + +&trackpad { + status = "fail-needs-probe"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi index b4d85147b77b0b7c72fd49b3f3a94c57b6352d64..eee64461421f83cf280dcf2c25e089d3739277e6 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi @@ -358,12 +358,12 @@ &i2c4 { clock-frequency = <400000>; status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&trackpad_irq>; trackpad: trackpad@15 { compatible = "elan,ekth3000"; interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&trackpad_irq>; reg = <0x15>; vcc-supply = <&mt6397_vgp6_reg>; wakeup-source; diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c index a523b519700f518ef7b7887e4f94be3dcb729e07..a2b5d6f20f4d151931b8f9d29dd945c674ed026a 100644 --- a/arch/arm64/crypto/aes-ce-ccm-glue.c +++ b/arch/arm64/crypto/aes-ce-ccm-glue.c @@ -18,7 +18,7 @@ #include "aes-ce-setkey.h" -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); static int num_rounds(struct crypto_aes_ctx *ctx) { diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index a147e847a5a181af2679398cab4d63f6259a6ba3..b0150999743f68361f6ef2541ebee07bcf915173 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c @@ -1048,7 +1048,7 @@ unregister_ciphers: #ifdef USE_V8_CRYPTO_EXTENSIONS module_cpu_feature_match(AES, aes_init); -EXPORT_SYMBOL_NS(ce_aes_mac_update, CRYPTO_INTERNAL); +EXPORT_SYMBOL_NS(ce_aes_mac_update, "CRYPTO_INTERNAL"); #else module_init(aes_init); EXPORT_SYMBOL(neon_aes_ecb_encrypt); diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c index aeaa6017ffd89f3a53938bb71b061e48d749d613..9b36218b48def495708f49b59e5f9211bd86cc0f 100644 --- a/arch/arm64/kvm/nested.c +++ b/arch/arm64/kvm/nested.c @@ -951,7 +951,7 @@ u64 kvm_vcpu_apply_reg_masks(const struct kvm_vcpu *vcpu, return v; } -static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1) +static __always_inline void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1) { int i = sr - __SANITISED_REG_START__; diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 8ad62284fa230c6fbccd336737c493cfe6cd590e..456102bc0b555b41a01da5a41d25b57099026bd9 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -274,12 +274,23 @@ void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) irq_work_sync(&vcpu->arch.pmu.overflow_work); } -bool kvm_pmu_counter_is_hyp(struct kvm_vcpu *vcpu, unsigned int idx) +static u64 kvm_pmu_hyp_counter_mask(struct kvm_vcpu *vcpu) { - unsigned int hpmn; + unsigned int hpmn, n; - if (!vcpu_has_nv(vcpu) || idx == ARMV8_PMU_CYCLE_IDX) - return false; + if (!vcpu_has_nv(vcpu)) + return 0; + + hpmn = SYS_FIELD_GET(MDCR_EL2, HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2)); + n = vcpu->kvm->arch.pmcr_n; + + /* + * Programming HPMN to a value greater than PMCR_EL0.N is + * CONSTRAINED UNPREDICTABLE. Make the implementation choice that an + * UNKNOWN number of counters (in our case, zero) are reserved for EL2. + */ + if (hpmn >= n) + return 0; /* * Programming HPMN=0 is CONSTRAINED UNPREDICTABLE if FEAT_HPMN0 isn't @@ -288,20 +299,22 @@ bool kvm_pmu_counter_is_hyp(struct kvm_vcpu *vcpu, unsigned int idx) * implementation choice that all counters are included in the second * range reserved for EL2/EL3. */ - hpmn = SYS_FIELD_GET(MDCR_EL2, HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2)); - return idx >= hpmn; + return GENMASK(n - 1, hpmn); +} + +bool kvm_pmu_counter_is_hyp(struct kvm_vcpu *vcpu, unsigned int idx) +{ + return kvm_pmu_hyp_counter_mask(vcpu) & BIT(idx); } u64 kvm_pmu_accessible_counter_mask(struct kvm_vcpu *vcpu) { u64 mask = kvm_pmu_implemented_counter_mask(vcpu); - u64 hpmn; if (!vcpu_has_nv(vcpu) || vcpu_is_el2(vcpu)) return mask; - hpmn = SYS_FIELD_GET(MDCR_EL2, HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2)); - return mask & ~GENMASK(vcpu->kvm->arch.pmcr_n - 1, hpmn); + return mask & ~kvm_pmu_hyp_counter_mask(vcpu); } u64 kvm_pmu_implemented_counter_mask(struct kvm_vcpu *vcpu) @@ -375,15 +388,30 @@ void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val) } } -static u64 kvm_pmu_overflow_status(struct kvm_vcpu *vcpu) +/* + * Returns the PMU overflow state, which is true if there exists an event + * counter where the values of the global enable control, PMOVSSET_EL0[n], and + * PMINTENSET_EL1[n] are all 1. + */ +static bool kvm_pmu_overflow_status(struct kvm_vcpu *vcpu) { - u64 reg = 0; + u64 reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); - if ((kvm_vcpu_read_pmcr(vcpu) & ARMV8_PMU_PMCR_E)) { - reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); - reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0); - reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1); - } + reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1); + + /* + * PMCR_EL0.E is the global enable control for event counters available + * to EL0 and EL1. + */ + if (!(kvm_vcpu_read_pmcr(vcpu) & ARMV8_PMU_PMCR_E)) + reg &= kvm_pmu_hyp_counter_mask(vcpu); + + /* + * Otherwise, MDCR_EL2.HPME is the global enable control for event + * counters reserved for EL2. + */ + if (!(vcpu_read_sys_reg(vcpu, MDCR_EL2) & MDCR_EL2_HPME)) + reg &= ~kvm_pmu_hyp_counter_mask(vcpu); return reg; } @@ -396,7 +424,7 @@ static void kvm_pmu_update_state(struct kvm_vcpu *vcpu) if (!kvm_vcpu_has_pmu(vcpu)) return; - overflow = !!kvm_pmu_overflow_status(vcpu); + overflow = kvm_pmu_overflow_status(vcpu); if (pmu->irq_level == overflow) return; diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index e1397ab2072a57b8357ec73bfe7574841a74e5ef..afb018528bc3be8adf4c4f67efaff4072fd1600e 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -287,7 +287,10 @@ static int vgic_debug_show(struct seq_file *s, void *v) * Expect this to succeed, as iter_mark_lpis() takes a reference on * every LPI to be visited. */ - irq = vgic_get_irq(kvm, vcpu, iter->intid); + if (iter->intid < VGIC_NR_PRIVATE_IRQS) + irq = vgic_get_vcpu_irq(vcpu, iter->intid); + else + irq = vgic_get_irq(kvm, iter->intid); if (WARN_ON_ONCE(!irq)) return -EINVAL; diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 48c952563e85fd5b0aea77be946cfb0f324c5bf8..bc7e22ab5d812256e6568d948b4de92f3fd0e5af 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -322,7 +322,7 @@ int vgic_init(struct kvm *kvm) goto out; for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) { - struct vgic_irq *irq = vgic_get_irq(kvm, vcpu, i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i); switch (dist->vgic_model) { case KVM_DEV_TYPE_ARM_VGIC_V3: diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index 198296933e7ebf4a1308cf1e3372a89094198357..f4c4494645c34bf145baedf63267cbdee16cbe4c 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -31,6 +31,41 @@ static int vgic_its_commit_v0(struct vgic_its *its); static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq, struct kvm_vcpu *filter_vcpu, bool needs_inv); +#define vgic_its_read_entry_lock(i, g, valp, t) \ + ({ \ + int __sz = vgic_its_get_abi(i)->t##_esz; \ + struct kvm *__k = (i)->dev->kvm; \ + int __ret; \ + \ + BUILD_BUG_ON(NR_ITS_ABIS == 1 && \ + sizeof(*(valp)) != ABI_0_ESZ); \ + if (NR_ITS_ABIS > 1 && \ + KVM_BUG_ON(__sz != sizeof(*(valp)), __k)) \ + __ret = -EINVAL; \ + else \ + __ret = kvm_read_guest_lock(__k, (g), \ + valp, __sz); \ + __ret; \ + }) + +#define vgic_its_write_entry_lock(i, g, val, t) \ + ({ \ + int __sz = vgic_its_get_abi(i)->t##_esz; \ + struct kvm *__k = (i)->dev->kvm; \ + typeof(val) __v = (val); \ + int __ret; \ + \ + BUILD_BUG_ON(NR_ITS_ABIS == 1 && \ + sizeof(__v) != ABI_0_ESZ); \ + if (NR_ITS_ABIS > 1 && \ + KVM_BUG_ON(__sz != sizeof(__v), __k)) \ + __ret = -EINVAL; \ + else \ + __ret = vgic_write_guest_lock(__k, (g), \ + &__v, __sz); \ + __ret; \ + }) + /* * Creates a new (reference to a) struct vgic_irq for a given LPI. * If this LPI is already mapped on another ITS, we increase its refcount @@ -42,7 +77,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, struct kvm_vcpu *vcpu) { struct vgic_dist *dist = &kvm->arch.vgic; - struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intid), *oldirq; + struct vgic_irq *irq = vgic_get_irq(kvm, intid), *oldirq; unsigned long flags; int ret; @@ -419,7 +454,7 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu) last_byte_offset = byte_offset; } - irq = vgic_get_irq(vcpu->kvm, NULL, intid); + irq = vgic_get_irq(vcpu->kvm, intid); if (!irq) continue; @@ -794,7 +829,7 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its, its_free_ite(kvm, ite); - return vgic_its_write_entry_lock(its, gpa, 0, ite_esz); + return vgic_its_write_entry_lock(its, gpa, 0ULL, ite); } return E_ITS_DISCARD_UNMAPPED_INTERRUPT; @@ -1143,7 +1178,6 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its, bool valid = its_cmd_get_validbit(its_cmd); u8 num_eventid_bits = its_cmd_get_size(its_cmd); gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd); - int dte_esz = vgic_its_get_abi(its)->dte_esz; struct its_device *device; gpa_t gpa; @@ -1168,7 +1202,7 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its, * is an error, so we are done in any case. */ if (!valid) - return vgic_its_write_entry_lock(its, gpa, 0, dte_esz); + return vgic_its_write_entry_lock(its, gpa, 0ULL, dte); device = vgic_its_alloc_device(its, device_id, itt_addr, num_eventid_bits); @@ -1288,7 +1322,7 @@ int vgic_its_invall(struct kvm_vcpu *vcpu) unsigned long intid; xa_for_each(&dist->lpi_xa, intid, irq) { - irq = vgic_get_irq(kvm, NULL, intid); + irq = vgic_get_irq(kvm, intid); if (!irq) continue; @@ -1354,7 +1388,7 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its, return 0; xa_for_each(&dist->lpi_xa, intid, irq) { - irq = vgic_get_irq(kvm, NULL, intid); + irq = vgic_get_irq(kvm, intid); if (!irq) continue; @@ -2090,7 +2124,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz, * vgic_its_save_ite - Save an interrupt translation entry at @gpa */ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev, - struct its_ite *ite, gpa_t gpa, int ite_esz) + struct its_ite *ite, gpa_t gpa) { u32 next_offset; u64 val; @@ -2101,7 +2135,7 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev, ite->collection->collection_id; val = cpu_to_le64(val); - return vgic_its_write_entry_lock(its, gpa, val, ite_esz); + return vgic_its_write_entry_lock(its, gpa, val, ite); } /** @@ -2201,7 +2235,7 @@ static int vgic_its_save_itt(struct vgic_its *its, struct its_device *device) if (ite->irq->hw && !kvm_vgic_global_state.has_gicv4_1) return -EACCES; - ret = vgic_its_save_ite(its, device, ite, gpa, ite_esz); + ret = vgic_its_save_ite(its, device, ite, gpa); if (ret) return ret; } @@ -2240,10 +2274,9 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev) * @its: ITS handle * @dev: ITS device * @ptr: GPA - * @dte_esz: device table entry size */ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev, - gpa_t ptr, int dte_esz) + gpa_t ptr) { u64 val, itt_addr_field; u32 next_offset; @@ -2256,7 +2289,7 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev, (dev->num_eventid_bits - 1)); val = cpu_to_le64(val); - return vgic_its_write_entry_lock(its, ptr, val, dte_esz); + return vgic_its_write_entry_lock(its, ptr, val, dte); } /** @@ -2332,10 +2365,8 @@ static int vgic_its_device_cmp(void *priv, const struct list_head *a, */ static int vgic_its_save_device_tables(struct vgic_its *its) { - const struct vgic_its_abi *abi = vgic_its_get_abi(its); u64 baser = its->baser_device_table; struct its_device *dev; - int dte_esz = abi->dte_esz; if (!(baser & GITS_BASER_VALID)) return 0; @@ -2354,7 +2385,7 @@ static int vgic_its_save_device_tables(struct vgic_its *its) if (ret) return ret; - ret = vgic_its_save_dte(its, dev, eaddr, dte_esz); + ret = vgic_its_save_dte(its, dev, eaddr); if (ret) return ret; } @@ -2435,7 +2466,7 @@ static int vgic_its_restore_device_tables(struct vgic_its *its) static int vgic_its_save_cte(struct vgic_its *its, struct its_collection *collection, - gpa_t gpa, int esz) + gpa_t gpa) { u64 val; @@ -2444,7 +2475,7 @@ static int vgic_its_save_cte(struct vgic_its *its, collection->collection_id); val = cpu_to_le64(val); - return vgic_its_write_entry_lock(its, gpa, val, esz); + return vgic_its_write_entry_lock(its, gpa, val, cte); } /* @@ -2452,7 +2483,7 @@ static int vgic_its_save_cte(struct vgic_its *its, * Return +1 on success, 0 if the entry was invalid (which should be * interpreted as end-of-table), and a negative error value for generic errors. */ -static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz) +static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa) { struct its_collection *collection; struct kvm *kvm = its->dev->kvm; @@ -2460,7 +2491,7 @@ static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz) u64 val; int ret; - ret = vgic_its_read_entry_lock(its, gpa, &val, esz); + ret = vgic_its_read_entry_lock(its, gpa, &val, cte); if (ret) return ret; val = le64_to_cpu(val); @@ -2507,7 +2538,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its) max_size = GITS_BASER_NR_PAGES(baser) * SZ_64K; list_for_each_entry(collection, &its->collection_list, coll_list) { - ret = vgic_its_save_cte(its, collection, gpa, cte_esz); + ret = vgic_its_save_cte(its, collection, gpa); if (ret) return ret; gpa += cte_esz; @@ -2521,7 +2552,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its) * table is not fully filled, add a last dummy element * with valid bit unset */ - return vgic_its_write_entry_lock(its, gpa, 0, cte_esz); + return vgic_its_write_entry_lock(its, gpa, 0ULL, cte); } /* @@ -2546,7 +2577,7 @@ static int vgic_its_restore_collection_table(struct vgic_its *its) max_size = GITS_BASER_NR_PAGES(baser) * SZ_64K; while (read < max_size) { - ret = vgic_its_restore_cte(its, gpa, cte_esz); + ret = vgic_its_restore_cte(its, gpa); if (ret <= 0) break; gpa += cte_esz; diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v2.c b/arch/arm64/kvm/vgic/vgic-mmio-v2.c index e070cda86e12ffeb12a94284cc34e93d55cf4353..f25fccb1f8e63c2813613f02faeff82d1a1f7b3d 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v2.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v2.c @@ -148,7 +148,7 @@ static void vgic_mmio_write_sgir(struct kvm_vcpu *source_vcpu, if (!(targets & (1U << c))) continue; - irq = vgic_get_irq(source_vcpu->kvm, vcpu, intid); + irq = vgic_get_vcpu_irq(vcpu, intid); raw_spin_lock_irqsave(&irq->irq_lock, flags); irq->pending_latch = true; @@ -167,7 +167,7 @@ static unsigned long vgic_mmio_read_target(struct kvm_vcpu *vcpu, u64 val = 0; for (i = 0; i < len; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); val |= (u64)irq->targets << (i * 8); @@ -191,7 +191,7 @@ static void vgic_mmio_write_target(struct kvm_vcpu *vcpu, return; for (i = 0; i < len; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid + i); + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, intid + i); int target; raw_spin_lock_irqsave(&irq->irq_lock, flags); @@ -213,7 +213,7 @@ static unsigned long vgic_mmio_read_sgipend(struct kvm_vcpu *vcpu, u64 val = 0; for (i = 0; i < len; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); val |= (u64)irq->source << (i * 8); @@ -231,7 +231,7 @@ static void vgic_mmio_write_sgipendc(struct kvm_vcpu *vcpu, unsigned long flags; for (i = 0; i < len; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); @@ -253,7 +253,7 @@ static void vgic_mmio_write_sgipends(struct kvm_vcpu *vcpu, unsigned long flags; for (i = 0; i < len; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index 9e50928f5d7dfd22880f8fb874a6bebb16f36989..ae4c0593d11455f395761d1fcb108cc23ce1fdd0 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -194,7 +194,7 @@ static unsigned long vgic_mmio_read_irouter(struct kvm_vcpu *vcpu, gpa_t addr, unsigned int len) { int intid = VGIC_ADDR_TO_INTID(addr, 64); - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid); + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, intid); unsigned long ret = 0; if (!irq) @@ -220,7 +220,7 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu, if (addr & 4) return; - irq = vgic_get_irq(vcpu->kvm, NULL, intid); + irq = vgic_get_irq(vcpu->kvm, intid); if (!irq) return; @@ -530,6 +530,7 @@ static void vgic_mmio_write_invlpi(struct kvm_vcpu *vcpu, unsigned long val) { struct vgic_irq *irq; + u32 intid; /* * If the guest wrote only to the upper 32bit part of the @@ -541,9 +542,13 @@ static void vgic_mmio_write_invlpi(struct kvm_vcpu *vcpu, if ((addr & 4) || !vgic_lpis_enabled(vcpu)) return; + intid = lower_32_bits(val); + if (intid < VGIC_MIN_LPI) + return; + vgic_set_rdist_busy(vcpu, true); - irq = vgic_get_irq(vcpu->kvm, NULL, lower_32_bits(val)); + irq = vgic_get_irq(vcpu->kvm, intid); if (irq) { vgic_its_inv_lpi(vcpu->kvm, irq); vgic_put_irq(vcpu->kvm, irq); @@ -1020,7 +1025,7 @@ int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr) static void vgic_v3_queue_sgi(struct kvm_vcpu *vcpu, u32 sgi, bool allow_group1) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, sgi); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, sgi); unsigned long flags; raw_spin_lock_irqsave(&irq->irq_lock, flags); diff --git a/arch/arm64/kvm/vgic/vgic-mmio.c b/arch/arm64/kvm/vgic/vgic-mmio.c index cf76523a219456dda0891ac9e6f21fb4eadf7e48..e416e433baff3ea5f8d743843e141374316bdf96 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio.c +++ b/arch/arm64/kvm/vgic/vgic-mmio.c @@ -50,7 +50,7 @@ unsigned long vgic_mmio_read_group(struct kvm_vcpu *vcpu, /* Loop over all IRQs affected by this read */ for (i = 0; i < len * 8; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); if (irq->group) value |= BIT(i); @@ -74,7 +74,7 @@ void vgic_mmio_write_group(struct kvm_vcpu *vcpu, gpa_t addr, unsigned long flags; for (i = 0; i < len * 8; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); irq->group = !!(val & BIT(i)); @@ -102,7 +102,7 @@ unsigned long vgic_mmio_read_enable(struct kvm_vcpu *vcpu, /* Loop over all IRQs affected by this read */ for (i = 0; i < len * 8; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); if (irq->enabled) value |= (1U << i); @@ -122,7 +122,7 @@ void vgic_mmio_write_senable(struct kvm_vcpu *vcpu, unsigned long flags; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); if (irq->hw && vgic_irq_is_sgi(irq->intid)) { @@ -171,7 +171,7 @@ void vgic_mmio_write_cenable(struct kvm_vcpu *vcpu, unsigned long flags; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); if (irq->hw && vgic_irq_is_sgi(irq->intid) && irq->enabled) @@ -193,7 +193,7 @@ int vgic_uaccess_write_senable(struct kvm_vcpu *vcpu, unsigned long flags; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); irq->enabled = true; @@ -214,7 +214,7 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, unsigned long flags; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); irq->enabled = false; @@ -236,7 +236,7 @@ static unsigned long __read_pending(struct kvm_vcpu *vcpu, /* Loop over all IRQs affected by this read */ for (i = 0; i < len * 8; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); unsigned long flags; bool val; @@ -309,7 +309,7 @@ static void __set_pending(struct kvm_vcpu *vcpu, gpa_t addr, unsigned int len, unsigned long flags; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); /* GICD_ISPENDR0 SGI bits are WI when written from the guest. */ if (is_vgic_v2_sgi(vcpu, irq) && !is_user) { @@ -395,7 +395,7 @@ static void __clear_pending(struct kvm_vcpu *vcpu, unsigned long flags; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); /* GICD_ICPENDR0 SGI bits are WI when written from the guest. */ if (is_vgic_v2_sgi(vcpu, irq) && !is_user) { @@ -494,7 +494,7 @@ static unsigned long __vgic_mmio_read_active(struct kvm_vcpu *vcpu, /* Loop over all IRQs affected by this read */ for (i = 0; i < len * 8; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); /* * Even for HW interrupts, don't evaluate the HW state as @@ -598,7 +598,7 @@ static void __vgic_mmio_write_cactive(struct kvm_vcpu *vcpu, int i; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); vgic_mmio_change_active(vcpu, irq, false); vgic_put_irq(vcpu->kvm, irq); } @@ -635,7 +635,7 @@ static void __vgic_mmio_write_sactive(struct kvm_vcpu *vcpu, int i; for_each_set_bit(i, &val, len * 8) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); vgic_mmio_change_active(vcpu, irq, true); vgic_put_irq(vcpu->kvm, irq); } @@ -672,7 +672,7 @@ unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu, u64 val = 0; for (i = 0; i < len; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); val |= (u64)irq->priority << (i * 8); @@ -698,7 +698,7 @@ void vgic_mmio_write_priority(struct kvm_vcpu *vcpu, unsigned long flags; for (i = 0; i < len; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); /* Narrow the priority range to what we actually support */ @@ -719,7 +719,7 @@ unsigned long vgic_mmio_read_config(struct kvm_vcpu *vcpu, int i; for (i = 0; i < len * 4; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i); if (irq->config == VGIC_CONFIG_EDGE) value |= (2U << (i * 2)); @@ -750,7 +750,7 @@ void vgic_mmio_write_config(struct kvm_vcpu *vcpu, if (intid + i < VGIC_NR_PRIVATE_IRQS) continue; - irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + irq = vgic_get_irq(vcpu->kvm, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); if (test_bit(i * 2 + 1, &val)) @@ -775,7 +775,7 @@ u32 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid) if ((intid + i) < VGIC_NR_SGIS || (intid + i) >= nr_irqs) continue; - irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + irq = vgic_get_vcpu_irq(vcpu, intid + i); if (irq->config == VGIC_CONFIG_LEVEL && irq->line_level) val |= (1U << i); @@ -799,7 +799,7 @@ void vgic_write_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid, if ((intid + i) < VGIC_NR_SGIS || (intid + i) >= nr_irqs) continue; - irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + irq = vgic_get_vcpu_irq(vcpu, intid + i); /* * Line level is set irrespective of irq type diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c index ae5a44d5702d14d23fec89c355d4b44b26ceba56..381673f03c395dc096849c85477054b6a63df5dd 100644 --- a/arch/arm64/kvm/vgic/vgic-v2.c +++ b/arch/arm64/kvm/vgic/vgic-v2.c @@ -72,7 +72,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) kvm_notify_acked_irq(vcpu->kvm, 0, intid - VGIC_NR_PRIVATE_IRQS); - irq = vgic_get_irq(vcpu->kvm, vcpu, intid); + irq = vgic_get_vcpu_irq(vcpu, intid); raw_spin_lock(&irq->irq_lock); diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index b217b256853c2aebffcfcf4e7bcb779cf08cf039..f267bc2486a18edfa41c6cbc10fac9457d1e4c18 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -65,7 +65,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) kvm_notify_acked_irq(vcpu->kvm, 0, intid - VGIC_NR_PRIVATE_IRQS); - irq = vgic_get_irq(vcpu->kvm, vcpu, intid); + irq = vgic_get_vcpu_irq(vcpu, intid); if (!irq) /* An LPI could have been unmapped. */ continue; diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index 74a67ad87f29de261a712c275573395e02d3351d..eedecbbbcf31bb746ecf839d1c0462f2dd9fea51 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -123,7 +123,7 @@ static void vgic_v4_enable_vsgis(struct kvm_vcpu *vcpu) * IRQ. The SGI code will do its magic. */ for (i = 0; i < VGIC_NR_SGIS; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i); struct irq_desc *desc; unsigned long flags; int ret; @@ -160,7 +160,7 @@ static void vgic_v4_disable_vsgis(struct kvm_vcpu *vcpu) int i; for (i = 0; i < VGIC_NR_SGIS; i++) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, i); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i); struct irq_desc *desc; unsigned long flags; int ret; diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index f50274fd558156dd42cdee19ee8ad0438bda1093..cc8c6b9b5dd8b10417cefc13070e38a07cfae711 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -84,17 +84,11 @@ static struct vgic_irq *vgic_get_lpi(struct kvm *kvm, u32 intid) * struct vgic_irq. It also increases the refcount, so any caller is expected * to call vgic_put_irq() once it's finished with this IRQ. */ -struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, - u32 intid) +struct vgic_irq *vgic_get_irq(struct kvm *kvm, u32 intid) { - /* SGIs and PPIs */ - if (intid <= VGIC_MAX_PRIVATE) { - intid = array_index_nospec(intid, VGIC_MAX_PRIVATE + 1); - return &vcpu->arch.vgic_cpu.private_irqs[intid]; - } - /* SPIs */ - if (intid < (kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) { + if (intid >= VGIC_NR_PRIVATE_IRQS && + intid < (kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) { intid = array_index_nospec(intid, kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS); return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS]; } @@ -106,6 +100,20 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, return NULL; } +struct vgic_irq *vgic_get_vcpu_irq(struct kvm_vcpu *vcpu, u32 intid) +{ + if (WARN_ON(!vcpu)) + return NULL; + + /* SGIs and PPIs */ + if (intid < VGIC_NR_PRIVATE_IRQS) { + intid = array_index_nospec(intid, VGIC_NR_PRIVATE_IRQS); + return &vcpu->arch.vgic_cpu.private_irqs[intid]; + } + + return vgic_get_irq(vcpu->kvm, intid); +} + /* * We can't do anything in here, because we lack the kvm pointer to * lock and remove the item from the lpi_list. So we keep this function @@ -437,7 +445,10 @@ int kvm_vgic_inject_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, trace_vgic_update_irq_pending(vcpu ? vcpu->vcpu_idx : 0, intid, level); - irq = vgic_get_irq(kvm, vcpu, intid); + if (intid < VGIC_NR_PRIVATE_IRQS) + irq = vgic_get_vcpu_irq(vcpu, intid); + else + irq = vgic_get_irq(kvm, intid); if (!irq) return -EINVAL; @@ -499,7 +510,7 @@ static inline void kvm_vgic_unmap_irq(struct vgic_irq *irq) int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, u32 vintid, struct irq_ops *ops) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, vintid); unsigned long flags; int ret; @@ -524,7 +535,7 @@ int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, */ void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, vintid); unsigned long flags; if (!irq->hw) @@ -547,7 +558,7 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid) if (!vgic_initialized(vcpu->kvm)) return -EAGAIN; - irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); + irq = vgic_get_vcpu_irq(vcpu, vintid); BUG_ON(!irq); raw_spin_lock_irqsave(&irq->irq_lock, flags); @@ -560,7 +571,7 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid) int kvm_vgic_get_map(struct kvm_vcpu *vcpu, unsigned int vintid) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); + struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, vintid); unsigned long flags; int ret = -1; @@ -596,7 +607,7 @@ int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner) if (!irq_is_ppi(intid) && !vgic_valid_spi(vcpu->kvm, intid)) return -EINVAL; - irq = vgic_get_irq(vcpu->kvm, vcpu, intid); + irq = vgic_get_vcpu_irq(vcpu, intid); raw_spin_lock_irqsave(&irq->irq_lock, flags); if (irq->owner && irq->owner != owner) ret = -EEXIST; @@ -1008,7 +1019,7 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid) if (!vgic_initialized(vcpu->kvm)) return false; - irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); + irq = vgic_get_vcpu_irq(vcpu, vintid); raw_spin_lock_irqsave(&irq->irq_lock, flags); map_is_active = irq->hw && irq->active; raw_spin_unlock_irqrestore(&irq->irq_lock, flags); diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 309295f5e1b0744f5ce88e1bbb0674008ace4094..122d95b4e2845ad45814fdc42dc528a0238b99ae 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -146,29 +146,6 @@ static inline int vgic_write_guest_lock(struct kvm *kvm, gpa_t gpa, return ret; } -static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr, - u64 *eval, unsigned long esize) -{ - struct kvm *kvm = its->dev->kvm; - - if (KVM_BUG_ON(esize != sizeof(*eval), kvm)) - return -EINVAL; - - return kvm_read_guest_lock(kvm, eaddr, eval, esize); - -} - -static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr, - u64 eval, unsigned long esize) -{ - struct kvm *kvm = its->dev->kvm; - - if (KVM_BUG_ON(esize != sizeof(eval), kvm)) - return -EINVAL; - - return vgic_write_guest_lock(kvm, eaddr, &eval, esize); -} - /* * This struct provides an intermediate representation of the fields contained * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC @@ -202,8 +179,8 @@ int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr, const struct vgic_register_region * vgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev, gpa_t addr, int len); -struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, - u32 intid); +struct vgic_irq *vgic_get_irq(struct kvm *kvm, u32 intid); +struct vgic_irq *vgic_get_vcpu_irq(struct kvm_vcpu *vcpu, u32 intid); void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq); bool vgic_get_phys_line_level(struct vgic_irq *irq); void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending); diff --git a/arch/loongarch/include/asm/hugetlb.h b/arch/loongarch/include/asm/hugetlb.h index b837c65a4894ea5caa9d021fc0962e8838cd3748..c8e4057734d0de763a3af9a177173726038134d4 100644 --- a/arch/loongarch/include/asm/hugetlb.h +++ b/arch/loongarch/include/asm/hugetlb.h @@ -24,6 +24,16 @@ static inline int prepare_hugepage_range(struct file *file, return 0; } +#define __HAVE_ARCH_HUGE_PTE_CLEAR +static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long sz) +{ + pte_t clear; + + pte_val(clear) = (unsigned long)invalid_pte_table; + set_pte_at(mm, addr, ptep, clear); +} + #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h index 944482063f14e32f57fbd9aa82488bb7418a6617..3089785ca97e78d49567b999a7f9ecc7dd9f7274 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -683,7 +683,17 @@ DEF_EMIT_REG2I16_FORMAT(blt, blt_op) DEF_EMIT_REG2I16_FORMAT(bge, bge_op) DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op) DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op) -DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op) + +static inline void emit_jirl(union loongarch_instruction *insn, + enum loongarch_gpr rd, + enum loongarch_gpr rj, + int offset) +{ + insn->reg2i16_format.opcode = jirl_op; + insn->reg2i16_format.immediate = offset; + insn->reg2i16_format.rd = rd; + insn->reg2i16_format.rj = rj; +} #define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP) \ static inline void emit_##NAME(union loongarch_instruction *insn, \ diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 2bf86aeda874c79f58ad6d6ba79477a4eda1811b..de21e72759eebcc126dae6f6739a0e7495cb380d 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -95,7 +95,7 @@ static void __init init_screen_info(void) memset(si, 0, sizeof(*si)); early_memunmap(si, sizeof(*si)); - memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); + memblock_reserve(__screen_info_lfb_base(&screen_info), screen_info.lfb_size); } void __init efi_init(void) diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index 3050329556d118c0933032739bc0662cc47ef29d..14d7d700bcb98ff3d666cc102e10a7be111313ca 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -332,7 +332,7 @@ u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm) return INSN_BREAK; } - emit_jirl(&insn, rj, rd, imm >> 2); + emit_jirl(&insn, rd, rj, imm >> 2); return insn.word; } diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 5d59e9ce2772d8a7f885ce35e715bff77c0fa021..fbf747447f13fd356edb056cc3f5dea502e813b7 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -82,7 +82,7 @@ void show_ipi_list(struct seq_file *p, int prec) for (i = 0; i < NR_IPI; i++) { seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, prec >= 4 ? " " : ""); for_each_online_cpu(cpu) - seq_printf(p, "%10u ", per_cpu(irq_stat, cpu).ipi_irqs[i]); + seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, cpu).ipi_irqs[i], 10); seq_printf(p, " LoongArch %d %s\n", i + 1, ipi_types[i]); } } diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c index 69f3e3782cc9efbc8a2b87e798fad2f2256e6772..a7893bd01e732a85e116762eb10e18edd806450c 100644 --- a/arch/loongarch/kvm/exit.c +++ b/arch/loongarch/kvm/exit.c @@ -156,7 +156,7 @@ static int kvm_handle_csr(struct kvm_vcpu *vcpu, larch_inst inst) int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu) { - int ret; + int idx, ret; unsigned long *val; u32 addr, rd, rj, opcode; @@ -167,7 +167,6 @@ int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu) rj = inst.reg2_format.rj; opcode = inst.reg2_format.opcode; addr = vcpu->arch.gprs[rj]; - ret = EMULATE_DO_IOCSR; run->iocsr_io.phys_addr = addr; run->iocsr_io.is_write = 0; val = &vcpu->arch.gprs[rd]; @@ -207,20 +206,28 @@ int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu) } if (run->iocsr_io.is_write) { - if (!kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, run->iocsr_io.len, val)) + idx = srcu_read_lock(&vcpu->kvm->srcu); + ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, run->iocsr_io.len, val); + srcu_read_unlock(&vcpu->kvm->srcu, idx); + if (ret == 0) ret = EMULATE_DONE; - else + else { + ret = EMULATE_DO_IOCSR; /* Save data and let user space to write it */ memcpy(run->iocsr_io.data, val, run->iocsr_io.len); - + } trace_kvm_iocsr(KVM_TRACE_IOCSR_WRITE, run->iocsr_io.len, addr, val); } else { - if (!kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, run->iocsr_io.len, val)) + idx = srcu_read_lock(&vcpu->kvm->srcu); + ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, run->iocsr_io.len, val); + srcu_read_unlock(&vcpu->kvm->srcu, idx); + if (ret == 0) ret = EMULATE_DONE; - else + else { + ret = EMULATE_DO_IOCSR; /* Save register id for iocsr read completion */ vcpu->arch.io_gpr = rd; - + } trace_kvm_iocsr(KVM_TRACE_IOCSR_READ, run->iocsr_io.len, addr, NULL); } @@ -359,7 +366,7 @@ static int kvm_handle_gspr(struct kvm_vcpu *vcpu) int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst) { - int ret; + int idx, ret; unsigned int op8, opcode, rd; struct kvm_run *run = vcpu->run; @@ -464,8 +471,10 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst) * it need not return to user space to handle the mmio * exception. */ + idx = srcu_read_lock(&vcpu->kvm->srcu); ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, vcpu->arch.badv, run->mmio.len, &vcpu->arch.gprs[rd]); + srcu_read_unlock(&vcpu->kvm->srcu, idx); if (!ret) { update_pc(&vcpu->arch); vcpu->mmio_needed = 0; @@ -531,7 +540,7 @@ int kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run) int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst) { - int ret; + int idx, ret; unsigned int rd, op8, opcode; unsigned long curr_pc, rd_val = 0; struct kvm_run *run = vcpu->run; @@ -631,7 +640,9 @@ int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst) * it need not return to user space to handle the mmio * exception. */ + idx = srcu_read_lock(&vcpu->kvm->srcu); ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, vcpu->arch.badv, run->mmio.len, data); + srcu_read_unlock(&vcpu->kvm->srcu, idx); if (!ret) return EMULATE_DONE; diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c index a233a323e29577bc6e4de96997dc2e204ba13900..93f4acd445236eb352233d766f47d6a78c789578 100644 --- a/arch/loongarch/kvm/intc/ipi.c +++ b/arch/loongarch/kvm/intc/ipi.c @@ -98,7 +98,7 @@ static void write_mailbox(struct kvm_vcpu *vcpu, int offset, uint64_t data, int static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) { - int i, ret; + int i, idx, ret; uint32_t val = 0, mask = 0; /* @@ -107,7 +107,9 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) */ if ((data >> 27) & 0xf) { /* Read the old val */ + idx = srcu_read_lock(&vcpu->kvm->srcu); ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); + srcu_read_unlock(&vcpu->kvm->srcu, idx); if (unlikely(ret)) { kvm_err("%s: : read date from addr %llx failed\n", __func__, addr); return ret; @@ -121,7 +123,9 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data) val &= mask; } val |= ((uint32_t)(data >> 32) & ~mask); + idx = srcu_read_lock(&vcpu->kvm->srcu); ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); + srcu_read_unlock(&vcpu->kvm->srcu, idx); if (unlikely(ret)) kvm_err("%s: : write date to addr %llx failed\n", __func__, addr); diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index cab1818be68d852ac66e4abfb9f941b8236c7e93..d18a4a2704150ebdac537fe6348f1c6ae4daaca7 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -240,7 +240,7 @@ static void kvm_late_check_requests(struct kvm_vcpu *vcpu) */ static int kvm_enter_guest_check(struct kvm_vcpu *vcpu) { - int ret; + int idx, ret; /* * Check conditions before entering the guest @@ -249,7 +249,9 @@ static int kvm_enter_guest_check(struct kvm_vcpu *vcpu) if (ret < 0) return ret; + idx = srcu_read_lock(&vcpu->kvm->srcu); ret = kvm_check_requests(vcpu); + srcu_read_unlock(&vcpu->kvm->srcu, idx); return ret; } diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index dd350cba1252f919685ff87ff5dc330758c62429..ea357a3edc094370ab8daff2d489efbe8ecdf91a 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -181,13 +181,13 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call) /* Set return value */ emit_insn(ctx, addiw, LOONGARCH_GPR_A0, regmap[BPF_REG_0], 0); /* Return to the caller */ - emit_insn(ctx, jirl, LOONGARCH_GPR_RA, LOONGARCH_GPR_ZERO, 0); + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0); } else { /* * Call the next bpf prog and skip the first instruction * of TCC initialization. */ - emit_insn(ctx, jirl, LOONGARCH_GPR_T3, LOONGARCH_GPR_ZERO, 1); + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 1); } } @@ -904,7 +904,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext return ret; move_addr(ctx, t1, func_addr); - emit_insn(ctx, jirl, t1, LOONGARCH_GPR_RA, 0); + emit_insn(ctx, jirl, LOONGARCH_GPR_RA, t1, 0); move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0); break; diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index f8edc9082724212a2e5d4dd3aac1208e8938fc8f..20d877cb4e308b10e48bfd872c45af795feed098 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -503,6 +503,7 @@ CONFIG_UHID=m # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y # CONFIG_RTC_NVMEM is not set +CONFIG_RTC_DRV_M48T59=m CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m CONFIG_RTC_DRV_GENERIC=m diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 71fc71bb660e0f4397632ed55d7e55acf7e9bab9..5e1c8d0d3da57de9397220b9544e0f883c4c2c30 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -391,6 +391,7 @@ CONFIG_UHID=m # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y # CONFIG_RTC_NVMEM is not set +CONFIG_RTC_DRV_M48T59=y CONFIG_RTC_DRV_GENERIC=m # CONFIG_VIRTIO_MENU is not set # CONFIG_VHOST_MENU is not set diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 41072e68028e2af494af93643cb312cdfbcc8e5d..5d1409e6a13773b43236ebe6d9a442348ac624a6 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -392,6 +392,7 @@ CONFIG_UHID=m # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y # CONFIG_RTC_NVMEM is not set +CONFIG_RTC_DRV_M48T59=y CONFIG_RTC_DRV_GENERIC=m # CONFIG_VIRTIO_MENU is not set # CONFIG_VHOST_MENU is not set diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h index dbf88059e47a4dd44199b2636b8697f2da153608..6ad93bac06f9d9e312a060aeda100fe24f5e1c5b 100644 --- a/arch/m68k/include/asm/mvme147hw.h +++ b/arch/m68k/include/asm/mvme147hw.h @@ -4,24 +4,7 @@ #include -typedef struct { - unsigned char - ctrl, - bcd_sec, - bcd_min, - bcd_hr, - bcd_dow, - bcd_dom, - bcd_mth, - bcd_year; -} MK48T02; - -#define RTC_WRITE 0x80 -#define RTC_READ 0x40 -#define RTC_STOP 0x20 - -#define m147_rtc ((MK48T02 * volatile)0xfffe07f8) - +#define MVME147_RTC_BASE 0xfffe0000 struct pcc_regs { volatile u_long dma_tadr; diff --git a/arch/m68k/include/asm/mvme16xhw.h b/arch/m68k/include/asm/mvme16xhw.h index cc7f5ae1220ff73e898c58b9a56247fd118c515a..ff1126a51fbecadbab757dbcf7141cf4458328ce 100644 --- a/arch/m68k/include/asm/mvme16xhw.h +++ b/arch/m68k/include/asm/mvme16xhw.h @@ -24,23 +24,7 @@ typedef struct { #define mvmelp ((*(volatile MVMElpPtr)(MVME_LPR_BASE))) -typedef struct { - unsigned char - ctrl, - bcd_sec, - bcd_min, - bcd_hr, - bcd_dow, - bcd_dom, - bcd_mth, - bcd_year; -} MK48T08_t, *MK48T08ptr_t; - -#define RTC_WRITE 0x80 -#define RTC_READ 0x40 -#define RTC_STOP 0x20 - -#define MVME_RTC_BASE 0xfffc1ff8 +#define MVME_RTC_BASE 0xfffc0000 #define MVME_I596_BASE 0xfff46000 diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index 824c42a302c6fd018a8b20a01c1dd11147fa90b3..3054d3857efa2b652375863071e15530810b62c0 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c @@ -19,8 +19,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -36,13 +37,9 @@ static void mvme147_get_model(char *model); static void __init mvme147_sched_init(void); -extern int mvme147_hwclk (int, struct rtc_time *); extern void mvme147_reset (void); -static int bcd2int (unsigned char b); - - int __init mvme147_parse_bootinfo(const struct bi_record *bi) { uint16_t tag = be16_to_cpu(bi->tag); @@ -80,7 +77,6 @@ void __init config_mvme147(void) { mach_sched_init = mvme147_sched_init; mach_init_IRQ = mvme147_init_IRQ; - mach_hwclk = mvme147_hwclk; mach_reset = mvme147_reset; mach_get_model = mvme147_get_model; @@ -89,6 +85,28 @@ void __init config_mvme147(void) vme_brdtype = VME_TYPE_MVME147; } +static struct resource m48t59_rsrc[] = { + DEFINE_RES_MEM(MVME147_RTC_BASE, 0x800), +}; + +static struct m48t59_plat_data m48t59_data = { + .type = M48T59RTC_TYPE_M48T02, + .yy_offset = 70, +}; + +static int __init mvme147_platform_init(void) +{ + if (!MACH_IS_MVME147) + return 0; + + platform_device_register_resndata(NULL, "rtc-m48t59", -1, + m48t59_rsrc, ARRAY_SIZE(m48t59_rsrc), + &m48t59_data, sizeof(m48t59_data)); + return 0; +} + +arch_initcall(mvme147_platform_init); + static u64 mvme147_read_clk(struct clocksource *cs); static struct clocksource mvme147_clk = { @@ -162,31 +180,6 @@ static u64 mvme147_read_clk(struct clocksource *cs) return ticks; } -static int bcd2int (unsigned char b) -{ - return ((b>>4)*10 + (b&15)); -} - -int mvme147_hwclk(int op, struct rtc_time *t) -{ - if (!op) { - m147_rtc->ctrl = RTC_READ; - t->tm_year = bcd2int (m147_rtc->bcd_year); - t->tm_mon = bcd2int(m147_rtc->bcd_mth) - 1; - t->tm_mday = bcd2int (m147_rtc->bcd_dom); - t->tm_hour = bcd2int (m147_rtc->bcd_hr); - t->tm_min = bcd2int (m147_rtc->bcd_min); - t->tm_sec = bcd2int (m147_rtc->bcd_sec); - m147_rtc->ctrl = 0; - if (t->tm_year < 70) - t->tm_year += 100; - } else { - /* FIXME Setting the time is not yet supported */ - return -EOPNOTSUPP; - } - return 0; -} - static void scc_delay(void) { __asm__ __volatile__ ("nop; nop;"); diff --git a/arch/m68k/mvme16x/Makefile b/arch/m68k/mvme16x/Makefile index a8a368c2cbea5c5899932609e0365cf8def7687d..02f9e4ad8209a692aeb306ef52d3a59e6325026d 100644 --- a/arch/m68k/mvme16x/Makefile +++ b/arch/m68k/mvme16x/Makefile @@ -3,4 +3,4 @@ # Makefile for Linux arch/m68k/mvme16x source directory # -obj-y := config.o rtc.o +obj-y := config.o diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index d1fbd1704d65822f7972c6f53c7adb66d268e7d5..99768fe8da73aa68b1a356cfbcf307cf360f0f70 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c @@ -21,9 +21,10 @@ #include #include #include -#include #include #include +#include +#include #include #include @@ -39,16 +40,10 @@ extern t_bdid mvme_bdid; -static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE; - static void mvme16x_get_model(char *model); extern void mvme16x_sched_init(void); -extern int mvme16x_hwclk (int, struct rtc_time *); extern void mvme16x_reset (void); -int bcd2int (unsigned char b); - - unsigned short mvme16x_config; EXPORT_SYMBOL(mvme16x_config); @@ -268,7 +263,6 @@ void __init config_mvme16x(void) mach_sched_init = mvme16x_sched_init; mach_init_IRQ = mvme16x_init_IRQ; - mach_hwclk = mvme16x_hwclk; mach_reset = mvme16x_reset; mach_get_model = mvme16x_get_model; mach_get_hardware_list = mvme16x_get_hardware_list; @@ -312,6 +306,28 @@ void __init config_mvme16x(void) } } +static struct resource m48t59_rsrc[] = { + DEFINE_RES_MEM(MVME_RTC_BASE, 0x2000), +}; + +static struct m48t59_plat_data m48t59_data = { + .type = M48T59RTC_TYPE_M48T08, + .yy_offset = 70, +}; + +static int __init mvme16x_platform_init(void) +{ + if (!MACH_IS_MVME16x) + return 0; + + platform_device_register_resndata(NULL, "rtc-m48t59", -1, + m48t59_rsrc, ARRAY_SIZE(m48t59_rsrc), + &m48t59_data, sizeof(m48t59_data)); + return 0; +} + +arch_initcall(mvme16x_platform_init); + static irqreturn_t mvme16x_abort_int (int irq, void *dev_id) { unsigned long *new = (unsigned long *)vectors; @@ -426,28 +442,3 @@ static u64 mvme16x_read_clk(struct clocksource *cs) return ticks; } - -int bcd2int (unsigned char b) -{ - return ((b>>4)*10 + (b&15)); -} - -int mvme16x_hwclk(int op, struct rtc_time *t) -{ - if (!op) { - rtc->ctrl = RTC_READ; - t->tm_year = bcd2int (rtc->bcd_year); - t->tm_mon = bcd2int(rtc->bcd_mth) - 1; - t->tm_mday = bcd2int (rtc->bcd_dom); - t->tm_hour = bcd2int (rtc->bcd_hr); - t->tm_min = bcd2int (rtc->bcd_min); - t->tm_sec = bcd2int (rtc->bcd_sec); - rtc->ctrl = 0; - if (t->tm_year < 70) - t->tm_year += 100; - } else { - /* FIXME Setting the time is not yet supported */ - return -EOPNOTSUPP; - } - return 0; -} diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c deleted file mode 100644 index ccbaae1125e6f11bb7cf432b4685e388ae8ebc37..0000000000000000000000000000000000000000 --- a/arch/m68k/mvme16x/rtc.c +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Real Time Clock interface for Linux on the MVME16x - * - * Based on the PC driver by Paul Gortmaker. - */ - -#define RTC_VERSION "1.00" - -#include -#include -#include -#include -#include -#include -#include -#include -#include /* For struct rtc_time and ioctls, etc */ -#include -#include - -#include -#include -#include - -/* - * We sponge a minor off of the misc major. No need slurping - * up another valuable major dev number for this. If you add - * an ioctl, make sure you don't conflict with SPARC's RTC - * ioctls. - */ - -static const unsigned char days_in_mo[] = -{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -static atomic_t rtc_ready = ATOMIC_INIT(1); - -static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE; - unsigned long flags; - struct rtc_time wtime; - void __user *argp = (void __user *)arg; - - switch (cmd) { - case RTC_RD_TIME: /* Read the time/date from RTC */ - { - local_irq_save(flags); - /* Ensure clock and real-time-mode-register are accessible */ - rtc->ctrl = RTC_READ; - memset(&wtime, 0, sizeof(struct rtc_time)); - wtime.tm_sec = bcd2bin(rtc->bcd_sec); - wtime.tm_min = bcd2bin(rtc->bcd_min); - wtime.tm_hour = bcd2bin(rtc->bcd_hr); - wtime.tm_mday = bcd2bin(rtc->bcd_dom); - wtime.tm_mon = bcd2bin(rtc->bcd_mth)-1; - wtime.tm_year = bcd2bin(rtc->bcd_year); - if (wtime.tm_year < 70) - wtime.tm_year += 100; - wtime.tm_wday = bcd2bin(rtc->bcd_dow)-1; - rtc->ctrl = 0; - local_irq_restore(flags); - return copy_to_user(argp, &wtime, sizeof wtime) ? - -EFAULT : 0; - } - case RTC_SET_TIME: /* Set the RTC */ - { - struct rtc_time rtc_tm; - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned int yrs; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - if (copy_from_user(&rtc_tm, argp, sizeof(struct rtc_time))) - return -EFAULT; - - yrs = rtc_tm.tm_year; - if (yrs < 1900) - yrs += 1900; - mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm.tm_mday; - hrs = rtc_tm.tm_hour; - min = rtc_tm.tm_min; - sec = rtc_tm.tm_sec; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if (yrs >= 2070) - return -EINVAL; - - local_irq_save(flags); - rtc->ctrl = RTC_WRITE; - - rtc->bcd_sec = bin2bcd(sec); - rtc->bcd_min = bin2bcd(min); - rtc->bcd_hr = bin2bcd(hrs); - rtc->bcd_dom = bin2bcd(day); - rtc->bcd_mth = bin2bcd(mon); - rtc->bcd_year = bin2bcd(yrs%100); - - rtc->ctrl = 0; - local_irq_restore(flags); - return 0; - } - default: - return -EINVAL; - } -} - -/* - * We enforce only one user at a time here with the open/close. - */ -static int rtc_open(struct inode *inode, struct file *file) -{ - if( !atomic_dec_and_test(&rtc_ready) ) - { - atomic_inc( &rtc_ready ); - return -EBUSY; - } - return 0; -} - -static int rtc_release(struct inode *inode, struct file *file) -{ - atomic_inc( &rtc_ready ); - return 0; -} - -/* - * The various file operations we support. - */ - -static const struct file_operations rtc_fops = { - .unlocked_ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, - .llseek = noop_llseek, -}; - -static struct miscdevice rtc_dev= -{ - .minor = RTC_MINOR, - .name = "rtc", - .fops = &rtc_fops -}; - -static int __init rtc_MK48T08_init(void) -{ - if (!MACH_IS_MVME16x) - return -ENODEV; - - pr_info("MK48T08 Real Time Clock Driver v%s\n", RTC_VERSION); - return misc_register(&rtc_dev); -} -device_initcall(rtc_MK48T08_init); diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi index cce9428afc41fc3ec1e347a344f6e48b9b345ca4..ee71045883e7e72baa938eb59787e2d7135c2cee 100644 --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi @@ -70,7 +70,6 @@ device_type = "pci"; #address-cells = <3>; #size-cells = <2>; - #interrupt-cells = <2>; msi-parent = <&msi>; reg = <0 0x1a000000 0 0x02000000>, @@ -234,7 +233,7 @@ }; }; - pci_bridge@9,0 { + pcie@9,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400", @@ -244,12 +243,16 @@ interrupts = <32 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 32 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@a,0 { + pcie@a,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400", @@ -259,12 +262,16 @@ interrupts = <33 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 33 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@b,0 { + pcie@b,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400", @@ -274,12 +281,16 @@ interrupts = <34 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 34 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@c,0 { + pcie@c,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400", @@ -289,12 +300,16 @@ interrupts = <35 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 35 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@d,0 { + pcie@d,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400", @@ -304,12 +319,16 @@ interrupts = <36 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 36 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@e,0 { + pcie@e,0 { compatible = "pci0014,7a09.1", "pci0014,7a09", "pciclass060400", @@ -319,12 +338,16 @@ interrupts = <37 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 37 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@f,0 { + pcie@f,0 { compatible = "pci0014,7a29.1", "pci0014,7a29", "pciclass060400", @@ -334,12 +357,16 @@ interrupts = <40 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 40 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@10,0 { + pcie@10,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400", @@ -349,12 +376,16 @@ interrupts = <41 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 41 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@11,0 { + pcie@11,0 { compatible = "pci0014,7a29.1", "pci0014,7a29", "pciclass060400", @@ -364,12 +395,16 @@ interrupts = <42 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 42 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@12,0 { + pcie@12,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400", @@ -379,12 +414,16 @@ interrupts = <43 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 43 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@13,0 { + pcie@13,0 { compatible = "pci0014,7a29.1", "pci0014,7a29", "pciclass060400", @@ -394,12 +433,16 @@ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 38 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; - pci_bridge@14,0 { + pcie@14,0 { compatible = "pci0014,7a19.1", "pci0014,7a19", "pciclass060400", @@ -409,9 +452,13 @@ interrupts = <39 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&pic>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &pic 39 IRQ_TYPE_LEVEL_HIGH>; + ranges; }; }; diff --git a/arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi b/arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi deleted file mode 100644 index 17a342cc744e57dc1f21262abdbfa97d4e4d58f3..0000000000000000000000000000000000000000 --- a/arch/mips/boot/dts/mobileye/eyeq5-clocks.dtsi +++ /dev/null @@ -1,270 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -/* - * Copyright 2023 Mobileye Vision Technologies Ltd. - */ - -#include - -/ { - /* Fixed clock */ - xtal: xtal { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <30000000>; - }; - -/* PLL_CPU derivatives */ - occ_cpu: occ-cpu { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_CPU>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - si_css0_ref_clk: si-css0-ref-clk { /* gate ClkRstGen_si_css0_ref */ - compatible = "fixed-factor-clock"; - clocks = <&occ_cpu>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - cpc_clk: cpc-clk { - compatible = "fixed-factor-clock"; - clocks = <&si_css0_ref_clk>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - core0_clk: core0-clk { - compatible = "fixed-factor-clock"; - clocks = <&si_css0_ref_clk>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - core1_clk: core1-clk { - compatible = "fixed-factor-clock"; - clocks = <&si_css0_ref_clk>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - core2_clk: core2-clk { - compatible = "fixed-factor-clock"; - clocks = <&si_css0_ref_clk>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - core3_clk: core3-clk { - compatible = "fixed-factor-clock"; - clocks = <&si_css0_ref_clk>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - cm_clk: cm-clk { - compatible = "fixed-factor-clock"; - clocks = <&si_css0_ref_clk>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - mem_clk: mem-clk { - compatible = "fixed-factor-clock"; - clocks = <&si_css0_ref_clk>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - occ_isram: occ-isram { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_CPU>; - #clock-cells = <0>; - clock-div = <2>; - clock-mult = <1>; - }; - isram_clk: isram-clk { /* gate ClkRstGen_isram */ - compatible = "fixed-factor-clock"; - clocks = <&occ_isram>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - occ_dbu: occ-dbu { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_CPU>; - #clock-cells = <0>; - clock-div = <10>; - clock-mult = <1>; - }; - si_dbu_tp_pclk: si-dbu-tp-pclk { /* gate ClkRstGen_dbu */ - compatible = "fixed-factor-clock"; - clocks = <&occ_dbu>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; -/* PLL_VDI derivatives */ - occ_vdi: occ-vdi { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_VDI>; - #clock-cells = <0>; - clock-div = <2>; - clock-mult = <1>; - }; - vdi_clk: vdi-clk { /* gate ClkRstGen_vdi */ - compatible = "fixed-factor-clock"; - clocks = <&occ_vdi>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - occ_can_ser: occ-can-ser { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_VDI>; - #clock-cells = <0>; - clock-div = <16>; - clock-mult = <1>; - }; - can_ser_clk: can-ser-clk { /* gate ClkRstGen_can_ser */ - compatible = "fixed-factor-clock"; - clocks = <&occ_can_ser>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - i2c_ser_clk: i2c-ser-clk { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_VDI>; - #clock-cells = <0>; - clock-div = <20>; - clock-mult = <1>; - }; -/* PLL_PER derivatives */ - occ_periph: occ-periph { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_PER>; - #clock-cells = <0>; - clock-div = <16>; - clock-mult = <1>; - }; - periph_clk: periph-clk { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - can_clk: can-clk { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - spi_clk: spi-clk { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - uart_clk: uart-clk { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - i2c_clk: i2c-clk { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clock-output-names = "i2c_clk"; - }; - timer_clk: timer-clk { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clock-output-names = "timer_clk"; - }; - gpio_clk: gpio-clk { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clock-output-names = "gpio_clk"; - }; - emmc_sys_clk: emmc-sys-clk { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_PER>; - #clock-cells = <0>; - clock-div = <10>; - clock-mult = <1>; - clock-output-names = "emmc_sys_clk"; - }; - ccf_ctrl_clk: ccf-ctrl-clk { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_PER>; - #clock-cells = <0>; - clock-div = <4>; - clock-mult = <1>; - clock-output-names = "ccf_ctrl_clk"; - }; - occ_mjpeg_core: occ-mjpeg-core { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_PER>; - #clock-cells = <0>; - clock-div = <2>; - clock-mult = <1>; - clock-output-names = "occ_mjpeg_core"; - }; - hsm_clk: hsm-clk { /* gate ClkRstGen_hsm */ - compatible = "fixed-factor-clock"; - clocks = <&occ_mjpeg_core>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clock-output-names = "hsm_clk"; - }; - mjpeg_core_clk: mjpeg-core-clk { /* gate ClkRstGen_mjpeg_gen */ - compatible = "fixed-factor-clock"; - clocks = <&occ_mjpeg_core>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - clock-output-names = "mjpeg_core_clk"; - }; - fcmu_a_clk: fcmu-a-clk { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_PER>; - #clock-cells = <0>; - clock-div = <20>; - clock-mult = <1>; - clock-output-names = "fcmu_a_clk"; - }; - occ_pci_sys: occ-pci-sys { - compatible = "fixed-factor-clock"; - clocks = <&olb EQ5C_PLL_PER>; - #clock-cells = <0>; - clock-div = <8>; - clock-mult = <1>; - clock-output-names = "occ_pci_sys"; - }; - pclk: pclk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <250000000>; /* 250MHz */ - }; - tsu_clk: tsu-clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <125000000>; /* 125MHz */ - }; -}; diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi index 0708771c193d064fa56be2c7f6115672b5c24d8d..5d73e8320b8efc1b4f68923482bf188c4345f1cb 100644 --- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi +++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi @@ -5,7 +5,7 @@ #include -#include "eyeq5-clocks.dtsi" +#include / { #address-cells = <2>; @@ -17,7 +17,7 @@ device_type = "cpu"; compatible = "img,i6500"; reg = <0>; - clocks = <&core0_clk>; + clocks = <&olb EQ5C_CPU_CORE0>; }; }; @@ -64,6 +64,24 @@ #interrupt-cells = <1>; }; + xtal: xtal { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + }; + + pclk: pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; /* 250MHz */ + }; + + tsu_clk: tsu-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; /* 125MHz */ + }; + soc: soc { #address-cells = <2>; #size-cells = <2>; @@ -76,7 +94,7 @@ reg-io-width = <4>; interrupt-parent = <&gic>; interrupts = ; - clocks = <&uart_clk>, <&occ_periph>; + clocks = <&olb EQ5C_PER_UART>, <&olb EQ5C_PER_OCC>; clock-names = "uartclk", "apb_pclk"; resets = <&olb 0 10>; pinctrl-names = "default"; @@ -89,7 +107,7 @@ reg-io-width = <4>; interrupt-parent = <&gic>; interrupts = ; - clocks = <&uart_clk>, <&occ_periph>; + clocks = <&olb EQ5C_PER_UART>, <&olb EQ5C_PER_OCC>; clock-names = "uartclk", "apb_pclk"; resets = <&olb 0 11>; pinctrl-names = "default"; @@ -102,7 +120,7 @@ reg-io-width = <4>; interrupt-parent = <&gic>; interrupts = ; - clocks = <&uart_clk>, <&occ_periph>; + clocks = <&olb EQ5C_PER_UART>, <&olb EQ5C_PER_OCC>; clock-names = "uartclk", "apb_pclk"; resets = <&olb 0 12>; pinctrl-names = "default"; @@ -135,7 +153,7 @@ timer { compatible = "mti,gic-timer"; interrupts = ; - clocks = <&core0_clk>; + clocks = <&olb EQ5C_CPU_CORE0>; }; }; }; diff --git a/arch/mips/boot/dts/mobileye/eyeq6h-fixed-clocks.dtsi b/arch/mips/boot/dts/mobileye/eyeq6h-fixed-clocks.dtsi deleted file mode 100644 index 5fa99e06fde7e8f4942aafe5f6064e2c6f7d83fd..0000000000000000000000000000000000000000 --- a/arch/mips/boot/dts/mobileye/eyeq6h-fixed-clocks.dtsi +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -/* - * Copyright 2023 Mobileye Vision Technologies Ltd. - */ - -#include - -/ { - xtal: clock-30000000 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <30000000>; - }; - - pll_west: clock-2000000000-west { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <2000000000>; - }; - - pll_cpu: clock-2000000000-cpu { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <2000000000>; - }; - - /* pll-cpu derivatives */ - occ_cpu: clock-2000000000-occ-cpu { - compatible = "fixed-factor-clock"; - clocks = <&pll_cpu>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - - /* pll-west derivatives */ - occ_periph_w: clock-200000000 { - compatible = "fixed-factor-clock"; - clocks = <&pll_west>; - #clock-cells = <0>; - clock-div = <10>; - clock-mult = <1>; - }; - uart_clk: clock-200000000-uart { - compatible = "fixed-factor-clock"; - clocks = <&occ_periph_w>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <1>; - }; - -}; diff --git a/arch/mips/boot/dts/mobileye/eyeq6h.dtsi b/arch/mips/boot/dts/mobileye/eyeq6h.dtsi index 1db3c3cda2e395025075387bcb66ea0737fd37f6..4a1a43f351d39625b520a16d035cacd2e29d157c 100644 --- a/arch/mips/boot/dts/mobileye/eyeq6h.dtsi +++ b/arch/mips/boot/dts/mobileye/eyeq6h.dtsi @@ -5,7 +5,7 @@ #include -#include "eyeq6h-fixed-clocks.dtsi" +#include / { #address-cells = <2>; @@ -17,7 +17,7 @@ device_type = "cpu"; compatible = "img,i6500"; reg = <0>; - clocks = <&occ_cpu>; + clocks = <&olb_central EQ6HC_CENTRAL_CPU_OCC>; }; }; @@ -32,19 +32,42 @@ #interrupt-cells = <1>; }; + xtal: clock-30000000 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + }; + soc: soc { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; ranges; + olb_acc: system-controller@d2003000 { + compatible = "mobileye,eyeq6h-acc-olb", "syscon"; + reg = <0x0 0xd2003000 0x0 0x1000>; + #reset-cells = <1>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + + olb_central: system-controller@d3100000 { + compatible = "mobileye,eyeq6h-central-olb", "syscon"; + reg = <0x0 0xd3100000 0x0 0x1000>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + uart0: serial@d3331000 { compatible = "arm,pl011", "arm,primecell"; reg = <0 0xd3331000 0x0 0x1000>; reg-io-width = <4>; interrupt-parent = <&gic>; interrupts = ; - clocks = <&occ_periph_w>, <&occ_periph_w>; + clocks = <&olb_west EQ6HC_WEST_PER_UART>, <&olb_west EQ6HC_WEST_PER_OCC>; clock-names = "uartclk", "apb_pclk"; }; @@ -56,6 +79,15 @@ pinctrl-single,function-mask = <0xffff>; }; + olb_west: system-controller@d3338000 { + compatible = "mobileye,eyeq6h-west-olb", "syscon"; + reg = <0x0 0xd3338000 0x0 0x1000>; + #reset-cells = <1>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + pinctrl_east: pinctrl@d3357000 { compatible = "pinctrl-single"; reg = <0x0 0xd3357000 0x0 0xb0>; @@ -64,6 +96,23 @@ pinctrl-single,function-mask = <0xffff>; }; + olb_east: system-controller@d3358000 { + compatible = "mobileye,eyeq6h-east-olb", "syscon"; + reg = <0x0 0xd3358000 0x0 0x1000>; + #reset-cells = <1>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + + olb_south: system-controller@d8013000 { + compatible = "mobileye,eyeq6h-south-olb", "syscon"; + reg = <0x0 0xd8013000 0x0 0x1000>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + pinctrl_south: pinctrl@d8014000 { compatible = "pinctrl-single"; reg = <0x0 0xd8014000 0x0 0xf8>; @@ -72,6 +121,22 @@ pinctrl-single,function-mask = <0xffff>; }; + olb_ddr0: system-controller@e4080000 { + compatible = "mobileye,eyeq6h-ddr0-olb", "syscon"; + reg = <0x0 0xe4080000 0x0 0x1000>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + + olb_ddr1: system-controller@e4081000 { + compatible = "mobileye,eyeq6h-ddr1-olb", "syscon"; + reg = <0x0 0xe4081000 0x0 0x1000>; + #clock-cells = <1>; + clocks = <&xtal>; + clock-names = "ref"; + }; + gic: interrupt-controller@f0920000 { compatible = "mti,gic"; reg = <0x0 0xf0920000 0x0 0x20000>; @@ -89,7 +154,7 @@ timer { compatible = "mti,gic-timer"; interrupts = ; - clocks = <&occ_cpu>; + clocks = <&olb_central EQ6HC_CENTRAL_CPU_OCC>; }; }; }; diff --git a/arch/mips/boot/dts/realtek/rtl930x.dtsi b/arch/mips/boot/dts/realtek/rtl930x.dtsi index 6a6f3f3fe389baf11e33c304ccb73693856a3cd5..17577457d15986582f6955e1e5545f009a155df2 100644 --- a/arch/mips/boot/dts/realtek/rtl930x.dtsi +++ b/arch/mips/boot/dts/realtek/rtl930x.dtsi @@ -61,6 +61,8 @@ }; &soc { + ranges = <0x0 0x18000000 0x20000>; + intc: interrupt-controller@3000 { compatible = "realtek,rtl9300-intc", "realtek,rtl-intc"; reg = <0x3000 0x18>, <0x3018 0x18>; @@ -88,6 +90,17 @@ interrupts = <7>, <8>, <9>, <10>, <11>; clocks = <&lx_clk>; }; + + snand: spi@1a400 { + compatible = "realtek,rtl9301-snand"; + reg = <0x1a400 0x44>; + interrupt-parent = <&intc>; + interrupts = <19>; + clocks = <&lx_clk>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; &uart0 { diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index b825ed4476c7023205c001810cd2ca04acdfe9df..e3ff6179c99f9bd3a9e7c32deffe8fd365438534 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -59,6 +59,7 @@ #endif .endm + __HEAD #ifndef CONFIG_NO_EXCEPT_FILL /* * Reserved space for exception handlers. diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 9ff55cb80a6457bba4c5a103c66372523380aff6..2b708fac8d2c17b8c8d093b4d9ca1d8e092d446a 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -61,6 +61,7 @@ SECTIONS /* read-only */ _text = .; /* Text and read-only data */ .text : { + HEAD_TEXT TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c index 45ddbaa6c1237985b90e7cc49b80ab7fdefb9ecc..dae856fb3e5bb22698b985f8f962077595ae6cd0 100644 --- a/arch/mips/pci/pci-xtalk-bridge.c +++ b/arch/mips/pci/pci-xtalk-bridge.c @@ -749,7 +749,7 @@ static void bridge_remove(struct platform_device *pdev) static struct platform_driver bridge_driver = { .probe = bridge_probe, - .remove_new = bridge_remove, + .remove = bridge_remove, .driver = { .name = "xtalk-bridge", } diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 41489483a602f698d16e73f5568fa560feb8958a..f3804103c56ccfdb16289468397ccaea71bf721e 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -403,10 +403,12 @@ PHONY += stack_protector_prepare stack_protector_prepare: prepare0 ifdef CONFIG_PPC64 $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \ - -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' \ + $(objtree)/include/generated/asm-offsets.h)) else $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \ - -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' \ + $(objtree)/include/generated/asm-offsets.h)) endif endif diff --git a/arch/powerpc/crypto/vmx.c b/arch/powerpc/crypto/vmx.c index 7eb713cc87c8cadc6b7c7bc5c251f8919f8c8790..0b725e826388fe94323b5a6109f6dd618b253c6c 100644 --- a/arch/powerpc/crypto/vmx.c +++ b/arch/powerpc/crypto/vmx.c @@ -74,4 +74,4 @@ MODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions " "support on Power 8"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0.0"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 73210e5bcfa774d691201d4034f1c9dcd3626803..8e776ba394978e5d0b1edf4a233b5df77c5e6bff 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -2848,7 +2848,7 @@ static void __init fixup_device_tree_chrp(void) #endif #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC) -static void __init fixup_device_tree_pmac(void) +static void __init fixup_device_tree_pmac64(void) { phandle u3, i2c, mpic; u32 u3_rev; @@ -2888,7 +2888,31 @@ static void __init fixup_device_tree_pmac(void) &parent, sizeof(parent)); } #else -#define fixup_device_tree_pmac() +#define fixup_device_tree_pmac64() +#endif + +#ifdef CONFIG_PPC_PMAC +static void __init fixup_device_tree_pmac(void) +{ + __be32 val = 1; + char type[8]; + phandle node; + + // Some pmacs are missing #size-cells on escc nodes + for (node = 0; prom_next_node(&node); ) { + type[0] = '\0'; + prom_getprop(node, "device_type", type, sizeof(type)); + if (prom_strcmp(type, "escc")) + continue; + + if (prom_getproplen(node, "#size-cells") != PROM_ERROR) + continue; + + prom_setprop(node, NULL, "#size-cells", &val, sizeof(val)); + } +} +#else +static inline void fixup_device_tree_pmac(void) { } #endif #ifdef CONFIG_PPC_EFIKA @@ -3111,6 +3135,7 @@ static void __init fixup_device_tree(void) { fixup_device_tree_chrp(); fixup_device_tree_pmac(); + fixup_device_tree_pmac64(); fixup_device_tree_efika(); fixup_device_tree_pasemi(); } diff --git a/arch/powerpc/platforms/pseries/svm.c b/arch/powerpc/platforms/pseries/svm.c index c5d0f92c7969996d49ebbac5fb2f22c69feb4f38..384c9dc1899abd34448535bda4e2697cd39132d5 100644 --- a/arch/powerpc/platforms/pseries/svm.c +++ b/arch/powerpc/platforms/pseries/svm.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index cc63aef41e94e1a74be422beb51793b84fd11260..d4a7ca0388c071b536df59c0eb11d55f9080c7cd 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -32,6 +32,7 @@ config RISCV select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GIGANTIC_PAGE + select ARCH_HAS_HW_PTE_YOUNG select ARCH_HAS_KCOV select ARCH_HAS_KERNEL_FPU_SUPPORT if 64BIT && FPU select ARCH_HAS_MEMBARRIER_CALLBACKS diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 9fe1ee740dda8544f5f85aaf37b322de53859205..13fbc0f94238797acad3b8991b48b0aa02c84990 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -135,7 +135,7 @@ stack_protector_prepare: prepare0 -mstack-protector-guard-reg=tp \ -mstack-protector-guard-offset=$(shell \ awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ - include/generated/asm-offsets.h)) + $(objtree)/include/generated/asm-offsets.h)) endif # arch specific predefines for sparse diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index fe5d4eb9adea1d4e3065a4d6e2ff361a52aecc44..37bdea65bbd8a1a313cc7ba00b80fc5071b9809a 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -199,6 +199,7 @@ /* xENVCFG flags */ #define ENVCFG_STCE (_AC(1, ULL) << 63) #define ENVCFG_PBMTE (_AC(1, ULL) << 62) +#define ENVCFG_ADUE (_AC(1, ULL) << 61) #define ENVCFG_PMM (_AC(0x3, ULL) << 32) #define ENVCFG_PMM_PMLEN_0 (_AC(0x0, ULL) << 32) #define ENVCFG_PMM_PMLEN_7 (_AC(0x2, ULL) << 32) diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index 08d2a5697466d07fe2319a2423f04657177db37f..869da082252a460559c9beea3829cc90860d6e9a 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -98,6 +98,8 @@ #define RISCV_ISA_EXT_SSNPM 89 #define RISCV_ISA_EXT_ZABHA 90 #define RISCV_ISA_EXT_ZICCRSE 91 +#define RISCV_ISA_EXT_SVADE 92 +#define RISCV_ISA_EXT_SVADU 93 #define RISCV_ISA_EXT_XLINUXENVCFG 127 diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 5d7f3e8c2e508cf6206b969910e2994a17382af1..d4e99eef90acf09a03ddb26978872e651be5f81a 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -113,6 +113,7 @@ #include #include #include +#include #define __page_val_to_pfn(_val) (((_val) & _PAGE_PFN_MASK) >> _PAGE_PFN_SHIFT) @@ -284,7 +285,6 @@ static inline pte_t pud_pte(pud_t pud) } #ifdef CONFIG_RISCV_ISA_SVNAPOT -#include static __always_inline bool has_svnapot(void) { @@ -655,6 +655,17 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) return __pgprot(prot); } +/* + * Both Svade and Svadu control the hardware behavior when the PTE A/D bits need to be set. By + * default the M-mode firmware enables the hardware updating scheme when only Svadu is present in + * DT. + */ +#define arch_has_hw_pte_young arch_has_hw_pte_young +static inline bool arch_has_hw_pte_young(void) +{ + return riscv_has_extension_unlikely(RISCV_ISA_EXT_SVADU); +} + /* * THP functions */ diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index 4f24201376b17215315cf1fb8888d0a562dc76ac..3482c9a73d1b644385182436192914f34b50b997 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -177,6 +177,8 @@ enum KVM_RISCV_ISA_EXT_ID { KVM_RISCV_ISA_EXT_ZAWRS, KVM_RISCV_ISA_EXT_SMNPM, KVM_RISCV_ISA_EXT_SSNPM, + KVM_RISCV_ISA_EXT_SVADE, + KVM_RISCV_ISA_EXT_SVADU, KVM_RISCV_ISA_EXT_MAX, }; diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 467c5c735bf567586305653c0d655d2e9c7c74a4..c0916ed318c20e2e2f6354a3a4be1f4437f7f564 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -136,6 +136,16 @@ static int riscv_ext_zcf_validate(const struct riscv_isa_ext_data *data, return -EPROBE_DEFER; } +static int riscv_ext_svadu_validate(const struct riscv_isa_ext_data *data, + const unsigned long *isa_bitmap) +{ + /* SVADE has already been detected, use SVADE only */ + if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_SVADE)) + return -EOPNOTSUPP; + + return 0; +} + static const unsigned int riscv_zk_bundled_exts[] = { RISCV_ISA_EXT_ZBKB, RISCV_ISA_EXT_ZBKC, @@ -387,6 +397,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), __RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_xlinuxenvcfg_exts), __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC), + __RISCV_ISA_EXT_DATA(svade, RISCV_ISA_EXT_SVADE), + __RISCV_ISA_EXT_DATA_VALIDATE(svadu, RISCV_ISA_EXT_SVADU, riscv_ext_svadu_validate), __RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL), __RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT), __RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT), diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index dc3f76f6e46ceafb25c88763e310db622715a447..e048dcc6e65e73c03232cb327ae9c85a16aede1f 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -551,6 +551,10 @@ static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu) if (riscv_isa_extension_available(isa, ZICBOZ)) cfg->henvcfg |= ENVCFG_CBZE; + if (riscv_isa_extension_available(isa, SVADU) && + !riscv_isa_extension_available(isa, SVADE)) + cfg->henvcfg |= ENVCFG_ADUE; + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) { cfg->hstateen0 |= SMSTATEEN0_HSENVCFG; if (riscv_isa_extension_available(isa, SSAIA)) diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index 5b68490ad9b75fef6a18289d8c5cf9291594e01e..753f66c8b70a72e76210075b4e07849741f614d4 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #define KVM_RISCV_BASE_ISA_MASK GENMASK(25, 0) @@ -40,6 +41,8 @@ static const unsigned long kvm_isa_ext_arr[] = { KVM_ISA_EXT_ARR(SSCOFPMF), KVM_ISA_EXT_ARR(SSNPM), KVM_ISA_EXT_ARR(SSTC), + KVM_ISA_EXT_ARR(SVADE), + KVM_ISA_EXT_ARR(SVADU), KVM_ISA_EXT_ARR(SVINVAL), KVM_ISA_EXT_ARR(SVNAPOT), KVM_ISA_EXT_ARR(SVPBMT), @@ -112,6 +115,12 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext) case KVM_RISCV_ISA_EXT_SSCOFPMF: /* Sscofpmf depends on interrupt filtering defined in ssaia */ return __riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSAIA); + case KVM_RISCV_ISA_EXT_SVADU: + /* + * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero. + * Guest OS can use Svadu only when host OS enable Svadu. + */ + return arch_has_hw_pte_young(); case KVM_RISCV_ISA_EXT_V: return riscv_v_vstate_ctrl_user_allowed(); default: @@ -185,6 +194,12 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext) /* Extensions which can be disabled using Smstateen */ case KVM_RISCV_ISA_EXT_SSAIA: return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN); + case KVM_RISCV_ISA_EXT_SVADE: + /* + * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero. + * Svade is not allowed to disable when the platform use Svade. + */ + return arch_has_hw_pte_young(); default: break; } diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c64b2987d10810fb895edcb8b7b642ac9ad06913..0077969170e8b4ca4c99e87ec75f6ea94f3e8e00 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -87,6 +87,7 @@ config S390 select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_MEM_ENCRYPT select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS + select ARCH_HAS_PREEMPT_LAZY select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_SCALED_CPUTIME select ARCH_HAS_SET_DIRECT_MAP @@ -218,6 +219,7 @@ config S390 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PREEMPT_DYNAMIC_KEY select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RELIABLE_STACKTRACE select HAVE_RETHOOK diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 8cc02d6e0d0fecbd3606bbf687ff050f2cae3688..9c46b1b630b1ad3dc308fd137ec59fcfed6ba4f2 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -1168,4 +1168,4 @@ MODULE_ALIAS_CRYPTO("aes-all"); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index ccd4e148b5ed47a2b64b9363f045287bcdf67a69..a7f7bdc9e19cae7ee15288a2c8093e75da62dc61 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h @@ -66,14 +66,15 @@ typedef int (debug_header_proc_t) (debug_info_t *id, struct debug_view *view, int area, debug_entry_t *entry, - char *out_buf); + char *out_buf, size_t out_buf_size); typedef int (debug_format_proc_t) (debug_info_t *id, struct debug_view *view, char *out_buf, + size_t out_buf_size, const char *in_buf); typedef int (debug_prolog_proc_t) (debug_info_t *id, struct debug_view *view, - char *out_buf); + char *out_buf, size_t out_buf_size); typedef int (debug_input_proc_t) (debug_info_t *id, struct debug_view *view, struct file *file, @@ -81,7 +82,8 @@ typedef int (debug_input_proc_t) (debug_info_t *id, size_t in_buf_size, loff_t *offset); int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view, - int area, debug_entry_t *entry, char *out_buf); + int area, debug_entry_t *entry, + char *out_buf, size_t out_buf_size); struct debug_view { char name[DEBUG_MAX_NAME_LEN]; diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h index 64761c78f77471c42af06d925af48faa806e6610..13f51a6a5bb1bf42fb00b6de163c426150b03f8f 100644 --- a/arch/s390/include/asm/gmap.h +++ b/arch/s390/include/asm/gmap.h @@ -17,8 +17,8 @@ #define GMAP_NOTIFY_MPROT 0x1 /* Status bits only for huge segment entries */ -#define _SEGMENT_ENTRY_GMAP_IN 0x8000 /* invalidation notify bit */ -#define _SEGMENT_ENTRY_GMAP_UC 0x4000 /* dirty (migration) */ +#define _SEGMENT_ENTRY_GMAP_IN 0x0800 /* invalidation notify bit */ +#define _SEGMENT_ENTRY_GMAP_UC 0x0002 /* dirty (migration) */ /** * struct gmap_struct - guest address space diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index 6f815d4ba0cabbf28dae0744dbc5754e23a9f15e..a40664b236e912213b46f9596bb2e8aa045a9434 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h @@ -10,6 +10,8 @@ #define _ASM_S390_HUGETLB_H #include +#include +#include #include #define hugepages_supported() (MACHINE_HAS_EDAT1) @@ -78,7 +80,7 @@ static inline int huge_pte_none(pte_t pte) #define __HAVE_ARCH_HUGE_PTE_NONE_MOSTLY static inline int huge_pte_none_mostly(pte_t pte) { - return huge_pte_none(pte); + return huge_pte_none(pte) || is_pte_marker(pte); } #define __HAVE_ARCH_HUGE_PTE_MKUFFD_WP diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 1cd8eaebd3c0d781b09ec0e6172e3710ab302819..97c7c8127543458858e95fb30ca1eebf02c3437b 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -94,11 +94,16 @@ union ipte_control { }; }; +/* + * Utility is defined as two bytes but having it four bytes wide + * generates more efficient code. Since the following bytes are + * reserved this makes no functional difference. + */ union sca_utility { - __u16 val; + __u32 val; struct { - __u16 mtcr : 1; - __u16 reserved : 15; + __u32 mtcr : 1; + __u32 : 31; }; }; @@ -107,7 +112,7 @@ struct bsca_block { __u64 reserved[5]; __u64 mcn; union sca_utility utility; - __u8 reserved2[6]; + __u8 reserved2[4]; struct bsca_entry cpu[KVM_S390_BSCA_CPU_SLOTS]; }; @@ -115,7 +120,7 @@ struct esca_block { union ipte_control ipte_control; __u64 reserved1[6]; union sca_utility utility; - __u8 reserved2[6]; + __u8 reserved2[4]; __u64 mcn[4]; __u64 reserved3[20]; struct esca_entry cpu[KVM_S390_ESCA_CPU_SLOTS]; diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 8b67036edb697e279cb7a912e09fe0f83393ba49..48268095b0a353da0d3ffcb31d93bf4c01873598 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -277,7 +277,8 @@ static inline int is_module_addr(void *addr) #define _REGION1_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INVALID) #define _REGION2_ENTRY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH) #define _REGION2_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INVALID) -#define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) +#define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH | \ + _REGION3_ENTRY_PRESENT) #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INVALID) #define _REGION3_ENTRY_HARDWARE_BITS 0xfffffffffffff6ffUL @@ -285,18 +286,27 @@ static inline int is_module_addr(void *addr) #define _REGION3_ENTRY_ORIGIN_LARGE ~0x7fffffffUL /* large page address */ #define _REGION3_ENTRY_DIRTY 0x2000 /* SW region dirty bit */ #define _REGION3_ENTRY_YOUNG 0x1000 /* SW region young bit */ +#define _REGION3_ENTRY_COMM 0x0010 /* Common-Region, marks swap entry */ #define _REGION3_ENTRY_LARGE 0x0400 /* RTTE-format control, large page */ -#define _REGION3_ENTRY_WRITE 0x0002 /* SW region write bit */ -#define _REGION3_ENTRY_READ 0x0001 /* SW region read bit */ +#define _REGION3_ENTRY_WRITE 0x8000 /* SW region write bit */ +#define _REGION3_ENTRY_READ 0x4000 /* SW region read bit */ #ifdef CONFIG_MEM_SOFT_DIRTY -#define _REGION3_ENTRY_SOFT_DIRTY 0x4000 /* SW region soft dirty bit */ +#define _REGION3_ENTRY_SOFT_DIRTY 0x0002 /* SW region soft dirty bit */ #else #define _REGION3_ENTRY_SOFT_DIRTY 0x0000 /* SW region soft dirty bit */ #endif #define _REGION_ENTRY_BITS 0xfffffffffffff22fUL +/* + * SW region present bit. For non-leaf region-third-table entries, bits 62-63 + * indicate the TABLE LENGTH and both must be set to 1. But such entries + * would always be considered as present, so it is safe to use bit 63 as + * PRESENT bit for PUD. + */ +#define _REGION3_ENTRY_PRESENT 0x0001 + /* Bits in the segment table entry */ #define _SEGMENT_ENTRY_BITS 0xfffffffffffffe3fUL #define _SEGMENT_ENTRY_HARDWARE_BITS 0xfffffffffffffe3cUL @@ -308,21 +318,29 @@ static inline int is_module_addr(void *addr) #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ #define _SEGMENT_ENTRY_TYPE_MASK 0x0c /* segment table type mask */ -#define _SEGMENT_ENTRY (0) +#define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PRESENT) #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) #define _SEGMENT_ENTRY_DIRTY 0x2000 /* SW segment dirty bit */ #define _SEGMENT_ENTRY_YOUNG 0x1000 /* SW segment young bit */ + +#define _SEGMENT_ENTRY_COMM 0x0010 /* Common-Segment, marks swap entry */ #define _SEGMENT_ENTRY_LARGE 0x0400 /* STE-format control, large page */ -#define _SEGMENT_ENTRY_WRITE 0x0002 /* SW segment write bit */ -#define _SEGMENT_ENTRY_READ 0x0001 /* SW segment read bit */ +#define _SEGMENT_ENTRY_WRITE 0x8000 /* SW segment write bit */ +#define _SEGMENT_ENTRY_READ 0x4000 /* SW segment read bit */ #ifdef CONFIG_MEM_SOFT_DIRTY -#define _SEGMENT_ENTRY_SOFT_DIRTY 0x4000 /* SW segment soft dirty bit */ +#define _SEGMENT_ENTRY_SOFT_DIRTY 0x0002 /* SW segment soft dirty bit */ #else #define _SEGMENT_ENTRY_SOFT_DIRTY 0x0000 /* SW segment soft dirty bit */ #endif +#define _SEGMENT_ENTRY_PRESENT 0x0001 /* SW segment present bit */ + +/* Common bits in region and segment table entries, for swap entries */ +#define _RST_ENTRY_COMM 0x0010 /* Common-Region/Segment, marks swap entry */ +#define _RST_ENTRY_INVALID 0x0020 /* invalid region/segment table entry */ + #define _CRST_ENTRIES 2048 /* number of region/segment table entries */ #define _PAGE_ENTRIES 256 /* number of page table entries */ @@ -454,17 +472,22 @@ static inline int is_module_addr(void *addr) /* * Segment entry (large page) protection definitions. */ -#define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_INVALID | \ +#define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_PRESENT | \ + _SEGMENT_ENTRY_INVALID | \ _SEGMENT_ENTRY_PROTECT) -#define SEGMENT_RO __pgprot(_SEGMENT_ENTRY_PROTECT | \ +#define SEGMENT_RO __pgprot(_SEGMENT_ENTRY_PRESENT | \ + _SEGMENT_ENTRY_PROTECT | \ _SEGMENT_ENTRY_READ | \ _SEGMENT_ENTRY_NOEXEC) -#define SEGMENT_RX __pgprot(_SEGMENT_ENTRY_PROTECT | \ +#define SEGMENT_RX __pgprot(_SEGMENT_ENTRY_PRESENT | \ + _SEGMENT_ENTRY_PROTECT | \ _SEGMENT_ENTRY_READ) -#define SEGMENT_RW __pgprot(_SEGMENT_ENTRY_READ | \ +#define SEGMENT_RW __pgprot(_SEGMENT_ENTRY_PRESENT | \ + _SEGMENT_ENTRY_READ | \ _SEGMENT_ENTRY_WRITE | \ _SEGMENT_ENTRY_NOEXEC) -#define SEGMENT_RWX __pgprot(_SEGMENT_ENTRY_READ | \ +#define SEGMENT_RWX __pgprot(_SEGMENT_ENTRY_PRESENT | \ + _SEGMENT_ENTRY_READ | \ _SEGMENT_ENTRY_WRITE) #define SEGMENT_KERNEL __pgprot(_SEGMENT_ENTRY | \ _SEGMENT_ENTRY_LARGE | \ @@ -491,6 +514,7 @@ static inline int is_module_addr(void *addr) */ #define REGION3_KERNEL __pgprot(_REGION_ENTRY_TYPE_R3 | \ + _REGION3_ENTRY_PRESENT | \ _REGION3_ENTRY_LARGE | \ _REGION3_ENTRY_READ | \ _REGION3_ENTRY_WRITE | \ @@ -498,12 +522,14 @@ static inline int is_module_addr(void *addr) _REGION3_ENTRY_DIRTY | \ _REGION_ENTRY_NOEXEC) #define REGION3_KERNEL_RO __pgprot(_REGION_ENTRY_TYPE_R3 | \ + _REGION3_ENTRY_PRESENT | \ _REGION3_ENTRY_LARGE | \ _REGION3_ENTRY_READ | \ _REGION3_ENTRY_YOUNG | \ _REGION_ENTRY_PROTECT | \ _REGION_ENTRY_NOEXEC) #define REGION3_KERNEL_EXEC __pgprot(_REGION_ENTRY_TYPE_R3 | \ + _REGION3_ENTRY_PRESENT | \ _REGION3_ENTRY_LARGE | \ _REGION3_ENTRY_READ | \ _REGION3_ENTRY_WRITE | \ @@ -746,7 +772,7 @@ static inline int pud_present(pud_t pud) { if (pud_folded(pud)) return 1; - return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL; + return (pud_val(pud) & _REGION3_ENTRY_PRESENT) != 0; } static inline int pud_none(pud_t pud) @@ -761,13 +787,18 @@ static inline bool pud_leaf(pud_t pud) { if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) != _REGION_ENTRY_TYPE_R3) return 0; - return !!(pud_val(pud) & _REGION3_ENTRY_LARGE); + return (pud_present(pud) && (pud_val(pud) & _REGION3_ENTRY_LARGE) != 0); +} + +static inline int pmd_present(pmd_t pmd) +{ + return (pmd_val(pmd) & _SEGMENT_ENTRY_PRESENT) != 0; } #define pmd_leaf pmd_leaf static inline bool pmd_leaf(pmd_t pmd) { - return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0; + return (pmd_present(pmd) && (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0); } static inline int pmd_bad(pmd_t pmd) @@ -799,11 +830,6 @@ static inline int p4d_bad(p4d_t p4d) return (p4d_val(p4d) & ~_REGION_ENTRY_BITS) != 0; } -static inline int pmd_present(pmd_t pmd) -{ - return pmd_val(pmd) != _SEGMENT_ENTRY_EMPTY; -} - static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) == _SEGMENT_ENTRY_EMPTY; @@ -1851,7 +1877,7 @@ static inline pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, static inline int pmd_trans_huge(pmd_t pmd) { - return pmd_val(pmd) & _SEGMENT_ENTRY_LARGE; + return pmd_leaf(pmd); } #define has_transparent_hugepage has_transparent_hugepage @@ -1911,6 +1937,53 @@ static inline swp_entry_t __swp_entry(unsigned long type, unsigned long offset) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +/* + * 64 bit swap entry format for REGION3 and SEGMENT table entries (RSTE) + * Bits 59 and 63 are used to indicate the swap entry. Bit 58 marks the rste + * as invalid. + * A swap entry is indicated by bit pattern (rste & 0x011) == 0x010 + * | offset |Xtype |11TT|S0| + * |0000000000111111111122222222223333333333444444444455|555555|5566|66| + * |0123456789012345678901234567890123456789012345678901|234567|8901|23| + * + * Bits 0-51 store the offset. + * Bits 53-57 store the type. + * Bit 62 (S) is used for softdirty tracking. + * Bits 60-61 (TT) indicate the table type: 0x01 for REGION3 and 0x00 for SEGMENT. + * Bit 52 (X) is unused. + */ + +#define __SWP_OFFSET_MASK_RSTE ((1UL << 52) - 1) +#define __SWP_OFFSET_SHIFT_RSTE 12 +#define __SWP_TYPE_MASK_RSTE ((1UL << 5) - 1) +#define __SWP_TYPE_SHIFT_RSTE 6 + +/* + * TT bits set to 0x00 == SEGMENT. For REGION3 entries, caller must add R3 + * bits 0x01. See also __set_huge_pte_at(). + */ +static inline unsigned long mk_swap_rste(unsigned long type, unsigned long offset) +{ + unsigned long rste; + + rste = _RST_ENTRY_INVALID | _RST_ENTRY_COMM; + rste |= (offset & __SWP_OFFSET_MASK_RSTE) << __SWP_OFFSET_SHIFT_RSTE; + rste |= (type & __SWP_TYPE_MASK_RSTE) << __SWP_TYPE_SHIFT_RSTE; + return rste; +} + +static inline unsigned long __swp_type_rste(swp_entry_t entry) +{ + return (entry.val >> __SWP_TYPE_SHIFT_RSTE) & __SWP_TYPE_MASK_RSTE; +} + +static inline unsigned long __swp_offset_rste(swp_entry_t entry) +{ + return (entry.val >> __SWP_OFFSET_SHIFT_RSTE) & __SWP_OFFSET_MASK_RSTE; +} + +#define __rste_to_swp_entry(rste) ((swp_entry_t) { rste }) + extern int vmem_add_mapping(unsigned long start, unsigned long size); extern void vmem_remove_mapping(unsigned long start, unsigned long size); extern int __vmem_map_4k_page(unsigned long addr, unsigned long phys, pgprot_t prot, bool alloc); diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h index 0cde7e2403736a31aab6614806a84badee8c79c9..2c29bdf1212722e4996e7d56a16386aafb06c307 100644 --- a/arch/s390/include/asm/preempt.h +++ b/arch/s390/include/asm/preempt.h @@ -130,10 +130,24 @@ static __always_inline bool should_resched(int preempt_offset) #define init_idle_preempt_count(p, cpu) do { } while (0) #ifdef CONFIG_PREEMPTION -extern void preempt_schedule(void); -#define __preempt_schedule() preempt_schedule() -extern void preempt_schedule_notrace(void); -#define __preempt_schedule_notrace() preempt_schedule_notrace() + +void preempt_schedule(void); +void preempt_schedule_notrace(void); + +#ifdef CONFIG_PREEMPT_DYNAMIC + +void dynamic_preempt_schedule(void); +void dynamic_preempt_schedule_notrace(void); +#define __preempt_schedule() dynamic_preempt_schedule() +#define __preempt_schedule_notrace() dynamic_preempt_schedule_notrace() + +#else /* CONFIG_PREEMPT_DYNAMIC */ + +#define __preempt_schedule() preempt_schedule() +#define __preempt_schedule_notrace() preempt_schedule_notrace() + +#endif /* CONFIG_PREEMPT_DYNAMIC */ + #endif /* CONFIG_PREEMPTION */ #endif /* __ASM_PREEMPT_H */ diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index ac868a9bb0d180fe5bc469106c043b5714f97083..f87dd0a84855da86815a4db2d7c6473fcb1947eb 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -82,9 +82,10 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp) kcsan_release(); asm_inline volatile( ALTERNATIVE("nop", ".insn rre,0xb2fa0000,7,0", ALT_FACILITY(49)) /* NIAI 7 */ - " sth %1,%0\n" - : "=R" (((unsigned short *) &lp->lock)[1]) - : "d" (0) : "cc", "memory"); + " mvhhi %[lock],0\n" + : [lock] "=Q" (((unsigned short *)&lp->lock)[1]) + : + : "memory"); } /* diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 00ac01874a129f560270b7ef9d8d9ecaa852a964..c33f7144d1b978f612b8c092a4fd03fbacfc059e 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -61,44 +61,45 @@ void arch_setup_new_exec(void); /* * thread information flags bit numbers */ -/* _TIF_WORK bits */ #define TIF_NOTIFY_RESUME 0 /* callback before returning to user */ #define TIF_SIGPENDING 1 /* signal pending */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_UPROBE 3 /* breakpointed or single-stepping */ -#define TIF_GUARDED_STORAGE 4 /* load guarded storage control block */ +#define TIF_NEED_RESCHED_LAZY 3 /* lazy rescheduling needed */ +#define TIF_UPROBE 4 /* breakpointed or single-stepping */ #define TIF_PATCH_PENDING 5 /* pending live patching update */ #define TIF_PGSTE 6 /* New mm's will use 4K page tables */ #define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */ +#define TIF_GUARDED_STORAGE 8 /* load guarded storage control block */ #define TIF_ISOLATE_BP_GUEST 9 /* Run KVM guests with isolated BP */ #define TIF_PER_TRAP 10 /* Need to handle PER trap on exit to usermode */ - #define TIF_31BIT 16 /* 32bit process */ #define TIF_MEMDIE 17 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 18 /* restore signal mask in do_signal() */ #define TIF_SINGLE_STEP 19 /* This task is single stepped */ #define TIF_BLOCK_STEP 20 /* This task is block stepped */ #define TIF_UPROBE_SINGLESTEP 21 /* This task is uprobe single stepped */ - -/* _TIF_TRACE bits */ #define TIF_SYSCALL_TRACE 24 /* syscall trace active */ #define TIF_SYSCALL_AUDIT 25 /* syscall auditing active */ #define TIF_SECCOMP 26 /* secure computing */ #define TIF_SYSCALL_TRACEPOINT 27 /* syscall tracepoint instrumentation */ #define _TIF_NOTIFY_RESUME BIT(TIF_NOTIFY_RESUME) -#define _TIF_NOTIFY_SIGNAL BIT(TIF_NOTIFY_SIGNAL) #define _TIF_SIGPENDING BIT(TIF_SIGPENDING) #define _TIF_NEED_RESCHED BIT(TIF_NEED_RESCHED) +#define _TIF_NEED_RESCHED_LAZY BIT(TIF_NEED_RESCHED_LAZY) #define _TIF_UPROBE BIT(TIF_UPROBE) -#define _TIF_GUARDED_STORAGE BIT(TIF_GUARDED_STORAGE) #define _TIF_PATCH_PENDING BIT(TIF_PATCH_PENDING) +#define _TIF_PGSTE BIT(TIF_PGSTE) +#define _TIF_NOTIFY_SIGNAL BIT(TIF_NOTIFY_SIGNAL) +#define _TIF_GUARDED_STORAGE BIT(TIF_GUARDED_STORAGE) #define _TIF_ISOLATE_BP_GUEST BIT(TIF_ISOLATE_BP_GUEST) #define _TIF_PER_TRAP BIT(TIF_PER_TRAP) - #define _TIF_31BIT BIT(TIF_31BIT) +#define _TIF_MEMDIE BIT(TIF_MEMDIE) +#define _TIF_RESTORE_SIGMASK BIT(TIF_RESTORE_SIGMASK) #define _TIF_SINGLE_STEP BIT(TIF_SINGLE_STEP) - +#define _TIF_BLOCK_STEP BIT(TIF_BLOCK_STEP) +#define _TIF_UPROBE_SINGLESTEP BIT(TIF_UPROBE_SINGLESTEP) #define _TIF_SYSCALL_TRACE BIT(TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT BIT(TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP BIT(TIF_SECCOMP) diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index a6e2cd89b609467baa486d29a1a5c17b7310f9a1..9dfd46dd03c64cf71985173e306892a2db9f53b3 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -46,11 +46,6 @@ static inline void __tlb_flush_mm(struct mm_struct *mm) { unsigned long gmap_asce; - /* - * If the machine has IDTE we prefer to do a per mm flush - * on all cpus instead of doing a local flush if the mm - * only ran on the local cpu. - */ preempt_disable(); atomic_inc(&mm->context.flush_count); /* Reset TLB flush mask */ diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index b3f2103694e411042be0cc972c315148043cf266..de19fd8a6a95456c6a70d0d3729e6eb387007032 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -77,12 +77,14 @@ static debug_info_t *debug_info_create(const char *name, int pages_per_area, static void debug_info_get(debug_info_t *); static void debug_info_put(debug_info_t *); static int debug_prolog_level_fn(debug_info_t *id, - struct debug_view *view, char *out_buf); + struct debug_view *view, char *out_buf, + size_t out_buf_size); static int debug_input_level_fn(debug_info_t *id, struct debug_view *view, struct file *file, const char __user *user_buf, size_t user_buf_size, loff_t *offset); static int debug_prolog_pages_fn(debug_info_t *id, - struct debug_view *view, char *out_buf); + struct debug_view *view, char *out_buf, + size_t out_buf_size); static int debug_input_pages_fn(debug_info_t *id, struct debug_view *view, struct file *file, const char __user *user_buf, size_t user_buf_size, loff_t *offset); @@ -90,9 +92,11 @@ static int debug_input_flush_fn(debug_info_t *id, struct debug_view *view, struct file *file, const char __user *user_buf, size_t user_buf_size, loff_t *offset); static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, - char *out_buf, const char *in_buf); + char *out_buf, size_t out_buf_size, + const char *in_buf); static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, - char *out_buf, const char *inbuf); + char *out_buf, size_t out_buf_size, + const char *inbuf); static void debug_areas_swap(debug_info_t *a, debug_info_t *b); static void debug_events_append(debug_info_t *dest, debug_info_t *src); @@ -391,8 +395,10 @@ static int debug_format_entry(file_private_info_t *p_info) if (p_info->act_entry == DEBUG_PROLOG_ENTRY) { /* print prolog */ - if (view->prolog_proc) - len += view->prolog_proc(id_snap, view, p_info->temp_buf); + if (view->prolog_proc) { + len += view->prolog_proc(id_snap, view, p_info->temp_buf, + sizeof(p_info->temp_buf)); + } goto out; } if (!id_snap->areas) /* this is true, if we have a prolog only view */ @@ -402,12 +408,16 @@ static int debug_format_entry(file_private_info_t *p_info) if (act_entry->clock == 0LL) goto out; /* empty entry */ - if (view->header_proc) + if (view->header_proc) { len += view->header_proc(id_snap, view, p_info->act_area, - act_entry, p_info->temp_buf + len); - if (view->format_proc) + act_entry, p_info->temp_buf + len, + sizeof(p_info->temp_buf) - len); + } + if (view->format_proc) { len += view->format_proc(id_snap, view, p_info->temp_buf + len, + sizeof(p_info->temp_buf) - len, DEBUG_DATA(act_entry)); + } out: return len; } @@ -1292,9 +1302,9 @@ static inline int debug_get_uint(char *buf) */ static int debug_prolog_pages_fn(debug_info_t *id, struct debug_view *view, - char *out_buf) + char *out_buf, size_t out_buf_size) { - return sprintf(out_buf, "%i\n", id->pages_per_area); + return scnprintf(out_buf, out_buf_size, "%i\n", id->pages_per_area); } /* @@ -1341,14 +1351,14 @@ out: * prints out actual debug level */ static int debug_prolog_level_fn(debug_info_t *id, struct debug_view *view, - char *out_buf) + char *out_buf, size_t out_buf_size) { int rc = 0; if (id->level == DEBUG_OFF_LEVEL) - rc = sprintf(out_buf, "-\n"); + rc = scnprintf(out_buf, out_buf_size, "-\n"); else - rc = sprintf(out_buf, "%i\n", id->level); + rc = scnprintf(out_buf, out_buf_size, "%i\n", id->level); return rc; } @@ -1465,22 +1475,24 @@ out: * prints debug data in hex/ascii format */ static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, - char *out_buf, const char *in_buf) + char *out_buf, size_t out_buf_size, const char *in_buf) { int i, rc = 0; - for (i = 0; i < id->buf_size; i++) - rc += sprintf(out_buf + rc, "%02x ", ((unsigned char *) in_buf)[i]); - rc += sprintf(out_buf + rc, "| "); + for (i = 0; i < id->buf_size; i++) { + rc += scnprintf(out_buf + rc, out_buf_size - rc, + "%02x ", ((unsigned char *)in_buf)[i]); + } + rc += scnprintf(out_buf + rc, out_buf_size - rc, "| "); for (i = 0; i < id->buf_size; i++) { unsigned char c = in_buf[i]; if (isascii(c) && isprint(c)) - rc += sprintf(out_buf + rc, "%c", c); + rc += scnprintf(out_buf + rc, out_buf_size - rc, "%c", c); else - rc += sprintf(out_buf + rc, "."); + rc += scnprintf(out_buf + rc, out_buf_size - rc, "."); } - rc += sprintf(out_buf + rc, "\n"); + rc += scnprintf(out_buf + rc, out_buf_size - rc, "\n"); return rc; } @@ -1488,7 +1500,8 @@ static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, * prints header for debug entry */ int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view, - int area, debug_entry_t *entry, char *out_buf) + int area, debug_entry_t *entry, char *out_buf, + size_t out_buf_size) { unsigned long sec, usec; unsigned long caller; @@ -1505,9 +1518,9 @@ int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view, else except_str = "-"; caller = (unsigned long) entry->caller; - rc += sprintf(out_buf, "%02i %011ld:%06lu %1u %1s %04u %px ", - area, sec, usec, level, except_str, - entry->cpu, (void *)caller); + rc += scnprintf(out_buf, out_buf_size, "%02i %011ld:%06lu %1u %1s %04u %px ", + area, sec, usec, level, except_str, + entry->cpu, (void *)caller); return rc; } EXPORT_SYMBOL(debug_dflt_header_fn); @@ -1520,7 +1533,7 @@ EXPORT_SYMBOL(debug_dflt_header_fn); #define DEBUG_SPRINTF_MAX_ARGS 10 static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, - char *out_buf, const char *inbuf) + char *out_buf, size_t out_buf_size, const char *inbuf) { debug_sprintf_entry_t *curr_event = (debug_sprintf_entry_t *)inbuf; int num_longs, num_used_args = 0, i, rc = 0; @@ -1533,8 +1546,9 @@ static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, goto out; /* bufsize of entry too small */ if (num_longs == 1) { /* no args, we use only the string */ - strcpy(out_buf, curr_event->string); - rc = strlen(curr_event->string); + rc = strscpy(out_buf, curr_event->string, out_buf_size); + if (rc == -E2BIG) + rc = out_buf_size; goto out; } @@ -1546,12 +1560,13 @@ static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, for (i = 0; i < num_used_args; i++) index[i] = i; - rc = sprintf(out_buf, curr_event->string, curr_event->args[index[0]], - curr_event->args[index[1]], curr_event->args[index[2]], - curr_event->args[index[3]], curr_event->args[index[4]], - curr_event->args[index[5]], curr_event->args[index[6]], - curr_event->args[index[7]], curr_event->args[index[8]], - curr_event->args[index[9]]); + rc = scnprintf(out_buf, out_buf_size, + curr_event->string, curr_event->args[index[0]], + curr_event->args[index[1]], curr_event->args[index[2]], + curr_event->args[index[3]], curr_event->args[index[4]], + curr_event->args[index[5]], curr_event->args[index[6]], + curr_event->args[index[7]], curr_event->args[index[8]], + curr_event->args[index[9]]); out: return rc; } diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 1ff13239d4e588eac75b696335ac5f88e05e6029..960c08700cf690df11c66b31f809478f8130f2ec 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -430,9 +430,13 @@ SYM_CODE_START(\name) SYM_CODE_END(\name) .endm + .section .irqentry.text, "ax" + INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq + .section .kprobes.text, "ax" + /* * Machine check handler routines */ diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 6295faf0987d86fcb20d5f2c2183bd0a0cb168c0..8b80ea57125f3c4cf305c8e479db6303045cc8a7 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -489,6 +489,12 @@ int __init arch_init_kprobes(void) return 0; } +int __init arch_populate_kprobe_blacklist(void) +{ + return kprobe_add_area_blacklist((unsigned long)__irqentry_text_start, + (unsigned long)__irqentry_text_end); +} + int arch_trampoline_kprobe(struct kprobe *p) { return 0; diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 0cde42f8af6ef582dc72747427655a26c58f0d4e..1e99514fb7ae3db42cef70e34255b4432e76c536 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -180,39 +180,27 @@ static int sf_buffer_available(struct cpu_hw_sf *cpuhw) */ static void free_sampling_buffer(struct sf_buffer *sfb) { - unsigned long *sdbt, *curr; - - if (!sfb->sdbt) - return; + unsigned long *sdbt, *curr, *head; sdbt = sfb->sdbt; - curr = sdbt; - + if (!sdbt) + return; + sfb->sdbt = NULL; /* Free the SDBT after all SDBs are processed... */ - while (1) { - if (!*curr || !sdbt) - break; - - /* Process table-link entries */ + head = sdbt; + curr = sdbt; + do { if (is_link_entry(curr)) { + /* Process table-link entries */ curr = get_next_sdbt(curr); - if (sdbt) - free_page((unsigned long)sdbt); - - /* If the origin is reached, sampling buffer is freed */ - if (curr == sfb->sdbt) - break; - else - sdbt = curr; + free_page((unsigned long)sdbt); + sdbt = curr; } else { /* Process SDB pointer */ - if (*curr) { - free_page((unsigned long)phys_to_virt(*curr)); - curr++; - } + free_page((unsigned long)phys_to_virt(*curr)); + curr++; } - } - + } while (curr != head); memset(sfb, 0, sizeof(*sfb)); } diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index 9f59837d159e0ccf2c622e3dc3a6cb26c33899dc..40edfde25f5b977230080f9c4f94fe6c0c87ed4a 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -151,7 +151,7 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo break; } if (!store_ip(consume_entry, cookie, entry, perf, ip)) - return; + break; first = false; } pagefault_enable(); diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index a688351f4ab5217d745444e6b8a95829c10a2f1f..9816b0060fbe541909c29818e88aeb2d3ef60749 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -129,8 +129,8 @@ static void ipte_lock_simple(struct kvm *kvm) retry: read_lock(&kvm->arch.sca_lock); ic = kvm_s390_get_ipte_control(kvm); + old = READ_ONCE(*ic); do { - old = READ_ONCE(*ic); if (old.k) { read_unlock(&kvm->arch.sca_lock); cond_resched(); @@ -138,7 +138,7 @@ retry: } new = old; new.k = 1; - } while (cmpxchg(&ic->val, old.val, new.val) != old.val); + } while (!try_cmpxchg(&ic->val, &old.val, new.val)); read_unlock(&kvm->arch.sca_lock); out: mutex_unlock(&kvm->arch.ipte_mutex); @@ -154,11 +154,11 @@ static void ipte_unlock_simple(struct kvm *kvm) goto out; read_lock(&kvm->arch.sca_lock); ic = kvm_s390_get_ipte_control(kvm); + old = READ_ONCE(*ic); do { - old = READ_ONCE(*ic); new = old; new.k = 0; - } while (cmpxchg(&ic->val, old.val, new.val) != old.val); + } while (!try_cmpxchg(&ic->val, &old.val, new.val)); read_unlock(&kvm->arch.sca_lock); wake_up(&kvm->arch.ipte_wq); out: @@ -172,8 +172,8 @@ static void ipte_lock_siif(struct kvm *kvm) retry: read_lock(&kvm->arch.sca_lock); ic = kvm_s390_get_ipte_control(kvm); + old = READ_ONCE(*ic); do { - old = READ_ONCE(*ic); if (old.kg) { read_unlock(&kvm->arch.sca_lock); cond_resched(); @@ -182,7 +182,7 @@ retry: new = old; new.k = 1; new.kh++; - } while (cmpxchg(&ic->val, old.val, new.val) != old.val); + } while (!try_cmpxchg(&ic->val, &old.val, new.val)); read_unlock(&kvm->arch.sca_lock); } @@ -192,13 +192,13 @@ static void ipte_unlock_siif(struct kvm *kvm) read_lock(&kvm->arch.sca_lock); ic = kvm_s390_get_ipte_control(kvm); + old = READ_ONCE(*ic); do { - old = READ_ONCE(*ic); new = old; new.kh--; if (!new.kh) new.k = 0; - } while (cmpxchg(&ic->val, old.val, new.val) != old.val); + } while (!try_cmpxchg(&ic->val, &old.val, new.val)); read_unlock(&kvm->arch.sca_lock); if (!new.kh) wake_up(&kvm->arch.ipte_wq); diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 4f0e7f61edf788bf94e10b9265f71436790bdf73..ea8dce299954a3ce2d291b6ca7c803e34bef5a6d 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -118,8 +118,6 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) static void sca_clear_ext_call(struct kvm_vcpu *vcpu) { - int rc, expect; - if (!kvm_s390_use_sca_entries()) return; kvm_s390_clear_cpuflags(vcpu, CPUSTAT_ECALL_PEND); @@ -128,23 +126,16 @@ static void sca_clear_ext_call(struct kvm_vcpu *vcpu) struct esca_block *sca = vcpu->kvm->arch.sca; union esca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union esca_sigp_ctrl old; - old = READ_ONCE(*sigp_ctrl); - expect = old.value; - rc = cmpxchg(&sigp_ctrl->value, old.value, 0); + WRITE_ONCE(sigp_ctrl->value, 0); } else { struct bsca_block *sca = vcpu->kvm->arch.sca; union bsca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union bsca_sigp_ctrl old; - old = READ_ONCE(*sigp_ctrl); - expect = old.value; - rc = cmpxchg(&sigp_ctrl->value, old.value, 0); + WRITE_ONCE(sigp_ctrl->value, 0); } read_unlock(&vcpu->kvm->arch.sca_lock); - WARN_ON(rc != expect); /* cannot clear? */ } int psw_extint_disabled(struct kvm_vcpu *vcpu) @@ -247,12 +238,12 @@ static inline int gisa_set_iam(struct kvm_s390_gisa *gisa, u8 iam) { u64 word, _word; + word = READ_ONCE(gisa->u64.word[0]); do { - word = READ_ONCE(gisa->u64.word[0]); if ((u64)gisa != word >> 32) return -EBUSY; _word = (word & ~0xffUL) | iam; - } while (cmpxchg(&gisa->u64.word[0], word, _word) != word); + } while (!try_cmpxchg(&gisa->u64.word[0], &word, _word)); return 0; } @@ -270,10 +261,10 @@ static inline void gisa_clear_ipm(struct kvm_s390_gisa *gisa) { u64 word, _word; + word = READ_ONCE(gisa->u64.word[0]); do { - word = READ_ONCE(gisa->u64.word[0]); _word = word & ~(0xffUL << 24); - } while (cmpxchg(&gisa->u64.word[0], word, _word) != word); + } while (!try_cmpxchg(&gisa->u64.word[0], &word, _word)); } /** @@ -291,14 +282,14 @@ static inline u8 gisa_get_ipm_or_restore_iam(struct kvm_s390_gisa_interrupt *gi) u8 pending_mask, alert_mask; u64 word, _word; + word = READ_ONCE(gi->origin->u64.word[0]); do { - word = READ_ONCE(gi->origin->u64.word[0]); alert_mask = READ_ONCE(gi->alert.mask); pending_mask = (u8)(word >> 24) & alert_mask; if (pending_mask) return pending_mask; _word = (word & ~0xffUL) | alert_mask; - } while (cmpxchg(&gi->origin->u64.word[0], word, _word) != word); + } while (!try_cmpxchg(&gi->origin->u64.word[0], &word, _word)); return 0; } diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 442d4a227c0e68e69d5522c79f9a1c2d23af1d2f..d8080c27d45bda85e59f8d5c4104d7f05b2a0e2a 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1937,11 +1937,11 @@ static void kvm_s390_update_topology_change_report(struct kvm *kvm, bool val) read_lock(&kvm->arch.sca_lock); sca = kvm->arch.sca; + old = READ_ONCE(sca->utility); do { - old = READ_ONCE(sca->utility); new = old; new.mtcr = val; - } while (cmpxchg(&sca->utility.val, old.val, new.val) != old.val); + } while (!try_cmpxchg(&sca->utility.val, &old.val, new.val)); read_unlock(&kvm->arch.sca_lock); } diff --git a/arch/s390/kvm/pci.c b/arch/s390/kvm/pci.c index a61518b549f00b108693b432a5e57114214a69b8..9b9e7fdd53807886cd24cda103f8f46650ddf53f 100644 --- a/arch/s390/kvm/pci.c +++ b/arch/s390/kvm/pci.c @@ -208,13 +208,12 @@ static inline int account_mem(unsigned long nr_pages) page_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + cur_pages = atomic_long_read(&user->locked_vm); do { - cur_pages = atomic_long_read(&user->locked_vm); new_pages = cur_pages + nr_pages; if (new_pages > page_limit) return -ENOMEM; - } while (atomic_long_cmpxchg(&user->locked_vm, cur_pages, - new_pages) != cur_pages); + } while (!atomic_long_try_cmpxchg(&user->locked_vm, &cur_pages, new_pages)); atomic64_add(nr_pages, ¤t->mm->pinned_vm); diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 09d735010ee1b8d17884ae9b8af627f3b9f37f55..a81a01c449272ebad77cb031992078ac8e255eb8 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -15,6 +15,7 @@ #include #include #include +#include int spin_retry = -1; @@ -76,24 +77,43 @@ static inline int arch_load_niai4(int *lock) asm_inline volatile( ALTERNATIVE("nop", ".insn rre,0xb2fa0000,4,0", ALT_FACILITY(49)) /* NIAI 4 */ - " l %0,%1\n" - : "=d" (owner) : "Q" (*lock) : "memory"); + " l %[owner],%[lock]\n" + : [owner] "=d" (owner) : [lock] "R" (*lock) : "memory"); return owner; } -static inline int arch_cmpxchg_niai8(int *lock, int old, int new) +#ifdef __HAVE_ASM_FLAG_OUTPUTS__ + +static inline int arch_try_cmpxchg_niai8(int *lock, int old, int new) +{ + int cc; + + asm_inline volatile( + ALTERNATIVE("nop", ".insn rre,0xb2fa0000,8,0", ALT_FACILITY(49)) /* NIAI 8 */ + " cs %[old],%[new],%[lock]\n" + : [old] "+d" (old), [lock] "+Q" (*lock), "=@cc" (cc) + : [new] "d" (new) + : "memory"); + return cc == 0; +} + +#else /* __HAVE_ASM_FLAG_OUTPUTS__ */ + +static inline int arch_try_cmpxchg_niai8(int *lock, int old, int new) { int expected = old; asm_inline volatile( ALTERNATIVE("nop", ".insn rre,0xb2fa0000,8,0", ALT_FACILITY(49)) /* NIAI 8 */ - " cs %0,%3,%1\n" - : "=d" (old), "=Q" (*lock) - : "0" (old), "d" (new), "Q" (*lock) + " cs %[old],%[new],%[lock]\n" + : [old] "+d" (old), [lock] "+Q" (*lock) + : [new] "d" (new) : "cc", "memory"); return expected == old; } +#endif /* __HAVE_ASM_FLAG_OUTPUTS__ */ + static inline struct spin_wait *arch_spin_decode_tail(int lock) { int ix, cpu; @@ -226,7 +246,7 @@ static inline void arch_spin_lock_classic(arch_spinlock_t *lp) /* Try to get the lock if it is free. */ if (!owner) { new = (old & _Q_TAIL_MASK) | lockval; - if (arch_cmpxchg_niai8(&lp->lock, old, new)) { + if (arch_try_cmpxchg_niai8(&lp->lock, old, new)) { /* Got the lock */ return; } diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 646326fa0fad85e6a96df928d89c762d251900b3..9b681f74dccc1f525bafe150acf91e666a60d2bd 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -338,7 +338,8 @@ done: handle_fault_error_nolock(regs, 0); else do_sigsegv(regs, SEGV_MAPERR); - } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) { + } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON | + VM_FAULT_HWPOISON_LARGE)) { if (!user_mode(regs)) handle_fault_error_nolock(regs, 0); else diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 643e47bfaddc71823c481081906dc692a7da58a2..16b8a36c56de11e007cf9e8de3ef6a99d9e60b22 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -587,7 +587,8 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) if (pmd_leaf(*pmd)) { *table = (pmd_val(*pmd) & _SEGMENT_ENTRY_HARDWARE_BITS_LARGE) - | _SEGMENT_ENTRY_GMAP_UC; + | _SEGMENT_ENTRY_GMAP_UC + | _SEGMENT_ENTRY; } else *table = pmd_val(*pmd) & _SEGMENT_ENTRY_HARDWARE_BITS; @@ -2396,7 +2397,8 @@ static void gmap_pmdp_clear(struct mm_struct *mm, unsigned long vmaddr, gaddr = __gmap_segment_gaddr((unsigned long *)pmdp); pmdp_notify_gmap(gmap, pmdp, gaddr); WARN_ON(pmd_val(*pmdp) & ~(_SEGMENT_ENTRY_HARDWARE_BITS_LARGE | - _SEGMENT_ENTRY_GMAP_UC)); + _SEGMENT_ENTRY_GMAP_UC | + _SEGMENT_ENTRY)); if (purge) __pmdp_csp(pmdp); set_pmd(pmdp, __pmd(_SEGMENT_ENTRY_EMPTY)); @@ -2450,7 +2452,8 @@ void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr) gaddr = __gmap_segment_gaddr(entry); pmdp_notify_gmap(gmap, pmdp, gaddr); WARN_ON(*entry & ~(_SEGMENT_ENTRY_HARDWARE_BITS_LARGE | - _SEGMENT_ENTRY_GMAP_UC)); + _SEGMENT_ENTRY_GMAP_UC | + _SEGMENT_ENTRY)); if (MACHINE_HAS_TLB_GUEST) __pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_LOCAL); @@ -2485,7 +2488,8 @@ void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr) gaddr = __gmap_segment_gaddr(entry); pmdp_notify_gmap(gmap, pmdp, gaddr); WARN_ON(*entry & ~(_SEGMENT_ENTRY_HARDWARE_BITS_LARGE | - _SEGMENT_ENTRY_GMAP_UC)); + _SEGMENT_ENTRY_GMAP_UC | + _SEGMENT_ENTRY)); if (MACHINE_HAS_TLB_GUEST) __pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_GLOBAL); diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 7c79cf1bc7d7601f89b26c1da561a21f3c4de337..d9ce199953de9e4241f0eb04f2e81271d3f26680 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -24,6 +24,7 @@ static inline unsigned long __pte_to_rste(pte_t pte) { + swp_entry_t arch_entry; unsigned long rste; /* @@ -48,6 +49,7 @@ static inline unsigned long __pte_to_rste(pte_t pte) */ if (pte_present(pte)) { rste = pte_val(pte) & PAGE_MASK; + rste |= _SEGMENT_ENTRY_PRESENT; rste |= move_set_bit(pte_val(pte), _PAGE_READ, _SEGMENT_ENTRY_READ); rste |= move_set_bit(pte_val(pte), _PAGE_WRITE, @@ -66,6 +68,10 @@ static inline unsigned long __pte_to_rste(pte_t pte) #endif rste |= move_set_bit(pte_val(pte), _PAGE_NOEXEC, _SEGMENT_ENTRY_NOEXEC); + } else if (!pte_none(pte)) { + /* swap pte */ + arch_entry = __pte_to_swp_entry(pte); + rste = mk_swap_rste(__swp_type(arch_entry), __swp_offset(arch_entry)); } else rste = _SEGMENT_ENTRY_EMPTY; return rste; @@ -73,13 +79,18 @@ static inline unsigned long __pte_to_rste(pte_t pte) static inline pte_t __rste_to_pte(unsigned long rste) { + swp_entry_t arch_entry; unsigned long pteval; - int present; + int present, none; + pte_t pte; - if ((rste & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) + if ((rste & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) { present = pud_present(__pud(rste)); - else + none = pud_none(__pud(rste)); + } else { present = pmd_present(__pmd(rste)); + none = pmd_none(__pmd(rste)); + } /* * Convert encoding pmd / pud bits pte bits @@ -114,6 +125,11 @@ static inline pte_t __rste_to_pte(unsigned long rste) pteval |= move_set_bit(rste, _SEGMENT_ENTRY_SOFT_DIRTY, _PAGE_SOFT_DIRTY); #endif pteval |= move_set_bit(rste, _SEGMENT_ENTRY_NOEXEC, _PAGE_NOEXEC); + } else if (!none) { + /* swap rste */ + arch_entry = __rste_to_swp_entry(rste); + pte = mk_swap_pte(__swp_type_rste(arch_entry), __swp_offset_rste(arch_entry)); + pteval = pte_val(pte); } else pteval = _PAGE_INVALID; return __pte(pteval); @@ -148,8 +164,6 @@ void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, unsigned long rste; rste = __pte_to_rste(pte); - if (!MACHINE_HAS_NX) - rste &= ~_SEGMENT_ENTRY_NOEXEC; /* Set correct table type for 2G hugepages */ if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) { @@ -223,11 +237,10 @@ pte_t *huge_pte_offset(struct mm_struct *mm, p4dp = p4d_offset(pgdp, addr); if (p4d_present(*p4dp)) { pudp = pud_offset(p4dp, addr); - if (pud_present(*pudp)) { - if (pud_leaf(*pudp)) - return (pte_t *) pudp; + if (sz == PUD_SIZE) + return (pte_t *)pudp; + if (pud_present(*pudp)) pmdp = pmd_offset(pudp, addr); - } } } return (pte_t *) pmdp; diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index cbff587dc4e31e22f69a1d1011e0b5d5cdd39408..88f72745fa59e16df26b1563de27594aac954a78 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -779,8 +779,9 @@ int zpci_hot_reset_device(struct zpci_dev *zdev) * @fh: Current Function Handle of the device to be created * @state: Initial state after creation either Standby or Configured * - * Creates a new zpci device and adds it to its, possibly newly created, zbus - * as well as zpci_list. + * Allocates a new struct zpci_dev and queries the platform for its details. + * If successful the device can subsequently be added to the zPCI subsystem + * using zpci_add_device(). * * Returns: the zdev on success or an error pointer otherwise */ @@ -803,7 +804,6 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state) goto error; zdev->state = state; - kref_init(&zdev->kref); mutex_init(&zdev->state_lock); mutex_init(&zdev->fmb_lock); mutex_init(&zdev->kzdev_lock); @@ -816,6 +816,17 @@ error: return ERR_PTR(rc); } +/** + * zpci_add_device() - Add a previously created zPCI device to the zPCI subsystem + * @zdev: The zPCI device to be added + * + * A struct zpci_dev is added to the zPCI subsystem and to a virtual PCI bus creating + * a new one as necessary. A hotplug slot is created and events start to be handled. + * If successful from this point on zpci_zdev_get() and zpci_zdev_put() must be used. + * If adding the struct zpci_dev fails the device was not added and should be freed. + * + * Return: 0 on success, or an error code otherwise + */ int zpci_add_device(struct zpci_dev *zdev) { int rc; @@ -829,6 +840,7 @@ int zpci_add_device(struct zpci_dev *zdev) if (rc) goto error_destroy_iommu; + kref_init(&zdev->kref); spin_lock(&zpci_list_lock); list_add_tail(&zdev->entry, &zpci_list); spin_unlock(&zpci_list_lock); @@ -928,10 +940,8 @@ void zpci_device_reserved(struct zpci_dev *zdev) void zpci_release_device(struct kref *kref) { struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref); - int ret; - if (zdev->has_hp_slot) - zpci_exit_slot(zdev); + WARN_ON(zdev->state != ZPCI_FN_STATE_RESERVED); if (zdev->zbus->bus) zpci_bus_remove_device(zdev, false); @@ -939,28 +949,14 @@ void zpci_release_device(struct kref *kref) if (zdev_enabled(zdev)) zpci_disable_device(zdev); - switch (zdev->state) { - case ZPCI_FN_STATE_CONFIGURED: - ret = sclp_pci_deconfigure(zdev->fid); - zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret); - fallthrough; - case ZPCI_FN_STATE_STANDBY: - if (zdev->has_hp_slot) - zpci_exit_slot(zdev); - spin_lock(&zpci_list_lock); - list_del(&zdev->entry); - spin_unlock(&zpci_list_lock); - zpci_dbg(3, "rsv fid:%x\n", zdev->fid); - fallthrough; - case ZPCI_FN_STATE_RESERVED: - if (zdev->has_resources) - zpci_cleanup_bus_resources(zdev); - zpci_bus_device_unregister(zdev); - zpci_destroy_iommu(zdev); - fallthrough; - default: - break; - } + if (zdev->has_hp_slot) + zpci_exit_slot(zdev); + + if (zdev->has_resources) + zpci_cleanup_bus_resources(zdev); + + zpci_bus_device_unregister(zdev); + zpci_destroy_iommu(zdev); zpci_dbg(3, "rem fid:%x\n", zdev->fid); kfree_rcu(zdev, rcu); } @@ -1121,7 +1117,8 @@ static void zpci_add_devices(struct list_head *scan_list) list_sort(NULL, scan_list, &zpci_cmp_rid); list_for_each_entry_safe(zdev, tmp, scan_list, entry) { list_del_init(&zdev->entry); - zpci_add_device(zdev); + if (zpci_add_device(zdev)) + kfree(zdev); } } diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index 47f934f4e828e9ac6f8cae46474346d14fb5375b..7f7b732b3f3efaecf9fd17420f911414d9d0ef7b 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -340,7 +340,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED); if (IS_ERR(zdev)) break; - zpci_add_device(zdev); + if (zpci_add_device(zdev)) { + kfree(zdev); + break; + } } else { /* the configuration request may be stale */ if (zdev->state != ZPCI_FN_STATE_STANDBY) @@ -354,7 +357,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY); if (IS_ERR(zdev)) break; - zpci_add_device(zdev); + if (zpci_add_device(zdev)) { + kfree(zdev); + break; + } } else { zpci_update_fh(zdev, ccdf->fh); } diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c index 1dea43381b5ae689aa768088ed833f271211cd85..2b51ad9d5586a42ea16f314aa3f72461bec6c6a7 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c @@ -110,7 +110,7 @@ static void switch_drv_remove(struct platform_device *pdev) static struct platform_driver switch_driver = { .probe = switch_drv_probe, - .remove_new = switch_drv_remove, + .remove = switch_drv_remove, .driver = { .name = DRV_NAME, }, diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c index a306bcd6b34130bf6c63f2e3c10da4c464eed917..5f6d0e827baeb06463e2c7ba8bd1c08299e8d12c 100644 --- a/arch/sh/kernel/cpu/proc.c +++ b/arch/sh/kernel/cpu/proc.c @@ -132,7 +132,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < NR_CPUS ? cpu_data + *pos : NULL; + return *pos < nr_cpu_ids ? cpu_data + *pos : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) { diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 757451c3ea1df63b948e68a45988c78f5974f9ea..0400078076e588be93a702d1c64eb9fd34466075 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -29,7 +29,7 @@ UTS_MACHINE := sparc # versions of gcc. Some gcc versions won't pass -Av8 to binutils when you # give -mcpu=v8. This silently worked with older bintutils versions but # does not any more. -KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 +KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu $(call cc-option,-fcall-used-g5) $(call cc-option,-fcall-used-g7) KBUILD_CFLAGS += -Wa,-Av8 KBUILD_AFLAGS += -m32 -Wa,-Av8 @@ -45,7 +45,7 @@ export BITS := 64 UTS_MACHINE := sparc64 KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow -KBUILD_CFLAGS += -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare +KBUILD_CFLAGS += -ffixed-g4 -ffixed-g5 $(call cc-option,-fcall-used-g7) -Wno-sign-compare KBUILD_CFLAGS += -Wa,--undeclared-regs KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3) KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs diff --git a/arch/sparc/include/asm/hvtramp.h b/arch/sparc/include/asm/hvtramp.h index 688ea43af0f5d90e98722b4be2efbefb75f2cdc1..ce2453ea4f2be2d04c8b4170f814b1cde91a5259 100644 --- a/arch/sparc/include/asm/hvtramp.h +++ b/arch/sparc/include/asm/hvtramp.h @@ -17,7 +17,7 @@ struct hvtramp_descr { __u64 fault_info_va; __u64 fault_info_pa; __u64 thread_reg; - struct hvtramp_mapping maps[1]; + struct hvtramp_mapping maps[]; }; void hv_cpu_startup(unsigned long hvdescr_pa); diff --git a/arch/sparc/include/asm/parport_64.h b/arch/sparc/include/asm/parport_64.h index 4f530a270760d33dcedb90697f4e8e0cc628d1bd..3068809ef9ad0cae3d9bbce69d7dea33f1a9136e 100644 --- a/arch/sparc/include/asm/parport_64.h +++ b/arch/sparc/include/asm/parport_64.h @@ -243,7 +243,7 @@ static struct platform_driver ecpp_driver = { .of_match_table = ecpp_match, }, .probe = ecpp_probe, - .remove_new = ecpp_remove, + .remove = ecpp_remove, }; static int parport_pc_find_nonpci_ports(int autoirq, int autodma) diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index e020740620011b1310893fea4d35f1649101de91..d4c74d6b2e1b83ed72b002d1af4f9919ba1d4252 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -814,7 +814,7 @@ static struct platform_driver us3mc_driver = { .of_match_table = us3mc_match, }, .probe = us3mc_probe, - .remove_new = us3mc_remove, + .remove = us3mc_remove, }; static inline bool us3mc_platform(void) diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index e40c395db2026cd8afd2ac6d6536014c78f80d00..5cbd6ed5ef6fabbde3aa3fdf49e9a6af8ebeee50 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -297,9 +297,7 @@ static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg, unsigned long hv_err; int i; - hdesc = kzalloc(sizeof(*hdesc) + - (sizeof(struct hvtramp_mapping) * - num_kernel_image_mappings - 1), + hdesc = kzalloc(struct_size(hdesc, maps, num_kernel_image_mappings), GFP_KERNEL); if (!hdesc) { printk(KERN_ERR "ldom_startcpu_cpuid: Cannot allocate " diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 08bbdc4585969c28b1ccc2d7df9934450abc64d3..578fd0d49f30668e2a2de9c8561fab5f43e7b81a 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -255,6 +255,7 @@ static void mostek_write_byte(struct device *dev, u32 ofs, u8 val) static struct m48t59_plat_data m48t59_data = { .read_byte = mostek_read_byte, .write_byte = mostek_write_byte, + .yy_offset = 68, }; /* resource is set at runtime */ diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 60f1c8cc5363e6947ac23d0404206340ade4c168..b32f27f929d1ab49a5aa05cde60d3b88e90928ba 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -544,6 +544,7 @@ static void mostek_write_byte(struct device *dev, u32 ofs, u8 val) static struct m48t59_plat_data m48t59_data = { .read_byte = mostek_read_byte, .write_byte = mostek_write_byte, + .yy_offset = 68, }; static struct platform_device m48t59_rtc = { diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index d317a843f7ea9b168b6824a7c7a9b99c8c812c3a..f1b86eb3034043ff9e9d568d4dcdb111b9b92dd6 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -48,6 +48,11 @@ SECTIONS { _text = .; HEAD_TEXT + ALIGN_FUNCTION(); +#ifdef CONFIG_SPARC64 + /* Match text section symbols in head_64.S first */ + *head_64.o(.text) +#endif TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile index 243dbfc4609d804fc221c3591eebe891107ffdab..50ec2978cda5397841daad6ffdc9682811b9b38e 100644 --- a/arch/sparc/vdso/Makefile +++ b/arch/sparc/vdso/Makefile @@ -46,7 +46,7 @@ CFL := $(PROFILING) -mcmodel=medlow -fPIC -O2 -fasynchronous-unwind-tables -m64 -fno-omit-frame-pointer -foptimize-sibling-calls \ -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO -SPARC_REG_CFLAGS = -ffixed-g4 -ffixed-g5 -fcall-used-g5 -fcall-used-g7 +SPARC_REG_CFLAGS = -ffixed-g4 -ffixed-g5 $(call cc-option,-fcall-used-g5) $(call cc-option,-fcall-used-g7) $(vobjs): KBUILD_CFLAGS := $(filter-out $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c index e794edde675548230e20d7b14fd3ff6c83405d32..79607804ea1b0f321215a9c4b5ead1edeb912e64 100644 --- a/arch/sparc/vdso/vclock_gettime.c +++ b/arch/sparc/vdso/vclock_gettime.c @@ -86,6 +86,11 @@ notrace static long vdso_fallback_gettimeofday(struct __kernel_old_timeval *tv, } #ifdef CONFIG_SPARC64 +notrace static __always_inline u64 __shr64(u64 val, int amt) +{ + return val >> amt; +} + notrace static __always_inline u64 vread_tick(void) { u64 ret; @@ -102,6 +107,21 @@ notrace static __always_inline u64 vread_tick_stick(void) return ret; } #else +notrace static __always_inline u64 __shr64(u64 val, int amt) +{ + u64 ret; + + __asm__ __volatile__("sllx %H1, 32, %%g1\n\t" + "srl %L1, 0, %L1\n\t" + "or %%g1, %L1, %%g1\n\t" + "srlx %%g1, %2, %L0\n\t" + "srlx %L0, 32, %H0" + : "=r" (ret) + : "r" (val), "r" (amt) + : "g1"); + return ret; +} + notrace static __always_inline u64 vread_tick(void) { register unsigned long long ret asm("o4"); @@ -154,7 +174,7 @@ notrace static __always_inline int do_realtime(struct vvar_data *vvar, ts->tv_sec = vvar->wall_time_sec; ns = vvar->wall_time_snsec; ns += vgetsns(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); @@ -174,7 +194,7 @@ notrace static __always_inline int do_realtime_stick(struct vvar_data *vvar, ts->tv_sec = vvar->wall_time_sec; ns = vvar->wall_time_snsec; ns += vgetsns_stick(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); @@ -194,7 +214,7 @@ notrace static __always_inline int do_monotonic(struct vvar_data *vvar, ts->tv_sec = vvar->monotonic_time_sec; ns = vvar->monotonic_time_snsec; ns += vgetsns(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); @@ -214,7 +234,7 @@ notrace static __always_inline int do_monotonic_stick(struct vvar_data *vvar, ts->tv_sec = vvar->monotonic_time_sec; ns = vvar->monotonic_time_snsec; ns += vgetsns_stick(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); diff --git a/arch/um/Kconfig b/arch/um/Kconfig index c89575d05021f19ee7b50b2445215fb35aa4f84c..18051b1cfce0a264f93c86f4054fadeff010de4c 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -5,6 +5,7 @@ menu "UML-specific options" config UML bool default y + select ARCH_WANTS_DYNAMIC_TASK_STRUCT select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL @@ -32,6 +33,8 @@ config UML select HAVE_ARCH_VMAP_STACK select HAVE_RUST select ARCH_HAS_UBSAN + select HAVE_ARCH_TRACEHOOK + select THREAD_INFO_IN_TASK config MMU bool @@ -94,7 +97,7 @@ config MAY_HAVE_RUNTIME_DEPS config STATIC_LINK bool "Force a static link" - depends on CC_CAN_LINK_STATIC_NO_RUNTIME_DEPS || !MAY_HAVE_RUNTIME_DEPS + depends on !MAY_HAVE_RUNTIME_DEPS help This option gives you the ability to force a static link of UML. Normally, UML is linked as a shared binary. This is inconvenient for @@ -209,8 +212,8 @@ config MMAPPER config PGTABLE_LEVELS int - default 3 if 3_LEVEL_PGTABLES - default 2 + default 4 if 64BIT + default 2 if !64BIT config UML_TIME_TRAVEL_SUPPORT bool @@ -227,6 +230,21 @@ config UML_TIME_TRAVEL_SUPPORT It is safe to say Y, but you probably don't need this. +config UML_MAX_USERSPACE_ITERATIONS + int + prompt "Maximum number of unscheduled userspace iterations" + default 10000 + depends on UML_TIME_TRAVEL_SUPPORT + help + In UML inf-cpu and ext time-travel mode userspace can run without being + interrupted. This will eventually overwhelm the kernel and create OOM + situations (mainly RCU not running). This setting specifies the number + of kernel/userspace switches (minor/major page fault, signal or syscall) + for the same userspace thread before the sched_clock is advanced by a + jiffie to trigger scheduling. + + Setting it to zero disables the feature. + config KASAN_SHADOW_OFFSET hex depends on KASAN diff --git a/arch/um/Makefile b/arch/um/Makefile index 00b63bac5effb5bcf18ffb00fa23cfc28c358f3b..1d36a613aad83dd96b9a79e56d2eb21c3597ab7f 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -61,7 +61,8 @@ KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ -Din6addr_loopback=kernel_in6addr_loopback \ - -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr \ + -D__close_range=kernel__close_range KBUILD_RUSTFLAGS += -Crelocation-model=pie @@ -70,7 +71,9 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE) USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \ $(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \ -D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \ - -idirafter $(objtree)/include -D__KERNEL__ -D__UM_HOST__ + -idirafter $(objtree)/include -D__KERNEL__ -D__UM_HOST__ \ + -include $(srctree)/include/linux/compiler-version.h \ + -include $(srctree)/include/linux/kconfig.h #This will adjust *FLAGS accordingly to the platform. include $(srctree)/$(ARCH_DIR)/Makefile-os-Linux diff --git a/arch/um/Makefile-skas b/arch/um/Makefile-skas index 67323b02899990b58c9f008565e7df2b7f7dcbda..1a27e65bcb9c15b97041c891d0df14a578bfd4f0 100644 --- a/arch/um/Makefile-skas +++ b/arch/um/Makefile-skas @@ -3,15 +3,15 @@ # Licensed under the GPL # -GPROF_OPT += -pg +export UM_GPROF_OPT += -pg ifdef CONFIG_CC_IS_CLANG -GCOV_OPT += -fprofile-instr-generate -fcoverage-mapping +export UM_GCOV_OPT += -fprofile-instr-generate -fcoverage-mapping else -GCOV_OPT += -fprofile-arcs -ftest-coverage +export UM_GCOV_OPT += -fprofile-arcs -ftest-coverage endif -CFLAGS-$(CONFIG_GCOV) += $(GCOV_OPT) -CFLAGS-$(CONFIG_GPROF) += $(GPROF_OPT) -LINK-$(CONFIG_GCOV) += $(GCOV_OPT) -LINK-$(CONFIG_GPROF) += $(GPROF_OPT) +CFLAGS-$(CONFIG_GCOV) += $(UM_GCOV_OPT) +CFLAGS-$(CONFIG_GPROF) += $(UM_GPROF_OPT) +LINK-$(CONFIG_GCOV) += $(UM_GCOV_OPT) +LINK-$(CONFIG_GPROF) += $(UM_GPROF_OPT) diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig index 9c9c77f1255ac306c59cb2c470d50e4f577cca4a..1ffa088739f4fe5ba9f2fc1997f353df9891892f 100644 --- a/arch/um/configs/i386_defconfig +++ b/arch/um/configs/i386_defconfig @@ -1,4 +1,3 @@ -CONFIG_3_LEVEL_PGTABLES=y # CONFIG_COMPACTION is not set CONFIG_BINFMT_MISC=m CONFIG_HOSTFS=y diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index a66e556012c4840fb629aa26dd82641d15dd185f..35f9beeb19b3fe6761dcd4735690600403ce3e53 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -161,6 +161,8 @@ static __noreturn int winch_thread(void *arg) int count; char c = 1; + os_set_pdeathsig(); + pty_fd = data->pty_fd; pipe_fd = data->pipe_fd; count = write(pipe_fd, &c, sizeof(c)); diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 9d228878cea2ed7d970992a46a18afa938c4a941..0ac149de1ac0132b9f68e6212c145a9d07226ca3 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -48,6 +48,7 @@ MODULE_PARM_DESC(mixer, MIXER_HELP); #ifndef MODULE static int set_dsp(char *name, int *add) { + *add = 0; dsp = name; return 0; } @@ -56,6 +57,7 @@ __uml_setup("dsp=", set_dsp, "dsp=\n" DSP_HELP); static int set_mixer(char *name, int *add) { + *add = 0; mixer = name; return 0; } diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 77c4afb8ab907170320b747d0a91016181192f02..75d04fb4994a06309a4dd85732c967569122d3ee 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -336,7 +336,7 @@ static struct platform_driver uml_net_driver = { static void net_device_release(struct device *dev) { - struct uml_net *device = dev_get_drvdata(dev); + struct uml_net *device = container_of(dev, struct uml_net, pdev.dev); struct net_device *netdev = device->dev; struct uml_net_private *lp = netdev_priv(netdev); diff --git a/arch/um/drivers/rtc_kern.c b/arch/um/drivers/rtc_kern.c index 3a1582219c4b85a1432ff4a127b85d76fd54a542..134a58f93c859d658dc2d9798037cac5de65b914 100644 --- a/arch/um/drivers/rtc_kern.c +++ b/arch/um/drivers/rtc_kern.c @@ -176,7 +176,7 @@ static void uml_rtc_remove(struct platform_device *pdev) static struct platform_driver uml_rtc_driver = { .probe = uml_rtc_probe, - .remove_new = uml_rtc_remove, + .remove = uml_rtc_remove, .driver = { .name = "uml-rtc", }, diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 7f28ec1929dc0b54341f43aa6497202c8b5f44f0..66c1a8835e362785bd4c8dff3940a5909376bc4a 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -779,7 +779,7 @@ static int ubd_open_dev(struct ubd *ubd_dev) static void ubd_device_release(struct device *dev) { - struct ubd *ubd_dev = dev_get_drvdata(dev); + struct ubd *ubd_dev = container_of(dev, struct ubd, pdev.dev); blk_mq_free_tag_set(&ubd_dev->tag_set); *ubd_dev = ((struct ubd) DEFAULT_UBD); @@ -898,6 +898,8 @@ static int ubd_add(int n, char **error_out) if (err) goto out_cleanup_disk; + ubd_dev->disk = disk; + return 0; out_cleanup_disk: @@ -1499,6 +1501,7 @@ int io_thread(void *arg) { int n, count, written, res; + os_set_pdeathsig(); os_fix_helper_signals(); while(1){ diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index c992da83268dd848be0e1d85445c8947447a3e71..64c09db392c16aea9948ee93a8eee3675fcb6ec7 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -815,7 +815,8 @@ static struct platform_driver uml_net_driver = { static void vector_device_release(struct device *dev) { - struct vector_device *device = dev_get_drvdata(dev); + struct vector_device *device = + container_of(dev, struct vector_device, pdev.dev); struct net_device *netdev = device->dev; list_del(&device->list); diff --git a/arch/um/drivers/vhost_user.h b/arch/um/drivers/vhost_user.h index 6f147cd3c9f76a81995a8229c6eac01c1f8c5227..fcfa3b7e021bae961cd76d830929b03b70ac5562 100644 --- a/arch/um/drivers/vhost_user.h +++ b/arch/um/drivers/vhost_user.h @@ -10,6 +10,7 @@ /* Feature bits */ #define VHOST_USER_F_PROTOCOL_FEATURES 30 /* Protocol feature bits */ +#define VHOST_USER_PROTOCOL_F_MQ 0 #define VHOST_USER_PROTOCOL_F_REPLY_ACK 3 #define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5 #define VHOST_USER_PROTOCOL_F_CONFIG 9 @@ -23,7 +24,8 @@ /* Supported transport features */ #define VHOST_USER_SUPPORTED_F BIT_ULL(VHOST_USER_F_PROTOCOL_FEATURES) /* Supported protocol features */ -#define VHOST_USER_SUPPORTED_PROTOCOL_F (BIT_ULL(VHOST_USER_PROTOCOL_F_REPLY_ACK) | \ +#define VHOST_USER_SUPPORTED_PROTOCOL_F (BIT_ULL(VHOST_USER_PROTOCOL_F_MQ) | \ + BIT_ULL(VHOST_USER_PROTOCOL_F_REPLY_ACK) | \ BIT_ULL(VHOST_USER_PROTOCOL_F_SLAVE_REQ) | \ BIT_ULL(VHOST_USER_PROTOCOL_F_CONFIG) | \ BIT_ULL(VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS)) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 2b6e701776b6b81339c3c48bcfb28152c887c807..65df43fa9be58d9ce33caedf2e5c6a1e11f721fd 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -56,6 +56,7 @@ struct virtio_uml_device { int sock, req_fd, irq; u64 features; u64 protocol_features; + u64 max_vqs; u8 status; u8 registered:1; u8 suspended:1; @@ -72,8 +73,6 @@ struct virtio_uml_vq_info { bool suspended; }; -extern unsigned long long physmem_size, highmem; - #define vu_err(vu_dev, ...) dev_err(&(vu_dev)->pdev->dev, ##__VA_ARGS__) /* Vhost-user protocol */ @@ -343,6 +342,17 @@ static int vhost_user_set_protocol_features(struct virtio_uml_device *vu_dev, protocol_features); } +static int vhost_user_get_queue_num(struct virtio_uml_device *vu_dev, + u64 *queue_num) +{ + int rc = vhost_user_send_no_payload(vu_dev, true, + VHOST_USER_GET_QUEUE_NUM); + + if (rc) + return rc; + return vhost_user_recv_u64(vu_dev, queue_num); +} + static void vhost_user_reply(struct virtio_uml_device *vu_dev, struct vhost_user_msg *msg, int response) { @@ -516,6 +526,15 @@ static int vhost_user_init(struct virtio_uml_device *vu_dev) return rc; } + if (vu_dev->protocol_features & + BIT_ULL(VHOST_USER_PROTOCOL_F_MQ)) { + rc = vhost_user_get_queue_num(vu_dev, &vu_dev->max_vqs); + if (rc) + return rc; + } else { + vu_dev->max_vqs = U64_MAX; + } + return 0; } @@ -625,7 +644,7 @@ static int vhost_user_set_mem_table(struct virtio_uml_device *vu_dev) { struct vhost_user_msg msg = { .header.request = VHOST_USER_SET_MEM_TABLE, - .header.size = sizeof(msg.payload.mem_regions), + .header.size = offsetof(typeof(msg.payload.mem_regions), regions[1]), .payload.mem_regions.num = 1, }; unsigned long reserved = uml_reserved - uml_physmem; @@ -673,13 +692,6 @@ static int vhost_user_set_mem_table(struct virtio_uml_device *vu_dev) if (rc < 0) return rc; - if (highmem) { - msg.payload.mem_regions.num++; - rc = vhost_user_init_mem_region(__pa(end_iomem), highmem, - &fds[1], &msg.payload.mem_regions.regions[1]); - if (rc < 0) - return rc; - } return vhost_user_send(vu_dev, false, &msg, fds, msg.payload.mem_regions.num); @@ -897,7 +909,7 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, { struct virtio_uml_vq_info *info = vq->priv; int call_fds[2]; - int rc; + int rc, irq; /* no call FD needed/desired in this case */ if (vu_dev->protocol_features & @@ -914,19 +926,23 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, return rc; info->call_fd = call_fds[0]; - rc = um_request_irq(vu_dev->irq, info->call_fd, IRQ_READ, - vu_interrupt, IRQF_SHARED, info->name, vq); - if (rc < 0) + irq = um_request_irq(vu_dev->irq, info->call_fd, IRQ_READ, + vu_interrupt, IRQF_SHARED, info->name, vq); + if (irq < 0) { + rc = irq; goto close_both; + } rc = vhost_user_set_vring_call(vu_dev, vq->index, call_fds[1]); if (rc) goto release_irq; + vu_dev->irq = irq; + goto out; release_irq: - um_free_irq(vu_dev->irq, vq); + um_free_irq(irq, vq); close_both: os_close_file(call_fds[0]); out: @@ -1023,7 +1039,9 @@ static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vq; /* not supported for now */ - if (WARN_ON(nvqs > 64)) + if (WARN(nvqs > 64 || nvqs > vu_dev->max_vqs, + "%d VQs requested, only up to 64 or %lld supported\n", + nvqs, vu_dev->max_vqs)) return -EINVAL; rc = vhost_user_set_mem_table(vu_dev); @@ -1210,6 +1228,7 @@ static int virtio_uml_probe(struct platform_device *pdev) vu_dev->vdev.id.vendor = VIRTIO_DEV_ANY_ID; vu_dev->pdev = pdev; vu_dev->req_fd = -1; + vu_dev->irq = UM_IRQ_ALLOC; time_travel_propagate_time(); @@ -1446,7 +1465,7 @@ static int virtio_uml_resume(struct platform_device *pdev) static struct platform_driver virtio_uml_driver = { .probe = virtio_uml_probe, - .remove_new = virtio_uml_remove, + .remove = virtio_uml_remove, .driver = { .name = "virtio-uml", .of_match_table = virtio_uml_match, diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 18f902da8e99769da857d34af43141ea97a0ca63..428f2c5158c2ac073ba6cfebb685381f61aea5ba 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 generic-y += bug.h generic-y += compat.h -generic-y += current.h generic-y += device.h generic-y += dma-mapping.h generic-y += emergency-restart.h diff --git a/arch/um/include/asm/current.h b/arch/um/include/asm/current.h new file mode 100644 index 0000000000000000000000000000000000000000..de64e032d66c1af64ad0d6c7942657a81b89fcbe --- /dev/null +++ b/arch/um/include/asm/current.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_CURRENT_H +#define __ASM_CURRENT_H + +#include +#include + +#ifndef __ASSEMBLY__ + +struct task_struct; +extern struct task_struct *cpu_tasks[NR_CPUS]; + +static __always_inline struct task_struct *get_current(void) +{ + return cpu_tasks[0]; +} + + +#define current get_current() + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_CURRENT_H */ diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 834313ecd3d65e2e4fb8b956e966ccf7f421a099..3d516f3ca9c745cef8b38b6149d79df32b88991a 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -29,51 +29,35 @@ struct page; #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) -#if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT) - typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; -#define pte_val(p) ((p).pte) -#define pte_get_bits(p, bits) ((p).pte & (bits)) -#define pte_set_bits(p, bits) ((p).pte |= (bits)) -#define pte_clear_bits(p, bits) ((p).pte &= ~(bits)) -#define pte_copy(to, from) ({ (to).pte = (from).pte; }) -#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE)) -#define pte_set_val(p, phys, prot) \ - ({ (p).pte = (phys) | pgprot_val(prot); }) +#if CONFIG_PGTABLE_LEVELS > 2 +typedef struct { unsigned long pmd; } pmd_t; #define pmd_val(x) ((x).pmd) #define __pmd(x) ((pmd_t) { (x) } ) -typedef unsigned long long phys_t; +#if CONFIG_PGTABLE_LEVELS > 3 -#else - -typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pud; } pud_t; +#define pud_val(x) ((x).pud) +#define __pud(x) ((pud_t) { (x) } ) -#ifdef CONFIG_3_LEVEL_PGTABLES -typedef struct { unsigned long pmd; } pmd_t; -#define pmd_val(x) ((x).pmd) -#define __pmd(x) ((pmd_t) { (x) } ) -#endif +#endif /* CONFIG_PGTABLE_LEVELS > 3 */ +#endif /* CONFIG_PGTABLE_LEVELS > 2 */ #define pte_val(x) ((x).pte) - #define pte_get_bits(p, bits) ((p).pte & (bits)) #define pte_set_bits(p, bits) ((p).pte |= (bits)) #define pte_clear_bits(p, bits) ((p).pte &= ~(bits)) #define pte_copy(to, from) ((to).pte = (from).pte) -#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE)) +#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEEDSYNC)) #define pte_set_val(p, phys, prot) (p).pte = (phys | pgprot_val(prot)) typedef unsigned long phys_t; -#endif - typedef struct { unsigned long pgprot; } pgprot_t; typedef struct page *pgtable_t; diff --git a/arch/um/include/asm/pgalloc.h b/arch/um/include/asm/pgalloc.h index de5e31c64793d7612daf27ec78a9a3e2e5f5b126..04fb4e6969a46d359efd59438a987330c8e71b2e 100644 --- a/arch/um/include/asm/pgalloc.h +++ b/arch/um/include/asm/pgalloc.h @@ -31,7 +31,7 @@ do { \ tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \ } while (0) -#ifdef CONFIG_3_LEVEL_PGTABLES +#if CONFIG_PGTABLE_LEVELS > 2 #define __pmd_free_tlb(tlb, pmd, address) \ do { \ @@ -39,6 +39,15 @@ do { \ tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(pmd)); \ } while (0) +#if CONFIG_PGTABLE_LEVELS > 3 + +#define __pud_free_tlb(tlb, pud, address) \ +do { \ + pagetable_pud_dtor(virt_to_ptdesc(pud)); \ + tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(pud)); \ +} while (0) + +#endif #endif #endif diff --git a/arch/um/include/asm/pgtable-2level.h b/arch/um/include/asm/pgtable-2level.h index 8256ecc5b919865b1bd2e1152fa40536c6feac96..ab0c8dd8656486d502b95e43a965da0a363f8592 100644 --- a/arch/um/include/asm/pgtable-2level.h +++ b/arch/um/include/asm/pgtable-2level.h @@ -31,7 +31,7 @@ printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), \ pgd_val(e)) -static inline int pgd_newpage(pgd_t pgd) { return 0; } +static inline int pgd_needsync(pgd_t pgd) { return 0; } static inline void pgd_mkuptodate(pgd_t pgd) { } #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-4level.h similarity index 60% rename from arch/um/include/asm/pgtable-3level.h rename to arch/um/include/asm/pgtable-4level.h index 8a5032ec231fd969b7e0dc916e76073a9c0105b7..0d279caee93ccdf2148051e305a0047380255edb 100644 --- a/arch/um/include/asm/pgtable-3level.h +++ b/arch/um/include/asm/pgtable-4level.h @@ -4,21 +4,25 @@ * Derived from include/asm-i386/pgtable.h */ -#ifndef __UM_PGTABLE_3LEVEL_H -#define __UM_PGTABLE_3LEVEL_H +#ifndef __UM_PGTABLE_4LEVEL_H +#define __UM_PGTABLE_4LEVEL_H -#include +#include -/* PGDIR_SHIFT determines what a third-level page table entry can map */ +/* PGDIR_SHIFT determines what a fourth-level page table entry can map */ -#ifdef CONFIG_64BIT -#define PGDIR_SHIFT 30 -#else -#define PGDIR_SHIFT 31 -#endif +#define PGDIR_SHIFT 39 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) +/* PUD_SHIFT determines the size of the area a third-level page table can + * map + */ + +#define PUD_SHIFT 30 +#define PUD_SIZE (1UL << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE-1)) + /* PMD_SHIFT determines the size of the area a second-level page table can * map */ @@ -32,13 +36,9 @@ */ #define PTRS_PER_PTE 512 -#ifdef CONFIG_64BIT #define PTRS_PER_PMD 512 +#define PTRS_PER_PUD 512 #define PTRS_PER_PGD 512 -#else -#define PTRS_PER_PMD 1024 -#define PTRS_PER_PGD 1024 -#endif #define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE) @@ -48,11 +48,14 @@ #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %p(%016lx).\n", __FILE__, __LINE__, &(e), \ pmd_val(e)) +#define pud_ERROR(e) \ + printk("%s:%d: bad pud %p(%016lx).\n", __FILE__, __LINE__, &(e), \ + pud_val(e)) #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), \ pgd_val(e)) -#define pud_none(x) (!(pud_val(x) & ~_PAGE_NEWPAGE)) +#define pud_none(x) (!(pud_val(x) & ~_PAGE_NEEDSYNC)) #define pud_bad(x) ((pud_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) #define pud_present(x) (pud_val(x) & _PAGE_PRESENT) #define pud_populate(mm, pud, pmd) \ @@ -60,23 +63,40 @@ #define set_pud(pudptr, pudval) (*(pudptr) = (pudval)) -static inline int pgd_newpage(pgd_t pgd) +#define p4d_none(x) (!(p4d_val(x) & ~_PAGE_NEEDSYNC)) +#define p4d_bad(x) ((p4d_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) +#define p4d_present(x) (p4d_val(x) & _PAGE_PRESENT) +#define p4d_populate(mm, p4d, pud) \ + set_p4d(p4d, __p4d(_PAGE_TABLE + __pa(pud))) + +#define set_p4d(p4dptr, p4dval) (*(p4dptr) = (p4dval)) + + +static inline int pgd_needsync(pgd_t pgd) { - return(pgd_val(pgd) & _PAGE_NEWPAGE); + return pgd_val(pgd) & _PAGE_NEEDSYNC; } -static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; } +static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEEDSYNC; } #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) static inline void pud_clear (pud_t *pud) { - set_pud(pud, __pud(_PAGE_NEWPAGE)); + set_pud(pud, __pud(_PAGE_NEEDSYNC)); +} + +static inline void p4d_clear (p4d_t *p4d) +{ + set_p4d(p4d, __p4d(_PAGE_NEEDSYNC)); } #define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK) #define pud_pgtable(pud) ((pmd_t *) __va(pud_val(pud) & PAGE_MASK)) +#define p4d_page(p4d) phys_to_page(p4d_val(p4d) & PAGE_MASK) +#define p4d_pgtable(p4d) ((pud_t *) __va(p4d_val(p4d) & PAGE_MASK)) + static inline unsigned long pte_pfn(pte_t pte) { return phys_to_pfn(pte_val(pte)); @@ -97,4 +117,3 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) } #endif - diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index faab5a2a4b061fbf60a2257244d812eec66309b5..0bd60afcc37d53d41a792794da636a8e6e31b609 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -11,8 +11,7 @@ #include #define _PAGE_PRESENT 0x001 -#define _PAGE_NEWPAGE 0x002 -#define _PAGE_NEWPROT 0x004 +#define _PAGE_NEEDSYNC 0x002 #define _PAGE_RW 0x020 #define _PAGE_USER 0x040 #define _PAGE_ACCESSED 0x080 @@ -24,10 +23,12 @@ /* We borrow bit 10 to store the exclusive marker in swap PTEs. */ #define _PAGE_SWP_EXCLUSIVE 0x400 -#ifdef CONFIG_3_LEVEL_PGTABLES -#include -#else +#if CONFIG_PGTABLE_LEVELS == 4 +#include +#elif CONFIG_PGTABLE_LEVELS == 2 #include +#else +#error "Unsupported number of page table levels" #endif extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; @@ -78,22 +79,22 @@ extern unsigned long end_iomem; */ #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) -#define pte_clear(mm,addr,xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEWPAGE)) +#define pte_clear(mm, addr, xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEEDSYNC)) -#define pmd_none(x) (!((unsigned long)pmd_val(x) & ~_PAGE_NEWPAGE)) +#define pmd_none(x) (!((unsigned long)pmd_val(x) & ~_PAGE_NEEDSYNC)) #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0) +#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEEDSYNC; } while (0) -#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE) -#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE) +#define pmd_needsync(x) (pmd_val(x) & _PAGE_NEEDSYNC) +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEEDSYNC) -#define pud_newpage(x) (pud_val(x) & _PAGE_NEWPAGE) -#define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEWPAGE) +#define pud_needsync(x) (pud_val(x) & _PAGE_NEEDSYNC) +#define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEEDSYNC) -#define p4d_newpage(x) (p4d_val(x) & _PAGE_NEWPAGE) -#define p4d_mkuptodate(x) (p4d_val(x) &= ~_PAGE_NEWPAGE) +#define p4d_needsync(x) (p4d_val(x) & _PAGE_NEEDSYNC) +#define p4d_mkuptodate(x) (p4d_val(x) &= ~_PAGE_NEEDSYNC) #define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT) #define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK) @@ -144,14 +145,9 @@ static inline int pte_young(pte_t pte) return pte_get_bits(pte, _PAGE_ACCESSED); } -static inline int pte_newpage(pte_t pte) +static inline int pte_needsync(pte_t pte) { - return pte_get_bits(pte, _PAGE_NEWPAGE); -} - -static inline int pte_newprot(pte_t pte) -{ - return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT))); + return pte_get_bits(pte, _PAGE_NEEDSYNC); } /* @@ -160,12 +156,6 @@ static inline int pte_newprot(pte_t pte) * ================================= */ -static inline pte_t pte_mknewprot(pte_t pte) -{ - pte_set_bits(pte, _PAGE_NEWPROT); - return(pte); -} - static inline pte_t pte_mkclean(pte_t pte) { pte_clear_bits(pte, _PAGE_DIRTY); @@ -180,19 +170,14 @@ static inline pte_t pte_mkold(pte_t pte) static inline pte_t pte_wrprotect(pte_t pte) { - if (likely(pte_get_bits(pte, _PAGE_RW))) - pte_clear_bits(pte, _PAGE_RW); - else - return pte; - return(pte_mknewprot(pte)); + pte_clear_bits(pte, _PAGE_RW); + return pte; } static inline pte_t pte_mkread(pte_t pte) { - if (unlikely(pte_get_bits(pte, _PAGE_USER))) - return pte; pte_set_bits(pte, _PAGE_USER); - return(pte_mknewprot(pte)); + return pte; } static inline pte_t pte_mkdirty(pte_t pte) @@ -209,23 +194,19 @@ static inline pte_t pte_mkyoung(pte_t pte) static inline pte_t pte_mkwrite_novma(pte_t pte) { - if (unlikely(pte_get_bits(pte, _PAGE_RW))) - return pte; pte_set_bits(pte, _PAGE_RW); - return(pte_mknewprot(pte)); + return pte; } static inline pte_t pte_mkuptodate(pte_t pte) { - pte_clear_bits(pte, _PAGE_NEWPAGE); - if(pte_present(pte)) - pte_clear_bits(pte, _PAGE_NEWPROT); - return(pte); + pte_clear_bits(pte, _PAGE_NEEDSYNC); + return pte; } -static inline pte_t pte_mknewpage(pte_t pte) +static inline pte_t pte_mkneedsync(pte_t pte) { - pte_set_bits(pte, _PAGE_NEWPAGE); + pte_set_bits(pte, _PAGE_NEEDSYNC); return(pte); } @@ -233,13 +214,11 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval) { pte_copy(*pteptr, pteval); - /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so - * fix_range knows to unmap it. _PAGE_NEWPROT is specific to - * mapped pages. + /* If it's a swap entry, it needs to be marked _PAGE_NEEDSYNC so + * update_pte_range knows to unmap it. */ - *pteptr = pte_mknewpage(*pteptr); - if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr); + *pteptr = pte_mkneedsync(*pteptr); } #define PFN_PTE_SHIFT PAGE_SHIFT @@ -279,7 +258,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr, #define __HAVE_ARCH_PTE_SAME static inline int pte_same(pte_t pte_a, pte_t pte_b) { - return !((pte_val(pte_a) ^ pte_val(pte_b)) & ~_PAGE_NEWPAGE); + return !((pte_val(pte_a) ^ pte_val(pte_b)) & ~_PAGE_NEEDSYNC); } /* @@ -294,8 +273,6 @@ static inline int pte_same(pte_t pte_a, pte_t pte_b) ({ pte_t pte; \ \ pte_set_val(pte, page_to_phys(page), (pgprot)); \ - if (pte_present(pte)) \ - pte_mknewprot(pte_mknewpage(pte)); \ pte;}) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) @@ -329,7 +306,7 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); * <--------------- offset ----------------> E < type -> 0 0 0 1 0 * * E is the exclusive marker that is not stored in swap entries. - * _PAGE_NEWPAGE (bit 1) is always set to 1 in set_pte(). + * _PAGE_NEEDSYNC (bit 1) is always set to 1 in set_pte(). */ #define __swp_type(x) (((x).val >> 5) & 0x1f) #define __swp_offset(x) ((x).val >> 11) diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index bce4595798dae5d244b1fba966d46a2129f742da..5d6356eafffee0c2e16e88d890c637b71088480f 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -20,10 +20,7 @@ struct task_struct; struct mm_struct; struct thread_struct { - struct pt_regs regs; struct pt_regs *segv_regs; - void *fault_addr; - jmp_buf *fault_catcher; struct task_struct *prev_sched; struct arch_thread arch; jmp_buf switch_buf; @@ -33,12 +30,14 @@ struct thread_struct { void *arg; } thread; } request; + + /* Contains variable sized FP registers */ + struct pt_regs regs; }; #define INIT_THREAD \ { \ .regs = EMPTY_REGS, \ - .fault_addr = NULL, \ .prev_sched = NULL, \ .arch = INIT_ARCH_THREAD, \ .request = { } \ diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index c7b4b49826a2aafc040d13fcc8a09765639f6cd2..f9ad06fcc991a2b10e2aa6059880b993e3d60a2d 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -17,35 +17,17 @@ #include struct thread_info { - struct task_struct *task; /* main task structure */ unsigned long flags; /* low level flags */ __u32 cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ - struct thread_info *real_thread; /* Points to non-IRQ stack */ - unsigned long aux_fp_regs[FP_SIZE]; /* auxiliary fp_regs to save/restore - them out-of-band */ }; #define INIT_THREAD_INFO(tsk) \ { \ - .task = &tsk, \ .flags = 0, \ .cpu = 0, \ .preempt_count = INIT_PREEMPT_COUNT, \ - .real_thread = NULL, \ -} - -/* how to get the thread information struct from C */ -static inline struct thread_info *current_thread_info(void) -{ - struct thread_info *ti; - unsigned long mask = THREAD_SIZE - 1; - void *p; - - asm volatile ("" : "=r" (p) : "0" (&ti)); - ti = (struct thread_info *) (((unsigned long)p) & ~mask); - return ti; } #endif diff --git a/arch/um/include/asm/tlbflush.h b/arch/um/include/asm/tlbflush.h index db997976b6eada6bc3df44a4d61fd564e1fb5f89..13a3009942be6bf95b25727d0be34a0c81f4ee1b 100644 --- a/arch/um/include/asm/tlbflush.h +++ b/arch/um/include/asm/tlbflush.h @@ -9,8 +9,8 @@ #include /* - * In UML, we need to sync the TLB over by using mmap/munmap/mprotect syscalls - * from the process handling the MM (which can be the kernel itself). + * In UML, we need to sync the TLB over by using mmap/munmap syscalls from + * the process handling the MM (which can be the kernel itself). * * To track updates, we can hook into set_ptes and flush_tlb_*. With set_ptes * we catch all PTE transitions where memory that was unusable becomes usable. diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 06292fca5a4da5afba0864fa73d888b39bff8039..ea65f151bf48473aa609eb455f3db970e3a9702a 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -30,25 +30,23 @@ #include -struct cpu_task { - void *task; -}; +struct task_struct; +extern struct task_struct *cpu_tasks[]; -extern struct cpu_task cpu_tasks[]; +extern unsigned long long physmem_size; extern unsigned long high_physmem; extern unsigned long uml_physmem; extern unsigned long uml_reserved; extern unsigned long end_vm; extern unsigned long start_vm; -extern unsigned long long highmem; extern unsigned long brk_start; extern unsigned long host_task_size; extern unsigned long stub_start; -extern int linux_main(int argc, char **argv); +extern int linux_main(int argc, char **argv, char **envp); extern void uml_finishsetup(void); struct siginfo; diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index 579ed946a3a9a11c4f40df86ebd09a48ce1f23a3..73f3a4792ed8bae6ecb3432f93262cc6955c6625 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -6,7 +6,6 @@ DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); -DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); DEFINE(UM_GFP_KERNEL, GFP_KERNEL); DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); @@ -15,17 +14,3 @@ DEFINE(UM_THREAD_SIZE, THREAD_SIZE); DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC); - -#ifdef CONFIG_PRINTK -DEFINE(UML_CONFIG_PRINTK, CONFIG_PRINTK); -#endif -#ifdef CONFIG_UML_X86 -DEFINE(UML_CONFIG_UML_X86, CONFIG_UML_X86); -#endif -#ifdef CONFIG_64BIT -DEFINE(UML_CONFIG_64BIT, CONFIG_64BIT); -#endif -#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT -DEFINE(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT, CONFIG_UML_TIME_TRAVEL_SUPPORT); -#endif - diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index d8ffd2db168e00a5e1e7c83f9008bdad091647cf..f21dc851753812018e41616a88ae44f885881cc6 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -60,7 +60,6 @@ extern unsigned long from_irq_stack(int nested); extern int singlestepping(void); extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); -extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs); extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); extern void fatal_sigsegv(void) __attribute__ ((noreturn)); diff --git a/arch/um/include/shared/mem_user.h b/arch/um/include/shared/mem_user.h index 11a723a58545e761dbd8d05e9b911d3cefe7ef9f..adfa08062f88e725f2d11645f2d35bf79191f3d8 100644 --- a/arch/um/include/shared/mem_user.h +++ b/arch/um/include/shared/mem_user.h @@ -47,10 +47,9 @@ extern int iomem_size; #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1)) extern unsigned long find_iomem(char *driver, unsigned long *len_out); -extern void mem_total_pages(unsigned long physmem, unsigned long iomem, - unsigned long highmem); +extern void mem_total_pages(unsigned long physmem, unsigned long iomem); extern void setup_physmem(unsigned long start, unsigned long usable, - unsigned long len, unsigned long long highmem); + unsigned long len); extern void map_memory(unsigned long virt, unsigned long phys, unsigned long len, int r, int w, int x); diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 9a039d6f1f748302113916afde21645a4601acc9..5babad8c5f75ed826269bbc853c7d5fb7acba631 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -145,7 +145,6 @@ extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg); extern int os_get_ifname(int fd, char *namebuf); extern int os_set_slip(int fd); extern int os_mode_fd(int fd, int mode); -extern int os_fsync_file(int fd); extern int os_seek_file(int fd, unsigned long long offset); extern int os_open_file(const char *file, struct openflags flags, int mode); @@ -199,15 +198,11 @@ extern int create_mem_file(unsigned long long len); extern void report_enomem(void); /* process.c */ -extern unsigned long os_process_pc(int pid); -extern int os_process_parent(int pid); extern void os_alarm_process(int pid); -extern void os_stop_process(int pid); extern void os_kill_process(int pid, int reap_child); extern void os_kill_ptraced_process(int pid, int reap_child); extern int os_getpid(void); -extern int os_getpgrp(void); extern void init_new_thread_signals(void); @@ -220,6 +215,8 @@ extern int os_drop_memory(void *addr, int length); extern int can_drop_memory(void); extern int os_mincore(void *addr, unsigned long len); +void os_set_pdeathsig(void); + /* execvp.c */ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ @@ -244,7 +241,6 @@ extern void block_signals(void); extern void unblock_signals(void); extern int um_set_signals(int enable); extern int um_set_signals_trace(int enable); -extern int os_is_signal_stack(void); extern void deliver_alarm(void); extern void register_pm_wake_signal(void); extern void block_signals_hard(void); @@ -283,13 +279,11 @@ int map(struct mm_id *mm_idp, unsigned long virt, unsigned long len, int prot, int phys_fd, unsigned long long offset); int unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len); -int protect(struct mm_id *mm_idp, unsigned long addr, - unsigned long len, unsigned int prot); /* skas/process.c */ extern int is_skas_winch(int pid, int fd, void *data); extern int start_userspace(unsigned long stub_stack); -extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs); +extern void userspace(struct uml_pt_regs *regs); extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); extern void switch_threads(jmp_buf *me, jmp_buf *you); extern int start_idle_thread(void *stack, jmp_buf *switch_buf); @@ -329,9 +323,6 @@ extern int __ignore_sigio_fd(int fd); /* tty.c */ extern int get_pty(void); -/* sys-$ARCH/task_size.c */ -extern unsigned long os_get_top_address(void); - long syscall(long number, ...); /* irqflags tracing */ diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h index a0450326521cd55e0ec81678dbca1ba435d119ee..7d81b2339a48ea4dcc682f1819ff4863e4bfe66c 100644 --- a/arch/um/include/shared/registers.h +++ b/arch/um/include/shared/registers.h @@ -8,12 +8,6 @@ #include -extern int save_i387_registers(int pid, unsigned long *fp_regs); -extern int restore_i387_registers(int pid, unsigned long *fp_regs); -extern int save_fp_registers(int pid, unsigned long *fp_regs); -extern int restore_fp_registers(int pid, unsigned long *fp_regs); -extern int save_fpx_registers(int pid, unsigned long *fp_regs); -extern int restore_fpx_registers(int pid, unsigned long *fp_regs); extern int init_pid_registers(int pid); extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); extern int get_fp_registers(int pid, unsigned long *regs); diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h index 2b6b44759dfaf142fcda4cca027e3168d763930e..81a4cace032c951e1726350e83139ae211343003 100644 --- a/arch/um/include/shared/skas/stub-data.h +++ b/arch/um/include/shared/skas/stub-data.h @@ -12,6 +12,17 @@ #include #include +struct stub_init_data { + unsigned long stub_start; + + int stub_code_fd; + unsigned long stub_code_offset; + int stub_data_fd; + unsigned long stub_data_offset; + + unsigned long segv_handler; +}; + #define STUB_NEXT_SYSCALL(s) \ ((struct stub_syscall *) (((unsigned long) s) + (s)->cmd_len)) @@ -19,7 +30,6 @@ enum stub_syscall_type { STUB_SYSCALL_UNSET = 0, STUB_SYSCALL_MMAP, STUB_SYSCALL_MUNMAP, - STUB_SYSCALL_MPROTECT, }; struct stub_syscall { diff --git a/arch/um/include/shared/timetravel.h b/arch/um/include/shared/timetravel.h index c8db2f213dbace04de30b1a4ccb660066efab7b7..7c2b277b7eb095490f00b394f159ebcdfc379615 100644 --- a/arch/um/include/shared/timetravel.h +++ b/arch/um/include/shared/timetravel.h @@ -12,14 +12,13 @@ enum time_travel_mode { TT_MODE_EXTERNAL, }; -#if defined(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT) || \ - defined(CONFIG_UML_TIME_TRAVEL_SUPPORT) +#if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT) extern enum time_travel_mode time_travel_mode; extern int time_travel_should_print_bc_msg; #else #define time_travel_mode TT_MODE_OFF #define time_travel_should_print_bc_msg 0 -#endif /* (UML_)CONFIG_UML_TIME_TRAVEL_SUPPORT */ +#endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ void _time_travel_print_bc_msg(void); static inline void time_travel_print_bc_msg(void) diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index bbab79c0c074ac05213545b43fe35dc4a2536fd7..139eb78a476748953fe66fd7d9df7c94d8547c89 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h @@ -38,7 +38,7 @@ extern void panic(const char *fmt, ...) #define UM_KERN_DEBUG KERN_DEBUG #define UM_KERN_CONT KERN_CONT -#ifdef UML_CONFIG_PRINTK +#if IS_ENABLED(CONFIG_PRINTK) #define printk(...) _printk(__VA_ARGS__) extern int _printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/arch/um/kernel/dtb.c b/arch/um/kernel/dtb.c index 8d78ced9e08f6de945a0e97eba6a41525e136794..15c342426489d96df0482d1406b08bc3de97d811 100644 --- a/arch/um/kernel/dtb.c +++ b/arch/um/kernel/dtb.c @@ -31,6 +31,7 @@ void uml_dtb_init(void) static int __init uml_dtb_setup(char *line, int *add) { + *add = 0; dtb = line; return 0; } diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 3385d653ebd0d04f5a342adb4b47affabcb0cfab..a36b7918a011ace9960ccaf1e0e8be5cd4b74bbc 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -116,8 +116,6 @@ SECTIONS .fini_array : { *(.fini_array) } .data : { INIT_TASK_DATA(KERNEL_STACK_SIZE) - . = ALIGN(KERNEL_STACK_SIZE); - *(.data..init_irqstack) DATA_DATA *(.data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) @@ -178,3 +176,6 @@ SECTIONS DISCARDS } + +ASSERT(__syscall_stub_end - __syscall_stub_start <= PAGE_SIZE, + "STUB code must not be larger than one page"); diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index 47b8cb1a1156185ecd31cc655ed719fa356a6d51..99dba827461c8acfc9c87f1ba17ac985df86a711 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -34,6 +34,7 @@ int __init read_initrd(void) static int __init uml_initrd_setup(char *line, int *add) { + *add = 0; initrd = line; return 0; } diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 534e91797f89275d8a2d29ff062493a9f84531a2..338450741aac5be6bda40ba12023be328939feb5 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -674,115 +674,3 @@ void __init init_IRQ(void) /* Initialize EPOLL Loop */ os_setup_epoll(); } - -/* - * IRQ stack entry and exit: - * - * Unlike i386, UML doesn't receive IRQs on the normal kernel stack - * and switch over to the IRQ stack after some preparation. We use - * sigaltstack to receive signals on a separate stack from the start. - * These two functions make sure the rest of the kernel won't be too - * upset by being on a different stack. The IRQ stack has a - * thread_info structure at the bottom so that current et al continue - * to work. - * - * to_irq_stack copies the current task's thread_info to the IRQ stack - * thread_info and sets the tasks's stack to point to the IRQ stack. - * - * from_irq_stack copies the thread_info struct back (flags may have - * been modified) and resets the task's stack pointer. - * - * Tricky bits - - * - * What happens when two signals race each other? UML doesn't block - * signals with sigprocmask, SA_DEFER, or sa_mask, so a second signal - * could arrive while a previous one is still setting up the - * thread_info. - * - * There are three cases - - * The first interrupt on the stack - sets up the thread_info and - * handles the interrupt - * A nested interrupt interrupting the copying of the thread_info - - * can't handle the interrupt, as the stack is in an unknown state - * A nested interrupt not interrupting the copying of the - * thread_info - doesn't do any setup, just handles the interrupt - * - * The first job is to figure out whether we interrupted stack setup. - * This is done by xchging the signal mask with thread_info->pending. - * If the value that comes back is zero, then there is no setup in - * progress, and the interrupt can be handled. If the value is - * non-zero, then there is stack setup in progress. In order to have - * the interrupt handled, we leave our signal in the mask, and it will - * be handled by the upper handler after it has set up the stack. - * - * Next is to figure out whether we are the outer handler or a nested - * one. As part of setting up the stack, thread_info->real_thread is - * set to non-NULL (and is reset to NULL on exit). This is the - * nesting indicator. If it is non-NULL, then the stack is already - * set up and the handler can run. - */ - -static unsigned long pending_mask; - -unsigned long to_irq_stack(unsigned long *mask_out) -{ - struct thread_info *ti; - unsigned long mask, old; - int nested; - - mask = xchg(&pending_mask, *mask_out); - if (mask != 0) { - /* - * If any interrupts come in at this point, we want to - * make sure that their bits aren't lost by our - * putting our bit in. So, this loop accumulates bits - * until xchg returns the same value that we put in. - * When that happens, there were no new interrupts, - * and pending_mask contains a bit for each interrupt - * that came in. - */ - old = *mask_out; - do { - old |= mask; - mask = xchg(&pending_mask, old); - } while (mask != old); - return 1; - } - - ti = current_thread_info(); - nested = (ti->real_thread != NULL); - if (!nested) { - struct task_struct *task; - struct thread_info *tti; - - task = cpu_tasks[ti->cpu].task; - tti = task_thread_info(task); - - *ti = *tti; - ti->real_thread = tti; - task->stack = ti; - } - - mask = xchg(&pending_mask, 0); - *mask_out |= mask | nested; - return 0; -} - -unsigned long from_irq_stack(int nested) -{ - struct thread_info *ti, *to; - unsigned long mask; - - ti = current_thread_info(); - - pending_mask = 1; - - to = ti->real_thread; - current->stack = to; - ti->real_thread = NULL; - *to = *ti; - - mask = xchg(&pending_mask, 0); - return mask & ~1; -} - diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index a5b4fe2ad93153aecc7d1d8618696f175b867c39..53248ed04771d1795342568981e2c8d15a1fd343 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -51,8 +50,6 @@ EXPORT_SYMBOL(empty_zero_page); pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* Initialized at boot time, and readonly after that */ -unsigned long long highmem; -EXPORT_SYMBOL(highmem); int kmalloc_ok = 0; /* Used during early boot */ @@ -98,7 +95,7 @@ static void __init one_page_table_init(pmd_t *pmd) static void __init one_md_table_init(pud_t *pud) { -#ifdef CONFIG_3_LEVEL_PGTABLES +#if CONFIG_PGTABLE_LEVELS > 2 pmd_t *pmd_table = (pmd_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); if (!pmd_table) panic("%s: Failed to allocate %lu bytes align=%lx\n", @@ -109,6 +106,19 @@ static void __init one_md_table_init(pud_t *pud) #endif } +static void __init one_ud_table_init(p4d_t *p4d) +{ +#if CONFIG_PGTABLE_LEVELS > 3 + pud_t *pud_table = (pud_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); + if (!pud_table) + panic("%s: Failed to allocate %lu bytes align=%lx\n", + __func__, PAGE_SIZE, PAGE_SIZE); + + set_p4d(p4d, __p4d(_KERNPG_TABLE + (unsigned long) __pa(pud_table))); + BUG_ON(pud_table != pud_offset(p4d, 0)); +#endif +} + static void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { @@ -126,6 +136,8 @@ static void __init fixrange_init(unsigned long start, unsigned long end, for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { p4d = p4d_offset(pgd, vaddr); + if (p4d_none(*p4d)) + one_ud_table_init(p4d); pud = pud_offset(p4d, vaddr); if (pud_none(*pud)) one_md_table_init(pud); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index fb2adfb499452bd2edfa418469bdf7160eaafdb9..a74f17b033c4175c4c68081ad0dbcd8fe493d609 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -22,19 +22,14 @@ static int physmem_fd = -1; unsigned long high_physmem; EXPORT_SYMBOL(high_physmem); -extern unsigned long long physmem_size; - -void __init mem_total_pages(unsigned long physmem, unsigned long iomem, - unsigned long highmem) +void __init mem_total_pages(unsigned long physmem, unsigned long iomem) { - unsigned long phys_pages, highmem_pages; - unsigned long iomem_pages, total_pages; + unsigned long phys_pages, iomem_pages, total_pages; - phys_pages = physmem >> PAGE_SHIFT; - iomem_pages = iomem >> PAGE_SHIFT; - highmem_pages = highmem >> PAGE_SHIFT; + phys_pages = physmem >> PAGE_SHIFT; + iomem_pages = iomem >> PAGE_SHIFT; - total_pages = phys_pages + iomem_pages + highmem_pages; + total_pages = phys_pages + iomem_pages; max_mapnr = total_pages; } @@ -64,13 +59,12 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, * @reserve_end: end address of the physical kernel memory. * @len: Length of total physical memory that should be mapped/made * available, in bytes. - * @highmem: Number of highmem bytes that should be mapped/made available. * - * Creates an unlinked temporary file of size (len + highmem) and memory maps + * Creates an unlinked temporary file of size (len) and memory maps * it on the last executable image address (uml_reserved). * * The offset is needed as the length of the total physical memory - * (len + highmem) includes the size of the memory used be the executable image, + * (len) includes the size of the memory used be the executable image, * but the mapped-to address is the last address of the executable image * (uml_reserved == end address of executable image). * @@ -78,24 +72,24 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, * of all user space processes/kernel tasks. */ void __init setup_physmem(unsigned long start, unsigned long reserve_end, - unsigned long len, unsigned long long highmem) + unsigned long len) { unsigned long reserve = reserve_end - start; - long map_size = len - reserve; + unsigned long map_size = len - reserve; int err; - if(map_size <= 0) { + if (len <= reserve) { os_warn("Too few physical memory! Needed=%lu, given=%lu\n", reserve, len); exit(1); } - physmem_fd = create_mem_file(len + highmem); + physmem_fd = create_mem_file(len); err = os_map_memory((void *) reserve_end, physmem_fd, reserve, map_size, 1, 1, 1); if (err < 0) { - os_warn("setup_physmem - mapping %ld bytes of memory at 0x%p " + os_warn("setup_physmem - mapping %lu bytes of memory at 0x%p " "failed - errno = %d\n", map_size, (void *) reserve_end, err); exit(1); @@ -107,9 +101,8 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, */ os_seek_file(physmem_fd, __pa(__syscall_stub_start)); os_write_file(physmem_fd, __syscall_stub_start, PAGE_SIZE); - os_fsync_file(physmem_fd); - memblock_add(__pa(start), len + highmem); + memblock_add(__pa(start), len); memblock_reserve(__pa(start), reserve); min_low_pfn = PFN_UP(__pa(reserve_end)); @@ -137,10 +130,6 @@ int phys_mapping(unsigned long phys, unsigned long long *offset_out) region = region->next; } } - else if (phys < __pa(end_iomem) + highmem) { - fd = physmem_fd; - *offset_out = phys - iomem_size; - } return fd; } @@ -149,6 +138,8 @@ EXPORT_SYMBOL(phys_mapping); static int __init uml_mem_setup(char *line, int *add) { char *retptr; + + *add = 0; physmem_size = memparse(line,&retptr); return 0; } diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index be2856af6d4c31fdc5b974bf6d1659c9f4e22c74..30bdc0a87dc854fe6742ac052e9560938fac3f0a 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -43,7 +43,8 @@ * cares about its entry, so it's OK if another processor is modifying its * entry. */ -struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { NULL } }; +struct task_struct *cpu_tasks[NR_CPUS]; +EXPORT_SYMBOL(cpu_tasks); void free_stack(unsigned long stack, int order) { @@ -64,7 +65,7 @@ unsigned long alloc_stack(int order, int atomic) static inline void set_current(struct task_struct *task) { - cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) { task }); + cpu_tasks[task_thread_info(task)->cpu] = task; } struct task_struct *__switch_to(struct task_struct *from, struct task_struct *to) @@ -116,7 +117,7 @@ void new_thread_handler(void) * callback returns only if the kernel thread execs a process */ fn(arg); - userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); + userspace(¤t->thread.regs.regs); } /* Called magically, see new_thread_handler above */ @@ -133,7 +134,7 @@ static void fork_handler(void) current->thread.prev_sched = NULL; - userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); + userspace(¤t->thread.regs.regs); } int copy_thread(struct task_struct * p, const struct kernel_clone_args *args) @@ -187,6 +188,13 @@ void initial_thread_cb(void (*proc)(void *), void *arg) kmalloc_ok = save_kmalloc_ok; } +int arch_dup_task_struct(struct task_struct *dst, + struct task_struct *src) +{ + memcpy(dst, src, arch_task_struct_size); + return 0; +} + void um_idle_sleep(void) { if (time_travel_mode != TT_MODE_OFF) @@ -287,11 +295,3 @@ unsigned long __get_wchan(struct task_struct *p) return 0; } - -int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu) -{ - int cpu = current_thread_info()->cpu; - - return save_i387_registers(userspace_pid[cpu], (unsigned long *) fpu); -} - diff --git a/arch/um/kernel/skas/.gitignore b/arch/um/kernel/skas/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c3409ced0f38c3d8dc4646036785c770a39b07c5 --- /dev/null +++ b/arch/um/kernel/skas/.gitignore @@ -0,0 +1,2 @@ +stub_exe +stub_exe.dbg diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index 6f86d53e3d69321ad15218a84eafc118834336e9..3384be42691f89343b4f5c5e40e2553d4576f81f 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile @@ -3,14 +3,48 @@ # Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) # -obj-y := stub.o mmu.o process.o syscall.o uaccess.o +obj-y := stub.o mmu.o process.o syscall.o uaccess.o \ + stub_exe_embed.o + +# Stub executable + +stub_exe_objs-y := stub_exe.o + +stub_exe_objs := $(foreach F,$(stub_exe_objs-y),$(obj)/$F) + +# Object file containing the ELF executable +$(obj)/stub_exe_embed.o: $(src)/stub_exe_embed.S $(obj)/stub_exe + +$(obj)/stub_exe.dbg: $(stub_exe_objs) FORCE + $(call if_changed,stub_exe) + +$(obj)/stub_exe: OBJCOPYFLAGS := -S +$(obj)/stub_exe: $(obj)/stub_exe.dbg FORCE + $(call if_changed,objcopy) + +quiet_cmd_stub_exe = STUB_EXE $@ + cmd_stub_exe = $(CC) -nostdlib -o $@ \ + $(filter-out $(UM_GPROF_OPT) $(UM_GCOV_OPT),$(KBUILD_CFLAGS)) $(STUB_EXE_LDFLAGS) \ + $(filter %.o,$^) + +STUB_EXE_LDFLAGS = -Wl,-n -static + +targets += stub_exe.dbg stub_exe $(stub_exe_objs-y) + +# end # stub.o is in the stub, so it can't be built with profiling # GCC hardened also auto-enables -fpic, but we need %ebx so it can't work -> # disable it CFLAGS_stub.o := $(CFLAGS_NO_HARDENING) -UNPROFILE_OBJS := stub.o +CFLAGS_stub_exe.o := $(CFLAGS_NO_HARDENING) + +# Clang will call memset() from __builtin_alloca() when stack variable +# initialization is enabled, which is used in stub_exe.c. +CFLAGS_stub_exe.o += $(call cc-option, -ftrivial-auto-var-init=uninitialized) + +UNPROFILE_OBJS := stub.o stub_exe.o KCOV_INSTRUMENT := n include $(srctree)/arch/um/scripts/Makefile.rules diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 886ed5e656743d44394e397017e677bb538a7383..0eb5a1d3ba70134f75d9b2af18544fca7248c6d6 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -40,35 +40,13 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) goto out_free; } - /* - * Ensure the new MM is clean and nothing unwanted is mapped. - * - * TODO: We should clear the memory up to STUB_START to ensure there is - * nothing mapped there, i.e. we (currently) have: - * - * |- user memory -|- unused -|- stub -|- unused -| - * ^ TASK_SIZE ^ STUB_START - * - * Meaning we have two unused areas where we may still have valid - * mappings from our internal clone(). That isn't really a problem as - * userspace is not going to access them, but it is definitely not - * correct. - * - * However, we are "lucky" and if rseq is configured, then on 32 bit - * it will fall into the first empty range while on 64 bit it is going - * to use an anonymous mapping in the second range. As such, things - * continue to work for now as long as we don't start unmapping these - * areas. - * - * Change this to STUB_START once we have a clean userspace. - */ - unmap(new_id, 0, TASK_SIZE); + /* Ensure the new MM is clean and nothing unwanted is mapped */ + unmap(new_id, 0, STUB_START); return 0; out_free: - if (new_id->stack != 0) - free_pages(new_id->stack, ilog2(STUB_DATA_PAGES)); + free_pages(new_id->stack, ilog2(STUB_DATA_PAGES)); out: return ret; } diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 68657988c8d1aea61280a5ed46543c5777a3e1e9..05dcdc057af9481a41c2e1168b3f7d96f5e9da86 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -22,15 +22,13 @@ static int __init start_kernel_proc(void *unused) { block_signals_trace(); - cpu_tasks[0].task = current; - start_kernel(); return 0; } extern int userspace_pid[]; -extern char cpu0_irqstack[]; +static char cpu0_irqstack[THREAD_SIZE] __aligned(THREAD_SIZE); int __init start_uml(void) { diff --git a/arch/um/kernel/skas/stub.c b/arch/um/kernel/skas/stub.c index 5d52ffa682dc48177422b569597fc339c31d9ffd..796fc266d3bb00e0a59a05da221f2b868e7387ef 100644 --- a/arch/um/kernel/skas/stub.c +++ b/arch/um/kernel/skas/stub.c @@ -35,16 +35,6 @@ static __always_inline int syscall_handler(struct stub_data *d) return -1; } break; - case STUB_SYSCALL_MPROTECT: - res = stub_syscall3(__NR_mprotect, - sc->mem.addr, sc->mem.length, - sc->mem.prot); - if (res) { - d->err = res; - d->syscall_data_len = i; - return -1; - } - break; default: d->err = -95; /* EOPNOTSUPP */ d->syscall_data_len = i; diff --git a/arch/um/kernel/skas/stub_exe.c b/arch/um/kernel/skas/stub_exe.c new file mode 100644 index 0000000000000000000000000000000000000000..23c99b285e82e79a1b5808af48f5c0af294738b2 --- /dev/null +++ b/arch/um/kernel/skas/stub_exe.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include + +void _start(void); + +noinline static void real_init(void) +{ + struct stub_init_data init_data; + unsigned long res; + struct { + void *ss_sp; + int ss_flags; + size_t ss_size; + } stack = { + .ss_size = STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, + }; + struct { + void *sa_handler_; + unsigned long sa_flags; + void *sa_restorer; + unsigned long long sa_mask; + } sa = { + /* Need to set SA_RESTORER (but the handler never returns) */ + .sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO | 0x04000000, + /* no need to mask any signals */ + .sa_mask = 0, + }; + + /* set a nice name */ + stub_syscall2(__NR_prctl, PR_SET_NAME, (unsigned long)"uml-userspace"); + + /* Make sure this process dies if the kernel dies */ + stub_syscall2(__NR_prctl, PR_SET_PDEATHSIG, SIGKILL); + + /* read information from STDIN and close it */ + res = stub_syscall3(__NR_read, 0, + (unsigned long)&init_data, sizeof(init_data)); + if (res != sizeof(init_data)) + stub_syscall1(__NR_exit, 10); + + stub_syscall1(__NR_close, 0); + + /* map stub code + data */ + res = stub_syscall6(STUB_MMAP_NR, + init_data.stub_start, UM_KERN_PAGE_SIZE, + PROT_READ | PROT_EXEC, MAP_FIXED | MAP_SHARED, + init_data.stub_code_fd, init_data.stub_code_offset); + if (res != init_data.stub_start) + stub_syscall1(__NR_exit, 11); + + res = stub_syscall6(STUB_MMAP_NR, + init_data.stub_start + UM_KERN_PAGE_SIZE, + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, + init_data.stub_data_fd, init_data.stub_data_offset); + if (res != init_data.stub_start + UM_KERN_PAGE_SIZE) + stub_syscall1(__NR_exit, 12); + + /* setup signal stack inside stub data */ + stack.ss_sp = (void *)init_data.stub_start + UM_KERN_PAGE_SIZE; + stub_syscall2(__NR_sigaltstack, (unsigned long)&stack, 0); + + /* register SIGSEGV handler */ + sa.sa_handler_ = (void *) init_data.segv_handler; + res = stub_syscall4(__NR_rt_sigaction, SIGSEGV, (unsigned long)&sa, 0, + sizeof(sa.sa_mask)); + if (res != 0) + stub_syscall1(__NR_exit, 13); + + stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0); + + stub_syscall2(__NR_kill, stub_syscall0(__NR_getpid), SIGSTOP); + + stub_syscall1(__NR_exit, 14); + + __builtin_unreachable(); +} + +__attribute__((naked)) void _start(void) +{ + /* + * Since the stack after exec() starts at the top-most address, + * but that's exactly where we also want to map the stub data + * and code, this must: + * - push the stack by 1 code and STUB_DATA_PAGES data pages + * - call real_init() + * This way, real_init() can use the stack normally, while the + * original stack further down (higher address) will become + * inaccessible after the mmap() calls above. + */ + stub_start(real_init); +} diff --git a/arch/um/kernel/skas/stub_exe_embed.S b/arch/um/kernel/skas/stub_exe_embed.S new file mode 100644 index 0000000000000000000000000000000000000000..6d8914fbe8f125e9e6a65b180dc7c518b15ed00e --- /dev/null +++ b/arch/um/kernel/skas/stub_exe_embed.S @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include + +__INITDATA + +SYM_DATA_START(stub_exe_start) + .incbin "arch/um/kernel/skas/stub_exe" +SYM_DATA_END_LABEL(stub_exe_start, SYM_L_GLOBAL, stub_exe_end) + +__FINIT diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index 4bb8622dc51226755e18d846361912b37e97e06b..13ee5666668dd450ed377289a3c222b566467c16 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c @@ -32,12 +32,6 @@ void show_stack(struct task_struct *task, unsigned long *stack, struct pt_regs *segv_regs = current->thread.segv_regs; int i; - if (!segv_regs && os_is_signal_stack()) { - pr_err("Received SIGSEGV in SIGSEGV handler," - " aborting stack trace!\n"); - return; - } - if (!stack) stack = get_stack_pointer(task, segv_regs); @@ -52,5 +46,5 @@ void show_stack(struct task_struct *task, unsigned long *stack, } printk("%sCall Trace:\n", loglvl); - dump_trace(current, &stackops, (void *)loglvl); + dump_trace(task ?: current, &stackops, (void *)loglvl); } diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 29b27b90581fbb06365b4b7e2962698c3bfdc15e..1394568c02106fdd706aad69387571baff803fa1 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -25,6 +25,8 @@ #include #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT +#include + enum time_travel_mode time_travel_mode; EXPORT_SYMBOL_GPL(time_travel_mode); @@ -47,6 +49,15 @@ static u16 time_travel_shm_id; static struct um_timetravel_schedshm *time_travel_shm; static union um_timetravel_schedshm_client *time_travel_shm_client; +unsigned long tt_extra_sched_jiffies; + +notrace unsigned long long sched_clock(void) +{ + return (unsigned long long)(jiffies - INITIAL_JIFFIES + + tt_extra_sched_jiffies) + * (NSEC_PER_SEC / HZ); +} + static void time_travel_set_time(unsigned long long ns) { if (unlikely(ns < time_travel_time)) @@ -443,6 +454,11 @@ static void time_travel_periodic_timer(struct time_travel_event *e) { time_travel_add_event(&time_travel_timer_event, time_travel_time + time_travel_timer_interval); + + /* clock tick; decrease extra jiffies by keeping sched_clock constant */ + if (tt_extra_sched_jiffies > 0) + tt_extra_sched_jiffies -= 1; + deliver_alarm(); } @@ -594,6 +610,10 @@ EXPORT_SYMBOL_GPL(time_travel_add_irq_event); static void time_travel_oneshot_timer(struct time_travel_event *e) { + /* clock tick; decrease extra jiffies by keeping sched_clock constant */ + if (tt_extra_sched_jiffies > 0) + tt_extra_sched_jiffies -= 1; + deliver_alarm(); } diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 548af31d4111bb49d74c333eb060558929d83a05..cf7e0d4407f2cd73777870ee6b087962bab79489 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -23,9 +23,6 @@ struct vm_ops { int phys_fd, unsigned long long offset); int (*unmap)(struct mm_id *mm_idp, unsigned long virt, unsigned long len); - int (*mprotect)(struct mm_id *mm_idp, - unsigned long virt, unsigned long len, - unsigned int prot); }; static int kern_map(struct mm_id *mm_idp, @@ -44,15 +41,6 @@ static int kern_unmap(struct mm_id *mm_idp, return os_unmap_memory((void *)virt, len); } -static int kern_mprotect(struct mm_id *mm_idp, - unsigned long virt, unsigned long len, - unsigned int prot) -{ - return os_protect_memory((void *)virt, len, - prot & UM_PROT_READ, prot & UM_PROT_WRITE, - 1); -} - void report_enomem(void) { printk(KERN_ERR "UML ran out of memory on the host side! " @@ -65,33 +53,37 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr, struct vm_ops *ops) { pte_t *pte; - int r, w, x, prot, ret = 0; + int ret = 0; pte = pte_offset_kernel(pmd, addr); do { - r = pte_read(*pte); - w = pte_write(*pte); - x = pte_exec(*pte); - if (!pte_young(*pte)) { - r = 0; - w = 0; - } else if (!pte_dirty(*pte)) - w = 0; - - prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | - (x ? UM_PROT_EXEC : 0)); - if (pte_newpage(*pte)) { - if (pte_present(*pte)) { - __u64 offset; - unsigned long phys = pte_val(*pte) & PAGE_MASK; - int fd = phys_mapping(phys, &offset); - - ret = ops->mmap(ops->mm_idp, addr, PAGE_SIZE, - prot, fd, offset); - } else - ret = ops->unmap(ops->mm_idp, addr, PAGE_SIZE); - } else if (pte_newprot(*pte)) - ret = ops->mprotect(ops->mm_idp, addr, PAGE_SIZE, prot); + if (!pte_needsync(*pte)) + continue; + + if (pte_present(*pte)) { + __u64 offset; + unsigned long phys = pte_val(*pte) & PAGE_MASK; + int fd = phys_mapping(phys, &offset); + int r, w, x, prot; + + r = pte_read(*pte); + w = pte_write(*pte); + x = pte_exec(*pte); + if (!pte_young(*pte)) { + r = 0; + w = 0; + } else if (!pte_dirty(*pte)) + w = 0; + + prot = (r ? UM_PROT_READ : 0) | + (w ? UM_PROT_WRITE : 0) | + (x ? UM_PROT_EXEC : 0); + + ret = ops->mmap(ops->mm_idp, addr, PAGE_SIZE, + prot, fd, offset); + } else + ret = ops->unmap(ops->mm_idp, addr, PAGE_SIZE); + *pte = pte_mkuptodate(*pte); } while (pte++, addr += PAGE_SIZE, ((addr < end) && !ret)); return ret; @@ -109,7 +101,7 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr, do { next = pmd_addr_end(addr, end); if (!pmd_present(*pmd)) { - if (pmd_newpage(*pmd)) { + if (pmd_needsync(*pmd)) { ret = ops->unmap(ops->mm_idp, addr, next - addr); pmd_mkuptodate(*pmd); @@ -132,7 +124,7 @@ static inline int update_pud_range(p4d_t *p4d, unsigned long addr, do { next = pud_addr_end(addr, end); if (!pud_present(*pud)) { - if (pud_newpage(*pud)) { + if (pud_needsync(*pud)) { ret = ops->unmap(ops->mm_idp, addr, next - addr); pud_mkuptodate(*pud); @@ -155,7 +147,7 @@ static inline int update_p4d_range(pgd_t *pgd, unsigned long addr, do { next = p4d_addr_end(addr, end); if (!p4d_present(*p4d)) { - if (p4d_newpage(*p4d)) { + if (p4d_needsync(*p4d)) { ret = ops->unmap(ops->mm_idp, addr, next - addr); p4d_mkuptodate(*p4d); @@ -180,18 +172,16 @@ int um_tlb_sync(struct mm_struct *mm) if (mm == &init_mm) { ops.mmap = kern_map; ops.unmap = kern_unmap; - ops.mprotect = kern_mprotect; } else { ops.mmap = map; ops.unmap = unmap; - ops.mprotect = protect; } pgd = pgd_offset(mm, addr); do { next = pgd_addr_end(addr, mm->context.sync_tlb_range_to); if (!pgd_present(*pgd)) { - if (pgd_newpage(*pgd)) { + if (pgd_needsync(*pgd)) { ret = ops.unmap(ops.mm_idp, addr, next - addr); pgd_mkuptodate(*pgd); diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 97c8df9c44017c3b24610b16190b2cae51efa096..cdaee3e94273418c51856b26da0e5c977929b8f4 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -201,7 +201,6 @@ void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, struct uml_pt_regs *regs) { - jmp_buf *catcher; int si_code; int err; int is_write = FAULT_WRITE(fi); @@ -246,15 +245,8 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, address = 0; } - catcher = current->thread.fault_catcher; if (!err) goto out; - else if (catcher != NULL) { - current->thread.fault_addr = (void *) address; - UML_LONGJMP(catcher, 1); - } - else if (current->thread.fault_addr != NULL) - panic("fault_addr set but no fault catcher"); else if (!is_user && arch_fixup(ip, regs)) goto out; @@ -310,14 +302,6 @@ void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs) } } -void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs) -{ - if (current->thread.fault_catcher != NULL) - UML_LONGJMP(current->thread.fault_catcher, 1); - else - relay_signal(sig, si, regs); -} - void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) { do_IRQ(WINCH_IRQ, regs); diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index e8e8b54b3037dc7e1b3534a41589bc648ba37127..8037a967225d82273abaac39f318e1d242d6a12f 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -65,9 +65,6 @@ struct cpuinfo_um boot_cpu_data = { EXPORT_SYMBOL(boot_cpu_data); -union thread_union cpu0_irqstack - __section(".data..init_irqstack") = - { .thread_info = INIT_THREAD_INFO(init_task) }; /* Changed in setup_arch, which is called in early boot */ static char host_info[(__NEW_UTS_LEN + 1) * 5]; @@ -131,7 +128,7 @@ static int have_root __initdata; static int have_console __initdata; /* Set in uml_mem_setup and modified in linux_main */ -long long physmem_size = 64 * 1024 * 1024; +unsigned long long physmem_size = 64 * 1024 * 1024; EXPORT_SYMBOL(physmem_size); static const char *usage_string = @@ -167,19 +164,6 @@ __uml_setup("root=", uml_root_setup, " root=/dev/ubd5\n\n" ); -static int __init no_skas_debug_setup(char *line, int *add) -{ - os_warn("'debug' is not necessary to gdb UML in skas mode - run\n"); - os_warn("'gdb linux'\n"); - - return 0; -} - -__uml_setup("debug", no_skas_debug_setup, -"debug\n" -" this flag is not needed to run gdb on UML in skas mode\n\n" -); - static int __init uml_console_setup(char *line, int *add) { have_console = 1; @@ -257,6 +241,8 @@ static struct notifier_block panic_exit_notifier = { void uml_finishsetup(void) { + cpu_tasks[0] = &init_task; + atomic_notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); @@ -302,7 +288,24 @@ static void parse_cache_line(char *line) } } -int __init linux_main(int argc, char **argv) +static unsigned long get_top_address(char **envp) +{ + unsigned long top_addr = (unsigned long) &top_addr; + int i; + + /* The earliest variable should be after the program name in ELF */ + for (i = 0; envp[i]; i++) { + if ((unsigned long) envp[i] > top_addr) + top_addr = (unsigned long) envp[i]; + } + + top_addr &= ~(UM_KERN_PAGE_SIZE - 1); + top_addr += UM_KERN_PAGE_SIZE; + + return top_addr; +} + +int __init linux_main(int argc, char **argv, char **envp) { unsigned long avail, diff; unsigned long virtmem_size, max_physmem; @@ -324,20 +327,23 @@ int __init linux_main(int argc, char **argv) if (have_console == 0) add_arg(DEFAULT_COMMAND_LINE_CONSOLE); - host_task_size = os_get_top_address(); - /* reserve a few pages for the stubs (taking care of data alignment) */ - /* align the data portion */ - BUILD_BUG_ON(!is_power_of_2(STUB_DATA_PAGES)); - stub_start = (host_task_size - 1) & ~(STUB_DATA_PAGES * PAGE_SIZE - 1); + host_task_size = get_top_address(envp); + /* reserve a few pages for the stubs */ + stub_start = host_task_size - STUB_DATA_PAGES * PAGE_SIZE; /* another page for the code portion */ stub_start -= PAGE_SIZE; host_task_size = stub_start; + /* Limit TASK_SIZE to what is addressable by the page table */ + task_size = host_task_size; + if (task_size > (unsigned long long) PTRS_PER_PGD * PGDIR_SIZE) + task_size = PTRS_PER_PGD * PGDIR_SIZE; + /* * TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps * out */ - task_size = host_task_size & PGDIR_MASK; + task_size = task_size & PGDIR_MASK; /* OS sanity checks that need to happen before the kernel runs */ os_early_checks(); @@ -366,18 +372,15 @@ int __init linux_main(int argc, char **argv) setup_machinename(init_utsname()->machine); - highmem = 0; + physmem_size = (physmem_size + PAGE_SIZE - 1) & PAGE_MASK; iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; + max_physmem = TASK_SIZE - uml_physmem - iomem_size - MIN_VMALLOC; - /* - * Zones have to begin on a 1 << MAX_PAGE_ORDER page boundary, - * so this makes sure that's true for highmem - */ - max_physmem &= ~((1 << (PAGE_SHIFT + MAX_PAGE_ORDER)) - 1); if (physmem_size + iomem_size > max_physmem) { - highmem = physmem_size + iomem_size - max_physmem; - physmem_size -= highmem; + physmem_size = max_physmem - iomem_size; + os_info("Physical memory size shrunk to %llu bytes\n", + physmem_size); } high_physmem = uml_physmem + physmem_size; @@ -398,6 +401,8 @@ int __init linux_main(int argc, char **argv) os_info("Kernel virtual memory size shrunk to %lu bytes\n", virtmem_size); + arch_task_struct_size = sizeof(struct task_struct) + host_fp_size; + os_flush_stdout(); return start_uml(); @@ -412,9 +417,9 @@ void __init setup_arch(char **cmdline_p) { u8 rng_seed[32]; - stack_protections((unsigned long) &init_thread_info); - setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); - mem_total_pages(physmem_size, iomem_size, highmem); + stack_protections((unsigned long) init_task.stack); + setup_physmem(uml_physmem, uml_reserved, physmem_size); + mem_total_pages(physmem_size, iomem_size); uml_dtb_init(); read_initrd(); diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 5c92d58a78e89cc940c77162a96b6433bc1078e4..a409d4b66114f786e4fc58b1639d3058d890e1de 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -77,8 +77,6 @@ SECTIONS .data : { INIT_TASK_DATA(KERNEL_STACK_SIZE) - . = ALIGN(KERNEL_STACK_SIZE); - *(.data..init_irqstack) DATA_DATA *(.gnu.linkonce.d*) CONSTRUCTORS diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 544e0b344c754aedcf51b73e91dca8e74211a225..049dfa5bc9c69a0d8d13916820a1b7e1880959ca 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -12,6 +12,8 @@ obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \ CFLAGS_signal.o += -Wframe-larger-than=4096 +CFLAGS_main.o += -Wno-frame-larger-than + obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o USER_OBJS := $(user-objs-y) elf_aux.o execvp.o file.o helper.o irq.o \ diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index f1d03cf3957fe820961f2e5b75130c1af2595fdc..a0d01c68ce3ee82d045756bca6dc1e4fe46a7a75 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -255,12 +255,6 @@ void os_close_file(int fd) { close(fd); } -int os_fsync_file(int fd) -{ - if (fsync(fd) < 0) - return -errno; - return 0; -} int os_seek_file(int fd, unsigned long long offset) { diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index f98ff79cdbf7980ecc5effa6914da9018201ebec..0afcdeb8995b755a59f6ee1c0010f6414cd1aa85 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,21 @@ int __init main(int argc, char **argv, char **envp) char **new_argv; int ret, i, err; + /* Disable randomization and re-exec if it was changed successfully */ + ret = personality(PER_LINUX | ADDR_NO_RANDOMIZE); + if (ret >= 0 && (ret & (PER_LINUX | ADDR_NO_RANDOMIZE)) != + (PER_LINUX | ADDR_NO_RANDOMIZE)) { + char buf[4096] = {}; + ssize_t ret; + + ret = readlink("/proc/self/exe", buf, sizeof(buf)); + if (ret < 0 || ret >= sizeof(buf)) { + perror("readlink failure"); + exit(1); + } + execve(buf, argv, envp); + } + set_stklim(); setup_env_path(); @@ -140,7 +156,7 @@ int __init main(int argc, char **argv, char **envp) #endif change_sig(SIGPIPE, 0); - ret = linux_main(argc, argv); + ret = linux_main(argc, argv, envp); /* * Disable SIGPROF - I have no idea why libc doesn't do this or turn @@ -182,6 +198,7 @@ int __init main(int argc, char **argv, char **envp) } extern void *__real_malloc(int); +extern void __real_free(void *); /* workaround for -Wmissing-prototypes warnings */ void *__wrap_malloc(int size); @@ -219,10 +236,6 @@ void *__wrap_calloc(int n, int size) return ptr; } -extern void __real_free(void *); - -extern unsigned long high_physmem; - void __wrap_free(void *ptr) { unsigned long addr = (unsigned long) ptr; diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index cf44d386f23ce3c295051bd110740feaed95352b..72f302f4d197f8d84fbf2242af3aa0ac57fc27c4 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -39,10 +39,22 @@ void kasan_map_memory(void *start, size_t len) strerror(errno)); exit(1); } + + if (madvise(start, len, MADV_DONTDUMP)) { + os_info("Couldn't set MAD_DONTDUMP on shadow memory: %s\n.", + strerror(errno)); + exit(1); + } + + if (madvise(start, len, MADV_DONTFORK)) { + os_info("Couldn't set MADV_DONTFORK on shadow memory: %s\n.", + strerror(errno)); + exit(1); + } } /* Set by make_tempfile() during early boot. */ -static char *tempdir = NULL; +char *tempdir = NULL; /* Check if dir is on tmpfs. Return 0 if yes, -1 if no or error. */ static int __init check_tmpfs(const char *dir) diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index e52dd37ddadccc5f07eebea20705db23d6f65ada..9f086f9394202d15776db4594c91cb51a405781c 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -12,94 +12,18 @@ #include #include #include +#include #include #include #include #include #include -#define ARBITRARY_ADDR -1 -#define FAILURE_PID -1 - -#define STAT_PATH_LEN sizeof("/proc/#######/stat\0") -#define COMM_SCANF "%*[^)])" - -unsigned long os_process_pc(int pid) -{ - char proc_stat[STAT_PATH_LEN], buf[256]; - unsigned long pc = ARBITRARY_ADDR; - int fd, err; - - sprintf(proc_stat, "/proc/%d/stat", pid); - fd = open(proc_stat, O_RDONLY, 0); - if (fd < 0) { - printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', " - "errno = %d\n", proc_stat, errno); - goto out; - } - CATCH_EINTR(err = read(fd, buf, sizeof(buf))); - if (err < 0) { - printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', " - "err = %d\n", proc_stat, errno); - goto out_close; - } - os_close_file(fd); - pc = ARBITRARY_ADDR; - if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %*d %lu", &pc) != 1) - printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n", - buf); - out_close: - close(fd); - out: - return pc; -} - -int os_process_parent(int pid) -{ - char stat[STAT_PATH_LEN]; - char data[256]; - int parent = FAILURE_PID, n, fd; - - if (pid == -1) - return parent; - - snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); - fd = open(stat, O_RDONLY, 0); - if (fd < 0) { - printk(UM_KERN_ERR "Couldn't open '%s', errno = %d\n", stat, - errno); - return parent; - } - - CATCH_EINTR(n = read(fd, data, sizeof(data))); - close(fd); - - if (n < 0) { - printk(UM_KERN_ERR "Couldn't read '%s', errno = %d\n", stat, - errno); - return parent; - } - - parent = FAILURE_PID; - n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent); - if (n != 1) - printk(UM_KERN_ERR "Failed to scan '%s'\n", data); - - return parent; -} - void os_alarm_process(int pid) { kill(pid, SIGALRM); } -void os_stop_process(int pid) -{ - kill(pid, SIGSTOP); -} - void os_kill_process(int pid, int reap_child) { kill(pid, SIGKILL); @@ -130,11 +54,6 @@ int os_getpid(void) return syscall(__NR_getpid); } -int os_getpgrp(void) -{ - return getpgrp(); -} - int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, int r, int w, int x) { @@ -285,3 +204,8 @@ void init_new_thread_signals(void) set_handler(SIGIO); signal(SIGWINCH, SIG_IGN); } + +void os_set_pdeathsig(void) +{ + prctl(PR_SET_PDEATHSIG, SIGKILL); +} diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c index bd80b921add06ce5c5c244a5cd29cc1e52ac1b74..d7ca148807b2828d4f99cde908c2f3ce13f05cfb 100644 --- a/arch/um/os-Linux/registers.c +++ b/arch/um/os-Linux/registers.c @@ -10,11 +10,12 @@ #include #include #include +#include /* This is set once at boot time and not changed thereafter */ static unsigned long exec_regs[MAX_REG_NR]; -static unsigned long exec_fp_regs[FP_SIZE]; +static unsigned long *exec_fp_regs; int init_pid_registers(int pid) { @@ -24,7 +25,11 @@ int init_pid_registers(int pid) if (err < 0) return -errno; - arch_init_registers(pid); + err = arch_init_registers(pid); + if (err < 0) + return err; + + exec_fp_regs = malloc(host_fp_size); get_fp_registers(pid, exec_fp_regs); return 0; } @@ -34,5 +39,5 @@ void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) memcpy(regs, exec_regs, sizeof(exec_regs)); if (fp_regs) - memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs)); + memcpy(fp_regs, exec_fp_regs, host_fp_size); } diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 9e71794839e87778d0f90d12c4db9b4c18427761..9aac8def4d6359c647d5385a9d2377262d4e7992 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -55,6 +55,7 @@ static int write_sigio_thread(void *unused) int i, n, respond_fd; char c; + os_set_pdeathsig(); os_fix_helper_signals(); fds = ¤t_poll; while (1) { diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index b11ed66c8bb0eaaf9e16997784ee98002ff5ab1a..9ea7269ffb778289086fa365b77d4eba124fa49a 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -26,7 +26,7 @@ void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { [SIGFPE] = relay_signal, [SIGILL] = relay_signal, [SIGWINCH] = winch, - [SIGBUS] = bus_handler, + [SIGBUS] = relay_signal, [SIGSEGV] = segv_handler, [SIGIO] = sigio_handler, }; @@ -65,7 +65,7 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) #define SIGALRM_MASK (1 << SIGALRM_BIT) int signals_enabled; -#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT +#if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT) static int signals_blocked, signals_blocked_pending; #endif static unsigned int signals_pending; @@ -75,7 +75,7 @@ static void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) { int enabled = signals_enabled; -#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT +#if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT) if ((signals_blocked || __atomic_load_n(&signals_blocked_pending, __ATOMIC_SEQ_CST)) && (sig == SIGIO)) { @@ -190,43 +190,8 @@ static void hard_handler(int sig, siginfo_t *si, void *p) { ucontext_t *uc = p; mcontext_t *mc = &uc->uc_mcontext; - unsigned long pending = 1UL << sig; - do { - int nested, bail; - - /* - * pending comes back with one bit set for each - * interrupt that arrived while setting up the stack, - * plus a bit for this interrupt, plus the zero bit is - * set if this is a nested interrupt. - * If bail is true, then we interrupted another - * handler setting up the stack. In this case, we - * have to return, and the upper handler will deal - * with this interrupt. - */ - bail = to_irq_stack(&pending); - if (bail) - return; - - nested = pending & 1; - pending &= ~1; - - while ((sig = ffs(pending)) != 0){ - sig--; - pending &= ~(1 << sig); - (*handlers[sig])(sig, (struct siginfo *)si, mc); - } - - /* - * Again, pending comes back with a mask of signals - * that arrived while tearing down the stack. If this - * is non-zero, we just go back, set up the stack - * again, and handle the new interrupts. - */ - if (!nested) - pending = from_irq_stack(nested); - } while (pending); + (*handlers[sig])(sig, (struct siginfo *)si, mc); } void set_handler(int sig) @@ -297,7 +262,7 @@ void unblock_signals(void) return; signals_enabled = 1; -#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT +#if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT) deliver_time_travel_irqs(); #endif @@ -389,7 +354,7 @@ int um_set_signals_trace(int enable) return ret; } -#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT +#if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT) void mark_sigio_pending(void) { /* @@ -487,11 +452,3 @@ void unblock_signals_hard(void) unblocking = false; } #endif - -int os_is_signal_stack(void) -{ - stack_t ss; - sigaltstack(NULL, &ss); - - return ss.ss_flags & SS_ONSTACK; -} diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 9a13ac23c60644b335e9648e495ae3e6e669f568..d7f1814b0e5abcfac3fc8aa6ec7175e0f5ee7e73 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -217,24 +217,3 @@ int unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len) return 0; } - -int protect(struct mm_id *mm_idp, unsigned long addr, unsigned long len, - unsigned int prot) -{ - struct stub_syscall *sc; - - /* Compress with previous syscall if that is possible */ - sc = syscall_stub_get_previous(mm_idp, STUB_SYSCALL_MPROTECT, addr); - if (sc && sc->mem.prot == prot) { - sc->mem.length += len; - return 0; - } - - sc = syscall_stub_alloc(mm_idp); - sc->syscall = STUB_SYSCALL_MPROTECT; - sc->mem.addr = addr; - sc->mem.length = len; - sc->mem.prot = prot; - - return 0; -} diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index b6f656bcffb1788736b116bdf9c2eda042fda51f..f683cfc9e51a54e1c78d477da74e96fabcfca011 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -10,8 +10,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -141,16 +144,10 @@ bad_wait: extern unsigned long current_stub_stack(void); -static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux_fp_regs) +static void get_skas_faultinfo(int pid, struct faultinfo *fi) { int err; - err = get_fp_registers(pid, aux_fp_regs); - if (err < 0) { - printk(UM_KERN_ERR "save_fp_registers returned %d\n", - err); - fatal_sigsegv(); - } err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); if (err) { printk(UM_KERN_ERR "Failed to continue stub, pid = %d, " @@ -164,18 +161,11 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux * the stub stack page. We just have to copy it. */ memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); - - err = put_fp_registers(pid, aux_fp_regs); - if (err < 0) { - printk(UM_KERN_ERR "put_fp_registers returned %d\n", - err); - fatal_sigsegv(); - } } -static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp_regs) +static void handle_segv(int pid, struct uml_pt_regs *regs) { - get_skas_faultinfo(pid, ®s->faultinfo, aux_fp_regs); + get_skas_faultinfo(pid, ®s->faultinfo); segv(regs->faultinfo, 0, 1, NULL); } @@ -189,69 +179,131 @@ static void handle_trap(int pid, struct uml_pt_regs *regs) extern char __syscall_stub_start[]; -/** - * userspace_tramp() - userspace trampoline - * @stack: pointer to the new userspace stack page - * - * The userspace trampoline is used to setup a new userspace process in start_userspace() after it was clone()'ed. - * This function will run on a temporary stack page. - * It ptrace()'es itself, then - * Two pages are mapped into the userspace address space: - * - STUB_CODE (with EXEC), which contains the skas stub code - * - STUB_DATA (with R/W), which contains a data page that is used to transfer certain data between the UML userspace process and the UML kernel. - * Also for the userspace process a SIGSEGV handler is installed to catch pagefaults in the userspace process. - * And last the process stops itself to give control to the UML kernel for this userspace process. - * - * Return: Always zero, otherwise the current userspace process is ended with non null exit() call - */ +static int stub_exe_fd; + static int userspace_tramp(void *stack) { - struct sigaction sa; - void *addr; - int fd; + char *const argv[] = { "uml-userspace", NULL }; + int pipe_fds[2]; unsigned long long offset; - unsigned long segv_handler = STUB_CODE + - (unsigned long) stub_segv_handler - - (unsigned long) __syscall_stub_start; - - ptrace(PTRACE_TRACEME, 0, 0, 0); - - signal(SIGTERM, SIG_DFL); - signal(SIGWINCH, SIG_IGN); - - fd = phys_mapping(uml_to_phys(__syscall_stub_start), &offset); - addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE, - PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); - if (addr == MAP_FAILED) { - os_info("mapping mmap stub at 0x%lx failed, errno = %d\n", - STUB_CODE, errno); - exit(1); + struct stub_init_data init_data = { + .stub_start = STUB_START, + .segv_handler = STUB_CODE + + (unsigned long) stub_segv_handler - + (unsigned long) __syscall_stub_start, + }; + struct iomem_region *iomem; + int ret; + + init_data.stub_code_fd = phys_mapping(uml_to_phys(__syscall_stub_start), + &offset); + init_data.stub_code_offset = MMAP_OFFSET(offset); + + init_data.stub_data_fd = phys_mapping(uml_to_phys(stack), &offset); + init_data.stub_data_offset = MMAP_OFFSET(offset); + + /* Set CLOEXEC on all FDs and then unset on all memory related FDs */ + close_range(0, ~0U, CLOSE_RANGE_CLOEXEC); + + fcntl(init_data.stub_data_fd, F_SETFD, 0); + for (iomem = iomem_regions; iomem; iomem = iomem->next) + fcntl(iomem->fd, F_SETFD, 0); + + /* Create a pipe for init_data (no CLOEXEC) and dup2 to STDIN */ + if (pipe(pipe_fds)) + exit(2); + + if (dup2(pipe_fds[0], 0) < 0) + exit(3); + close(pipe_fds[0]); + + /* Write init_data and close write side */ + ret = write(pipe_fds[1], &init_data, sizeof(init_data)); + close(pipe_fds[1]); + + if (ret != sizeof(init_data)) + exit(4); + + execveat(stub_exe_fd, "", argv, NULL, AT_EMPTY_PATH); + + exit(5); +} + +extern char stub_exe_start[]; +extern char stub_exe_end[]; + +extern char *tempdir; + +#define STUB_EXE_NAME_TEMPLATE "/uml-userspace-XXXXXX" + +#ifndef MFD_EXEC +#define MFD_EXEC 0x0010U +#endif + +static int __init init_stub_exe_fd(void) +{ + size_t written = 0; + char *tmpfile = NULL; + + stub_exe_fd = memfd_create("uml-userspace", + MFD_EXEC | MFD_CLOEXEC | MFD_ALLOW_SEALING); + + if (stub_exe_fd < 0) { + printk(UM_KERN_INFO "Could not create executable memfd, using temporary file!"); + + tmpfile = malloc(strlen(tempdir) + + strlen(STUB_EXE_NAME_TEMPLATE) + 1); + if (tmpfile == NULL) + panic("Failed to allocate memory for stub binary name"); + + strcpy(tmpfile, tempdir); + strcat(tmpfile, STUB_EXE_NAME_TEMPLATE); + + stub_exe_fd = mkstemp(tmpfile); + if (stub_exe_fd < 0) + panic("Could not create temporary file for stub binary: %d", + -errno); } - fd = phys_mapping(uml_to_phys(stack), &offset); - addr = mmap((void *) STUB_DATA, - STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, fd, offset); - if (addr == MAP_FAILED) { - os_info("mapping segfault stack at 0x%lx failed, errno = %d\n", - STUB_DATA, errno); - exit(1); + while (written < stub_exe_end - stub_exe_start) { + ssize_t res = write(stub_exe_fd, stub_exe_start + written, + stub_exe_end - stub_exe_start - written); + if (res < 0) { + if (errno == EINTR) + continue; + + if (tmpfile) + unlink(tmpfile); + panic("Failed write stub binary: %d", -errno); + } + + written += res; } - set_sigstack((void *) STUB_DATA, STUB_DATA_PAGES * UM_KERN_PAGE_SIZE); - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO; - sa.sa_sigaction = (void *) segv_handler; - sa.sa_restorer = NULL; - if (sigaction(SIGSEGV, &sa, NULL) < 0) { - os_info("%s - setting SIGSEGV handler failed - errno = %d\n", - __func__, errno); - exit(1); + if (!tmpfile) { + fcntl(stub_exe_fd, F_ADD_SEALS, + F_SEAL_WRITE | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL); + } else { + if (fchmod(stub_exe_fd, 00500) < 0) { + unlink(tmpfile); + panic("Could not make stub binary executable: %d", + -errno); + } + + close(stub_exe_fd); + stub_exe_fd = open(tmpfile, O_RDONLY | O_CLOEXEC | O_NOFOLLOW); + if (stub_exe_fd < 0) { + unlink(tmpfile); + panic("Could not reopen stub binary: %d", -errno); + } + + unlink(tmpfile); + free(tmpfile); } - kill(os_getpid(), SIGSTOP); return 0; } +__initcall(init_stub_exe_fd); int userspace_pid[NR_CPUS]; @@ -270,7 +322,7 @@ int start_userspace(unsigned long stub_stack) { void *stack; unsigned long sp; - int pid, status, n, flags, err; + int pid, status, n, err; /* setup a temporary stack page */ stack = mmap(NULL, UM_KERN_PAGE_SIZE, @@ -286,10 +338,10 @@ int start_userspace(unsigned long stub_stack) /* set stack pointer to the end of the stack page, so it can grow downwards */ sp = (unsigned long)stack + UM_KERN_PAGE_SIZE; - flags = CLONE_FILES | SIGCHLD; - /* clone into new userspace process */ - pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); + pid = clone(userspace_tramp, (void *) sp, + CLONE_VFORK | CLONE_VM | SIGCHLD, + (void *)stub_stack); if (pid < 0) { err = -errno; printk(UM_KERN_ERR "%s : clone failed, errno = %d\n", @@ -336,7 +388,10 @@ int start_userspace(unsigned long stub_stack) return err; } -void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) +int unscheduled_userspace_iterations; +extern unsigned long tt_extra_sched_jiffies; + +void userspace(struct uml_pt_regs *regs) { int err, status, op, pid = userspace_pid[0]; siginfo_t si; @@ -345,6 +400,29 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) interrupt_end(); while (1) { + /* + * When we are in time-travel mode, userspace can theoretically + * do a *lot* of work without being scheduled. The problem with + * this is that it will prevent kernel bookkeeping (primarily + * the RCU) from running and this can for example cause OOM + * situations. + * + * This code accounts a jiffie against the scheduling clock + * after the defined userspace iterations in the same thread. + * By doing so the situation is effectively prevented. + */ + if (time_travel_mode == TT_MODE_INFCPU || + time_travel_mode == TT_MODE_EXTERNAL) { +#ifdef CONFIG_UML_MAX_USERSPACE_ITERATIONS + if (CONFIG_UML_MAX_USERSPACE_ITERATIONS && + unscheduled_userspace_iterations++ > + CONFIG_UML_MAX_USERSPACE_ITERATIONS) { + tt_extra_sched_jiffies += 1; + unscheduled_userspace_iterations = 0; + } +#endif + } + time_travel_print_bc_msg(); current_mm_sync(); @@ -435,11 +513,11 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) case SIGSEGV: if (PTRACE_FULL_FAULTINFO) { get_skas_faultinfo(pid, - ®s->faultinfo, aux_fp_regs); + ®s->faultinfo); (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, regs); } - else handle_segv(pid, regs, aux_fp_regs); + else handle_segv(pid, regs); break; case SIGTRAP + 0x80: handle_trap(pid, regs); @@ -487,6 +565,8 @@ void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) void switch_threads(jmp_buf *me, jmp_buf *you) { + unscheduled_userspace_iterations = 0; + if (UML_SETJMP(me) == 0) UML_LONGJMP(you, 1); } @@ -570,6 +650,7 @@ static bool noreboot; static int __init noreboot_cmd_param(char *str, int *add) { + *add = 0; noreboot = true; return 0; } diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index e09d65b05d1cab8892915d9eff2a586c4f6077a7..eb523ab1e2189be26c92e607761a7df6fd88b363 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -358,6 +358,8 @@ char *get_umid(void) static int __init set_uml_dir(char *name, int *add) { + *add = 0; + if (*name == '\0') { os_warn("uml_dir can't be an empty string\n"); return 0; diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 1dca4ffbd572f77ac0747feff11cdb9379ac5936..4193e04d7e4a7fb511545c11f6e23928bfe13547 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -52,8 +52,8 @@ void setup_machinename(char *machine_out) struct utsname host; uname(&host); -#ifdef UML_CONFIG_UML_X86 -# ifndef UML_CONFIG_64BIT +#if IS_ENABLED(CONFIG_UML_X86) +# if !IS_ENABLED(CONFIG_64BIT) if (!strcmp(host.machine, "x86_64")) { strcpy(machine_out, "i686"); return; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6c633d93c6390ab3dfa3ed40ae0e16ef51c869c4..9d7bd0ae48c4260f4abb6dbedc696e3915c230ea 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -128,6 +128,8 @@ config X86 select ARCH_SUPPORTS_LTO_CLANG select ARCH_SUPPORTS_LTO_CLANG_THIN select ARCH_SUPPORTS_RT + select ARCH_SUPPORTS_AUTOFDO_CLANG + select ARCH_SUPPORTS_PROPELLER_CLANG if X86_64 select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF if X86_CMPXCHG64 select ARCH_USE_MEMTEST diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index 580636cdc257b78930db0d9b9236cfa9fd62ed21..4d3c9d00d6b6b2e08617e068f449ac8564f203a6 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h @@ -34,4 +34,8 @@ static inline void __tlb_remove_table(void *table) free_page_and_swap_cache(table); } +static inline void invlpg(unsigned long addr) +{ + asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); +} #endif /* _ASM_X86_TLB_H */ diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 823f44f7bc94659b4cb46bf728780dc33ca2cdbe..d8408aafeed988454a570b0d7c423a8cee2a1bc4 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -798,6 +798,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c) static const struct x86_cpu_desc erratum_1386_microcode[] = { AMD_CPU_DESC(0x17, 0x1, 0x2, 0x0800126e), AMD_CPU_DESC(0x17, 0x31, 0x0, 0x08301052), + {}, }; static void fix_erratum_1386(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index ca327cfa42ae297937fa6512b45651d15edd9092..a5c28975c608ee0a62809a75d55ea95e34e36842 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -169,7 +169,7 @@ static void ppin_init(struct cpuinfo_x86 *c) } clear_ppin: - clear_cpu_cap(c, info->feature); + setup_clear_cpu_cap(info->feature); } static void default_init(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 31a73715d7553142ba6291078698d8fb8eb40d87..fb5d0c67fbab1797021db885122f8486e0410656 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "internal.h" @@ -483,11 +484,25 @@ static void scan_containers(u8 *ucode, size_t size, struct cont_desc *desc) } } -static int __apply_microcode_amd(struct microcode_amd *mc) +static int __apply_microcode_amd(struct microcode_amd *mc, unsigned int psize) { + unsigned long p_addr = (unsigned long)&mc->hdr.data_code; u32 rev, dummy; - native_wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc->hdr.data_code); + native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr); + + if (x86_family(bsp_cpuid_1_eax) == 0x17) { + unsigned long p_addr_end = p_addr + psize - 1; + + invlpg(p_addr); + + /* + * Flush next page too if patch image is crossing a page + * boundary. + */ + if (p_addr >> PAGE_SHIFT != p_addr_end >> PAGE_SHIFT) + invlpg(p_addr_end); + } /* verify patch application was successful */ native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); @@ -529,7 +544,7 @@ static bool early_apply_microcode(u32 old_rev, void *ucode, size_t size) if (old_rev > mc->hdr.patch_id) return ret; - return !__apply_microcode_amd(mc); + return !__apply_microcode_amd(mc, desc.psize); } static bool get_builtin_microcode(struct cpio_data *cp) @@ -745,7 +760,7 @@ void reload_ucode_amd(unsigned int cpu) rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); if (rev < mc->hdr.patch_id) { - if (!__apply_microcode_amd(mc)) + if (!__apply_microcode_amd(mc, p->size)) pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id); } } @@ -798,7 +813,7 @@ static enum ucode_state apply_microcode_amd(int cpu) goto out; } - if (__apply_microcode_amd(mc_amd)) { + if (__apply_microcode_amd(mc_amd, p->size)) { pr_err("CPU%d: update failed for patch_level=0x%08x\n", cpu, mc_amd->hdr.patch_id); return UCODE_ERROR; diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 68efd8cd8bf1b41f887f422a250c563714c4541d..fab3ac9a4574ab406fee90e6c5d86fd4a81af319 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -420,6 +420,10 @@ SECTIONS STABS_DEBUG DWARF_DEBUG +#ifdef CONFIG_PROPELLER_CLANG + .llvm_bb_addr_map : { *(.llvm_bb_addr_map) } +#endif + ELF_DETAILS DISCARDS diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 069e421c22474e5f2ce214c6bc1784b2241ca497..95bc50a8541c6a8154a3d880251c86115647c4e9 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -354,7 +354,7 @@ bool cpu_cache_has_invalidate_memregion(void) { return !cpu_feature_enabled(X86_FEATURE_HYPERVISOR); } -EXPORT_SYMBOL_NS_GPL(cpu_cache_has_invalidate_memregion, DEVMEM); +EXPORT_SYMBOL_NS_GPL(cpu_cache_has_invalidate_memregion, "DEVMEM"); int cpu_cache_invalidate_memregion(int res_desc) { @@ -363,7 +363,7 @@ int cpu_cache_invalidate_memregion(int res_desc) wbinvd_on_all_cpus(); return 0; } -EXPORT_SYMBOL_NS_GPL(cpu_cache_invalidate_memregion, DEVMEM); +EXPORT_SYMBOL_NS_GPL(cpu_cache_invalidate_memregion, "DEVMEM"); #endif static void __cpa_flush_all(void *arg) diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index b0d5a644fc84dc2c405d42bb102fd20873441744..a2becb85bea79689439fb1ebe43f2d20d4957953 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "mm_internal.h" @@ -1140,7 +1141,7 @@ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr) bool cpu_pcide; /* Flush 'addr' from the kernel PCID: */ - asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); + invlpg(addr); /* If PTI is off there is no user PCID and nothing to flush. */ if (!static_cpu_has(X86_FEATURE_PTI)) diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig index 186f13268401bd097246b9e11854c2518f4ea76c..986045d5e638542704b33f66078397e9edf484aa 100644 --- a/arch/x86/um/Kconfig +++ b/arch/x86/um/Kconfig @@ -10,6 +10,7 @@ config UML_X86 def_bool y select ARCH_BINFMT_ELF_EXTRA_PHDRS if X86_32 select DCACHE_WORD_ACCESS + select HAVE_EFFICIENT_UNALIGNED_ACCESS config 64BIT bool "64-bit kernel" if "$(SUBARCH)" = "x86" @@ -28,17 +29,6 @@ config X86_64 def_bool 64BIT select MODULES_USE_ELF_RELA -config 3_LEVEL_PGTABLES - bool "Three-level pagetables" if !64BIT - default 64BIT - help - Three-level pagetables will let UML have more than 4G of physical - memory. All the memory that can't be mapped directly will be treated - as high memory. - - However, this it experimental on 32-bit architectures, so if unsure say - N (on x86-64 it's automatically enabled, instead, as it's safe there). - config ARCH_HAS_SC_SIGNALS def_bool !64BIT diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile index 36e67fc97c22fd0702c5a29162820f18e4331055..b42c31cd2390cbabba183c22bd373893d544f5aa 100644 --- a/arch/x86/um/Makefile +++ b/arch/x86/um/Makefile @@ -10,7 +10,7 @@ else endif obj-y = bugs_$(BITS).o delay.o fault.o \ - ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \ + ptrace.o ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \ stub_segv.o \ sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \ mem_$(BITS).o subarch.o os-Linux/ diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h index 6052200fe9256882859dcd0f19eef8b70f1245f5..62ed5d68a9788ffbf9dd0b4ebbe2caad4ac7a7c6 100644 --- a/arch/x86/um/asm/elf.h +++ b/arch/x86/um/asm/elf.h @@ -8,6 +8,8 @@ #include #include +#define CORE_DUMP_USE_REGSET + #ifdef CONFIG_X86_32 #define R_386_NONE 0 diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h index 2fef3da55533777db972603779575fefffd51cac..2641d28d115ca6075ac83858ca1838addad047b3 100644 --- a/arch/x86/um/asm/ptrace.h +++ b/arch/x86/um/asm/ptrace.h @@ -2,6 +2,16 @@ #ifndef __UM_X86_PTRACE_H #define __UM_X86_PTRACE_H +/* This is here because signal.c needs the REGSET_FP_LEGACY definition */ +enum { + REGSET_GENERAL, +#ifdef CONFIG_X86_32 + REGSET_FP_LEGACY, +#endif + REGSET_FP, + REGSET_XSTATE, +}; + #include #ifndef CONFIG_X86_32 #define __FRAME_OFFSETS /* Needed to get the R* macros */ diff --git a/arch/x86/um/os-Linux/Makefile b/arch/x86/um/os-Linux/Makefile index 5249bbc30dcdb107ed45d7f0d76328f650308f28..77a308aaa5ec9afdc7e5e463220abf8c8a8e018d 100644 --- a/arch/x86/um/os-Linux/Makefile +++ b/arch/x86/um/os-Linux/Makefile @@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-y = registers.o task_size.o mcontext.o +obj-y = registers.o mcontext.o obj-$(CONFIG_X86_32) += tls.o diff --git a/arch/x86/um/os-Linux/registers.c b/arch/x86/um/os-Linux/registers.c index f3638dd09cececd365463464f31762a39d0769f6..76eaeb93928ccec426ed8aea1c68d388dd6e62c3 100644 --- a/arch/x86/um/os-Linux/registers.c +++ b/arch/x86/um/os-Linux/registers.c @@ -16,133 +16,58 @@ #include #include #include +#include -static int have_xstate_support; +unsigned long host_fp_size; -int save_i387_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int save_fp_registers(int pid, unsigned long *fp_regs) +int get_fp_registers(int pid, unsigned long *regs) { -#ifdef PTRACE_GETREGSET - struct iovec iov; + struct iovec iov = { + .iov_base = regs, + .iov_len = host_fp_size, + }; - if (have_xstate_support) { - iov.iov_base = fp_regs; - iov.iov_len = FP_SIZE * sizeof(unsigned long); - if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0) - return -errno; - return 0; - } else -#endif - return save_i387_registers(pid, fp_regs); -} - -int restore_i387_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0) return -errno; return 0; } -int restore_fp_registers(int pid, unsigned long *fp_regs) -{ -#ifdef PTRACE_SETREGSET - struct iovec iov; - if (have_xstate_support) { - iov.iov_base = fp_regs; - iov.iov_len = FP_SIZE * sizeof(unsigned long); - if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0) - return -errno; - return 0; - } else -#endif - return restore_i387_registers(pid, fp_regs); -} - -#ifdef __i386__ -int have_fpx_regs = 1; -int save_fpx_registers(int pid, unsigned long *fp_regs) +int put_fp_registers(int pid, unsigned long *regs) { - if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} + struct iovec iov = { + .iov_base = regs, + .iov_len = host_fp_size, + }; -int restore_fpx_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) + if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0) return -errno; return 0; } -int get_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return save_fpx_registers(pid, regs); - else - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return restore_fpx_registers(pid, regs); - else - return restore_fp_registers(pid, regs); -} - -void arch_init_registers(int pid) -{ - struct user_fpxregs_struct fpx_regs; - int err; - - err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); - if (!err) - return; - - if (errno != EIO) - panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", - errno); - - have_fpx_regs = 0; -} -#else - -int get_fp_registers(int pid, unsigned long *regs) +int arch_init_registers(int pid) { - return save_fp_registers(pid, regs); + struct iovec iov = { + /* Just use plenty of space, it does not cost us anything */ + .iov_len = 2 * 1024 * 1024, + }; + int ret; + + iov.iov_base = mmap(NULL, iov.iov_len, PROT_WRITE | PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (iov.iov_base == MAP_FAILED) + return -ENOMEM; + + /* GDB has x86_xsave_length, which uses x86_cpuid_count */ + ret = ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov); + if (ret) + ret = -errno; + munmap(iov.iov_base, 2 * 1024 * 1024); + + host_fp_size = iov.iov_len; + + return ret; } -int put_fp_registers(int pid, unsigned long *regs) -{ - return restore_fp_registers(pid, regs); -} - -void arch_init_registers(int pid) -{ -#ifdef PTRACE_GETREGSET - void * fp_regs; - struct iovec iov; - - fp_regs = malloc(FP_SIZE * sizeof(unsigned long)); - if(fp_regs == NULL) - return; - - iov.iov_base = fp_regs; - iov.iov_len = FP_SIZE * sizeof(unsigned long); - if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) == 0) - have_xstate_support = 1; - - free(fp_regs); -#endif -} -#endif - unsigned long get_thread_reg(int reg, jmp_buf *buf) { switch (reg) { diff --git a/arch/x86/um/os-Linux/task_size.c b/arch/x86/um/os-Linux/task_size.c deleted file mode 100644 index 1dc9adc20b1ca0efa949d8303b34724d4c24278c..0000000000000000000000000000000000000000 --- a/arch/x86/um/os-Linux/task_size.c +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include - -#ifdef __i386__ - -static jmp_buf buf; - -static void segfault(int sig) -{ - longjmp(buf, 1); -} - -static int page_ok(unsigned long page) -{ - unsigned long *address = (unsigned long *) (page << UM_KERN_PAGE_SHIFT); - unsigned long n = ~0UL; - void *mapped = NULL; - int ok = 0; - - /* - * First see if the page is readable. If it is, it may still - * be a VDSO, so we go on to see if it's writable. If not - * then try mapping memory there. If that fails, then we're - * still in the kernel area. As a sanity check, we'll fail if - * the mmap succeeds, but gives us an address different from - * what we wanted. - */ - if (setjmp(buf) == 0) - n = *address; - else { - mapped = mmap(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (mapped == MAP_FAILED) - return 0; - if (mapped != address) - goto out; - } - - /* - * Now, is it writeable? If so, then we're in user address - * space. If not, then try mprotecting it and try the write - * again. - */ - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - goto out; - } else if (mprotect(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE) != 0) - goto out; - - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - } - - out: - if (mapped != NULL) - munmap(mapped, UM_KERN_PAGE_SIZE); - return ok; -} - -unsigned long os_get_top_address(void) -{ - struct sigaction sa, old; - unsigned long bottom = 0; - /* - * A 32-bit UML on a 64-bit host gets confused about the VDSO at - * 0xffffe000. It is mapped, is readable, can be reprotected writeable - * and written. However, exec discovers later that it can't be - * unmapped. So, just set the highest address to be checked to just - * below it. This might waste some address space on 4G/4G 32-bit - * hosts, but shouldn't hurt otherwise. - */ - unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; - unsigned long test, original; - - printf("Locating the bottom of the address space ... "); - fflush(stdout); - - /* - * We're going to be longjmping out of the signal handler, so - * SA_DEFER needs to be set. - */ - sa.sa_handler = segfault; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NODEFER; - if (sigaction(SIGSEGV, &sa, &old)) { - perror("os_get_top_address"); - exit(1); - } - - /* Manually scan the address space, bottom-up, until we find - * the first valid page (or run out of them). - */ - for (bottom = 0; bottom < top; bottom++) { - if (page_ok(bottom)) - break; - } - - /* If we've got this far, we ran out of pages. */ - if (bottom == top) { - fprintf(stderr, "Unable to determine bottom of address " - "space.\n"); - exit(1); - } - - printf("0x%lx\n", bottom << UM_KERN_PAGE_SHIFT); - printf("Locating the top of the address space ... "); - fflush(stdout); - - original = bottom; - - /* This could happen with a 4G/4G split */ - if (page_ok(top)) - goto out; - - do { - test = bottom + (top - bottom) / 2; - if (page_ok(test)) - bottom = test; - else - top = test; - } while (top - bottom > 1); - -out: - /* Restore the old SIGSEGV handling */ - if (sigaction(SIGSEGV, &old, NULL)) { - perror("os_get_top_address"); - exit(1); - } - top <<= UM_KERN_PAGE_SHIFT; - printf("0x%lx\n", top); - - return top; -} - -#else - -unsigned long os_get_top_address(void) -{ - /* The old value of CONFIG_TOP_ADDR */ - return 0x7fc0002000; -} - -#endif diff --git a/arch/x86/um/ptrace.c b/arch/x86/um/ptrace.c new file mode 100644 index 0000000000000000000000000000000000000000..57c504fd5626e59476c6f918f989e64b648f932a --- /dev/null +++ b/arch/x86/um/ptrace.c @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#ifdef CONFIG_X86_32 +/* + * FPU tag word conversions. + */ + +static inline unsigned short twd_i387_to_fxsr(unsigned short twd) +{ + unsigned int tmp; /* to avoid 16 bit prefixes in the code */ + + /* Transform each pair of bits into 01 (valid) or 00 (empty) */ + tmp = ~twd; + tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ + /* and move the valid bits to the lower byte. */ + tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ + tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ + tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ + return tmp; +} + +static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) +{ + struct _fpxreg *st = NULL; + unsigned long twd = (unsigned long) fxsave->twd; + unsigned long tag; + unsigned long ret = 0xffff0000; + int i; + +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16) + + for (i = 0; i < 8; i++) { + if (twd & 0x1) { + st = (struct _fpxreg *) FPREG_ADDR(fxsave, i); + + switch (st->exponent & 0x7fff) { + case 0x7fff: + tag = 2; /* Special */ + break; + case 0x0000: + if (!st->significand[0] && + !st->significand[1] && + !st->significand[2] && + !st->significand[3]) { + tag = 1; /* Zero */ + } else { + tag = 2; /* Special */ + } + break; + default: + if (st->significand[3] & 0x8000) + tag = 0; /* Valid */ + else + tag = 2; /* Special */ + break; + } + } else { + tag = 3; /* Empty */ + } + ret |= (tag << (2 * i)); + twd = twd >> 1; + } + return ret; +} + +/* Get/set the old 32bit i387 registers (pre-FPX) */ +static int fpregs_legacy_get(struct task_struct *target, + const struct user_regset *regset, + struct membuf to) +{ + struct user_fxsr_struct *fxsave = (void *)target->thread.regs.regs.fp; + int i; + + membuf_store(&to, (unsigned long)fxsave->cwd | 0xffff0000ul); + membuf_store(&to, (unsigned long)fxsave->swd | 0xffff0000ul); + membuf_store(&to, twd_fxsr_to_i387(fxsave)); + membuf_store(&to, fxsave->fip); + membuf_store(&to, fxsave->fcs | ((unsigned long)fxsave->fop << 16)); + membuf_store(&to, fxsave->foo); + membuf_store(&to, fxsave->fos); + + for (i = 0; i < 8; i++) + membuf_write(&to, (void *)fxsave->st_space + i * 16, 10); + + return 0; +} + +static int fpregs_legacy_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + struct user_fxsr_struct *fxsave = (void *)target->thread.regs.regs.fp; + const struct user_i387_struct *from; + struct user_i387_struct buf; + int i; + + if (ubuf) { + if (copy_from_user(&buf, ubuf, sizeof(buf))) + return -EFAULT; + from = &buf; + } else { + from = kbuf; + } + + fxsave->cwd = (unsigned short)(from->cwd & 0xffff); + fxsave->swd = (unsigned short)(from->swd & 0xffff); + fxsave->twd = twd_i387_to_fxsr((unsigned short)(from->twd & 0xffff)); + fxsave->fip = from->fip; + fxsave->fop = (unsigned short)((from->fcs & 0xffff0000ul) >> 16); + fxsave->fcs = (from->fcs & 0xffff); + fxsave->foo = from->foo; + fxsave->fos = from->fos; + + for (i = 0; i < 8; i++) { + memcpy((void *)fxsave->st_space + i * 16, + (void *)from->st_space + i * 10, 10); + } + + return 0; +} +#endif + +static int genregs_get(struct task_struct *target, + const struct user_regset *regset, + struct membuf to) +{ + int reg; + + for (reg = 0; to.left; reg++) + membuf_store(&to, getreg(target, reg * sizeof(unsigned long))); + return 0; +} + +static int genregs_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret = 0; + + if (kbuf) { + const unsigned long *k = kbuf; + + while (count >= sizeof(*k) && !ret) { + ret = putreg(target, pos, *k++); + count -= sizeof(*k); + pos += sizeof(*k); + } + } else { + const unsigned long __user *u = ubuf; + + while (count >= sizeof(*u) && !ret) { + unsigned long word; + + ret = __get_user(word, u++); + if (ret) + break; + ret = putreg(target, pos, word); + count -= sizeof(*u); + pos += sizeof(*u); + } + } + return ret; +} + +static int generic_fpregs_active(struct task_struct *target, const struct user_regset *regset) +{ + return regset->n; +} + +static int generic_fpregs_get(struct task_struct *target, + const struct user_regset *regset, + struct membuf to) +{ + void *fpregs = task_pt_regs(target)->regs.fp; + + membuf_write(&to, fpregs, regset->size * regset->n); + return 0; +} + +static int generic_fpregs_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + void *fpregs = task_pt_regs(target)->regs.fp; + + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + fpregs, 0, regset->size * regset->n); +} + +static struct user_regset uml_regsets[] __ro_after_init = { + [REGSET_GENERAL] = { + .core_note_type = NT_PRSTATUS, + .n = sizeof(struct user_regs_struct) / sizeof(long), + .size = sizeof(long), + .align = sizeof(long), + .regset_get = genregs_get, + .set = genregs_set + }, +#ifdef CONFIG_X86_32 + /* Old FP registers, they are needed in signal frames */ + [REGSET_FP_LEGACY] = { + .core_note_type = NT_PRFPREG, + .n = sizeof(struct user_i387_ia32_struct) / sizeof(long), + .size = sizeof(long), + .align = sizeof(long), + .active = generic_fpregs_active, + .regset_get = fpregs_legacy_get, + .set = fpregs_legacy_set, + }, +#endif + [REGSET_FP] = { +#ifdef CONFIG_X86_32 + .core_note_type = NT_PRXFPREG, + .n = sizeof(struct user32_fxsr_struct) / sizeof(long), +#else + .core_note_type = NT_PRFPREG, + .n = sizeof(struct user_i387_struct) / sizeof(long), +#endif + .size = sizeof(long), + .align = sizeof(long), + .active = generic_fpregs_active, + .regset_get = generic_fpregs_get, + .set = generic_fpregs_set, + }, + [REGSET_XSTATE] = { + .core_note_type = NT_X86_XSTATE, + .size = sizeof(long), + .align = sizeof(long), + .active = generic_fpregs_active, + .regset_get = generic_fpregs_get, + .set = generic_fpregs_set, + }, + /* TODO: Add TLS regset for 32bit */ +}; + +static const struct user_regset_view user_uml_view = { +#ifdef CONFIG_X86_32 + .name = "i386", .e_machine = EM_386, +#else + .name = "x86_64", .e_machine = EM_X86_64, +#endif + .regsets = uml_regsets, .n = ARRAY_SIZE(uml_regsets) +}; + +const struct user_regset_view * +task_user_regset_view(struct task_struct *tsk) +{ + return &user_uml_view; +} + +static int __init init_regset_xstate_info(void) +{ + uml_regsets[REGSET_XSTATE].n = + host_fp_size / uml_regsets[REGSET_XSTATE].size; + + return 0; +} +arch_initcall(init_regset_xstate_info); diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c index b0a71c6cdc6e6cdfb1ced4cee1ea58bb0e040663..3af3cb821524bf8760f8ba413062a7a0368ed629 100644 --- a/arch/x86/um/ptrace_32.c +++ b/arch/x86/um/ptrace_32.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -168,65 +169,6 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long __user *) data); } -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = task_cpu(child); - struct user_i387_struct fpregs; - - err = save_i387_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = task_cpu(child); - struct user_i387_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_i387_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - -static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = task_cpu(child); - struct user_fxsr_struct fpregs; - - err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int n, cpu = task_cpu(child); - struct user_fxsr_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fpx_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { @@ -234,17 +176,25 @@ long subarch_ptrace(struct task_struct *child, long request, void __user *datap = (void __user *) data; switch (request) { case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; + return copy_regset_to_user(child, task_user_regset_view(child), + REGSET_FP_LEGACY, + 0, sizeof(struct user_i387_struct), + datap); case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; + return copy_regset_from_user(child, task_user_regset_view(child), + REGSET_FP_LEGACY, + 0, sizeof(struct user_i387_struct), + datap); case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpxregs(datap, child); - break; + return copy_regset_to_user(child, task_user_regset_view(child), + REGSET_FP, + 0, sizeof(struct user_fxsr_struct), + datap); case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpxregs(datap, child); - break; + return copy_regset_from_user(child, task_user_regset_view(child), + REGSET_FP, + 0, sizeof(struct user_fxsr_struct), + datap); default: ret = -EIO; } diff --git a/arch/x86/um/ptrace_64.c b/arch/x86/um/ptrace_64.c index aa68d83d3f441b746e0b11a9ffa8bec3ca51a996..e0d4120a45c8bc31cbc30b8046599d017e4cc239 100644 --- a/arch/x86/um/ptrace_64.c +++ b/arch/x86/um/ptrace_64.c @@ -8,6 +8,7 @@ #include #include #include +#include #define __FRAME_OFFSETS #include #include @@ -188,36 +189,6 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long *) data); } -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - err = save_i387_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return n; -} - -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_i387_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { @@ -226,11 +197,15 @@ long subarch_ptrace(struct task_struct *child, long request, switch (request) { case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; + return copy_regset_to_user(child, task_user_regset_view(child), + REGSET_FP, + 0, sizeof(struct user_i387_struct), + datap); case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; + return copy_regset_from_user(child, task_user_regset_view(child), + REGSET_FP, + 0, sizeof(struct user_i387_struct), + datap); case PTRACE_ARCH_PRCTL: /* XXX Calls ptrace on the host - needs some SMP thinking */ ret = arch_prctl(child, data, (void __user *) addr); diff --git a/arch/x86/um/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace.h index 6ca4ecabc55b55c478359e60cdd28afb52c1f6ca..2dd4ca6713f8bf62ad12a65312ffcca809e1e271 100644 --- a/arch/x86/um/shared/sysdep/ptrace.h +++ b/arch/x86/um/shared/sysdep/ptrace.h @@ -56,12 +56,16 @@ struct syscall_args { UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG6(r) } } ) +extern unsigned long host_fp_size; + struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; - unsigned long fp[MAX_FP_NR]; struct faultinfo faultinfo; long syscall; int is_user; + + /* Dynamically sized FP registers (holds an XSTATE) */ + unsigned long fp[]; }; #define EMPTY_UML_PT_REGS { } @@ -72,4 +76,6 @@ struct uml_pt_regs { extern int user_context(unsigned long sp); +extern int arch_init_registers(int pid); + #endif /* __SYSDEP_X86_PTRACE_H */ diff --git a/arch/x86/um/shared/sysdep/ptrace_32.h b/arch/x86/um/shared/sysdep/ptrace_32.h index 0c4989842fbe6caaefb47e7f43acdc13bf58ed60..2392470cac4dbe5b952882d71e3507bc17f15afe 100644 --- a/arch/x86/um/shared/sysdep/ptrace_32.h +++ b/arch/x86/um/shared/sysdep/ptrace_32.h @@ -6,8 +6,6 @@ #ifndef __SYSDEP_I386_PTRACE_H #define __SYSDEP_I386_PTRACE_H -#define MAX_FP_NR HOST_FPX_SIZE - #define UPT_SYSCALL_ARG1(r) UPT_BX(r) #define UPT_SYSCALL_ARG2(r) UPT_CX(r) #define UPT_SYSCALL_ARG3(r) UPT_DX(r) @@ -15,6 +13,4 @@ #define UPT_SYSCALL_ARG5(r) UPT_DI(r) #define UPT_SYSCALL_ARG6(r) UPT_BP(r) -extern void arch_init_registers(int pid); - #endif diff --git a/arch/x86/um/shared/sysdep/ptrace_64.h b/arch/x86/um/shared/sysdep/ptrace_64.h index 0dc223aa1c2db5ebb0df8a0bae1814ec0d8131e6..e73573ac871fc9a55298668ddf0af7591b39caa2 100644 --- a/arch/x86/um/shared/sysdep/ptrace_64.h +++ b/arch/x86/um/shared/sysdep/ptrace_64.h @@ -8,8 +8,6 @@ #ifndef __SYSDEP_X86_64_PTRACE_H #define __SYSDEP_X86_64_PTRACE_H -#define MAX_FP_NR HOST_FP_SIZE - #define REGS_R8(r) ((r)[HOST_R8]) #define REGS_R9(r) ((r)[HOST_R9]) #define REGS_R10(r) ((r)[HOST_R10]) @@ -57,6 +55,4 @@ #define UPT_SYSCALL_ARG5(r) UPT_R8(r) #define UPT_SYSCALL_ARG6(r) UPT_R9(r) -extern void arch_init_registers(int pid); - #endif diff --git a/arch/x86/um/shared/sysdep/ptrace_user.h b/arch/x86/um/shared/sysdep/ptrace_user.h index 1d1a824fa65282a2b111a9677dc60243f7c2c0c5..98da23120538618a2cd98825a35cf057c62449b2 100644 --- a/arch/x86/um/shared/sysdep/ptrace_user.h +++ b/arch/x86/um/shared/sysdep/ptrace_user.h @@ -11,12 +11,6 @@ #define REGS_IP_INDEX HOST_IP #define REGS_SP_INDEX HOST_SP -#ifdef __i386__ -#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) -#else -#define FP_SIZE HOST_FP_SIZE -#endif - /* * glibc before 2.27 does not include PTRACE_SYSEMU_SINGLESTEP in its enum, * ensure we have a definition by (re-)defining it here. diff --git a/arch/x86/um/shared/sysdep/stub_32.h b/arch/x86/um/shared/sysdep/stub_32.h index 0b44a86dd346e414505b7f91279388fc02d03e8f..390988132c0a7a62e7a1a08e02940796a7e4759f 100644 --- a/arch/x86/um/shared/sysdep/stub_32.h +++ b/arch/x86/um/shared/sysdep/stub_32.h @@ -112,11 +112,23 @@ static __always_inline void *get_stub_data(void) unsigned long ret; asm volatile ( - "movl %%esp,%0 ;" - "andl %1,%0" + "call _here_%=;" + "_here_%=:" + "popl %0;" + "andl %1, %0 ;" + "addl %2, %0 ;" : "=a" (ret) - : "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1))); + : "g" (~(UM_KERN_PAGE_SIZE - 1)), + "g" (UM_KERN_PAGE_SIZE)); return (void *)ret; } + +#define stub_start(fn) \ + asm volatile ( \ + "subl %0,%%esp ;" \ + "movl %1, %%eax ; " \ + "call *%%eax ;" \ + :: "i" ((1 + STUB_DATA_PAGES) * UM_KERN_PAGE_SIZE), \ + "i" (&fn)) #endif diff --git a/arch/x86/um/shared/sysdep/stub_64.h b/arch/x86/um/shared/sysdep/stub_64.h index 67f44284f1aa41b4279bf67f7d93a3fd92155cd2..294affbec74293026942450ddef3a5951f32bcde 100644 --- a/arch/x86/um/shared/sysdep/stub_64.h +++ b/arch/x86/um/shared/sysdep/stub_64.h @@ -28,6 +28,17 @@ static __always_inline long stub_syscall0(long syscall) return ret; } +static __always_inline long stub_syscall1(long syscall, long arg1) +{ + long ret; + + __asm__ volatile (__syscall + : "=a" (ret) + : "0" (syscall), "D" (arg1) : __syscall_clobber ); + + return ret; +} + static __always_inline long stub_syscall2(long syscall, long arg1, long arg2) { long ret; @@ -106,11 +117,21 @@ static __always_inline void *get_stub_data(void) unsigned long ret; asm volatile ( - "movq %%rsp,%0 ;" - "andq %1,%0" + "lea 0(%%rip), %0;" + "andq %1, %0 ;" + "addq %2, %0 ;" : "=a" (ret) - : "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1))); + : "g" (~(UM_KERN_PAGE_SIZE - 1)), + "g" (UM_KERN_PAGE_SIZE)); return (void *)ret; } + +#define stub_start(fn) \ + asm volatile ( \ + "subq %0,%%rsp ;" \ + "movq %1,%%rax ;" \ + "call *%%rax ;" \ + :: "i" ((1 + STUB_DATA_PAGES) * UM_KERN_PAGE_SIZE), \ + "i" (&fn)) #endif diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c index 2cc8c230902287b87711a7bea394779168401f6d..75087e85b6fdb7fb51cf71d96e97b2574fc10be2 100644 --- a/arch/x86/um/signal.c +++ b/arch/x86/um/signal.c @@ -16,145 +16,24 @@ #include #include -#ifdef CONFIG_X86_32 - -/* - * FPU tag word conversions. - */ - -static inline unsigned short twd_i387_to_fxsr(unsigned short twd) -{ - unsigned int tmp; /* to avoid 16 bit prefixes in the code */ - - /* Transform each pair of bits into 01 (valid) or 00 (empty) */ - tmp = ~twd; - tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ - /* and move the valid bits to the lower byte. */ - tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ - tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ - tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ - return tmp; -} - -static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) -{ - struct _fpxreg *st = NULL; - unsigned long twd = (unsigned long) fxsave->twd; - unsigned long tag; - unsigned long ret = 0xffff0000; - int i; - -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16) - - for (i = 0; i < 8; i++) { - if (twd & 0x1) { - st = (struct _fpxreg *) FPREG_ADDR(fxsave, i); - - switch (st->exponent & 0x7fff) { - case 0x7fff: - tag = 2; /* Special */ - break; - case 0x0000: - if ( !st->significand[0] && - !st->significand[1] && - !st->significand[2] && - !st->significand[3] ) { - tag = 1; /* Zero */ - } else { - tag = 2; /* Special */ - } - break; - default: - if (st->significand[3] & 0x8000) { - tag = 0; /* Valid */ - } else { - tag = 2; /* Special */ - } - break; - } - } else { - tag = 3; /* Empty */ - } - ret |= (tag << (2 * i)); - twd = twd >> 1; - } - return ret; -} - -static int convert_fxsr_to_user(struct _fpstate __user *buf, - struct user_fxsr_struct *fxsave) -{ - unsigned long env[7]; - struct _fpreg __user *to; - struct _fpxreg *from; - int i; - - env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; - env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; - env[2] = twd_fxsr_to_i387(fxsave); - env[3] = fxsave->fip; - env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); - env[5] = fxsave->foo; - env[6] = fxsave->fos; - - if (__copy_to_user(buf, env, 7 * sizeof(unsigned long))) - return 1; - - to = &buf->_st[0]; - from = (struct _fpxreg *) &fxsave->st_space[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long __user *t = (unsigned long __user *)to; - unsigned long *f = (unsigned long *)from; - - if (__put_user(*f, t) || - __put_user(*(f + 1), t + 1) || - __put_user(from->exponent, &to->exponent)) - return 1; - } - return 0; -} - -static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave, - struct _fpstate __user *buf) -{ - unsigned long env[7]; - struct _fpxreg *to; - struct _fpreg __user *from; - int i; - - if (copy_from_user( env, buf, 7 * sizeof(long))) - return 1; - - fxsave->cwd = (unsigned short)(env[0] & 0xffff); - fxsave->swd = (unsigned short)(env[1] & 0xffff); - fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); - fxsave->fip = env[3]; - fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); - fxsave->fcs = (env[4] & 0xffff); - fxsave->foo = env[5]; - fxsave->fos = env[6]; - - to = (struct _fpxreg *) &fxsave->st_space[0]; - from = &buf->_st[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long *t = (unsigned long *)to; - unsigned long __user *f = (unsigned long __user *)from; - - if (__get_user(*t, f) || - __get_user(*(t + 1), f + 1) || - __get_user(to->exponent, &from->exponent)) - return 1; - } - return 0; -} - -extern int have_fpx_regs; +#include +#include +#ifdef CONFIG_X86_32 +struct _xstate_64 { + struct _fpstate_64 fpstate; + struct _header xstate_hdr; + struct _ymmh_state ymmh; + /* New processor state extensions go here: */ +}; +#else +#define _xstate_64 _xstate #endif static int copy_sc_from_user(struct pt_regs *regs, struct sigcontext __user *from) { + struct _xstate_64 __user *from_fp64; struct sigcontext sc; int err; @@ -203,35 +82,27 @@ static int copy_sc_from_user(struct pt_regs *regs, #undef GETREG #ifdef CONFIG_X86_32 - if (have_fpx_regs) { - struct user_fxsr_struct fpx; - int pid = userspace_pid[current_thread_info()->cpu]; + from_fp64 = ((void __user *)sc.fpstate) + + offsetof(struct _fpstate_32, _fxsr_env); +#else + from_fp64 = (void __user *)sc.fpstate; +#endif - err = copy_from_user(&fpx, - &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0], - sizeof(struct user_fxsr_struct)); - if (err) - return 1; + err = copy_from_user(regs->regs.fp, from_fp64, host_fp_size); + if (err) + return 1; - err = convert_fxsr_from_user(&fpx, (void *)sc.fpstate); - if (err) - return 1; - - err = restore_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fpx_registers failed, errno = %d\n", - -err); - return 1; - } - } else +#ifdef CONFIG_X86_32 + /* Data is duplicated and this copy is the important one */ + err = copy_regset_from_user(current, + task_user_regset_view(current), + REGSET_FP_LEGACY, 0, + sizeof(struct user_i387_struct), + (void __user *)sc.fpstate); + if (err < 0) + return err; #endif - { - err = copy_from_user(regs->regs.fp, (void *)sc.fpstate, - sizeof(struct _xstate)); - if (err) - return 1; - } + return 0; } @@ -239,6 +110,7 @@ static int copy_sc_to_user(struct sigcontext __user *to, struct _xstate __user *to_fp, struct pt_regs *regs, unsigned long mask) { + struct _xstate_64 __user *to_fp64; struct sigcontext sc; struct faultinfo * fi = ¤t->thread.arch.faultinfo; int err; @@ -290,35 +162,46 @@ static int copy_sc_to_user(struct sigcontext __user *to, return 1; #ifdef CONFIG_X86_32 - if (have_fpx_regs) { - int pid = userspace_pid[current_thread_info()->cpu]; - struct user_fxsr_struct fpx; - - err = save_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0){ - printk(KERN_ERR "copy_sc_to_user - save_fpx_registers " - "failed, errno = %d\n", err); - return 1; - } - - err = convert_fxsr_to_user(&to_fp->fpstate, &fpx); - if (err) - return 1; + err = copy_regset_to_user(current, + task_user_regset_view(current), + REGSET_FP_LEGACY, 0, + sizeof(struct _fpstate_32), to_fp); + if (err < 0) + return err; - err |= __put_user(fpx.swd, &to_fp->fpstate.status); - err |= __put_user(X86_FXSR_MAGIC, &to_fp->fpstate.magic); - if (err) - return 1; + __put_user(X86_FXSR_MAGIC, &to_fp->fpstate.magic); + + BUILD_BUG_ON(offsetof(struct _xstate, xstate_hdr) != + offsetof(struct _xstate_64, xstate_hdr) + + offsetof(struct _fpstate_32, _fxsr_env)); + to_fp64 = (void __user *)to_fp + + offsetof(struct _fpstate_32, _fxsr_env); +#else + to_fp64 = to_fp; +#endif /* CONFIG_X86_32 */ + + if (copy_to_user(to_fp64, regs->regs.fp, host_fp_size)) + return 1; - if (copy_to_user(&to_fp->fpstate._fxsr_env[0], &fpx, - sizeof(struct user_fxsr_struct))) - return 1; - } else + /* + * Put magic/size values for userspace. We do not bother to verify them + * later on, however, userspace needs them should it try to read the + * XSTATE data. And ptrace does not fill in these parts. + */ + BUILD_BUG_ON(sizeof(int) != FP_XSTATE_MAGIC2_SIZE); +#ifdef CONFIG_X86_32 + __put_user(offsetof(struct _fpstate_32, _fxsr_env) + + host_fp_size + FP_XSTATE_MAGIC2_SIZE, + &to_fp64->fpstate.sw_reserved.extended_size); +#else + __put_user(host_fp_size + FP_XSTATE_MAGIC2_SIZE, + &to_fp64->fpstate.sw_reserved.extended_size); #endif - { - if (copy_to_user(to_fp, regs->regs.fp, sizeof(struct _xstate))) - return 1; - } + __put_user(host_fp_size, &to_fp64->fpstate.sw_reserved.xstate_size); + + __put_user(FP_XSTATE_MAGIC1, &to_fp64->fpstate.sw_reserved.magic1); + __put_user(FP_XSTATE_MAGIC2, + (int __user *)((void __user *)to_fp64 + host_fp_size)); return 0; } @@ -336,34 +219,15 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, return err; } -struct sigframe -{ - char __user *pretcode; - int sig; - struct sigcontext sc; - struct _xstate fpstate; - unsigned long extramask[_NSIG_WORDS-1]; - char retcode[8]; -}; - -struct rt_sigframe -{ - char __user *pretcode; - int sig; - struct siginfo __user *pinfo; - void __user *puc; - struct siginfo info; - struct ucontext uc; - struct _xstate fpstate; - char retcode[8]; -}; - int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig, struct pt_regs *regs, sigset_t *mask) { + size_t math_size = offsetof(struct _fpstate_32, _fxsr_env) + + host_fp_size + FP_XSTATE_MAGIC2_SIZE; struct sigframe __user *frame; void __user *restorer; int err = 0, sig = ksig->sig; + unsigned long fp_to; /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ stack_top = ((stack_top + 4) & -16UL) - 4; @@ -371,13 +235,21 @@ int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig, if (!access_ok(frame, sizeof(*frame))) return 1; + /* Add required space for math frame */ + frame = (struct sigframe __user *)((unsigned long)frame - math_size); + restorer = frame->retcode; if (ksig->ka.sa.sa_flags & SA_RESTORER) restorer = ksig->ka.sa.sa_restorer; - err |= __put_user(restorer, &frame->pretcode); + err |= __put_user(restorer, (void __user * __user *)&frame->pretcode); err |= __put_user(sig, &frame->sig); - err |= copy_sc_to_user(&frame->sc, &frame->fpstate, regs, mask->sig[0]); + + fp_to = (unsigned long)frame + sizeof(*frame); + + err |= copy_sc_to_user(&frame->sc, + (struct _xstate __user *)fp_to, + regs, mask->sig[0]); if (_NSIG_WORDS > 1) err |= __copy_to_user(&frame->extramask, &mask->sig[1], sizeof(frame->extramask)); @@ -407,26 +279,35 @@ int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig, int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig, struct pt_regs *regs, sigset_t *mask) { + size_t math_size = offsetof(struct _fpstate_32, _fxsr_env) + + host_fp_size + FP_XSTATE_MAGIC2_SIZE; struct rt_sigframe __user *frame; void __user *restorer; int err = 0, sig = ksig->sig; + unsigned long fp_to; stack_top &= -8UL; frame = (struct rt_sigframe __user *) stack_top - 1; if (!access_ok(frame, sizeof(*frame))) return 1; + /* Add required space for math frame */ + frame = (struct rt_sigframe __user *)((unsigned long)frame - math_size); + restorer = frame->retcode; if (ksig->ka.sa.sa_flags & SA_RESTORER) restorer = ksig->ka.sa.sa_restorer; - err |= __put_user(restorer, &frame->pretcode); + err |= __put_user(restorer, (void __user * __user *)&frame->pretcode); err |= __put_user(sig, &frame->sig); - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); + err |= __put_user(&frame->info, (void __user * __user *)&frame->pinfo); + err |= __put_user(&frame->uc, (void __user * __user *)&frame->puc); err |= copy_siginfo_to_user(&frame->info, &ksig->info); - err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, - PT_REGS_SP(regs)); + + fp_to = (unsigned long)frame + sizeof(*frame); + + err |= copy_ucontext_to_user(&frame->uc, (struct _xstate __user *)fp_to, + mask, PT_REGS_SP(regs)); /* * This is movl $,%eax ; int $0x80 @@ -478,27 +359,24 @@ SYSCALL_DEFINE0(sigreturn) #else -struct rt_sigframe -{ - char __user *pretcode; - struct ucontext uc; - struct siginfo info; - struct _xstate fpstate; -}; - int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig, struct pt_regs *regs, sigset_t *set) { + unsigned long math_size = host_fp_size + FP_XSTATE_MAGIC2_SIZE; struct rt_sigframe __user *frame; int err = 0, sig = ksig->sig; unsigned long fp_to; frame = (struct rt_sigframe __user *) round_down(stack_top - sizeof(struct rt_sigframe), 16); + + /* Add required space for math frame */ + frame = (struct rt_sigframe __user *)((unsigned long)frame - math_size); + /* Subtract 128 for a red zone and 8 for proper alignment */ frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); - if (!access_ok(frame, sizeof(*frame))) + if (!access_ok(frame, sizeof(*frame) + math_size)) goto out; if (ksig->ka.sa.sa_flags & SA_SIGINFO) { @@ -509,12 +387,14 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig, /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user(NULL, &frame->uc.uc_link); err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs)); - err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, - set->sig[0]); - fp_to = (unsigned long)&frame->fpstate; + fp_to = (unsigned long)frame + sizeof(*frame); + + err |= copy_sc_to_user(&frame->uc.uc_mcontext, + (struct _xstate __user *)fp_to, + regs, set->sig[0]); err |= __put_user(fp_to, &frame->uc.uc_mcontext.fpstate); if (sizeof(*set) == 16) { @@ -531,7 +411,7 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig, */ /* x86-64 should always use SA_RESTORER. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) - err |= __put_user((void *)ksig->ka.sa.sa_restorer, + err |= __put_user((void __user *)ksig->ka.sa.sa_restorer, &frame->pretcode); else /* could use a vstub here */ diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c index 1c77d9946199854200659ed7c4df117df563961d..d6e1cd9956bf99e9e5a272bfa0ddc47be6a0702c 100644 --- a/arch/x86/um/user-offsets.c +++ b/arch/x86/um/user-offsets.c @@ -20,9 +20,6 @@ void foo(void); void foo(void) { #ifdef __i386__ - DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); - DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); - DEFINE(HOST_IP, EIP); DEFINE(HOST_SP, UESP); DEFINE(HOST_EFLAGS, EFL); @@ -41,11 +38,6 @@ void foo(void) DEFINE(HOST_GS, GS); DEFINE(HOST_ORIG_AX, ORIG_EAX); #else -#ifdef FP_XSTATE_MAGIC1 - DEFINE_LONGS(HOST_FP_SIZE, 2696); -#else - DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); -#endif DEFINE_LONGS(HOST_BX, RBX); DEFINE_LONGS(HOST_CX, RCX); DEFINE_LONGS(HOST_DI, RDI); diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile index 6a77ea6434ffde178d07b4466ec18ca83718baae..7478d11dacb713384655ed76af3b469aeb5bae81 100644 --- a/arch/x86/um/vdso/Makefile +++ b/arch/x86/um/vdso/Makefile @@ -56,7 +56,6 @@ CFLAGS_REMOVE_um_vdso.o = -pg -fprofile-arcs -ftest-coverage quiet_cmd_vdso = VDSO $@ cmd_vdso = $(CC) -nostdlib -o $@ \ $(CC_FLAGS_LTO) $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ - -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ - sh $(src)/checkundef.sh '$(NM)' '$@' + -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) -VDSO_LDFLAGS = -fPIC -shared -Wl,--hash-style=sysv -z noexecstack +VDSO_LDFLAGS = -fPIC -shared -Wl,--hash-style=sysv -z noexecstack -Wl,--no-undefined diff --git a/arch/x86/um/vdso/checkundef.sh b/arch/x86/um/vdso/checkundef.sh deleted file mode 100644 index 8e3ea6bb956fc8fead5e280bf82a52287d1328a4..0000000000000000000000000000000000000000 --- a/arch/x86/um/vdso/checkundef.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -nm="$1" -file="$2" -$nm "$file" | grep '^ *U' > /dev/null 2>&1 -if [ $? -eq 1 ]; then - exit 0 -else - echo "$file: undefined symbols found" >&2 - exit 1 -fi diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index e831aedb464329ab8c1c06855338eb47d086089e..9fb9f353315025a4004b8097bb138ddfe34a0dd2 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -736,6 +736,7 @@ static void bfq_sync_bfqq_move(struct bfq_data *bfqd, */ bfq_put_cooperator(sync_bfqq); bic_set_bfqq(bic, NULL, true, act_idx); + bfq_release_process_ref(bfqd, sync_bfqq); } } diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 0747d9d0e48c8a159114903553d94493ae5fa8ec..95dd7b795935658b8709de7eab81b4730ece022d 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -582,23 +582,31 @@ static struct request *bfq_choose_req(struct bfq_data *bfqd, #define BFQ_LIMIT_INLINE_DEPTH 16 #ifdef CONFIG_BFQ_GROUP_IOSCHED -static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit) +static bool bfqq_request_over_limit(struct bfq_data *bfqd, + struct bfq_io_cq *bic, blk_opf_t opf, + unsigned int act_idx, int limit) { - struct bfq_data *bfqd = bfqq->bfqd; - struct bfq_entity *entity = &bfqq->entity; struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH]; struct bfq_entity **entities = inline_entities; - int depth, level, alloc_depth = BFQ_LIMIT_INLINE_DEPTH; - int class_idx = bfqq->ioprio_class - 1; + int alloc_depth = BFQ_LIMIT_INLINE_DEPTH; struct bfq_sched_data *sched_data; + struct bfq_entity *entity; + struct bfq_queue *bfqq; unsigned long wsum; bool ret = false; - - if (!entity->on_st_or_in_serv) - return false; + int depth; + int level; retry: spin_lock_irq(&bfqd->lock); + bfqq = bic_to_bfqq(bic, op_is_sync(opf), act_idx); + if (!bfqq) + goto out; + + entity = &bfqq->entity; + if (!entity->on_st_or_in_serv) + goto out; + /* +1 for bfqq entity, root cgroup not included */ depth = bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup->level + 1; if (depth > alloc_depth) { @@ -643,7 +651,7 @@ retry: * class. */ wsum = 0; - for (i = 0; i <= class_idx; i++) { + for (i = 0; i <= bfqq->ioprio_class - 1; i++) { wsum = wsum * IOPRIO_BE_NR + sched_data->service_tree[i].wsum; } @@ -666,7 +674,9 @@ out: return ret; } #else -static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit) +static bool bfqq_request_over_limit(struct bfq_data *bfqd, + struct bfq_io_cq *bic, blk_opf_t opf, + unsigned int act_idx, int limit) { return false; } @@ -704,8 +714,9 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data) } for (act_idx = 0; bic && act_idx < bfqd->num_actuators; act_idx++) { - struct bfq_queue *bfqq = - bic_to_bfqq(bic, op_is_sync(opf), act_idx); + /* Fast path to check if bfqq is already allocated. */ + if (!bic_to_bfqq(bic, op_is_sync(opf), act_idx)) + continue; /* * Does queue (or any parent entity) exceed number of @@ -713,7 +724,7 @@ static void bfq_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data) * limit depth so that it cannot consume more * available requests and thus starve other entities. */ - if (bfqq && bfqq_request_over_limit(bfqq, limit)) { + if (bfqq_request_over_limit(bfqd, bic, opf, act_idx, limit)) { depth = 1; break; } @@ -5434,8 +5445,6 @@ void bfq_put_cooperator(struct bfq_queue *bfqq) bfq_put_queue(__bfqq); __bfqq = next; } - - bfq_release_process_ref(bfqq->bfqd, bfqq); } static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) @@ -5448,6 +5457,8 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, bfqq->ref); bfq_put_cooperator(bfqq); + + bfq_release_process_ref(bfqd, bfqq); } static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync, @@ -6734,6 +6745,8 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) bic_set_bfqq(bic, NULL, true, bfqq->actuator_idx); bfq_put_cooperator(bfqq); + + bfq_release_process_ref(bfqq->bfqd, bfqq); return NULL; } diff --git a/block/blk-merge.c b/block/blk-merge.c index e0b28e9298c9fb5315225e6a1daacc50ba4786fa..e01383c6e534b0a27a0db8c45d98a2a14d9ec69a 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -864,17 +864,10 @@ static struct request *attempt_merge(struct request_queue *q, if (req_op(req) != req_op(next)) return NULL; - if (rq_data_dir(req) != rq_data_dir(next)) + if (req->bio->bi_write_hint != next->bio->bi_write_hint) + return NULL; + if (req->bio->bi_ioprio != next->bio->bi_ioprio) return NULL; - - if (req->bio && next->bio) { - /* Don't merge requests with different write hints. */ - if (req->bio->bi_write_hint != next->bio->bi_write_hint) - return NULL; - if (req->bio->bi_ioprio != next->bio->bi_ioprio) - return NULL; - } - if (!blk_atomic_write_mergeable_rqs(req, next)) return NULL; @@ -986,30 +979,16 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio) if (req_op(rq) != bio_op(bio)) return false; - /* different data direction or already started, don't merge */ - if (bio_data_dir(bio) != rq_data_dir(rq)) - return false; - - /* don't merge across cgroup boundaries */ if (!blk_cgroup_mergeable(rq, bio)) return false; - - /* only merge integrity protected bio into ditto rq */ if (blk_integrity_merge_bio(rq->q, rq, bio) == false) return false; - - /* Only merge if the crypt contexts are compatible */ if (!bio_crypt_rq_ctx_compatible(rq, bio)) return false; - - if (rq->bio) { - /* Don't merge requests with different write hints. */ - if (rq->bio->bi_write_hint != bio->bi_write_hint) - return false; - if (rq->bio->bi_ioprio != bio->bi_ioprio) - return false; - } - + if (rq->bio->bi_write_hint != bio->bi_write_hint) + return false; + if (rq->bio->bi_ioprio != bio->bi_ioprio) + return false; if (blk_atomic_write_mergeable_rq_bio(rq, bio) == false) return false; diff --git a/block/blk-mq.c b/block/blk-mq.c index 270cfd9fc6b0c1f197cd673e29179ac4ec040c3d..424239c075e28c301d0d17e03bf114bc8f582780 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -388,7 +388,6 @@ void blk_rq_init(struct request_queue *q, struct request *rq) rq->tag = BLK_MQ_NO_TAG; rq->internal_tag = BLK_MQ_NO_TAG; rq->start_time_ns = blk_time_get_ns(); - rq->part = NULL; blk_crypto_rq_set_defaults(rq); } EXPORT_SYMBOL(blk_rq_init); @@ -3273,19 +3272,21 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src, int (*bio_ctr)(struct bio *, struct bio *, void *), void *data) { - struct bio *bio, *bio_src; + struct bio *bio_src; if (!bs) bs = &fs_bio_set; __rq_for_each_bio(bio_src, rq_src) { - bio = bio_alloc_clone(rq->q->disk->part0, bio_src, gfp_mask, - bs); + struct bio *bio = bio_alloc_clone(rq->q->disk->part0, bio_src, + gfp_mask, bs); if (!bio) goto free_and_out; - if (bio_ctr && bio_ctr(bio, bio_src, data)) + if (bio_ctr && bio_ctr(bio, bio_src, data)) { + bio_put(bio); goto free_and_out; + } if (rq->bio) { rq->biotail->bi_next = bio; @@ -3293,7 +3294,6 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src, } else { rq->bio = rq->biotail = bio; } - bio = NULL; } /* Copy attributes of the original request to the clone request. */ @@ -3311,8 +3311,6 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src, return 0; free_and_out: - if (bio) - bio_put(bio); blk_rq_unprep_clone(rq); return -ENOMEM; diff --git a/block/blk-settings.c b/block/blk-settings.c index f1d4dfdc37a71a5401b9742a599070926edb3174..8f09e33f41f68ae20277244622715471c139fbe6 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -178,9 +178,26 @@ static void blk_validate_atomic_write_limits(struct queue_limits *lim) if (!lim->atomic_write_hw_max) goto unsupported; + if (WARN_ON_ONCE(!is_power_of_2(lim->atomic_write_hw_unit_min))) + goto unsupported; + + if (WARN_ON_ONCE(!is_power_of_2(lim->atomic_write_hw_unit_max))) + goto unsupported; + + if (WARN_ON_ONCE(lim->atomic_write_hw_unit_min > + lim->atomic_write_hw_unit_max)) + goto unsupported; + + if (WARN_ON_ONCE(lim->atomic_write_hw_unit_max > + lim->atomic_write_hw_max)) + goto unsupported; + boundary_sectors = lim->atomic_write_hw_boundary >> SECTOR_SHIFT; if (boundary_sectors) { + if (WARN_ON_ONCE(lim->atomic_write_hw_max > + lim->atomic_write_hw_boundary)) + goto unsupported; /* * A feature of boundary support is that it disallows bios to * be merged which would result in a merged request which @@ -248,6 +265,13 @@ int blk_validate_limits(struct queue_limits *lim) if (lim->io_min < lim->physical_block_size) lim->io_min = lim->physical_block_size; + /* + * The optimal I/O size may not be aligned to physical block size + * (because it may be limited by dma engines which have no clue about + * block size of the disks attached to them), so we round it down here. + */ + lim->io_opt = round_down(lim->io_opt, lim->physical_block_size); + /* * max_hw_sectors has a somewhat weird default for historical reason, * but driver really should set their own instead of relying on this @@ -458,8 +482,6 @@ static unsigned int queue_limit_discard_alignment( /* Why are these in bytes, not sectors? */ alignment = lim->discard_alignment >> SECTOR_SHIFT; granularity = lim->discard_granularity >> SECTOR_SHIFT; - if (!granularity) - return 0; /* Offset of the partition start in 'granularity' sectors */ offset = sector_div(sector, granularity); @@ -479,6 +501,119 @@ static unsigned int blk_round_down_sectors(unsigned int sectors, unsigned int lb return sectors; } +/* Check if second and later bottom devices are compliant */ +static bool blk_stack_atomic_writes_tail(struct queue_limits *t, + struct queue_limits *b) +{ + /* We're not going to support different boundary sizes.. yet */ + if (t->atomic_write_hw_boundary != b->atomic_write_hw_boundary) + return false; + + /* Can't support this */ + if (t->atomic_write_hw_unit_min > b->atomic_write_hw_unit_max) + return false; + + /* Or this */ + if (t->atomic_write_hw_unit_max < b->atomic_write_hw_unit_min) + return false; + + t->atomic_write_hw_max = min(t->atomic_write_hw_max, + b->atomic_write_hw_max); + t->atomic_write_hw_unit_min = max(t->atomic_write_hw_unit_min, + b->atomic_write_hw_unit_min); + t->atomic_write_hw_unit_max = min(t->atomic_write_hw_unit_max, + b->atomic_write_hw_unit_max); + return true; +} + +/* Check for valid boundary of first bottom device */ +static bool blk_stack_atomic_writes_boundary_head(struct queue_limits *t, + struct queue_limits *b) +{ + /* + * Ensure atomic write boundary is aligned with chunk sectors. Stacked + * devices store chunk sectors in t->io_min. + */ + if (b->atomic_write_hw_boundary > t->io_min && + b->atomic_write_hw_boundary % t->io_min) + return false; + if (t->io_min > b->atomic_write_hw_boundary && + t->io_min % b->atomic_write_hw_boundary) + return false; + + t->atomic_write_hw_boundary = b->atomic_write_hw_boundary; + return true; +} + + +/* Check stacking of first bottom device */ +static bool blk_stack_atomic_writes_head(struct queue_limits *t, + struct queue_limits *b) +{ + if (b->atomic_write_hw_boundary && + !blk_stack_atomic_writes_boundary_head(t, b)) + return false; + + if (t->io_min <= SECTOR_SIZE) { + /* No chunk sectors, so use bottom device values directly */ + t->atomic_write_hw_unit_max = b->atomic_write_hw_unit_max; + t->atomic_write_hw_unit_min = b->atomic_write_hw_unit_min; + t->atomic_write_hw_max = b->atomic_write_hw_max; + return true; + } + + /* + * Find values for limits which work for chunk size. + * b->atomic_write_hw_unit_{min, max} may not be aligned with chunk + * size (t->io_min), as chunk size is not restricted to a power-of-2. + * So we need to find highest power-of-2 which works for the chunk + * size. + * As an example scenario, we could have b->unit_max = 16K and + * t->io_min = 24K. For this case, reduce t->unit_max to a value + * aligned with both limits, i.e. 8K in this example. + */ + t->atomic_write_hw_unit_max = b->atomic_write_hw_unit_max; + while (t->io_min % t->atomic_write_hw_unit_max) + t->atomic_write_hw_unit_max /= 2; + + t->atomic_write_hw_unit_min = min(b->atomic_write_hw_unit_min, + t->atomic_write_hw_unit_max); + t->atomic_write_hw_max = min(b->atomic_write_hw_max, t->io_min); + + return true; +} + +static void blk_stack_atomic_writes_limits(struct queue_limits *t, + struct queue_limits *b) +{ + if (!(t->features & BLK_FEAT_ATOMIC_WRITES_STACKED)) + goto unsupported; + + if (!b->atomic_write_unit_min) + goto unsupported; + + /* + * If atomic_write_hw_max is set, we have already stacked 1x bottom + * device, so check for compliance. + */ + if (t->atomic_write_hw_max) { + if (!blk_stack_atomic_writes_tail(t, b)) + goto unsupported; + return; + } + + if (!blk_stack_atomic_writes_head(t, b)) + goto unsupported; + return; + +unsupported: + t->atomic_write_hw_max = 0; + t->atomic_write_hw_unit_max = 0; + t->atomic_write_hw_unit_min = 0; + t->atomic_write_hw_boundary = 0; + t->features &= ~BLK_FEAT_ATOMIC_WRITES_STACKED; +} + /** * blk_stack_limits - adjust queue_limits for stacked devices * @t: the stacking driver limits (top device) @@ -639,6 +774,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->zone_write_granularity = 0; t->max_zone_append_sectors = 0; } + blk_stack_atomic_writes_limits(t, b); + return ret; } EXPORT_SYMBOL(blk_stack_limits); diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index d80a202cd170635eeb27abad08129f483e507b8f..4241aea84161ca7611bbdad70bd524ab79922898 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -810,10 +810,8 @@ int blk_register_queue(struct gendisk *disk) * faster to shut down and is made fully functional here as * request_queues for non-existent devices never get registered. */ - if (!blk_queue_init_done(q)) { - blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q); - percpu_ref_switch_to_percpu(&q->q_usage_counter); - } + blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q); + percpu_ref_switch_to_percpu(&q->q_usage_counter); return ret; diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 70211751df16eba0d7c5e0df32e110851a166782..263e28b720538f0d441f1584ef82539717437ac5 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -1551,6 +1551,7 @@ static int disk_update_zone_resources(struct gendisk *disk, unsigned int nr_seq_zones, nr_conv_zones; unsigned int pool_size; struct queue_limits lim; + int ret; disk->nr_zones = args->nr_zones; disk->zone_capacity = args->zone_capacity; @@ -1601,7 +1602,11 @@ static int disk_update_zone_resources(struct gendisk *disk, } commit: - return queue_limits_commit_update(q, &lim); + blk_mq_freeze_queue(q); + ret = queue_limits_commit_update(q, &lim); + blk_mq_unfreeze_queue(q); + + return ret; } static int blk_revalidate_conv_zone(struct blk_zone *zone, unsigned int idx, @@ -1816,14 +1821,15 @@ int blk_revalidate_disk_zones(struct gendisk *disk) * Set the new disk zone parameters only once the queue is frozen and * all I/Os are completed. */ - blk_mq_freeze_queue(q); if (ret > 0) ret = disk_update_zone_resources(disk, &args); else pr_warn("%s: failed to revalidate zones\n", disk->disk_name); - if (ret) + if (ret) { + blk_mq_freeze_queue(q); disk_free_zone_resources(disk); - blk_mq_unfreeze_queue(q); + blk_mq_unfreeze_queue(q); + } return ret; } diff --git a/block/fops.c b/block/fops.c index 2d01c900768139430301c82d8457a968f022c7e3..13a67940d0408d60130dd66604a5281f5ef06324 100644 --- a/block/fops.c +++ b/block/fops.c @@ -677,6 +677,7 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) struct file *file = iocb->ki_filp; struct inode *bd_inode = bdev_file_inode(file); struct block_device *bdev = I_BDEV(bd_inode); + bool atomic = iocb->ki_flags & IOCB_ATOMIC; loff_t size = bdev_nr_bytes(bdev); size_t shorted = 0; ssize_t ret; @@ -696,7 +697,7 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT) return -EOPNOTSUPP; - if (iocb->ki_flags & IOCB_ATOMIC) { + if (atomic) { ret = generic_atomic_write_valid(iocb, from); if (ret) return ret; @@ -704,6 +705,8 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) size -= iocb->ki_pos; if (iov_iter_count(from) > size) { + if (atomic) + return -EINVAL; shorted = iov_iter_count(from) - size; iov_iter_truncate(from, size); } diff --git a/block/genhd.c b/block/genhd.c index 9130e163e1913ad6f3b4e4b0297d49328dea1c57..79230c109fca036816667f4cf0c9839fa120c562 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -742,13 +742,10 @@ void del_gendisk(struct gendisk *disk) * If the disk does not own the queue, allow using passthrough requests * again. Else leave the queue frozen to fail all I/O. */ - if (!test_bit(GD_OWNS_QUEUE, &disk->state)) { - blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q); + if (!test_bit(GD_OWNS_QUEUE, &disk->state)) __blk_mq_unfreeze_queue(q, true); - } else { - if (queue_is_mq(q)) - blk_mq_exit_queue(q); - } + else if (queue_is_mq(q)) + blk_mq_exit_queue(q); if (start_drain) blk_unfreeze_release_lock(q, true, queue_dying); diff --git a/block/mq-deadline.c b/block/mq-deadline.c index acdc28756d9d778ef4ac5e32cb5a1c363a08827f..91b3789f710e7a9b8ac3da53fa98632eff5f6abe 100644 --- a/block/mq-deadline.c +++ b/block/mq-deadline.c @@ -685,10 +685,9 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, prio = ioprio_class_to_prio[ioprio_class]; per_prio = &dd->per_prio[prio]; - if (!rq->elv.priv[0]) { + if (!rq->elv.priv[0]) per_prio->stats.inserted++; - rq->elv.priv[0] = (void *)(uintptr_t)1; - } + rq->elv.priv[0] = per_prio; if (blk_mq_sched_try_insert_merge(q, rq, free)) return; @@ -753,18 +752,14 @@ static void dd_prepare_request(struct request *rq) */ static void dd_finish_request(struct request *rq) { - struct request_queue *q = rq->q; - struct deadline_data *dd = q->elevator->elevator_data; - const u8 ioprio_class = dd_rq_ioclass(rq); - const enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; - struct dd_per_prio *per_prio = &dd->per_prio[prio]; + struct dd_per_prio *per_prio = rq->elv.priv[0]; /* * The block layer core may call dd_finish_request() without having * called dd_insert_requests(). Skip requests that bypassed I/O * scheduling. See also blk_mq_request_bypass_insert(). */ - if (rq->elv.priv[0]) + if (per_prio) atomic_inc(&per_prio->stats.completed); } diff --git a/crypto/adiantum.c b/crypto/adiantum.c index 60f3883b736aa823e7106fcb90baa853c79d5a26..c3ef583598b4f45ae26d9196dead59b5b928e257 100644 --- a/crypto/adiantum.c +++ b/crypto/adiantum.c @@ -646,4 +646,4 @@ MODULE_DESCRIPTION("Adiantum length-preserving encryption mode"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Eric Biggers "); MODULE_ALIAS_CRYPTO("adiantum"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index 3f512efaba3aa11209cf6a9e9a6db1ae87d2501f..64f57c4c4b06213443cf4831e112568d7cf4dd00 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c @@ -471,4 +471,4 @@ subsys_initcall(prng_mod_init); module_exit(prng_mod_fini); MODULE_ALIAS_CRYPTO("stdrng"); MODULE_ALIAS_CRYPTO("ansi_cprng"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/ccm.c b/crypto/ccm.c index 36f0acec32e196e0d086631851b36c192963924b..06476b53b4916338f27ea784bca2ab23d0fde342 100644 --- a/crypto/ccm.c +++ b/crypto/ccm.c @@ -949,4 +949,4 @@ MODULE_ALIAS_CRYPTO("ccm_base"); MODULE_ALIAS_CRYPTO("rfc4309"); MODULE_ALIAS_CRYPTO("ccm"); MODULE_ALIAS_CRYPTO("cbcmac"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/cipher.c b/crypto/cipher.c index 40cae908788ecaeaa73e9df3eb7aebc91edf3f1c..1fe62bf79656bb89b7aaa01ee1b07de5b3c3c4b9 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -53,7 +53,7 @@ int crypto_cipher_setkey(struct crypto_cipher *tfm, return cia->cia_setkey(crypto_cipher_tfm(tfm), key, keylen); } -EXPORT_SYMBOL_NS_GPL(crypto_cipher_setkey, CRYPTO_INTERNAL); +EXPORT_SYMBOL_NS_GPL(crypto_cipher_setkey, "CRYPTO_INTERNAL"); static inline void cipher_crypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src, bool enc) @@ -81,14 +81,14 @@ void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, { cipher_crypt_one(tfm, dst, src, true); } -EXPORT_SYMBOL_NS_GPL(crypto_cipher_encrypt_one, CRYPTO_INTERNAL); +EXPORT_SYMBOL_NS_GPL(crypto_cipher_encrypt_one, "CRYPTO_INTERNAL"); void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src) { cipher_crypt_one(tfm, dst, src, false); } -EXPORT_SYMBOL_NS_GPL(crypto_cipher_decrypt_one, CRYPTO_INTERNAL); +EXPORT_SYMBOL_NS_GPL(crypto_cipher_decrypt_one, "CRYPTO_INTERNAL"); struct crypto_cipher *crypto_clone_cipher(struct crypto_cipher *cipher) { diff --git a/crypto/cmac.c b/crypto/cmac.c index c7aa3665b076e4012d7b9e93119f58c9145bd6be..c66a0f4d88080659da439e32e34e2dfe4f5057e2 100644 --- a/crypto/cmac.c +++ b/crypto/cmac.c @@ -313,4 +313,4 @@ module_exit(crypto_cmac_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CMAC keyed hash algorithm"); MODULE_ALIAS_CRYPTO("cmac"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/ctr.c b/crypto/ctr.c index 1420496062d57d6c200aa3ebe7e895ace3446e4f..73c0d6e53b2fd0e54061065dfcede824a93b40ad 100644 --- a/crypto/ctr.c +++ b/crypto/ctr.c @@ -357,4 +357,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CTR block cipher mode of operation"); MODULE_ALIAS_CRYPTO("rfc3686"); MODULE_ALIAS_CRYPTO("ctr"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/drbg.c b/crypto/drbg.c index c323f40bed4f7b0b317b80b8cd0753111307c2d3..f28dfc2511a2b919c9e31bfb378ee5e207f0c8cf 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -2151,4 +2151,4 @@ MODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG) " CRYPTO_DRBG_HMAC_STRING CRYPTO_DRBG_CTR_STRING); MODULE_ALIAS_CRYPTO("stdrng"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/ecb.c b/crypto/ecb.c index e3a67789050ee286441af5e5bc5a36b40086f59e..95d7e972865a86195428e3daa41f784fcdeab76b 100644 --- a/crypto/ecb.c +++ b/crypto/ecb.c @@ -225,4 +225,4 @@ module_exit(crypto_ecb_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ECB block cipher mode of operation"); MODULE_ALIAS_CRYPTO("ecb"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/essiv.c b/crypto/essiv.c index e63fc6442e3201a3334f260315374aa6f12c5d73..1c00c3324058c227b650ec15d707d8b38a4efa25 100644 --- a/crypto/essiv.c +++ b/crypto/essiv.c @@ -649,4 +649,4 @@ module_exit(essiv_module_exit); MODULE_DESCRIPTION("ESSIV skcipher/aead wrapper for block encryption"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS_CRYPTO("essiv"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/hctr2.c b/crypto/hctr2.c index 87e7547ad18623b8f75c6c33f49116e60410a133..cbcd673be481f9e8d37594176830662869fcd31c 100644 --- a/crypto/hctr2.c +++ b/crypto/hctr2.c @@ -576,4 +576,4 @@ module_exit(hctr2_module_exit); MODULE_DESCRIPTION("HCTR2 length-preserving encryption mode"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS_CRYPTO("hctr2"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/keywrap.c b/crypto/keywrap.c index 054d9a216fc9f3dbabeecbdd12a28954b1e0fa5e..385ffdfd5a9b4a979e816fab776c0b8ab37892f1 100644 --- a/crypto/keywrap.c +++ b/crypto/keywrap.c @@ -317,4 +317,4 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Stephan Mueller "); MODULE_DESCRIPTION("Key Wrapping (RFC3394 / NIST SP800-38F)"); MODULE_ALIAS_CRYPTO("kw"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/pcbc.c b/crypto/pcbc.c index ab469ba50c13d2af653f8f14d9137c3a6ef2e224..cbfb3ac14b3a8084a21a91e73a8765e47b1b5469 100644 --- a/crypto/pcbc.c +++ b/crypto/pcbc.c @@ -192,4 +192,4 @@ module_exit(crypto_pcbc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("PCBC block cipher mode of operation"); MODULE_ALIAS_CRYPTO("pcbc"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/skcipher.c b/crypto/skcipher.c index ceed7f33a67ba5755244bcbbbc78fa0945c02353..f74e4d0d87a22dc282ac643448340feee39400b4 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c @@ -1085,4 +1085,4 @@ EXPORT_SYMBOL_GPL(skcipher_alloc_instance_simple); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Symmetric key cipher type"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 3fc908bac21aea487b5ef7cd996c1c61865cfaa5..1f5f48ab18c741c2405b5318293048ced27a4bb1 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -39,7 +39,7 @@ #include "internal.h" -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); static bool notests; module_param(notests, bool, 0644); diff --git a/crypto/vmac.c b/crypto/vmac.c index bd9d70eac22e00388deacb889b06b69b833101f4..2ea384645ecf7d405a1fca9e9d0fdddae2504577 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -693,4 +693,4 @@ module_exit(vmac_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("VMAC hash algorithm"); MODULE_ALIAS_CRYPTO("vmac64"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/xcbc.c b/crypto/xcbc.c index a9e8ee9c1949cba2b20e55d0d1fd334ad7a20086..fc785667b134d954f7bc5a579772574ec6152209 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -261,4 +261,4 @@ module_exit(crypto_xcbc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("XCBC keyed hash algorithm"); MODULE_ALIAS_CRYPTO("xcbc"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/xctr.c b/crypto/xctr.c index 5c00147e8ec40b08d8b77c59ae8d9d190bf9839d..6ed9c85ededa0901bf29c068437bf49d8b626abb 100644 --- a/crypto/xctr.c +++ b/crypto/xctr.c @@ -188,4 +188,4 @@ module_exit(crypto_xctr_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("XCTR block cipher mode of operation"); MODULE_ALIAS_CRYPTO("xctr"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/xts.c b/crypto/xts.c index 672e1a3f0b0c933f6d1bd54fb597ab68ac02f50a..821060ede2cf001c62c471861019768d2c803dd9 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -472,5 +472,5 @@ module_exit(xts_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("XTS block cipher mode"); MODULE_ALIAS_CRYPTO("xts"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); MODULE_SOFTDEP("pre: ecb"); diff --git a/drivers/accel/habanalabs/common/memory.c b/drivers/accel/habanalabs/common/memory.c index 3348ad12c23751afef2fa98d860a5a0a1f4c781b..601fdbe701790b2d242949e394990caa6783e30b 100644 --- a/drivers/accel/habanalabs/common/memory.c +++ b/drivers/accel/habanalabs/common/memory.c @@ -14,7 +14,7 @@ #include #include -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); #define HL_MMU_DEBUG 0 diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c index 3575e0c984d69f84baab6b03cb7b954741db1fab..4ddf89308ff5a44624ab6209744c0290fd824c94 100644 --- a/drivers/accel/qaic/qaic_drv.c +++ b/drivers/accel/qaic/qaic_drv.c @@ -32,7 +32,7 @@ #include "qaic_timesync.h" #include "sahara.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); #define PCI_DEV_AIC080 0xa080 #define PCI_DEV_AIC100 0xa100 diff --git a/drivers/accessibility/speakup/Makefile b/drivers/accessibility/speakup/Makefile index 6f6a83565c0ded227260a93a16243e5ae240fe7a..14ba1cca87f47ea2e5500c02b739084d2b45a091 100644 --- a/drivers/accessibility/speakup/Makefile +++ b/drivers/accessibility/speakup/Makefile @@ -40,9 +40,7 @@ hostprogs += makemapdata makemapdata-objs := makemapdata.o quiet_cmd_mkmap = MKMAP $@ - cmd_mkmap = TOPDIR=$(srctree) \ - SPKDIR=$(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD),$(srctree)/drivers/accessibility/speakup) \ - $(obj)/makemapdata > $@ + cmd_mkmap = TOPDIR=$(srctree) SPKDIR=$(src) $(obj)/makemapdata > $@ $(obj)/mapdata.h: $(obj)/makemapdata $(call cmd,mkmap) diff --git a/drivers/acpi/apei/einj-cxl.c b/drivers/acpi/apei/einj-cxl.c index a4e709937236f66146790c044df473b151257892..78da9ae543a2b1782b5114f2da7b97970356d27d 100644 --- a/drivers/acpi/apei/einj-cxl.c +++ b/drivers/acpi/apei/einj-cxl.c @@ -45,7 +45,7 @@ int einj_cxl_available_error_type_show(struct seq_file *m, void *v) return 0; } -EXPORT_SYMBOL_NS_GPL(einj_cxl_available_error_type_show, CXL); +EXPORT_SYMBOL_NS_GPL(einj_cxl_available_error_type_show, "CXL"); static int cxl_dport_get_sbdf(struct pci_dev *dport_dev, u64 *sbdf) { @@ -83,7 +83,7 @@ int einj_cxl_inject_rch_error(u64 rcrb, u64 type) return einj_cxl_rch_error_inject(type, 0x2, rcrb, GENMASK_ULL(63, 0), 0, 0); } -EXPORT_SYMBOL_NS_GPL(einj_cxl_inject_rch_error, CXL); +EXPORT_SYMBOL_NS_GPL(einj_cxl_inject_rch_error, "CXL"); int einj_cxl_inject_error(struct pci_dev *dport, u64 type) { @@ -104,10 +104,10 @@ int einj_cxl_inject_error(struct pci_dev *dport, u64 type) return einj_error_inject(type, 0x4, 0, 0, 0, param4); } -EXPORT_SYMBOL_NS_GPL(einj_cxl_inject_error, CXL); +EXPORT_SYMBOL_NS_GPL(einj_cxl_inject_error, "CXL"); bool einj_cxl_is_initialized(void) { return einj_initialized; } -EXPORT_SYMBOL_NS_GPL(einj_cxl_is_initialized, CXL); +EXPORT_SYMBOL_NS_GPL(einj_cxl_is_initialized, "CXL"); diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index a2491905f165114287d709a150f5f37c40a7cee0..07789f0b59bcdad5f478f12febe515ac318ef122 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -726,7 +726,7 @@ int cxl_cper_register_work(struct work_struct *work) cxl_cper_work = work; return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_cper_register_work, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_cper_register_work, "CXL"); int cxl_cper_unregister_work(struct work_struct *work) { @@ -737,13 +737,13 @@ int cxl_cper_unregister_work(struct work_struct *work) cxl_cper_work = NULL; return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_work, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_work, "CXL"); int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd) { return kfifo_get(&cxl_cper_fifo, wd); } -EXPORT_SYMBOL_NS_GPL(cxl_cper_kfifo_get, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_cper_kfifo_get, "CXL"); static bool ghes_do_proc(struct ghes *ghes, const struct acpi_hest_generic_status *estatus) diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 1a902a02390f6d7809cbc71434a976bcea02e9a2..80a3481c04701d39a63162ce51db81f2c58c9d0a 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -151,7 +151,7 @@ int acpi_get_genport_coordinates(u32 uid, return 0; } -EXPORT_SYMBOL_NS_GPL(acpi_get_genport_coordinates, CXL); +EXPORT_SYMBOL_NS_GPL(acpi_get_genport_coordinates, "CXL"); static __init void alloc_memory_initiator(unsigned int cpu_pxm) { diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 6671537cb4b7dc641df278640625520270470de9..95982c098d5bd59f2830ef3e545c7d9ed02268f4 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1082,7 +1082,7 @@ static void __exit acpi_thermal_exit(void) module_init(acpi_thermal_init); module_exit(acpi_thermal_exit); -MODULE_IMPORT_NS(ACPI_THERMAL); +MODULE_IMPORT_NS("ACPI_THERMAL"); MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/acpi/thermal_lib.c b/drivers/acpi/thermal_lib.c index 6214d6ebe1fa31d16158fba9a501c6ed09c57d56..f81591927e8658f14be242f89a7e6af3be315803 100644 --- a/drivers/acpi/thermal_lib.c +++ b/drivers/acpi/thermal_lib.c @@ -53,25 +53,25 @@ int acpi_active_trip_temp(struct acpi_device *adev, int id, int *ret_temp) return acpi_trip_temp(adev, obj_name, ret_temp); } -EXPORT_SYMBOL_NS_GPL(acpi_active_trip_temp, ACPI_THERMAL); +EXPORT_SYMBOL_NS_GPL(acpi_active_trip_temp, "ACPI_THERMAL"); int acpi_passive_trip_temp(struct acpi_device *adev, int *ret_temp) { return acpi_trip_temp(adev, "_PSV", ret_temp); } -EXPORT_SYMBOL_NS_GPL(acpi_passive_trip_temp, ACPI_THERMAL); +EXPORT_SYMBOL_NS_GPL(acpi_passive_trip_temp, "ACPI_THERMAL"); int acpi_hot_trip_temp(struct acpi_device *adev, int *ret_temp) { return acpi_trip_temp(adev, "_HOT", ret_temp); } -EXPORT_SYMBOL_NS_GPL(acpi_hot_trip_temp, ACPI_THERMAL); +EXPORT_SYMBOL_NS_GPL(acpi_hot_trip_temp, "ACPI_THERMAL"); int acpi_critical_trip_temp(struct acpi_device *adev, int *ret_temp) { return acpi_trip_temp(adev, "_CRT", ret_temp); } -EXPORT_SYMBOL_NS_GPL(acpi_critical_trip_temp, ACPI_THERMAL); +EXPORT_SYMBOL_NS_GPL(acpi_critical_trip_temp, "ACPI_THERMAL"); static int thermal_temp(int error, int temp_decik, int *ret_temp) { diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 0230c43377c1da23230d7fe28833f0603f55686e..8ef259b4d0378a27cccc2183e7e0cab62dae2342 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -449,6 +449,12 @@ const struct bus_type amba_bustype = { }; EXPORT_SYMBOL_GPL(amba_bustype); +bool dev_is_amba(const struct device *dev) +{ + return dev->bus == &amba_bustype; +} +EXPORT_SYMBOL_GPL(dev_is_amba); + static int __init amba_init(void) { return bus_register(&amba_bustype); diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 978740537a1aacd9eb4d6fedc83136747eae026e..ef353ca13c356acac42b08e4e2fed41a360ccb4f 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -1225,6 +1225,12 @@ static void binder_cleanup_ref_olocked(struct binder_ref *ref) binder_dequeue_work(ref->proc, &ref->death->work); binder_stats_deleted(BINDER_STAT_DEATH); } + + if (ref->freeze) { + binder_dequeue_work(ref->proc, &ref->freeze->work); + binder_stats_deleted(BINDER_STAT_FREEZE); + } + binder_stats_deleted(BINDER_STAT_REF); } @@ -3850,7 +3856,6 @@ binder_request_freeze_notification(struct binder_proc *proc, { struct binder_ref_freeze *freeze; struct binder_ref *ref; - bool is_frozen; freeze = kzalloc(sizeof(*freeze), GFP_KERNEL); if (!freeze) @@ -3866,32 +3871,31 @@ binder_request_freeze_notification(struct binder_proc *proc, } binder_node_lock(ref->node); - - if (ref->freeze || !ref->node->proc) { - binder_user_error("%d:%d invalid BC_REQUEST_FREEZE_NOTIFICATION %s\n", - proc->pid, thread->pid, - ref->freeze ? "already set" : "dead node"); + if (ref->freeze) { + binder_user_error("%d:%d BC_REQUEST_FREEZE_NOTIFICATION already set\n", + proc->pid, thread->pid); binder_node_unlock(ref->node); binder_proc_unlock(proc); kfree(freeze); return -EINVAL; } - binder_inner_proc_lock(ref->node->proc); - is_frozen = ref->node->proc->is_frozen; - binder_inner_proc_unlock(ref->node->proc); binder_stats_created(BINDER_STAT_FREEZE); INIT_LIST_HEAD(&freeze->work.entry); freeze->cookie = handle_cookie->cookie; freeze->work.type = BINDER_WORK_FROZEN_BINDER; - freeze->is_frozen = is_frozen; - ref->freeze = freeze; - binder_inner_proc_lock(proc); - binder_enqueue_work_ilocked(&ref->freeze->work, &proc->todo); - binder_wakeup_proc_ilocked(proc); - binder_inner_proc_unlock(proc); + if (ref->node->proc) { + binder_inner_proc_lock(ref->node->proc); + freeze->is_frozen = ref->node->proc->is_frozen; + binder_inner_proc_unlock(ref->node->proc); + + binder_inner_proc_lock(proc); + binder_enqueue_work_ilocked(&freeze->work, &proc->todo); + binder_wakeup_proc_ilocked(proc); + binder_inner_proc_unlock(proc); + } binder_node_unlock(ref->node); binder_proc_unlock(proc); @@ -5151,6 +5155,16 @@ static void binder_release_work(struct binder_proc *proc, } break; case BINDER_WORK_NODE: break; + case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION: { + struct binder_ref_freeze *freeze; + + freeze = container_of(w, struct binder_ref_freeze, work); + binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, + "undelivered freeze notification, %016llx\n", + (u64)freeze->cookie); + kfree(freeze); + binder_stats_deleted(BINDER_STAT_FREEZE); + } break; default: pr_err("unexpected work type, %d, not freed\n", wtype); @@ -5552,6 +5566,7 @@ static bool binder_txns_pending_ilocked(struct binder_proc *proc) static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) { + struct binder_node *prev = NULL; struct rb_node *n; struct binder_ref *ref; @@ -5560,7 +5575,10 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) struct binder_node *node; node = rb_entry(n, struct binder_node, rb_node); + binder_inc_node_tmpref_ilocked(node); binder_inner_proc_unlock(proc); + if (prev) + binder_put_node(prev); binder_node_lock(node); hlist_for_each_entry(ref, &node->refs, node_entry) { /* @@ -5586,10 +5604,15 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) } binder_inner_proc_unlock(ref->proc); } + prev = node; binder_node_unlock(node); binder_inner_proc_lock(proc); + if (proc->is_dead) + break; } binder_inner_proc_unlock(proc); + if (prev) + binder_put_node(prev); } static int binder_ioctl_freeze(struct binder_freeze_info *info, @@ -6260,6 +6283,7 @@ static void binder_deferred_release(struct binder_proc *proc) binder_release_work(proc, &proc->todo); binder_release_work(proc, &proc->delivered_death); + binder_release_work(proc, &proc->delivered_freeze); binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d\n", @@ -6393,6 +6417,12 @@ static void print_binder_work_ilocked(struct seq_file *m, case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: seq_printf(m, "%shas cleared death notification\n", prefix); break; + case BINDER_WORK_FROZEN_BINDER: + seq_printf(m, "%shas frozen binder\n", prefix); + break; + case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION: + seq_printf(m, "%shas cleared freeze notification\n", prefix); + break; default: seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); break; @@ -6539,6 +6569,10 @@ static void print_binder_proc(struct seq_file *m, seq_puts(m, " has delivered dead binder\n"); break; } + list_for_each_entry(w, &proc->delivered_freeze, entry) { + seq_puts(m, " has delivered freeze binder\n"); + break; + } binder_inner_proc_unlock(proc); if (!print_all && m->count == header_pos) m->count = start_pos; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index cb00f8244e4110b8bf0170ea6b2dc57d2bcc7e36..4fea1149e00371eeb93f16d8b6d498bf853b4137 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2569,7 +2569,7 @@ static struct platform_driver fore200e_sba_driver = { .of_match_table = fore200e_sba_match, }, .probe = fore200e_sba_probe, - .remove_new = fore200e_sba_remove, + .remove = fore200e_sba_remove, }; #endif diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c index 2b74dabe7e17573711419aeff9af44e409e9780a..24baf6b2c587644a3cde43dd9179fac0984c18de 100644 --- a/drivers/auxdisplay/cfag12864bfb.c +++ b/drivers/auxdisplay/cfag12864bfb.c @@ -108,7 +108,7 @@ static void cfag12864bfb_remove(struct platform_device *device) static struct platform_driver cfag12864bfb_driver = { .probe = cfag12864bfb_probe, - .remove_new = cfag12864bfb_remove, + .remove = cfag12864bfb_remove, .driver = { .name = CFAG12864BFB_NAME, }, diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c index 025dc6855cb253e45015d9ea95d681ddd6f6b97c..0526f0d90a793e4524a698e3148e4941c3703c1a 100644 --- a/drivers/auxdisplay/hd44780.c +++ b/drivers/auxdisplay/hd44780.c @@ -339,7 +339,7 @@ MODULE_DEVICE_TABLE(of, hd44780_of_match); static struct platform_driver hd44780_driver = { .probe = hd44780_probe, - .remove_new = hd44780_remove, + .remove = hd44780_remove, .driver = { .name = "hd44780", .of_match_table = hd44780_of_match, diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index 09deb864b27ae4a44c46e20bcf81ac82a9f61986..0b8ba754b3430a690ecfc632ae0b412bc8fce997 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -780,5 +780,5 @@ module_i2c_driver(ht16k33_driver); MODULE_DESCRIPTION("Holtek HT16K33 driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LINEDISP); +MODULE_IMPORT_NS("LINEDISP"); MODULE_AUTHOR("Robin van der Gracht "); diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c index 9ba132dc6143ad9c847841c9044831c38ae9f023..a802678a6f7448f9224e83ff129057effca594b2 100644 --- a/drivers/auxdisplay/img-ascii-lcd.c +++ b/drivers/auxdisplay/img-ascii-lcd.c @@ -291,11 +291,11 @@ static struct platform_driver img_ascii_lcd_driver = { .of_match_table = img_ascii_lcd_matches, }, .probe = img_ascii_lcd_probe, - .remove_new = img_ascii_lcd_remove, + .remove = img_ascii_lcd_remove, }; module_platform_driver(img_ascii_lcd_driver); MODULE_DESCRIPTION("Imagination Technologies ASCII LCD Display"); MODULE_AUTHOR("Paul Burton "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LINEDISP); +MODULE_IMPORT_NS("LINEDISP"); diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c index 731ffdfafc4ed9caa1f87700c2fcae8f012040fe..fcec77f100ce946cf57e4501174c1498a033a21e 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -381,7 +381,7 @@ out_put_device: put_device(&linedisp->dev); return err; } -EXPORT_SYMBOL_NS_GPL(linedisp_register, LINEDISP); +EXPORT_SYMBOL_NS_GPL(linedisp_register, "LINEDISP"); /** * linedisp_unregister - unregister a character line display @@ -394,7 +394,7 @@ void linedisp_unregister(struct linedisp *linedisp) del_timer_sync(&linedisp->timer); put_device(&linedisp->dev); } -EXPORT_SYMBOL_NS_GPL(linedisp_unregister, LINEDISP); +EXPORT_SYMBOL_NS_GPL(linedisp_unregister, "LINEDISP"); MODULE_DESCRIPTION("Character line display core support"); MODULE_LICENSE("GPL"); diff --git a/drivers/auxdisplay/max6959.c b/drivers/auxdisplay/max6959.c index 5519c014bd2950747a486866556689f5aa78b882..962488197b9e97470b10a8534898be511543c299 100644 --- a/drivers/auxdisplay/max6959.c +++ b/drivers/auxdisplay/max6959.c @@ -191,4 +191,4 @@ module_i2c_driver(max6959_i2c_driver); MODULE_DESCRIPTION("MAX6958/6959 7-segment LED controller"); MODULE_AUTHOR("Andy Shevchenko "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LINEDISP); +MODULE_IMPORT_NS("LINEDISP"); diff --git a/drivers/auxdisplay/seg-led-gpio.c b/drivers/auxdisplay/seg-led-gpio.c index 183ab3011cbb1904e1c5ae40705a33b73ff859f3..f10c25e6bf126cfaac3e4c353f8bfc6639d94a60 100644 --- a/drivers/auxdisplay/seg-led-gpio.c +++ b/drivers/auxdisplay/seg-led-gpio.c @@ -97,7 +97,7 @@ MODULE_DEVICE_TABLE(of, seg_led_of_match); static struct platform_driver seg_led_driver = { .probe = seg_led_probe, - .remove_new = seg_led_remove, + .remove = seg_led_remove, .driver = { .name = "seg-led-gpio", .of_match_table = seg_led_of_match, @@ -108,4 +108,4 @@ module_platform_driver(seg_led_driver); MODULE_AUTHOR("Chris Packham "); MODULE_DESCRIPTION("7 segment LED driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LINEDISP); +MODULE_IMPORT_NS("LINEDISP"); diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index 7823888af4f68472627e9c31f296ebda1ee7b565..afa4df4c5a3f371b91d8dd8c4325495d32ad1291 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -92,7 +92,7 @@ * Auxiliary devices are created and registered by a subsystem-level core * device that needs to break up its functionality into smaller fragments. One * way to extend the scope of an auxiliary_device is to encapsulate it within a - * domain- pecific structure defined by the parent device. This structure + * domain-specific structure defined by the parent device. This structure * contains the auxiliary_device and any associated shared data/callbacks * needed to establish the connection with the parent. * @@ -335,35 +335,6 @@ int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) } EXPORT_SYMBOL_GPL(__auxiliary_device_add); -/** - * auxiliary_find_device - auxiliary device iterator for locating a particular device. - * @start: Device to begin with - * @data: Data to pass to match function - * @match: Callback function to check device - * - * This function returns a reference to a device that is 'found' - * for later use, as determined by the @match callback. - * - * The reference returned should be released with put_device(). - * - * The callback should return 0 if the device doesn't match and non-zero - * if it does. If the callback returns non-zero, this function will - * return to the caller and not iterate over any more devices. - */ -struct auxiliary_device *auxiliary_find_device(struct device *start, - const void *data, - device_match_t match) -{ - struct device *dev; - - dev = bus_find_device(&auxiliary_bus_type, start, data, match); - if (!dev) - return NULL; - - return to_auxiliary_dev(dev); -} -EXPORT_SYMBOL_GPL(auxiliary_find_device); - /** * __auxiliary_driver_register - register a driver for auxiliary bus devices * @auxdrv: auxiliary_driver structure diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 7a7609298e18bdc1fbf703c0284da4a8656e33e1..609935ad5091570839e9b5824e360f7701964f96 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -254,11 +254,11 @@ static int of_count_cache_leaves(struct device_node *np) { unsigned int leaves = 0; - if (of_property_read_bool(np, "cache-size")) + if (of_property_present(np, "cache-size")) ++leaves; - if (of_property_read_bool(np, "i-cache-size")) + if (of_property_present(np, "i-cache-size")) ++leaves; - if (of_property_read_bool(np, "d-cache-size")) + if (of_property_present(np, "d-cache-size")) ++leaves; if (!leaves) { @@ -367,9 +367,7 @@ static int cache_shared_cpu_map_setup(unsigned int cpu) cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); for_each_online_cpu(i) { - struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i); - - if (i == cpu || !sib_cpu_ci->info_list) + if (i == cpu || !per_cpu_cacheinfo(i)) continue;/* skip if itself or no cacheinfo */ for (sib_index = 0; sib_index < cache_leaves(i); sib_index++) { sib_leaf = per_cpu_cacheinfo_idx(i, sib_index); @@ -409,10 +407,7 @@ static void cache_shared_cpu_map_remove(unsigned int cpu) for (index = 0; index < cache_leaves(cpu); index++) { this_leaf = per_cpu_cacheinfo_idx(cpu, index); for_each_cpu(sibling, &this_leaf->shared_cpu_map) { - struct cpu_cacheinfo *sib_cpu_ci = - get_cpu_cacheinfo(sibling); - - if (sibling == cpu || !sib_cpu_ci->info_list) + if (sibling == cpu || !per_cpu_cacheinfo(sibling)) continue;/* skip if itself or no cacheinfo */ for (sib_index = 0; sib_index < cache_leaves(sibling); sib_index++) { diff --git a/drivers/base/class.c b/drivers/base/class.c index cb5359235c7020cd6b79c4d64c2f894f92352fca..582b5a02a5c410113326601fe00eb6d7231f988f 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -405,7 +405,7 @@ int class_for_each_device(const struct class *class, const struct device *start, if (!class) return -EINVAL; if (!sp) { - WARN(1, "%s called for class '%s' before it was initialized", + WARN(1, "%s called for class '%s' before it was registered", __func__, class->name); return -EINVAL; } @@ -453,7 +453,7 @@ struct device *class_find_device(const struct class *class, const struct device if (!class) return NULL; if (!sp) { - WARN(1, "%s called for class '%s' before it was initialized", + WARN(1, "%s called for class '%s' before it was registered", __func__, class->name); return NULL; } diff --git a/drivers/base/core.c b/drivers/base/core.c index 529af59e25ffb9b92ff8e5614bddeeae5c22f288..94865c9d8adcf5f2ce5002ffd7bf0ef4fc85e4d7 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -552,7 +552,7 @@ void device_link_wait_removal(void) } EXPORT_SYMBOL_GPL(device_link_wait_removal); -static struct class devlink_class = { +static const struct class devlink_class = { .name = "devlink", .dev_groups = devlink_groups, .dev_release = devlink_dev_release, @@ -1971,7 +1971,7 @@ static struct device *fwnode_get_next_parent_dev(const struct fwnode_handle *fwn /** * __fw_devlink_relax_cycles - Relax and mark dependency cycles. - * @con: Potential consumer device. + * @con_handle: Potential consumer device fwnode. * @sup_handle: Potential supplier's fwnode. * * Needs to be called with fwnode_lock and device link lock held. @@ -1989,10 +1989,10 @@ static struct device *fwnode_get_next_parent_dev(const struct fwnode_handle *fwn * * Return true if one or more cycles were found. Otherwise, return false. */ -static bool __fw_devlink_relax_cycles(struct device *con, +static bool __fw_devlink_relax_cycles(struct fwnode_handle *con_handle, struct fwnode_handle *sup_handle) { - struct device *sup_dev = NULL, *par_dev = NULL; + struct device *sup_dev = NULL, *par_dev = NULL, *con_dev = NULL; struct fwnode_link *link; struct device_link *dev_link; bool ret = false; @@ -2009,22 +2009,22 @@ static bool __fw_devlink_relax_cycles(struct device *con, sup_handle->flags |= FWNODE_FLAG_VISITED; - sup_dev = get_dev_from_fwnode(sup_handle); - /* Termination condition. */ - if (sup_dev == con) { + if (sup_handle == con_handle) { pr_debug("----- cycle: start -----\n"); ret = true; goto out; } + sup_dev = get_dev_from_fwnode(sup_handle); + con_dev = get_dev_from_fwnode(con_handle); /* * If sup_dev is bound to a driver and @con hasn't started binding to a * driver, sup_dev can't be a consumer of @con. So, no need to check * further. */ if (sup_dev && sup_dev->links.status == DL_DEV_DRIVER_BOUND && - con->links.status == DL_DEV_NO_DRIVER) { + con_dev && con_dev->links.status == DL_DEV_NO_DRIVER) { ret = false; goto out; } @@ -2033,7 +2033,7 @@ static bool __fw_devlink_relax_cycles(struct device *con, if (link->flags & FWLINK_FLAG_IGNORE) continue; - if (__fw_devlink_relax_cycles(con, link->supplier)) { + if (__fw_devlink_relax_cycles(con_handle, link->supplier)) { __fwnode_link_cycle(link); ret = true; } @@ -2048,7 +2048,7 @@ static bool __fw_devlink_relax_cycles(struct device *con, else par_dev = fwnode_get_next_parent_dev(sup_handle); - if (par_dev && __fw_devlink_relax_cycles(con, par_dev->fwnode)) { + if (par_dev && __fw_devlink_relax_cycles(con_handle, par_dev->fwnode)) { pr_debug("%pfwf: cycle: child of %pfwf\n", sup_handle, par_dev->fwnode); ret = true; @@ -2066,7 +2066,7 @@ static bool __fw_devlink_relax_cycles(struct device *con, !(dev_link->flags & DL_FLAG_CYCLE)) continue; - if (__fw_devlink_relax_cycles(con, + if (__fw_devlink_relax_cycles(con_handle, dev_link->supplier->fwnode)) { pr_debug("%pfwf: cycle: depends on %pfwf\n", sup_handle, dev_link->supplier->fwnode); @@ -2114,11 +2114,6 @@ static int fw_devlink_create_devlink(struct device *con, if (link->flags & FWLINK_FLAG_IGNORE) return 0; - if (con->fwnode == link->consumer) - flags = fw_devlink_get_flags(link->flags); - else - flags = FW_DEVLINK_FLAGS_PERMISSIVE; - /* * In some cases, a device P might also be a supplier to its child node * C. However, this would defer the probe of C until the probe of P @@ -2139,25 +2134,23 @@ static int fw_devlink_create_devlink(struct device *con, return -EINVAL; /* - * SYNC_STATE_ONLY device links don't block probing and supports cycles. - * So, one might expect that cycle detection isn't necessary for them. - * However, if the device link was marked as SYNC_STATE_ONLY because - * it's part of a cycle, then we still need to do cycle detection. This - * is because the consumer and supplier might be part of multiple cycles - * and we need to detect all those cycles. + * Don't try to optimize by not calling the cycle detection logic under + * certain conditions. There's always some corner case that won't get + * detected. */ - if (!device_link_flag_is_sync_state_only(flags) || - flags & DL_FLAG_CYCLE) { - device_links_write_lock(); - if (__fw_devlink_relax_cycles(con, sup_handle)) { - __fwnode_link_cycle(link); - flags = fw_devlink_get_flags(link->flags); - pr_debug("----- cycle: end -----\n"); - dev_info(con, "Fixed dependency cycle(s) with %pfwf\n", - sup_handle); - } - device_links_write_unlock(); + device_links_write_lock(); + if (__fw_devlink_relax_cycles(link->consumer, sup_handle)) { + __fwnode_link_cycle(link); + pr_debug("----- cycle: end -----\n"); + pr_info("%pfwf: Fixed dependency cycle(s) with %pfwf\n", + link->consumer, sup_handle); } + device_links_write_unlock(); + + if (con->fwnode == link->consumer) + flags = fw_devlink_get_flags(link->flags); + else + flags = FW_DEVLINK_FLAGS_PERMISSIVE; if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE) sup_dev = fwnode_get_next_parent_dev(sup_handle); @@ -2180,8 +2173,8 @@ static int fw_devlink_create_devlink(struct device *con, } if (con != sup_dev && !device_link_add(con, sup_dev, flags)) { - dev_err(con, "Failed to create device link (0x%x) with %s\n", - flags, dev_name(sup_dev)); + dev_err(con, "Failed to create device link (0x%x) with supplier %s for %pfwf\n", + flags, dev_name(sup_dev), link->consumer); ret = -EINVAL; } diff --git a/drivers/base/firmware_loader/builtin/main.c b/drivers/base/firmware_loader/builtin/main.c index a065c31508973642e0f2c2aa2f6a064e40a63362..d36befebb1b937f1e573188377248d7a1e103bfc 100644 --- a/drivers/base/firmware_loader/builtin/main.c +++ b/drivers/base/firmware_loader/builtin/main.c @@ -61,7 +61,7 @@ bool firmware_request_builtin(struct firmware *fw, const char *name) return false; } -EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, TEST_FIRMWARE); +EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, "TEST_FIRMWARE"); /** * firmware_request_builtin_buf() - load builtin firmware into optional buffer diff --git a/drivers/base/firmware_loader/fallback_table.c b/drivers/base/firmware_loader/fallback_table.c index 8432ab2c3b3ccda0f74579009658231b25473651..ddb70e29eb423394c8c124df076eaeb6354c5cfa 100644 --- a/drivers/base/firmware_loader/fallback_table.c +++ b/drivers/base/firmware_loader/fallback_table.c @@ -22,7 +22,7 @@ struct firmware_fallback_config fw_fallback_config = { .loading_timeout = 60, .old_timeout = 60, }; -EXPORT_SYMBOL_NS_GPL(fw_fallback_config, FIRMWARE_LOADER_PRIVATE); +EXPORT_SYMBOL_NS_GPL(fw_fallback_config, "FIRMWARE_LOADER_PRIVATE"); #ifdef CONFIG_SYSCTL static struct ctl_table firmware_config_table[] = { @@ -56,13 +56,13 @@ int register_firmware_config_sysctl(void) return -ENOMEM; return 0; } -EXPORT_SYMBOL_NS_GPL(register_firmware_config_sysctl, FIRMWARE_LOADER_PRIVATE); +EXPORT_SYMBOL_NS_GPL(register_firmware_config_sysctl, "FIRMWARE_LOADER_PRIVATE"); void unregister_firmware_config_sysctl(void) { unregister_sysctl_table(firmware_config_sysct_table_header); firmware_config_sysct_table_header = NULL; } -EXPORT_SYMBOL_NS_GPL(unregister_firmware_config_sysctl, FIRMWARE_LOADER_PRIVATE); +EXPORT_SYMBOL_NS_GPL(unregister_firmware_config_sysctl, "FIRMWARE_LOADER_PRIVATE"); #endif /* CONFIG_SYSCTL */ diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 324a9a3c087aa2e2c4e0b53b30a2f11f61195aa3..cb0912ea3e627e92f2009257314531981a279a92 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -829,19 +829,18 @@ static void fw_log_firmware_info(const struct firmware *fw, const char *name, st shash->tfm = alg; if (crypto_shash_digest(shash, fw->data, fw->size, sha256buf) < 0) - goto out_shash; + goto out_free; for (int i = 0; i < SHA256_DIGEST_SIZE; i++) sprintf(&outbuf[i * 2], "%02x", sha256buf[i]); outbuf[SHA256_BLOCK_SIZE] = 0; dev_dbg(device, "Loaded FW: %s, sha256: %s\n", name, outbuf); -out_shash: - crypto_free_shash(alg); out_free: kfree(shash); kfree(outbuf); kfree(sha256buf); + crypto_free_shash(alg); } #else static void fw_log_firmware_info(const struct firmware *fw, const char *name, @@ -1075,8 +1074,8 @@ EXPORT_SYMBOL_GPL(firmware_request_platform); /** * firmware_request_cache() - cache firmware for suspend so resume can use it - * @name: name of firmware file * @device: device for which firmware should be cached for + * @name: name of firmware file * * There are some devices with an optimization that enables the device to not * require loading firmware on system reboot. This optimization may still diff --git a/drivers/base/firmware_loader/sysfs.h b/drivers/base/firmware_loader/sysfs.h index 2060add8ef81b7e27eeb3a27b0b96d2e46d2f93b..1cabea544a40bc5391e347ceaf02d46381b46318 100644 --- a/drivers/base/firmware_loader/sysfs.h +++ b/drivers/base/firmware_loader/sysfs.h @@ -6,7 +6,7 @@ #include "firmware.h" -MODULE_IMPORT_NS(FIRMWARE_LOADER_PRIVATE); +MODULE_IMPORT_NS("FIRMWARE_LOADER_PRIVATE"); extern struct firmware_fallback_config fw_fallback_config; extern struct device_attribute dev_attr_loading; diff --git a/drivers/base/node.c b/drivers/base/node.c index eb72580288e62727e5b2198a6451cf9c2533225a..0ea653fa34330eb2d89daae455b4b9f101b79f4e 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -27,7 +27,7 @@ static const struct bus_type node_subsys = { }; static inline ssize_t cpumap_read(struct file *file, struct kobject *kobj, - struct bin_attribute *attr, char *buf, + const struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct device *dev = kobj_to_dev(kobj); @@ -45,10 +45,10 @@ static inline ssize_t cpumap_read(struct file *file, struct kobject *kobj, return n; } -static BIN_ATTR_RO(cpumap, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(cpumap, CPUMAP_FILE_MAX_BYTES); static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj, - struct bin_attribute *attr, char *buf, + const struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct device *dev = kobj_to_dev(kobj); @@ -66,7 +66,7 @@ static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj, return n; } -static BIN_ATTR_RO(cpulist, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(cpulist, CPULIST_FILE_MAX_BYTES); /** * struct node_access_nodes - Access class device to hold user visible @@ -578,7 +578,7 @@ static struct attribute *node_dev_attrs[] = { NULL }; -static struct bin_attribute *node_dev_bin_attrs[] = { +static const struct bin_attribute *node_dev_bin_attrs[] = { &bin_attr_cpumap, &bin_attr_cpulist, NULL @@ -586,7 +586,7 @@ static struct bin_attribute *node_dev_bin_attrs[] = { static const struct attribute_group node_dev_group = { .attrs = node_dev_attrs, - .bin_attrs = node_dev_bin_attrs + .bin_attrs_new = node_dev_bin_attrs, }; static const struct attribute_group *node_dev_groups[] = { diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index a1474fb67db9b2f09812b293127730efc6655243..f8163b559bf992718f341a64948471c060843320 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -509,14 +509,6 @@ static ssize_t wakeup_last_time_ms_show(struct device *dev, return sysfs_emit(buf, "%lld\n", msec); } -static inline int dpm_sysfs_wakeup_change_owner(struct device *dev, kuid_t kuid, - kgid_t kgid) -{ - if (dev->power.wakeup && dev->power.wakeup->dev) - return device_change_owner(dev->power.wakeup->dev, kuid, kgid); - return 0; -} - static DEVICE_ATTR_RO(wakeup_last_time_ms); #ifdef CONFIG_PM_AUTOSLEEP @@ -541,6 +533,15 @@ static ssize_t wakeup_prevent_sleep_time_ms_show(struct device *dev, static DEVICE_ATTR_RO(wakeup_prevent_sleep_time_ms); #endif /* CONFIG_PM_AUTOSLEEP */ + +static inline int dpm_sysfs_wakeup_change_owner(struct device *dev, kuid_t kuid, + kgid_t kgid) +{ + if (dev->power.wakeup && dev->power.wakeup->dev) + return device_change_owner(dev->power.wakeup->dev, kuid, kgid); + return 0; +} + #else /* CONFIG_PM_SLEEP */ static inline int dpm_sysfs_wakeup_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 89f98be5c5b9915b2974e184bf89c4c25c183095..cf160dd2c27bd7302bb8d181ca54ec9aa840fe1c 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -23,7 +23,7 @@ static ssize_t name##_show(struct device *dev, \ #define define_siblings_read_func(name, mask) \ static ssize_t name##_read(struct file *file, struct kobject *kobj, \ - struct bin_attribute *attr, char *buf, \ + const struct bin_attribute *attr, char *buf, \ loff_t off, size_t count) \ { \ struct device *dev = kobj_to_dev(kobj); \ @@ -33,7 +33,7 @@ static ssize_t name##_read(struct file *file, struct kobject *kobj, \ } \ \ static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \ - struct bin_attribute *attr, char *buf, \ + const struct bin_attribute *attr, char *buf, \ loff_t off, size_t count) \ { \ struct device *dev = kobj_to_dev(kobj); \ @@ -62,50 +62,50 @@ define_id_show_func(ppin, "0x%llx"); static DEVICE_ATTR_ADMIN_RO(ppin); define_siblings_read_func(thread_siblings, sibling_cpumask); -static BIN_ATTR_RO(thread_siblings, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(thread_siblings_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(thread_siblings, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(thread_siblings_list, CPULIST_FILE_MAX_BYTES); define_siblings_read_func(core_cpus, sibling_cpumask); -static BIN_ATTR_RO(core_cpus, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(core_cpus_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(core_cpus, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(core_cpus_list, CPULIST_FILE_MAX_BYTES); define_siblings_read_func(core_siblings, core_cpumask); -static BIN_ATTR_RO(core_siblings, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(core_siblings_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(core_siblings, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(core_siblings_list, CPULIST_FILE_MAX_BYTES); #ifdef TOPOLOGY_CLUSTER_SYSFS define_siblings_read_func(cluster_cpus, cluster_cpumask); -static BIN_ATTR_RO(cluster_cpus, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(cluster_cpus_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(cluster_cpus, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(cluster_cpus_list, CPULIST_FILE_MAX_BYTES); #endif #ifdef TOPOLOGY_DIE_SYSFS define_siblings_read_func(die_cpus, die_cpumask); -static BIN_ATTR_RO(die_cpus, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(die_cpus_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(die_cpus, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(die_cpus_list, CPULIST_FILE_MAX_BYTES); #endif define_siblings_read_func(package_cpus, core_cpumask); -static BIN_ATTR_RO(package_cpus, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(package_cpus_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(package_cpus, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(package_cpus_list, CPULIST_FILE_MAX_BYTES); #ifdef TOPOLOGY_BOOK_SYSFS define_id_show_func(book_id, "%d"); static DEVICE_ATTR_RO(book_id); define_siblings_read_func(book_siblings, book_cpumask); -static BIN_ATTR_RO(book_siblings, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(book_siblings_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(book_siblings, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(book_siblings_list, CPULIST_FILE_MAX_BYTES); #endif #ifdef TOPOLOGY_DRAWER_SYSFS define_id_show_func(drawer_id, "%d"); static DEVICE_ATTR_RO(drawer_id); define_siblings_read_func(drawer_siblings, drawer_cpumask); -static BIN_ATTR_RO(drawer_siblings, CPUMAP_FILE_MAX_BYTES); -static BIN_ATTR_RO(drawer_siblings_list, CPULIST_FILE_MAX_BYTES); +static const BIN_ATTR_RO(drawer_siblings, CPUMAP_FILE_MAX_BYTES); +static const BIN_ATTR_RO(drawer_siblings_list, CPULIST_FILE_MAX_BYTES); #endif -static struct bin_attribute *bin_attrs[] = { +static const struct bin_attribute *const bin_attrs[] = { &bin_attr_core_cpus, &bin_attr_core_cpus_list, &bin_attr_thread_siblings, @@ -163,7 +163,7 @@ static umode_t topology_is_visible(struct kobject *kobj, static const struct attribute_group topology_attr_group = { .attrs = default_attrs, - .bin_attrs = bin_attrs, + .bin_attrs_new = bin_attrs, .is_visible = topology_is_visible, .name = "topology" }; diff --git a/drivers/base/trace.h b/drivers/base/trace.h index e52b6eae060dde5ca793baa400c5706ca2a9936d..3b83b13a57ff1edfdb0e2a29e3e4dfa4b17936d7 100644 --- a/drivers/base/trace.h +++ b/drivers/base/trace.h @@ -24,18 +24,18 @@ DECLARE_EVENT_CLASS(devres, __field(struct device *, dev) __field(const char *, op) __field(void *, node) - __field(const char *, name) + __string(name, name) __field(size_t, size) ), TP_fast_assign( __assign_str(devname); __entry->op = op; __entry->node = node; - __entry->name = name; + __assign_str(name); __entry->size = size; ), TP_printk("%s %3s %p %s (%zu bytes)", __get_str(devname), - __entry->op, __entry->node, __entry->name, __entry->size) + __entry->op, __entry->node, __get_str(name), __entry->size) ); DEFINE_EVENT(devres, devres_log, diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c index 8ae0b918e74038d00603304f5e4c2e33529fe07d..20b1816c570b235dc61b98ae69482be6808f71be 100644 --- a/drivers/bcma/host_soc.c +++ b/drivers/bcma/host_soc.c @@ -261,7 +261,7 @@ static struct platform_driver bcma_host_soc_driver = { .of_match_table = bcma_host_soc_of_match, }, .probe = bcma_host_soc_probe, - .remove_new = bcma_host_soc_remove, + .remove = bcma_host_soc_remove, }; int __init bcma_host_soc_register_driver(void) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 5a95671d81515c094d46ddae2c347639c7bdfcd8..292f127cae0abe9f5f8dc8165946ddff9e60f99b 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -231,8 +231,10 @@ static void brd_do_discard(struct brd_device *brd, sector_t sector, u32 size) xa_lock(&brd->brd_pages); while (size >= PAGE_SIZE && aligned_sector < rd_size * 2) { page = __xa_erase(&brd->brd_pages, aligned_sector >> PAGE_SECTORS_SHIFT); - if (page) + if (page) { __free_page(page); + brd->brd_nr_pages--; + } aligned_sector += PAGE_SECTORS; size -= PAGE_SIZE; } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index fe9bb4fb5f1ba743b3fd678922d5962ac838cb3d..8f6761c27c68b2a8a2088c2b1b33e85c291fedac 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -770,12 +770,11 @@ static void loop_sysfs_exit(struct loop_device *lo) &loop_attribute_group); } -static void loop_config_discard(struct loop_device *lo, - struct queue_limits *lim) +static void loop_get_discard_config(struct loop_device *lo, + u32 *granularity, u32 *max_discard_sectors) { struct file *file = lo->lo_backing_file; struct inode *inode = file->f_mapping->host; - u32 granularity = 0, max_discard_sectors = 0; struct kstatfs sbuf; /* @@ -788,24 +787,17 @@ static void loop_config_discard(struct loop_device *lo, if (S_ISBLK(inode->i_mode)) { struct block_device *bdev = I_BDEV(inode); - max_discard_sectors = bdev_write_zeroes_sectors(bdev); - granularity = bdev_discard_granularity(bdev); + *max_discard_sectors = bdev_write_zeroes_sectors(bdev); + *granularity = bdev_discard_granularity(bdev); /* * We use punch hole to reclaim the free space used by the * image a.k.a. discard. */ } else if (file->f_op->fallocate && !vfs_statfs(&file->f_path, &sbuf)) { - max_discard_sectors = UINT_MAX >> 9; - granularity = sbuf.f_bsize; + *max_discard_sectors = UINT_MAX >> 9; + *granularity = sbuf.f_bsize; } - - lim->max_hw_discard_sectors = max_discard_sectors; - lim->max_write_zeroes_sectors = max_discard_sectors; - if (max_discard_sectors) - lim->discard_granularity = granularity; - else - lim->discard_granularity = 0; } struct loop_worker { @@ -991,6 +983,7 @@ static int loop_reconfigure_limits(struct loop_device *lo, unsigned int bsize) struct inode *inode = file->f_mapping->host; struct block_device *backing_bdev = NULL; struct queue_limits lim; + u32 granularity = 0, max_discard_sectors = 0; if (S_ISBLK(inode->i_mode)) backing_bdev = I_BDEV(inode); @@ -1000,6 +993,8 @@ static int loop_reconfigure_limits(struct loop_device *lo, unsigned int bsize) if (!bsize) bsize = loop_default_blocksize(lo, backing_bdev); + loop_get_discard_config(lo, &granularity, &max_discard_sectors); + lim = queue_limits_start_update(lo->lo_queue); lim.logical_block_size = bsize; lim.physical_block_size = bsize; @@ -1009,7 +1004,12 @@ static int loop_reconfigure_limits(struct loop_device *lo, unsigned int bsize) lim.features |= BLK_FEAT_WRITE_CACHE; if (backing_bdev && !bdev_nonrot(backing_bdev)) lim.features |= BLK_FEAT_ROTATIONAL; - loop_config_discard(lo, &lim); + lim.max_hw_discard_sectors = max_discard_sectors; + lim.max_write_zeroes_sectors = max_discard_sectors; + if (max_discard_sectors) + lim.discard_granularity = granularity; + else + lim.discard_granularity = 0; return queue_limits_commit_update(lo->lo_queue, &lim); } diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 126f151c4f2cf0e800023f53b958f89cd4fef9ab..be4ac58afe4191e3b172c2a4f1c79e337d830092 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -944,7 +944,7 @@ static void swim_remove(struct platform_device *dev) static struct platform_driver swim_driver = { .probe = swim_probe, - .remove_new = swim_remove, + .remove = swim_remove, .driver = { .name = CARDNAME, }, diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index c6d18cd8af44edbe2677690b8632a49c9d35e8e9..d4aed12dd436be4cdc1d70894ba657503dcf0d94 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -3041,7 +3041,7 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, ret = ublk_ctrl_end_recovery(ub, cmd); break; default: - ret = -ENOTSUPP; + ret = -EOPNOTSUPP; break; } diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c index 88dbb2f3fabf98cdffcd7162f9fbec084ebfbc5c..c0eb71d6ffd3bde03299ea3bd0983129592722ac 100644 --- a/drivers/bluetooth/btqcomsmd.c +++ b/drivers/bluetooth/btqcomsmd.c @@ -216,7 +216,7 @@ MODULE_DEVICE_TABLE(of, btqcomsmd_of_match); static struct platform_driver btqcomsmd_driver = { .probe = btqcomsmd_probe, - .remove_new = btqcomsmd_remove, + .remove = btqcomsmd_remove, .driver = { .name = "btqcomsmd", .of_match_table = btqcomsmd_of_match, diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 521b785f29081a7d99f6a1d81dd5bb333980a892..9684eb16059bb09b3e9ec002354a46b4283cee96 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -1498,7 +1498,7 @@ static const struct dev_pm_ops bcm_pm_ops = { static struct platform_driver bcm_driver = { .probe = bcm_probe, - .remove_new = bcm_remove, + .remove = bcm_remove, .driver = { .name = "hci_bcm", .acpi_match_table = ACPI_PTR(bcm_acpi_match), diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 999ccd5bb4f2485af6290c60ec1cf67fc41cc793..811f33701f847736ac6ac18b435d06c962a33662 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -1206,7 +1206,7 @@ static void intel_remove(struct platform_device *pdev) static struct platform_driver intel_driver = { .probe = intel_probe, - .remove_new = intel_remove, + .remove = intel_remove, .driver = { .name = "hci_intel", .acpi_match_table = ACPI_PTR(intel_acpi_match), diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index dedd29ca8db355ec0c1b9673f5c8a7f606451d83..e8c92972f9df92bc836e9608a2401b64b35ecc5a 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -82,9 +82,9 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) * other cores to shutdown while we're collecting RDDM buffer. After * returning from this function, we expect the device to reset. * - * Normaly, we read/write pm_state only after grabbing the + * Normally, we read/write pm_state only after grabbing the * pm_lock, since we're in a panic, skipping it. Also there is no - * gurantee that this state change would take effect since + * guarantee that this state change would take effect since * we're setting it w/o grabbing pm_lock */ mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT; diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index d057e877932e3a0e7eab5ef08545257bf09e6a27..3134f111be3533afdb6d4af74b749dab91821ecd 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -255,7 +255,7 @@ struct mhi_chan { /* * Important: When consuming, increment tre_ring first and when * releasing, decrement buf_ring first. If tre_ring has space, buf_ring - * is guranteed to have space so we do not need to check both rings. + * is guaranteed to have space so we do not need to check both rings. */ struct mhi_ring buf_ring; struct mhi_ring tre_ring; diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index 9938bb034c1cbc2c3a1a2b9409a7d35a9efe68f9..07645ce2119a71c9277356e962252b840379cd81 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -917,12 +917,12 @@ static int mhi_pci_claim(struct mhi_controller *mhi_cntrl, return err; } - err = pcim_iomap_regions(pdev, 1 << bar_num, pci_name(pdev)); - if (err) { + mhi_cntrl->regs = pcim_iomap_region(pdev, 1 << bar_num, pci_name(pdev)); + if (IS_ERR(mhi_cntrl->regs)) { + err = PTR_ERR(mhi_cntrl->regs); dev_err(&pdev->dev, "failed to map pci region: %d\n", err); return err; } - mhi_cntrl->regs = pcim_iomap_table(pdev)[bar_num]; mhi_cntrl->reg_len = pci_resource_len(pdev, bar_num); err = dma_set_mask_and_coherent(&pdev->dev, dma_mask); diff --git a/drivers/bus/mhi/host/trace.h b/drivers/bus/mhi/host/trace.h index 95613c8ebe0691724d2ea7f87a38874410a0a683..3e0c41777429eb9718bddac8860a6182d933cc77 100644 --- a/drivers/bus/mhi/host/trace.h +++ b/drivers/bus/mhi/host/trace.h @@ -9,6 +9,7 @@ #if !defined(_TRACE_EVENT_MHI_HOST_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_EVENT_MHI_HOST_H +#include #include #include #include "../common.h" @@ -97,18 +98,18 @@ TRACE_EVENT(mhi_gen_tre, __string(name, mhi_cntrl->mhi_dev->name) __field(int, ch_num) __field(void *, wp) - __field(__le64, tre_ptr) - __field(__le32, dword0) - __field(__le32, dword1) + __field(uint64_t, tre_ptr) + __field(uint32_t, dword0) + __field(uint32_t, dword1) ), TP_fast_assign( __assign_str(name); __entry->ch_num = mhi_chan->chan; __entry->wp = mhi_tre; - __entry->tre_ptr = mhi_tre->ptr; - __entry->dword0 = mhi_tre->dword[0]; - __entry->dword1 = mhi_tre->dword[1]; + __entry->tre_ptr = le64_to_cpu(mhi_tre->ptr); + __entry->dword0 = le32_to_cpu(mhi_tre->dword[0]); + __entry->dword1 = le32_to_cpu(mhi_tre->dword[1]); ), TP_printk("%s: Chan: %d TRE: 0x%p TRE buf: 0x%llx DWORD0: 0x%08x DWORD1: 0x%08x\n", @@ -176,19 +177,19 @@ DECLARE_EVENT_CLASS(mhi_process_event_ring, TP_STRUCT__entry( __string(name, mhi_cntrl->mhi_dev->name) - __field(__le32, dword0) - __field(__le32, dword1) + __field(uint32_t, dword0) + __field(uint32_t, dword1) __field(int, state) - __field(__le64, ptr) + __field(uint64_t, ptr) __field(void *, rp) ), TP_fast_assign( __assign_str(name); __entry->rp = rp; - __entry->ptr = rp->ptr; - __entry->dword0 = rp->dword[0]; - __entry->dword1 = rp->dword[1]; + __entry->ptr = le64_to_cpu(rp->ptr); + __entry->dword0 = le32_to_cpu(rp->dword[0]); + __entry->dword1 = le32_to_cpu(rp->dword[1]); __entry->state = MHI_TRE_GET_EV_STATE(rp); ), diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 71cfe7a85913c4a39a3f96710ad6ddaaf43838b2..64b097e830d464d74c6940db4c26c0a88493a000 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -847,7 +847,7 @@ static void remove_gdrom(struct platform_device *devptr) static struct platform_driver gdrom_driver = { .probe = probe_gdrom, - .remove_new = remove_gdrom, + .remove = remove_gdrom, .driver = { .name = GDROM_DEV_NAME, }, diff --git a/drivers/cdx/Makefile b/drivers/cdx/Makefile index 749a3295c2bdc130f4bc1929bc339fbc29de1046..3ca7068a305256dc30691cfd469fce94da873186 100644 --- a/drivers/cdx/Makefile +++ b/drivers/cdx/Makefile @@ -5,7 +5,7 @@ # Copyright (C) 2022-2023, Advanced Micro Devices, Inc. # -ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CDX_BUS +ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"CDX_BUS"' obj-$(CONFIG_CDX_BUS) += cdx.o controller/ diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c index 07371cb653d356977cbd3dd99a1b848146d5a993..76eac3653b1c64d358b898e48c8d6f5f22db2c6e 100644 --- a/drivers/cdx/cdx.c +++ b/drivers/cdx/cdx.c @@ -707,7 +707,7 @@ static const struct vm_operations_struct cdx_phys_vm_ops = { * Return: true on success, false otherwise. */ static int cdx_mmap_resource(struct file *fp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { struct cdx_device *cdx_dev = to_cdx_device(kobj_to_dev(kobj)); @@ -868,7 +868,7 @@ fail: return ret; } -EXPORT_SYMBOL_NS_GPL(cdx_device_add, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_device_add, "CDX_BUS_CONTROLLER"); struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num) { @@ -915,7 +915,7 @@ device_add_fail: return NULL; } -EXPORT_SYMBOL_NS_GPL(cdx_bus_add, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_bus_add, "CDX_BUS_CONTROLLER"); int cdx_register_controller(struct cdx_controller *cdx) { @@ -940,7 +940,7 @@ int cdx_register_controller(struct cdx_controller *cdx) return 0; } -EXPORT_SYMBOL_NS_GPL(cdx_register_controller, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_register_controller, "CDX_BUS_CONTROLLER"); void cdx_unregister_controller(struct cdx_controller *cdx) { @@ -955,7 +955,7 @@ void cdx_unregister_controller(struct cdx_controller *cdx) mutex_unlock(&cdx_controller_lock); } -EXPORT_SYMBOL_NS_GPL(cdx_unregister_controller, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_unregister_controller, "CDX_BUS_CONTROLLER"); static int __init cdx_bus_init(void) { diff --git a/drivers/cdx/cdx_msi.c b/drivers/cdx/cdx_msi.c index e55f1716cfcb20c23b16c71082e396dd56dab4a1..06d7239782327b99816b85aeeaaee3b6475d20a0 100644 --- a/drivers/cdx/cdx_msi.c +++ b/drivers/cdx/cdx_msi.c @@ -189,4 +189,4 @@ struct irq_domain *cdx_msi_domain_init(struct device *dev) return cdx_msi_domain; } -EXPORT_SYMBOL_NS_GPL(cdx_msi_domain_init, CDX_BUS_CONTROLLER); +EXPORT_SYMBOL_NS_GPL(cdx_msi_domain_init, "CDX_BUS_CONTROLLER"); diff --git a/drivers/cdx/controller/cdx_controller.c b/drivers/cdx/controller/cdx_controller.c index 201f9a6fbde702691d6c1cf53e2bdef1cf507f28..d623f9c7517a86c06082c0db348688e7f33b7be6 100644 --- a/drivers/cdx/controller/cdx_controller.c +++ b/drivers/cdx/controller/cdx_controller.c @@ -250,7 +250,7 @@ static struct platform_driver cdx_pdriver = { .of_match_table = cdx_match_table, }, .probe = xlnx_cdx_probe, - .remove_new = xlnx_cdx_remove, + .remove = xlnx_cdx_remove, }; static int __init cdx_controller_init(void) @@ -275,4 +275,4 @@ module_exit(cdx_controller_exit); MODULE_AUTHOR("AMD Inc."); MODULE_DESCRIPTION("CDX controller for AMD devices"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CDX_BUS_CONTROLLER); +MODULE_IMPORT_NS("CDX_BUS_CONTROLLER"); diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c index b8b9c07d3b5de91815d533616635801bdf9d5ff3..009e32033b174df7a4a76b4727ba4a2f3a81ead3 100644 --- a/drivers/char/ipmi/bt-bmc.c +++ b/drivers/char/ipmi/bt-bmc.c @@ -481,7 +481,7 @@ static struct platform_driver bt_bmc_driver = { .of_match_table = bt_bmc_match, }, .probe = bt_bmc_probe, - .remove_new = bt_bmc_remove, + .remove = bt_bmc_remove, }; module_platform_driver(bt_bmc_driver); diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c index c59a86eb58c7ba3fba03dd6a130bab84ff63552a..4a2efafcd1f85537ba2ef46ce00237bda8bdecd3 100644 --- a/drivers/char/ipmi/ipmi_powernv.c +++ b/drivers/char/ipmi/ipmi_powernv.c @@ -302,7 +302,7 @@ static struct platform_driver powernv_ipmi_driver = { .of_match_table = ipmi_powernv_match, }, .probe = ipmi_powernv_probe, - .remove_new = ipmi_powernv_remove, + .remove = ipmi_powernv_remove, }; diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c index 96ba85648120d4d1ee4a97de5d1f805dd34d336b..550cabd43ae61658ccb94d48068b72fc8f2c799d 100644 --- a/drivers/char/ipmi/ipmi_si_platform.c +++ b/drivers/char/ipmi/ipmi_si_platform.c @@ -445,7 +445,7 @@ struct platform_driver ipmi_platform_driver = { .acpi_match_table = ACPI_PTR(acpi_ipmi_match), }, .probe = ipmi_probe, - .remove_new = ipmi_remove, + .remove = ipmi_remove, .id_table = si_plat_ids }; diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index d04b391048fbaa9e0a5dae6facdaa8ade784efac..506d9988721efb527de2470f5b73ba675188c84a 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -2114,7 +2114,7 @@ static struct platform_driver ipmi_driver = { .name = DEVICE_NAME, }, .probe = ssif_platform_probe, - .remove_new = ssif_platform_remove, + .remove = ssif_platform_remove, .id_table = ssif_plat_ids }; diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index 227bf06c7ca4920ae65cc8d8c16772d9da1bd84c..c03bc1ec593ad9f7d0a47c5de448a2aaabf25876 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -672,7 +672,7 @@ static struct platform_driver ast_kcs_bmc_driver = { .of_match_table = ast_kcs_bmc_match, }, .probe = aspeed_kcs_probe, - .remove_new = aspeed_kcs_remove, + .remove = aspeed_kcs_remove, }; module_platform_driver(ast_kcs_bmc_driver); diff --git a/drivers/char/ipmi/kcs_bmc_npcm7xx.c b/drivers/char/ipmi/kcs_bmc_npcm7xx.c index 07710198233a2f09439e5153cf68e3920144fe0e..4808a61bf273d3f36ba9d41e118ec42f216a5b6e 100644 --- a/drivers/char/ipmi/kcs_bmc_npcm7xx.c +++ b/drivers/char/ipmi/kcs_bmc_npcm7xx.c @@ -241,7 +241,7 @@ static struct platform_driver npcm_kcs_bmc_driver = { .of_match_table = npcm_kcs_bmc_match, }, .probe = npcm7xx_kcs_probe, - .remove_new = npcm7xx_kcs_remove, + .remove = npcm7xx_kcs_remove, }; module_platform_driver(npcm_kcs_bmc_driver); diff --git a/drivers/char/powernv-op-panel.c b/drivers/char/powernv-op-panel.c index f2cff1a6fed520d1dce659e8ab348524f0dba8ee..53467b0a6187f5c2769b2165d8a085fd59559149 100644 --- a/drivers/char/powernv-op-panel.c +++ b/drivers/char/powernv-op-panel.c @@ -213,7 +213,7 @@ static struct platform_driver oppanel_driver = { .of_match_table = oppanel_match, }, .probe = oppanel_probe, - .remove_new = oppanel_remove, + .remove = oppanel_remove, }; module_platform_driver(oppanel_driver); diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 0f8185e541ed478d359a64f8f533fd8ddcc8cd93..f887569fd3d0f0e9102a69692df519dd30a43976 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1467,7 +1467,7 @@ static struct platform_driver sonypi_driver = { .pm = SONYPI_PM, }, .probe = sonypi_probe, - .remove_new = sonypi_remove, + .remove = sonypi_remove, .shutdown = sonypi_shutdown, }; diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c index 2ea4882251cf7fe87a32bd8a0135a68f549ff42b..139556b21cc6493d10ea7fdde49183a1517a2c54 100644 --- a/drivers/char/tpm/tpm_ftpm_tee.c +++ b/drivers/char/tpm/tpm_ftpm_tee.c @@ -366,7 +366,7 @@ static struct platform_driver ftpm_tee_plat_driver = { }, .shutdown = ftpm_plat_tee_shutdown, .probe = ftpm_plat_tee_probe, - .remove_new = ftpm_plat_tee_remove, + .remove = ftpm_plat_tee_remove, }; /* UUID of the fTPM TA */ diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 2f7326d297adb99102625306ba56c79c316190b2..9aa230a6361662435e00d3a5c260e788665670ae 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -356,7 +356,7 @@ MODULE_DEVICE_TABLE(of, tis_of_platform_match); static struct platform_driver tis_drv = { .probe = tpm_tis_plat_probe, - .remove_new = tpm_tis_plat_remove, + .remove = tpm_tis_plat_remove, .driver = { .name = "tpm_tis", .pm = &tpm_tis_pm, diff --git a/drivers/char/tpm/tpm_tis_synquacer.c b/drivers/char/tpm/tpm_tis_synquacer.c index 0621ebec530b479b6b7a7bcb7f6f73cac191f833..4927714d277a1232533079482c42e507f5d03492 100644 --- a/drivers/char/tpm/tpm_tis_synquacer.c +++ b/drivers/char/tpm/tpm_tis_synquacer.c @@ -152,7 +152,7 @@ MODULE_DEVICE_TABLE(acpi, tpm_synquacer_acpi_tbl); static struct platform_driver tis_synquacer_drv = { .probe = tpm_tis_synquacer_probe, - .remove_new = tpm_tis_synquacer_remove, + .remove = tpm_tis_synquacer_remove, .driver = { .name = "tpm_tis_synquacer", .pm = &tpm_tis_synquacer_pm, diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 4f6c3cb8aa4138e6948d7b5971595d0dd4de07b7..34a345dc5e724df5b20bd52caab12bc85aba5c8c 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -738,7 +738,7 @@ MODULE_DEVICE_TABLE(of, hwicap_of_match); static struct platform_driver hwicap_platform_driver = { .probe = hwicap_drv_probe, - .remove_new = hwicap_drv_remove, + .remove = hwicap_drv_remove, .driver = { .name = DRIVER_NAME, .of_match_table = hwicap_of_match, diff --git a/drivers/char/xillybus/xillybus_of.c b/drivers/char/xillybus/xillybus_of.c index 8802e2a6fd20b779dfafa1708ad25cb109327843..1a1e64133315bc0fbfa12e66944c3bc97c6ca1cc 100644 --- a/drivers/char/xillybus/xillybus_of.c +++ b/drivers/char/xillybus/xillybus_of.c @@ -74,7 +74,7 @@ static void xilly_drv_remove(struct platform_device *op) static struct platform_driver xillybus_platform_driver = { .probe = xilly_drv_probe, - .remove_new = xilly_drv_remove, + .remove = xilly_drv_remove, .driver = { .name = xillyname, .of_match_table = xillybus_of_match, diff --git a/drivers/clk/meson/a1-peripherals.c b/drivers/clk/meson/a1-peripherals.c index 7aa6abb2eb1f2b804916d5c2515eefc15149433d..36489e0f948a544d7ef95bc34381b83b2bee30b4 100644 --- a/drivers/clk/meson/a1-peripherals.c +++ b/drivers/clk/meson/a1-peripherals.c @@ -2246,4 +2246,4 @@ MODULE_DESCRIPTION("Amlogic A1 Peripherals Clock Controller driver"); MODULE_AUTHOR("Jian Hu "); MODULE_AUTHOR("Dmitry Rokosov "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c index 8e5a42d1afbbcd82341a5dcdd19b9f352e725e91..8d7c7b4493c4069bbceb5e04a7f1e312931d119b 100644 --- a/drivers/clk/meson/a1-pll.c +++ b/drivers/clk/meson/a1-pll.c @@ -360,4 +360,4 @@ MODULE_DESCRIPTION("Amlogic S4 PLL Clock Controller driver"); MODULE_AUTHOR("Jian Hu "); MODULE_AUTHOR("Dmitry Rokosov "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c index 1dabc81535a6f77a6420f075f1bbef8ab8b31fd2..f44091ffb57d93c624049b2ced878ede5540e246 100644 --- a/drivers/clk/meson/axg-aoclk.c +++ b/drivers/clk/meson/axg-aoclk.c @@ -342,4 +342,4 @@ module_platform_driver(axg_aoclkc_driver); MODULE_DESCRIPTION("Amlogic AXG Always-ON Clock Controller driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 7714bde5ffc038a7a36d267a7149bc9f4e820be2..7a3460804424456bf275e9dd4a1d9014c81a7bec 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -1821,4 +1821,4 @@ module_platform_driver(axg_audio_driver); MODULE_DESCRIPTION("Amlogic AXG/G12A/SM1 Audio Clock driver"); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 1b08daf579b2e57c4f618ce13d10206330fdce3e..448eece246ca752da576d257b33f822ec92f4192 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -2181,4 +2181,4 @@ module_platform_driver(axg_driver); MODULE_DESCRIPTION("Amlogic AXG Main Clock Controller driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c index 7dcbf4ebee078abaebc28c666c6ffe8160d8d7e5..2075668ed3062e8957f2a79049ea5c56a61ba867 100644 --- a/drivers/clk/meson/c3-peripherals.c +++ b/drivers/clk/meson/c3-peripherals.c @@ -2364,4 +2364,4 @@ module_platform_driver(c3_peripherals_driver); MODULE_DESCRIPTION("Amlogic C3 Peripherals Clock Controller driver"); MODULE_AUTHOR("Chuan Liu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c index 35fda31a19e218bb6db71346a264ec20e832382c..ed4bc495862e1a1f49e2026979d7f5be5caaf2c0 100644 --- a/drivers/clk/meson/c3-pll.c +++ b/drivers/clk/meson/c3-pll.c @@ -746,4 +746,4 @@ module_platform_driver(c3_pll_driver); MODULE_DESCRIPTION("Amlogic C3 PLL Clock Controller driver"); MODULE_AUTHOR("Chuan Liu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/clk-cpu-dyndiv.c b/drivers/clk/meson/clk-cpu-dyndiv.c index 6c1f58826e24a2bf7706f0fc98cdcdb44fd60b64..cb043b52b65d8a6ae0933935f07fb14c40855700 100644 --- a/drivers/clk/meson/clk-cpu-dyndiv.c +++ b/drivers/clk/meson/clk-cpu-dyndiv.c @@ -65,9 +65,9 @@ const struct clk_ops meson_clk_cpu_dyndiv_ops = { .determine_rate = meson_clk_cpu_dyndiv_determine_rate, .set_rate = meson_clk_cpu_dyndiv_set_rate, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_cpu_dyndiv_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_cpu_dyndiv_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider"); MODULE_AUTHOR("Neil Armstrong "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/clk-dualdiv.c b/drivers/clk/meson/clk-dualdiv.c index 913bf25d3771bdffa8db28e9b08dc566d1aac1ff..c896cf29b318ca3debf7447a9c44be01523abe47 100644 --- a/drivers/clk/meson/clk-dualdiv.c +++ b/drivers/clk/meson/clk-dualdiv.c @@ -130,15 +130,15 @@ const struct clk_ops meson_clk_dualdiv_ops = { .determine_rate = meson_clk_dualdiv_determine_rate, .set_rate = meson_clk_dualdiv_set_rate, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ops, "CLK_MESON"); const struct clk_ops meson_clk_dualdiv_ro_ops = { .recalc_rate = meson_clk_dualdiv_recalc_rate, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ro_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ro_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic dual divider driver"); MODULE_AUTHOR("Neil Armstrong "); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c index aa9abd06ae653585f68043bb1ddc2b0b96feeb6d..ee91e32b4050bf40cf6f19c8152ae11c2ab4ec11 100644 --- a/drivers/clk/meson/clk-mpll.c +++ b/drivers/clk/meson/clk-mpll.c @@ -154,7 +154,7 @@ const struct clk_ops meson_clk_mpll_ro_ops = { .recalc_rate = mpll_recalc_rate, .determine_rate = mpll_determine_rate, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_mpll_ro_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_mpll_ro_ops, "CLK_MESON"); const struct clk_ops meson_clk_mpll_ops = { .recalc_rate = mpll_recalc_rate, @@ -162,9 +162,9 @@ const struct clk_ops meson_clk_mpll_ops = { .set_rate = mpll_set_rate, .init = mpll_init, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_mpll_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_mpll_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic MPLL driver"); MODULE_AUTHOR("Michael Turquette "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/clk-phase.c b/drivers/clk/meson/clk-phase.c index c1526fbfb6c4ccdd4034df465f70a56e0f9214ac..7012111206107a25ca77a5c51cb5b19d9755f3c1 100644 --- a/drivers/clk/meson/clk-phase.c +++ b/drivers/clk/meson/clk-phase.c @@ -61,7 +61,7 @@ const struct clk_ops meson_clk_phase_ops = { .get_phase = meson_clk_phase_get_phase, .set_phase = meson_clk_phase_set_phase, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_phase_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_phase_ops, "CLK_MESON"); /* * This is a special clock for the audio controller. @@ -123,7 +123,7 @@ const struct clk_ops meson_clk_triphase_ops = { .get_phase = meson_clk_triphase_get_phase, .set_phase = meson_clk_triphase_set_phase, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_triphase_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_triphase_ops, "CLK_MESON"); /* * This is a special clock for the audio controller. @@ -178,9 +178,9 @@ const struct clk_ops meson_sclk_ws_inv_ops = { .get_phase = meson_sclk_ws_inv_get_phase, .set_phase = meson_sclk_ws_inv_set_phase, }; -EXPORT_SYMBOL_NS_GPL(meson_sclk_ws_inv_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_sclk_ws_inv_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic phase driver"); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 89f0f04a16abad99748e1ff3784e7ed91abd0f88..e8e53855b00a81bc8eaa4213173948c964debc8a 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -474,7 +474,7 @@ const struct clk_ops meson_clk_pcie_pll_ops = { .enable = meson_clk_pcie_pll_enable, .disable = meson_clk_pll_disable }; -EXPORT_SYMBOL_NS_GPL(meson_clk_pcie_pll_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_pcie_pll_ops, "CLK_MESON"); const struct clk_ops meson_clk_pll_ops = { .init = meson_clk_pll_init, @@ -485,16 +485,16 @@ const struct clk_ops meson_clk_pll_ops = { .enable = meson_clk_pll_enable, .disable = meson_clk_pll_disable }; -EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ops, "CLK_MESON"); const struct clk_ops meson_clk_pll_ro_ops = { .recalc_rate = meson_clk_pll_recalc_rate, .is_enabled = meson_clk_pll_is_enabled, }; -EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ro_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ro_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic PLL driver"); MODULE_AUTHOR("Carlo Caione "); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c index 07f7e441b9161c47fdb38ec61ed162a2f9d4fe41..f3e504f6757152868e60d5a9fac5c5e5bf3e2e56 100644 --- a/drivers/clk/meson/clk-regmap.c +++ b/drivers/clk/meson/clk-regmap.c @@ -49,12 +49,12 @@ const struct clk_ops clk_regmap_gate_ops = { .disable = clk_regmap_gate_disable, .is_enabled = clk_regmap_gate_is_enabled, }; -EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ops, "CLK_MESON"); const struct clk_ops clk_regmap_gate_ro_ops = { .is_enabled = clk_regmap_gate_is_enabled, }; -EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ro_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ro_ops, "CLK_MESON"); static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw, unsigned long prate) @@ -125,13 +125,13 @@ const struct clk_ops clk_regmap_divider_ops = { .determine_rate = clk_regmap_div_determine_rate, .set_rate = clk_regmap_div_set_rate, }; -EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ops, "CLK_MESON"); const struct clk_ops clk_regmap_divider_ro_ops = { .recalc_rate = clk_regmap_div_recalc_rate, .determine_rate = clk_regmap_div_determine_rate, }; -EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ro_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ro_ops, "CLK_MESON"); static u8 clk_regmap_mux_get_parent(struct clk_hw *hw) { @@ -174,14 +174,14 @@ const struct clk_ops clk_regmap_mux_ops = { .set_parent = clk_regmap_mux_set_parent, .determine_rate = clk_regmap_mux_determine_rate, }; -EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ops, "CLK_MESON"); const struct clk_ops clk_regmap_mux_ro_ops = { .get_parent = clk_regmap_mux_get_parent, }; -EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ro_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ro_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic regmap backed clock driver"); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/g12a-aoclk.c b/drivers/clk/meson/g12a-aoclk.c index f0a18d8c9fc2318d04dde0e63b4a53d0e1f88db5..71c758ffa4934d984a73012b37e43833de953637 100644 --- a/drivers/clk/meson/g12a-aoclk.c +++ b/drivers/clk/meson/g12a-aoclk.c @@ -477,4 +477,4 @@ module_platform_driver(g12a_aoclkc_driver); MODULE_DESCRIPTION("Amlogic G12A Always-ON Clock Controller driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index d3539fe9f7af5538201a78ce560f662ddb3935f2..cfffd434e998ef2dbb0d15627aca3eff4aba9b9e 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -5610,4 +5610,4 @@ module_platform_driver(g12a_driver); MODULE_DESCRIPTION("Amlogic G12/SM1 Main Clock Controller driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 83b034157b3534dd157c6cc2b0ae5ba320197400..43940232f7180262d458f1914f94b1bc3dc5e20e 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -303,4 +303,4 @@ module_platform_driver(gxbb_aoclkc_driver); MODULE_DESCRIPTION("Amlogic GXBB Always-ON Clock Controller driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 262c318edbd512239b79e5ad26643ae6c7b0173b..8575b848538598fcd5b7f4504fd6be48037a2743 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -3565,4 +3565,4 @@ module_platform_driver(gxbb_driver); MODULE_DESCRIPTION("Amlogic GXBB Main Clock Controller driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index 053940ee8940d7ca785ad89f026071244e247d7f..995be51987f4821311f9db6606547352d9235c57 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -88,8 +88,8 @@ int meson_aoclkc_probe(struct platform_device *pdev) return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, (void *)&data->hw_clks); } -EXPORT_SYMBOL_NS_GPL(meson_aoclkc_probe, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_aoclkc_probe, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic Always-ON Clock Controller helpers"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/meson-clkc-utils.c b/drivers/clk/meson/meson-clkc-utils.c index a8cd2c21fab77f6d32f527624f4b838b9932c5b5..6937d1482719bda00da127381025a165907e5db6 100644 --- a/drivers/clk/meson/meson-clkc-utils.c +++ b/drivers/clk/meson/meson-clkc-utils.c @@ -20,8 +20,8 @@ struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_da return data->hws[idx]; } -EXPORT_SYMBOL_NS_GPL(meson_clk_hw_get, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_clk_hw_get, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic Clock Controller Utilities"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c index 66f79e384fe5118dcbf6b29daf2b20e01fee9934..3053ee7425eb5cccaa8430b1b67e5cbb43af4d2e 100644 --- a/drivers/clk/meson/meson-eeclk.c +++ b/drivers/clk/meson/meson-eeclk.c @@ -57,8 +57,8 @@ int meson_eeclkc_probe(struct platform_device *pdev) return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, (void *)&data->hw_clks); } -EXPORT_SYMBOL_NS_GPL(meson_eeclkc_probe, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_eeclkc_probe, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic Main Clock Controller Helpers"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c index c930cf0614a0f4250a712dc20ce8e8a0ed812e6d..8a403737778749cdd9ded56c5134a1a081671e42 100644 --- a/drivers/clk/meson/s4-peripherals.c +++ b/drivers/clk/meson/s4-peripherals.c @@ -3814,4 +3814,4 @@ module_platform_driver(s4_driver); MODULE_DESCRIPTION("Amlogic S4 Peripherals Clock Controller driver"); MODULE_AUTHOR("Yu Tu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/s4-pll.c b/drivers/clk/meson/s4-pll.c index d8e621e794281a14cdbc90e1990f677a087771ef..f9cc05a506e3952ca37b851a3acff04bbe090499 100644 --- a/drivers/clk/meson/s4-pll.c +++ b/drivers/clk/meson/s4-pll.c @@ -872,4 +872,4 @@ module_platform_driver(s4_driver); MODULE_DESCRIPTION("Amlogic S4 PLL Clock Controller driver"); MODULE_AUTHOR("Yu Tu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c index ae03b048182f3bbaf4a7e86b605fb4fb37b9cfd5..9c4945234f2682ea4c4e9c2fc2158fe37dc46f74 100644 --- a/drivers/clk/meson/sclk-div.c +++ b/drivers/clk/meson/sclk-div.c @@ -247,9 +247,9 @@ const struct clk_ops meson_sclk_div_ops = { .set_duty_cycle = sclk_div_set_duty_cycle, .init = sclk_div_init, }; -EXPORT_SYMBOL_NS_GPL(meson_sclk_div_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_sclk_div_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic Sample divider driver"); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/vclk.c b/drivers/clk/meson/vclk.c index 36f637d2d01b5d86bf5d85196643ad9d66c6f19b..6a167ebdc8d74b9e5371100c6461ae395b7cc8af 100644 --- a/drivers/clk/meson/vclk.c +++ b/drivers/clk/meson/vclk.c @@ -49,7 +49,7 @@ const struct clk_ops meson_vclk_gate_ops = { .disable = meson_vclk_gate_disable, .is_enabled = meson_vclk_gate_is_enabled, }; -EXPORT_SYMBOL_NS_GPL(meson_vclk_gate_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_vclk_gate_ops, "CLK_MESON"); /* The VCLK Divider has supplementary reset & enable bits */ @@ -134,9 +134,9 @@ const struct clk_ops meson_vclk_div_ops = { .disable = meson_vclk_div_disable, .is_enabled = meson_vclk_div_is_enabled, }; -EXPORT_SYMBOL_NS_GPL(meson_vclk_div_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_vclk_div_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic vclk clock driver"); MODULE_AUTHOR("Neil Armstrong "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/vid-pll-div.c b/drivers/clk/meson/vid-pll-div.c index 486cf68fc97a0205ee5139056b1eabc6e743ff35..965ed7281f57edf3c5d550dfdbe0c61b016e4684 100644 --- a/drivers/clk/meson/vid-pll-div.c +++ b/drivers/clk/meson/vid-pll-div.c @@ -92,9 +92,9 @@ static unsigned long meson_vid_pll_div_recalc_rate(struct clk_hw *hw, const struct clk_ops meson_vid_pll_div_ro_ops = { .recalc_rate = meson_vid_pll_div_recalc_rate, }; -EXPORT_SYMBOL_NS_GPL(meson_vid_pll_div_ro_ops, CLK_MESON); +EXPORT_SYMBOL_NS_GPL(meson_vid_pll_div_ro_ops, "CLK_MESON"); MODULE_DESCRIPTION("Amlogic video pll divider driver"); MODULE_AUTHOR("Neil Armstrong "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CLK_MESON); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index 28ec0da88cb3897338868ebeb4f8ae5dc3d2e604..c22632a7439c5d2352d2bcbe960398eda531fd0c 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -443,4 +443,4 @@ MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Driver"); MODULE_AUTHOR("Padmarao Begari "); MODULE_AUTHOR("Daire McNamara "); MODULE_AUTHOR("Conor Dooley "); -MODULE_IMPORT_NS(MCHP_CLK_MPFS); +MODULE_IMPORT_NS("MCHP_CLK_MPFS"); diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c b/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c index 4084714adb15b01eed1eb53ebb9eed9bc85e29ed..44b2ebdebdac4904405058f869d42168cdc9e9f5 100644 --- a/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c @@ -137,6 +137,6 @@ static struct platform_driver sun20i_d1_r_ccu_driver = { }; module_platform_driver(sun20i_d1_r_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner D1/R528/T113 PRCM CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c index c80ac2dfbb60c3212d6f75ffd84221b1f73546d4..bb66c906ebbb62fe8af1fbae3ebe1a324dfa9a4e 100644 --- a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c +++ b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c @@ -1406,6 +1406,6 @@ static struct platform_driver sun20i_d1_ccu_driver = { }; module_platform_driver(sun20i_d1_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner D1/R528/T113 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c index 54c794c508286e31ff5b1cf3e8e9eb0084c6f973..409feb085021faf0ca4336171d0e9ae861d85288 100644 --- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c @@ -1493,6 +1493,6 @@ static struct platform_driver sun4i_a10_ccu_driver = { }; module_platform_driver(sun4i_a10_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A10/A20 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c index cdd9721f9e7d65c1fdcb8534252d236d8cd21309..cb0f8d110c3204be6fa58bf8bf427b9ca876516a 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c @@ -214,6 +214,6 @@ static struct platform_driver sun50i_a100_r_ccu_driver = { }; module_platform_driver(sun50i_a100_r_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A100 PRCM CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c index 1b6a49bc718459f9593fd2266b082434cfc3e5bd..7133377d41630f20eb7fd3ae144fac302bb63ec4 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c @@ -1276,6 +1276,6 @@ static struct platform_driver sun50i_a100_ccu_driver = { }; module_platform_driver(sun50i_a100_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A100 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 82d7dcbca1cc94cd89c7ce4eca21554acbe98aa3..3a7d61c816672d9e6f538390b04a0caa8fc9395f 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -994,6 +994,6 @@ static struct platform_driver sun50i_a64_ccu_driver = { }; module_platform_driver(sun50i_a64_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A64 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c index d0ce2779c55085a2546bc1fb489ad9fa964dcfeb..acb4e8b9b1bae9b902e9fd414e2d91004aa73b10 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c @@ -256,6 +256,6 @@ static struct platform_driver sun50i_h6_r_ccu_driver = { }; module_platform_driver(sun50i_h6_r_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner H6 and H616 PRCM CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index bd6fc3df911d792ecd77e86613221c83ae9b54c9..7fccda96d4449f01ff643c29e7eeb4b696fc9513 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -1286,6 +1286,6 @@ static struct platform_driver sun50i_h6_ccu_driver = { }; module_platform_driver(sun50i_h6_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner H6 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c index b001d0c03534f97b9cea8100066ee8e1d53b5132..1086669b91da660780bfa89b58c9c9586c6d2979 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c @@ -1185,6 +1185,6 @@ static struct platform_driver sun50i_h616_ccu_driver = { }; module_platform_driver(sun50i_h616_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner H616 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index c2ad1209633ee85e8d1efd5ad221324031dd019d..bab65cfe9501d778696cc45d1c29d7c3f1acebd9 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c @@ -1283,6 +1283,6 @@ static struct platform_driver sun6i_a31_ccu_driver = { }; module_platform_driver(sun6i_a31_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A31/A31s CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c index 724b202863a81e9c208e6aa9d4fc97fc1064ec54..0536e880b80fe19453fb1594606ecbb2b0c5f449 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c @@ -381,6 +381,6 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg) return devm_sunxi_ccu_probe(dev, reg, &sun6i_rtc_ccu_desc); } -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner H616/R329 RTC CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c index 9433dbac038e16a2f1bf8dbc30ddfcfd6568b0ee..78cf3818ab09a5579b5909400f6c1577d4d75000 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c @@ -763,6 +763,6 @@ static struct platform_driver sun8i_a23_ccu_driver = { }; module_platform_driver(sun8i_a23_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A23 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index 1ffc5ab9bc3cbab036ef44f49e0c17319a54b7dd..b039d419512ce81060e62d2f921cb3453ecff812 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c @@ -835,6 +835,6 @@ static struct platform_driver sun8i_a33_ccu_driver = { }; module_platform_driver(sun8i_a33_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A33 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c index a51fb2c10c94256efc52483c82af6a87ca938446..60e918965a720814bf1f78750f30f8f9a7311202 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c @@ -923,6 +923,6 @@ static struct platform_driver sun8i_a83t_ccu_driver = { }; module_platform_driver(sun8i_a83t_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A83T CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index a742f83746d1ec30f9ef61078f110cbf9cfed6f7..f2aa71206bc207042d165b7e92acf3edd3260b91 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c @@ -348,6 +348,6 @@ static struct platform_driver sunxi_de2_clk_driver = { }; module_platform_driver(sunxi_de2_clk_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner SoCs DE2 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 74da5d27af72ac616f1f7947ffb970b0689949c0..740c4c97331c1ac9653f0c58ec2d61cb0d5ecdb3 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -1094,6 +1094,6 @@ static struct platform_driver sun8i_h3_ccu_driver = { }; module_platform_driver(sun8i_h3_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner H3 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c index 2b3e094a32cbdc411c451d6d57628535ef97df68..0e324344673b61706900bab1be5d212c05be7256 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c @@ -274,6 +274,6 @@ static struct platform_driver sun8i_r_ccu_driver = { }; module_platform_driver(sun8i_r_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for Allwinner SoCs' PRCM CCUs"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c index a374aeeca3f4c5ded2d0bafcabad9063e6b0e396..8b729c9b3545c87fae572f04b72e27e51cc1b7e2 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c @@ -1375,6 +1375,6 @@ static struct platform_driver sun8i_r40_ccu_driver = { }; module_platform_driver(sun8i_r40_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner R40 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index 00d04f7ad94db451b35a7b0f004adc372582261f..579a81bb46df39042136965f47468f3444359ed9 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -780,6 +780,6 @@ static struct platform_driver sun8i_v3s_ccu_driver = { }; module_platform_driver(sun8i_v3s_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner V3s CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c index d561c15f51221af17ad2ebfb532d6243b87f5795..91e5dc448bc0ed7dba779dc88af948eab391d79b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c @@ -266,6 +266,6 @@ static struct platform_driver sun9i_a80_de_clk_driver = { }; module_platform_driver(sun9i_a80_de_clk_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A80 Display Engine CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c index 9e2b8d47fc546eaf35b03d053e53724c49aaa6e7..62063f525616da61400f872381bfe88bd507032d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c @@ -138,6 +138,6 @@ static struct platform_driver sun9i_a80_usb_clk_driver = { }; module_platform_driver(sun9i_a80_usb_clk_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A80 USB CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c index 5da9a16b4ec706f5baf1e78c055ff0c36b8d0a0a..3377519980051dfd0451109f1431d03572a666d6 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c @@ -1248,6 +1248,6 @@ static struct platform_driver sun9i_a80_ccu_driver = { }; module_platform_driver(sun9i_a80_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner A80 CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c index fb37c0fc4fdec0ae66225fe32865ca0186e26baf..35935423145e8063d25e69636a94e38b26405c41 100644 --- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c +++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c @@ -577,6 +577,6 @@ static struct platform_driver suniv_f1c100s_ccu_driver = { }; module_platform_driver(suniv_f1c100s_ccu_driver); -MODULE_IMPORT_NS(SUNXI_CCU); +MODULE_IMPORT_NS("SUNXI_CCU"); MODULE_DESCRIPTION("Support for the Allwinner newer F1C100s CCU"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index 4117b0bea26712e8dbb3d1abb820ddf4f0f59185..88ed89658d4579ddb99235e4cc10ddb4bc1528c6 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -37,7 +37,7 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000)); } -EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, "SUNXI_CCU"); bool ccu_is_better_rate(struct ccu_common *common, unsigned long target_rate, @@ -59,7 +59,7 @@ bool ccu_is_better_rate(struct ccu_common *common, return current_rate <= target_rate && current_rate > best_rate; } -EXPORT_SYMBOL_NS_GPL(ccu_is_better_rate, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_is_better_rate, "SUNXI_CCU"); /* * This clock notifier is called when the frequency of a PLL clock is @@ -107,7 +107,7 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb) return clk_notifier_register(pll_nb->common->hw.clk, &pll_nb->clk_nb); } -EXPORT_SYMBOL_NS_GPL(ccu_pll_notifier_register, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_pll_notifier_register, "SUNXI_CCU"); static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, struct device_node *node, void __iomem *reg, @@ -234,7 +234,7 @@ int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, return 0; } -EXPORT_SYMBOL_NS_GPL(devm_sunxi_ccu_probe, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(devm_sunxi_ccu_probe, "SUNXI_CCU"); void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, const struct sunxi_ccu_desc *desc) diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index cb10a3ea23f9f04f385581e40f092ffa536661c6..7f4691f09e01fc36d8908a296182666352305730 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c @@ -141,4 +141,4 @@ const struct clk_ops ccu_div_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_div_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_div_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_div_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_frac.c b/drivers/clk/sunxi-ng/ccu_frac.c index b31f3ad946d6adeb694ef4e82d729f8c7570c5f8..75323912608a3b7d6834062cca071da433877f60 100644 --- a/drivers/clk/sunxi-ng/ccu_frac.c +++ b/drivers/clk/sunxi-ng/ccu_frac.c @@ -18,7 +18,7 @@ bool ccu_frac_helper_is_enabled(struct ccu_common *common, return !(readl(common->base + common->reg) & cf->enable); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_is_enabled, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_is_enabled, "SUNXI_CCU"); void ccu_frac_helper_enable(struct ccu_common *common, struct ccu_frac_internal *cf) @@ -34,7 +34,7 @@ void ccu_frac_helper_enable(struct ccu_common *common, writel(reg & ~cf->enable, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_enable, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_enable, "SUNXI_CCU"); void ccu_frac_helper_disable(struct ccu_common *common, struct ccu_frac_internal *cf) @@ -50,7 +50,7 @@ void ccu_frac_helper_disable(struct ccu_common *common, writel(reg | cf->enable, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_disable, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_disable, "SUNXI_CCU"); bool ccu_frac_helper_has_rate(struct ccu_common *common, struct ccu_frac_internal *cf, @@ -61,7 +61,7 @@ bool ccu_frac_helper_has_rate(struct ccu_common *common, return (cf->rates[0] == rate) || (cf->rates[1] == rate); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_has_rate, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_has_rate, "SUNXI_CCU"); unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, struct ccu_frac_internal *cf) @@ -83,7 +83,7 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, return (reg & cf->select) ? cf->rates[1] : cf->rates[0]; } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_read_rate, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_read_rate, "SUNXI_CCU"); int ccu_frac_helper_set_rate(struct ccu_common *common, struct ccu_frac_internal *cf, @@ -112,4 +112,4 @@ int ccu_frac_helper_set_rate(struct ccu_common *common, return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_set_rate, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_set_rate, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_gate.c b/drivers/clk/sunxi-ng/ccu_gate.c index a2115a21807d17f714e48cbc0a60a3a023a704f2..ac52fd6bff677600817748e12274902bc48e2419 100644 --- a/drivers/clk/sunxi-ng/ccu_gate.c +++ b/drivers/clk/sunxi-ng/ccu_gate.c @@ -24,7 +24,7 @@ void ccu_gate_helper_disable(struct ccu_common *common, u32 gate) spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_disable, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_disable, "SUNXI_CCU"); static void ccu_gate_disable(struct clk_hw *hw) { @@ -50,7 +50,7 @@ int ccu_gate_helper_enable(struct ccu_common *common, u32 gate) return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_enable, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_enable, "SUNXI_CCU"); static int ccu_gate_enable(struct clk_hw *hw) { @@ -66,7 +66,7 @@ int ccu_gate_helper_is_enabled(struct ccu_common *common, u32 gate) return readl(common->base + common->reg) & gate; } -EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_is_enabled, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_is_enabled, "SUNXI_CCU"); static int ccu_gate_is_enabled(struct clk_hw *hw) { @@ -127,4 +127,4 @@ const struct clk_ops ccu_gate_ops = { .set_rate = ccu_gate_set_rate, .recalc_rate = ccu_gate_recalc_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_gate_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_gate_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index cc94a694cb676c554a3d9e088890fde7c9928207..2bb8987ddcc20500e74b921444a9115fa6d57c34 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -246,7 +246,7 @@ const struct clk_ops ccu_mp_ops = { .recalc_rate = ccu_mp_recalc_rate, .set_rate = ccu_mp_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mp_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mp_ops, "SUNXI_CCU"); /* * Support for MMC timing mode switching @@ -327,4 +327,4 @@ const struct clk_ops ccu_mp_mmc_ops = { .recalc_rate = ccu_mp_mmc_recalc_rate, .set_rate = ccu_mp_mmc_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mp_mmc_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mp_mmc_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 7bee217ef1116b4a84a6edfa8988bca0462f9290..8d5720f3dec1d4eb34bf22166277fdf5a270da42 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c @@ -170,4 +170,4 @@ const struct clk_ops ccu_mult_ops = { .recalc_rate = ccu_mult_recalc_rate, .set_rate = ccu_mult_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mult_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mult_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index 5edc63b466516cc0717e2533045cc87f10c6d88d..d7ffbdeee9e0475cb9be1c1ba333c23d00efbb2d 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c @@ -66,7 +66,7 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, { return parent_rate / ccu_mux_get_prediv(common, cm, parent_index); } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_apply_prediv, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_apply_prediv, "SUNXI_CCU"); static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common, struct ccu_mux_internal *cm, @@ -155,7 +155,7 @@ out: req->rate = best_rate; return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_determine_rate, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_determine_rate, "SUNXI_CCU"); u8 ccu_mux_helper_get_parent(struct ccu_common *common, struct ccu_mux_internal *cm) @@ -178,7 +178,7 @@ u8 ccu_mux_helper_get_parent(struct ccu_common *common, return parent; } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_get_parent, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_get_parent, "SUNXI_CCU"); int ccu_mux_helper_set_parent(struct ccu_common *common, struct ccu_mux_internal *cm, @@ -205,7 +205,7 @@ int ccu_mux_helper_set_parent(struct ccu_common *common, return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_set_parent, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_set_parent, "SUNXI_CCU"); static void ccu_mux_disable(struct clk_hw *hw) { @@ -273,7 +273,7 @@ const struct clk_ops ccu_mux_ops = { .determine_rate = ccu_mux_determine_rate, .recalc_rate = ccu_mux_recalc_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mux_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mux_ops, "SUNXI_CCU"); /* * This clock notifier is called when the frequency of the of the parent @@ -308,4 +308,4 @@ int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb) return clk_notifier_register(clk, &mux_nb->clk_nb); } -EXPORT_SYMBOL_NS_GPL(ccu_mux_notifier_register, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_mux_notifier_register, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c index 8aa35d5804f3039ee8d689ed8c24faf19eba6c05..555e99de2cc6ee0c84ccaaac9ee83be2d88741a0 100644 --- a/drivers/clk/sunxi-ng/ccu_nk.c +++ b/drivers/clk/sunxi-ng/ccu_nk.c @@ -158,4 +158,4 @@ const struct clk_ops ccu_nk_ops = { .round_rate = ccu_nk_round_rate, .set_rate = ccu_nk_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nk_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_nk_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 1168d894d636bfdd46dcba0980f1e4a022348199..784eec9ac9979b22e8f384e0abbb5c1a381ae953 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -267,4 +267,4 @@ const struct clk_ops ccu_nkm_ops = { .recalc_rate = ccu_nkm_recalc_rate, .set_rate = ccu_nkm_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nkm_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_nkm_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index 99359a06892d4767a8419c2b4473362c3daf572e..6e03b69d402848b237154319d2296ffb4133a213 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -230,4 +230,4 @@ const struct clk_ops ccu_nkmp_ops = { .round_rate = ccu_nkmp_round_rate, .set_rate = ccu_nkmp_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nkmp_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_nkmp_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index ffac3deb89d6621e992882898eac62cb034da745..a4e2243b8d6b4a8fdd9ea1ff2ca06e2f1a009632 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -236,4 +236,4 @@ const struct clk_ops ccu_nm_ops = { .round_rate = ccu_nm_round_rate, .set_rate = ccu_nm_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nm_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_nm_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_phase.c b/drivers/clk/sunxi-ng/ccu_phase.c index e4cae2afe9db9db6099a8599b9e96fd69c22d82f..ca43cf448666bdd258cb41cf2fd54d79cca3a28c 100644 --- a/drivers/clk/sunxi-ng/ccu_phase.c +++ b/drivers/clk/sunxi-ng/ccu_phase.c @@ -121,4 +121,4 @@ const struct clk_ops ccu_phase_ops = { .get_phase = ccu_phase_get_phase, .set_phase = ccu_phase_set_phase, }; -EXPORT_SYMBOL_NS_GPL(ccu_phase_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_phase_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_reset.c b/drivers/clk/sunxi-ng/ccu_reset.c index 6577aa18cb01e34d66f42336eb7726d404f11556..55bc7c7cda0fcf9aa34ba75e5cd3762a0e32702f 100644 --- a/drivers/clk/sunxi-ng/ccu_reset.c +++ b/drivers/clk/sunxi-ng/ccu_reset.c @@ -75,4 +75,4 @@ const struct reset_control_ops ccu_reset_ops = { .reset = ccu_reset_reset, .status = ccu_reset_status, }; -EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_sdm.c b/drivers/clk/sunxi-ng/ccu_sdm.c index 41937ed0766dbf2aa4b2afaa685b01db736b9891..c564e5f9e61040c1d498e48a0a03d60bb5eb00b9 100644 --- a/drivers/clk/sunxi-ng/ccu_sdm.c +++ b/drivers/clk/sunxi-ng/ccu_sdm.c @@ -20,7 +20,7 @@ bool ccu_sdm_helper_is_enabled(struct ccu_common *common, return !!(readl(common->base + sdm->tuning_reg) & sdm->tuning_enable); } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_is_enabled, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_is_enabled, "SUNXI_CCU"); void ccu_sdm_helper_enable(struct ccu_common *common, struct ccu_sdm_internal *sdm, @@ -50,7 +50,7 @@ void ccu_sdm_helper_enable(struct ccu_common *common, writel(reg | sdm->enable, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_enable, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_enable, "SUNXI_CCU"); void ccu_sdm_helper_disable(struct ccu_common *common, struct ccu_sdm_internal *sdm) @@ -71,7 +71,7 @@ void ccu_sdm_helper_disable(struct ccu_common *common, writel(reg & ~sdm->tuning_enable, common->base + sdm->tuning_reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_disable, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_disable, "SUNXI_CCU"); /* * Sigma delta modulation provides a way to do fractional-N frequency @@ -105,7 +105,7 @@ bool ccu_sdm_helper_has_rate(struct ccu_common *common, return false; } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_has_rate, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_has_rate, "SUNXI_CCU"); unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common, struct ccu_sdm_internal *sdm, @@ -136,7 +136,7 @@ unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common, /* We can't calculate the effective clock rate, so just fail. */ return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_read_rate, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_read_rate, "SUNXI_CCU"); int ccu_sdm_helper_get_factors(struct ccu_common *common, struct ccu_sdm_internal *sdm, @@ -158,4 +158,4 @@ int ccu_sdm_helper_get_factors(struct ccu_common *common, /* nothing found */ return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_get_factors, SUNXI_CCU); +EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_get_factors, "SUNXI_CCU"); diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c index 0d229a9058dad856a897ddbfab6612d549573d25..6b48a9006444dd2e82c6599d43df97b6e050b943 100644 --- a/drivers/clocksource/timer-sun5i.c +++ b/drivers/clocksource/timer-sun5i.c @@ -318,7 +318,7 @@ MODULE_DEVICE_TABLE(of, sun5i_timer_of_match); static struct platform_driver sun5i_timer_driver = { .probe = sun5i_timer_probe, - .remove_new = sun5i_timer_remove, + .remove = sun5i_timer_remove, .driver = { .name = "sun5i-timer", .of_match_table = sun5i_timer_of_match, diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c index 304537dadf2c1c14ff08aa54b6f3b1bb457d20b0..5d4cf5237a113cdd6a300072500f878b08d09163 100644 --- a/drivers/clocksource/timer-tegra186.c +++ b/drivers/clocksource/timer-tegra186.c @@ -502,7 +502,7 @@ static struct platform_driver tegra186_wdt_driver = { .of_match_table = tegra186_timer_of_match, }, .probe = tegra186_timer_probe, - .remove_new = tegra186_timer_remove, + .remove = tegra186_timer_remove, }; module_platform_driver(tegra186_wdt_driver); diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c index 3666d94cc8ddc5b2e9c967b1d0c7ae787b11861c..e9e32df6b56664bc0bd94050380314a757d05ebd 100644 --- a/drivers/clocksource/timer-ti-dm.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -1295,7 +1295,7 @@ MODULE_DEVICE_TABLE(of, omap_timer_match); static struct platform_driver omap_dm_timer_driver = { .probe = omap_dm_timer_probe, - .remove_new = omap_dm_timer_remove, + .remove = omap_dm_timer_remove, .driver = { .name = "omap_timer", .of_match_table = omap_timer_match, diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c index 1b481731df964ed67e1e8909ee084ed7292941b7..b9df9b19d4bd97cdbc7a594ae928a8c4821f871f 100644 --- a/drivers/comedi/comedi_fops.c +++ b/drivers/comedi/comedi_fops.c @@ -2407,6 +2407,18 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) start += PAGE_SIZE; } + +#ifdef CONFIG_MMU + /* + * Leaving behind a partial mapping of a buffer we're about to + * drop is unsafe, see remap_pfn_range_notrack(). + * We need to zap the range here ourselves instead of relying + * on the automatic zapping in remap_pfn_range() because we call + * remap_pfn_range() in a loop. + */ + if (retval) + zap_vma_ptes(vma, vma->vm_start, size); +#endif } if (retval == 0) { diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c index 4a6868b8f58bce508ce2d50b1416275f6aeb582b..ce81fc4e1ae76319e1a20327135a7419bdb91ae1 100644 --- a/drivers/counter/104-quad-8.c +++ b/drivers/counter/104-quad-8.c @@ -1360,4 +1360,4 @@ module_isa_driver_with_irq(quad8_driver, num_quad8, num_irq); MODULE_AUTHOR("William Breathitt Gray "); MODULE_DESCRIPTION("ACCES 104-QUAD-8 driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c index 3ee75e1a78cd5eaf1aaf94b8be8829d412fc1f11..23fdf0caf712a2e8cefcfae4ce2c9d3fee5998b3 100644 --- a/drivers/counter/counter-chrdev.c +++ b/drivers/counter/counter-chrdev.c @@ -672,4 +672,4 @@ exit_early: if (copied) wake_up_poll(&counter->events_wait, EPOLLIN); } -EXPORT_SYMBOL_NS_GPL(counter_push_event, COUNTER); +EXPORT_SYMBOL_NS_GPL(counter_push_event, "COUNTER"); diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c index 893b4f0726d2e6064f81846f2aeffb1cca38059b..50bd30ba3d03775b7e67d96d80e8e56d979b684d 100644 --- a/drivers/counter/counter-core.c +++ b/drivers/counter/counter-core.c @@ -74,7 +74,7 @@ void *counter_priv(const struct counter_device *const counter) return &ch->privdata; } -EXPORT_SYMBOL_NS_GPL(counter_priv, COUNTER); +EXPORT_SYMBOL_NS_GPL(counter_priv, "COUNTER"); /** * counter_alloc - allocate a counter_device @@ -134,13 +134,13 @@ err_ida_alloc: return NULL; } -EXPORT_SYMBOL_NS_GPL(counter_alloc, COUNTER); +EXPORT_SYMBOL_NS_GPL(counter_alloc, "COUNTER"); void counter_put(struct counter_device *counter) { put_device(&counter->dev); } -EXPORT_SYMBOL_NS_GPL(counter_put, COUNTER); +EXPORT_SYMBOL_NS_GPL(counter_put, "COUNTER"); /** * counter_add - complete registration of a counter @@ -167,7 +167,7 @@ int counter_add(struct counter_device *counter) /* implies device_add(dev) */ return cdev_device_add(&counter->chrdev, dev); } -EXPORT_SYMBOL_NS_GPL(counter_add, COUNTER); +EXPORT_SYMBOL_NS_GPL(counter_add, "COUNTER"); /** * counter_unregister - unregister Counter from the system @@ -189,7 +189,7 @@ void counter_unregister(struct counter_device *const counter) mutex_unlock(&counter->ops_exist_lock); } -EXPORT_SYMBOL_NS_GPL(counter_unregister, COUNTER); +EXPORT_SYMBOL_NS_GPL(counter_unregister, "COUNTER"); static void devm_counter_release(void *counter) { @@ -224,7 +224,7 @@ struct counter_device *devm_counter_alloc(struct device *dev, size_t sizeof_priv return counter; } -EXPORT_SYMBOL_NS_GPL(devm_counter_alloc, COUNTER); +EXPORT_SYMBOL_NS_GPL(devm_counter_alloc, "COUNTER"); /** * devm_counter_add - complete registration of a counter @@ -245,7 +245,7 @@ int devm_counter_add(struct device *dev, return devm_add_action_or_reset(dev, devm_counter_release, counter); } -EXPORT_SYMBOL_NS_GPL(devm_counter_add, COUNTER); +EXPORT_SYMBOL_NS_GPL(devm_counter_add, "COUNTER"); #define COUNTER_DEV_MAX 256 diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c index 200876f3ec0486baadf84eb34c1db769014606fa..c47741292ae1112d4300f9aa41534a423aad56bf 100644 --- a/drivers/counter/ftm-quaddec.c +++ b/drivers/counter/ftm-quaddec.c @@ -311,6 +311,7 @@ static const struct of_device_id ftm_quaddec_match[] = { { .compatible = "fsl,ftm-quaddec" }, {}, }; +MODULE_DEVICE_TABLE(of, ftm_quaddec_match); static struct platform_driver ftm_quaddec_driver = { .driver = { @@ -326,4 +327,4 @@ MODULE_DESCRIPTION("Flex Timer Module Quadrature decoder"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kjeld Flarup "); MODULE_AUTHOR("Patrick Havelange "); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/i8254.c b/drivers/counter/i8254.c index 6d74e8ef92f009d31e5806fbfe2d37d46ee0dae6..95ad928725eca4b12c70a4da9c8836361ce1af01 100644 --- a/drivers/counter/i8254.c +++ b/drivers/counter/i8254.c @@ -439,9 +439,9 @@ int devm_i8254_regmap_register(struct device *const dev, return 0; } -EXPORT_SYMBOL_NS_GPL(devm_i8254_regmap_register, I8254); +EXPORT_SYMBOL_NS_GPL(devm_i8254_regmap_register, "I8254"); MODULE_AUTHOR("William Breathitt Gray"); MODULE_DESCRIPTION("Intel 8254 Programmable Interval Timer"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/intel-qep.c b/drivers/counter/intel-qep.c index af5942e66f7d0c584a61d936498a0d43fd465a7e..c49c178056f451be872eec02148a7396c8595fa9 100644 --- a/drivers/counter/intel-qep.c +++ b/drivers/counter/intel-qep.c @@ -408,13 +408,9 @@ static int intel_qep_probe(struct pci_dev *pci, const struct pci_device_id *id) pci_set_master(pci); - ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci)); - if (ret) - return ret; - - regs = pcim_iomap_table(pci)[0]; - if (!regs) - return -ENOMEM; + regs = pcim_iomap_region(pci, 0, pci_name(pci)); + if (IS_ERR(regs)) + return PTR_ERR(regs); qep->dev = dev; qep->regs = regs; @@ -523,4 +519,4 @@ MODULE_AUTHOR("Jarkko Nikula "); MODULE_AUTHOR("Raymond Tan "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Intel Quadrature Encoder Peripheral driver"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c index 229473855c5b38abf9900046d184a32ce6943c5e..949598d51575a1a2e575095f298d7fe8fae3e14c 100644 --- a/drivers/counter/interrupt-cnt.c +++ b/drivers/counter/interrupt-cnt.c @@ -253,4 +253,4 @@ MODULE_ALIAS("platform:interrupt-counter"); MODULE_AUTHOR("Oleksij Rempel "); MODULE_DESCRIPTION("Interrupt counter driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c index b3e615cbd2caa63f1bc7f8f34cc86f8bc41be477..2f096a5b973d18edf5de5a2b33f2f72571deefb7 100644 --- a/drivers/counter/microchip-tcb-capture.c +++ b/drivers/counter/microchip-tcb-capture.c @@ -403,4 +403,4 @@ module_platform_driver(mchp_tc_driver); MODULE_AUTHOR("Kamel Bouhara "); MODULE_DESCRIPTION("Microchip TCB Capture driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/rz-mtu3-cnt.c b/drivers/counter/rz-mtu3-cnt.c index ee821493b16649da292137308eeadb8e9710eb6f..e755d54dfece944c27f14bcfb867f499e6f27b18 100644 --- a/drivers/counter/rz-mtu3-cnt.c +++ b/drivers/counter/rz-mtu3-cnt.c @@ -903,4 +903,4 @@ MODULE_AUTHOR("Biju Das "); MODULE_ALIAS("platform:rz-mtu3-counter"); MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a counter driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c index 8439755559b2195d82196b0c98b32d32320c89a3..cf73f65baf606ce1cba820e1fc44a03fc72a3627 100644 --- a/drivers/counter/stm32-lptimer-cnt.c +++ b/drivers/counter/stm32-lptimer-cnt.c @@ -520,4 +520,4 @@ MODULE_AUTHOR("Fabrice Gasnier "); MODULE_ALIAS("platform:stm32-lptimer-counter"); MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM counter driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index 186e73d6ccb455d57c70566a281c62d5299ebe0f..e75b69476a00a818ad7c4fa627ea7868e4df57c4 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -214,11 +214,17 @@ static int stm32_count_enable_write(struct counter_device *counter, { struct stm32_timer_cnt *const priv = counter_priv(counter); u32 cr1; + int ret; if (enable) { regmap_read(priv->regmap, TIM_CR1, &cr1); - if (!(cr1 & TIM_CR1_CEN)) - clk_enable(priv->clk); + if (!(cr1 & TIM_CR1_CEN)) { + ret = clk_enable(priv->clk); + if (ret) { + dev_err(counter->parent, "Cannot enable clock %d\n", ret); + return ret; + } + } regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); @@ -694,6 +700,7 @@ static int stm32_timer_cnt_probe_encoder(struct device *dev, } ret = of_property_read_u32(tnode, "reg", &idx); + of_node_put(tnode); if (ret) { dev_err(dev, "Can't get index (%d)\n", ret); return ret; @@ -816,7 +823,11 @@ static int __maybe_unused stm32_timer_cnt_resume(struct device *dev) return ret; if (priv->enabled) { - clk_enable(priv->clk); + ret = clk_enable(priv->clk); + if (ret) { + dev_err(dev, "Cannot enable clock %d\n", ret); + return ret; + } /* Restore registers that may have been lost */ regmap_write(priv->regmap, TIM_SMCR, priv->bak.smcr); @@ -853,4 +864,4 @@ MODULE_AUTHOR("Benjamin Gaignard "); MODULE_ALIAS("platform:stm32-timer-counter"); MODULE_DESCRIPTION("STMicroelectronics STM32 TIMER counter driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/ti-ecap-capture.c b/drivers/counter/ti-ecap-capture.c index 675447315cafb831b36ccd27676904b4c5ff600f..3faaf7f60539ac3fc6b02f8e4c4bc905943d3f43 100644 --- a/drivers/counter/ti-ecap-capture.c +++ b/drivers/counter/ti-ecap-capture.c @@ -574,8 +574,13 @@ static int ecap_cnt_resume(struct device *dev) { struct counter_device *counter_dev = dev_get_drvdata(dev); struct ecap_cnt_dev *ecap_dev = counter_priv(counter_dev); + int ret; - clk_enable(ecap_dev->clk); + ret = clk_enable(ecap_dev->clk); + if (ret) { + dev_err(dev, "Cannot enable clock %d\n", ret); + return ret; + } ecap_cnt_capture_set_evmode(counter_dev, ecap_dev->pm_ctx.ev_mode); @@ -598,7 +603,7 @@ MODULE_DEVICE_TABLE(of, ecap_cnt_of_match); static struct platform_driver ecap_cnt_driver = { .probe = ecap_cnt_probe, - .remove_new = ecap_cnt_remove, + .remove = ecap_cnt_remove, .driver = { .name = "ecap-capture", .of_match_table = ecap_cnt_of_match, @@ -610,4 +615,4 @@ module_platform_driver(ecap_cnt_driver); MODULE_DESCRIPTION("ECAP Capture driver"); MODULE_AUTHOR("Julien Panis "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c index 313b91456f2652b145e5418d7da590f32a8b398c..bc586eff0daeb52857c10fc89e4f9c0262c3441b 100644 --- a/drivers/counter/ti-eqep.c +++ b/drivers/counter/ti-eqep.c @@ -548,7 +548,7 @@ MODULE_DEVICE_TABLE(of, ti_eqep_of_match); static struct platform_driver ti_eqep_driver = { .probe = ti_eqep_probe, - .remove_new = ti_eqep_remove, + .remove = ti_eqep_remove, .driver = { .name = "ti-eqep-cnt", .of_match_table = ti_eqep_of_match, @@ -559,4 +559,4 @@ module_platform_driver(ti_eqep_driver); MODULE_AUTHOR("David Lechner "); MODULE_DESCRIPTION("TI eQEP counter driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(COUNTER); +MODULE_IMPORT_NS("COUNTER"); diff --git a/drivers/cpuidle/cpuidle-kirkwood.c b/drivers/cpuidle/cpuidle-kirkwood.c index 602c4dfdd7e2ead6bc1d44efe3185d2baf7d6cee..5235e6e8f360fbb4c174c450860c52c15d091d9a 100644 --- a/drivers/cpuidle/cpuidle-kirkwood.c +++ b/drivers/cpuidle/cpuidle-kirkwood.c @@ -66,7 +66,7 @@ static void kirkwood_cpuidle_remove(struct platform_device *pdev) static struct platform_driver kirkwood_cpuidle_driver = { .probe = kirkwood_cpuidle_probe, - .remove_new = kirkwood_cpuidle_remove, + .remove = kirkwood_cpuidle_remove, .driver = { .name = "kirkwood_cpuidle", }, diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index fa5a9f207bc90afb94a26b101e8b018e3f3eb0aa..d933f26aeb3aaadb0099d6d15ee0a635f5044100 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -433,4 +433,4 @@ module_pci_driver(geode_aes_driver); MODULE_AUTHOR("Advanced Micro Devices, Inc."); MODULE_DESCRIPTION("Geode LX Hardware AES driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c index 45758c7aa80e6edd6b88b6ad088f1f8c097e35ef..9ca80d082c4fb74fc726eb9808abd55e6bacb5da 100644 --- a/drivers/crypto/inside-secure/safexcel.c +++ b/drivers/crypto/inside-secure/safexcel.c @@ -2031,7 +2031,7 @@ MODULE_AUTHOR("Ofer Heifetz "); MODULE_AUTHOR("Igal Liberman "); MODULE_DESCRIPTION("Support for SafeXcel cryptographic engines: EIP97 & EIP197"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); MODULE_FIRMWARE("ifpp.bin"); MODULE_FIRMWARE("ipue.bin"); diff --git a/drivers/crypto/intel/iaa/Makefile b/drivers/crypto/intel/iaa/Makefile index b64b208d2344085740f788c62697c1abfd72dc6a..55bda7770fac7949935272899e6da3898ede78a6 100644 --- a/drivers/crypto/intel/iaa/Makefile +++ b/drivers/crypto/intel/iaa/Makefile @@ -3,7 +3,7 @@ # Makefile for IAA crypto device drivers # -ccflags-y += -I $(srctree)/drivers/dma/idxd -DDEFAULT_SYMBOL_NAMESPACE=IDXD +ccflags-y += -I $(srctree)/drivers/dma/idxd -DDEFAULT_SYMBOL_NAMESPACE='"IDXD"' obj-$(CONFIG_CRYPTO_DEV_IAA_CRYPTO) := iaa_crypto.o diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c index 8fced88d3d069e7394842a73649e9cda7badefcf..9e557649e5d084f408c2ba35235c0c1f3949e514 100644 --- a/drivers/crypto/intel/iaa/iaa_crypto_main.c +++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c @@ -2094,7 +2094,7 @@ static void __exit iaa_crypto_cleanup_module(void) pr_debug("cleaned up\n"); } -MODULE_IMPORT_NS(IDXD); +MODULE_IMPORT_NS("IDXD"); MODULE_LICENSE("GPL"); MODULE_ALIAS_IDXD_DEVICE(0); MODULE_AUTHOR("Intel Corporation"); diff --git a/drivers/crypto/intel/qat/qat_420xx/adf_drv.c b/drivers/crypto/intel/qat/qat_420xx/adf_drv.c index 788a11cdb34b5a8fe566159cf80a72272bca2b40..9589d60fb281da06dabe843c65fd72b5ec58b7d0 100644 --- a/drivers/crypto/intel/qat/qat_420xx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_420xx/adf_drv.c @@ -204,4 +204,4 @@ MODULE_FIRMWARE(ADF_420XX_MMP); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); MODULE_SOFTDEP("pre: crypto-intel_qat"); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c index 115eabfd1f6ba3c7e5a93c0efa3876fca5ddb733..d7de1cad1335436095c58c63a025df41bdc2698a 100644 --- a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c @@ -208,4 +208,4 @@ MODULE_FIRMWARE(ADF_402XX_MMP); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); MODULE_SOFTDEP("pre: crypto-intel_qat"); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c index 4d18057745d4442c2491b15b5dc1eea3f12e73f4..caa53882fda65599c6b3fdd59d9dac7c6cdc9b21 100644 --- a/drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c @@ -252,4 +252,4 @@ MODULE_FIRMWARE(ADF_C3XXX_FW); MODULE_FIRMWARE(ADF_C3XXX_MMP); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c b/drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c index f0023cfb234cddcf7dcd6e116ad21d2483faa57d..c622793e94a87577d34f57a381c44cd11c71cf75 100644 --- a/drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c @@ -226,4 +226,4 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Intel"); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/intel/qat/qat_c62x/adf_drv.c b/drivers/crypto/intel/qat/qat_c62x/adf_drv.c index e6b5de55434ec1a82ad53c81a4285ee0177be038..b7398fee19edef3e9aa41e1930b6e68d26afaa85 100644 --- a/drivers/crypto/intel/qat/qat_c62x/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_c62x/adf_drv.c @@ -252,4 +252,4 @@ MODULE_FIRMWARE(ADF_C62X_FW); MODULE_FIRMWARE(ADF_C62X_MMP); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c b/drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c index 2bd5b0ff00e36975d62699a0268ef36520e2a626..4840d44bbd5b2e2a70ee883fa7a680612927032e 100644 --- a/drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c @@ -226,4 +226,4 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Intel"); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/intel/qat/qat_common/Makefile b/drivers/crypto/intel/qat/qat_common/Makefile index eac73cbfdd38e269e6d9a6f2b8dd13da136fb425..7acf9c576149baeed2becf8c8b25fc47a4759487 100644 --- a/drivers/crypto/intel/qat/qat_common/Makefile +++ b/drivers/crypto/intel/qat/qat_common/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o -ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CRYPTO_QAT +ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"CRYPTO_QAT"' intel_qat-objs := adf_cfg.o \ adf_isr.o \ adf_ctl_drv.o \ diff --git a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c index 70fa0f6497a968480a01a2001a9c44b93ef50425..48c62a14a6a75bcadef21f7fba40cefc185034df 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c +++ b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c @@ -475,4 +475,4 @@ MODULE_AUTHOR("Intel"); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_ALIAS_CRYPTO("intel_qat"); MODULE_VERSION(ADF_DRV_VERSION); -MODULE_IMPORT_NS(CRYPTO_INTERNAL); +MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c b/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c index 2a50cce415151bf004ce57576b8e05646acd5532..3137fc3b5cf651a95fc4564706cad64aa9219b40 100644 --- a/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c @@ -252,4 +252,4 @@ MODULE_FIRMWARE(ADF_DH895XCC_FW); MODULE_FIRMWARE(ADF_DH895XCC_MMP); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c b/drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c index 7cb015b5512234a2b1121d0ff72df85776fdb62c..7cd528ee31e77c44a9eed4912b996ea54c4db068 100644 --- a/drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c @@ -226,4 +226,4 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Intel"); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/crypto/marvell/octeontx2/cn10k_cpt.c b/drivers/crypto/marvell/octeontx2/cn10k_cpt.c index 6bfc59e6774780763e43c449653979fdea3f2eec..5cae8fafa15189ff61449fd2663294c49e7623e7 100644 --- a/drivers/crypto/marvell/octeontx2/cn10k_cpt.c +++ b/drivers/crypto/marvell/octeontx2/cn10k_cpt.c @@ -73,7 +73,7 @@ int cn10k_cptpf_lmtst_init(struct otx2_cptpf_dev *cptpf) return 0; } -EXPORT_SYMBOL_NS_GPL(cn10k_cptpf_lmtst_init, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(cn10k_cptpf_lmtst_init, "CRYPTO_DEV_OCTEONTX2_CPT"); int cn10k_cptvf_lmtst_init(struct otx2_cptvf_dev *cptvf) { @@ -94,7 +94,7 @@ int cn10k_cptvf_lmtst_init(struct otx2_cptvf_dev *cptvf) return 0; } -EXPORT_SYMBOL_NS_GPL(cn10k_cptvf_lmtst_init, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(cn10k_cptvf_lmtst_init, "CRYPTO_DEV_OCTEONTX2_CPT"); void cn10k_cpt_hw_ctx_clear(struct pci_dev *pdev, struct cn10k_cpt_errata_ctx *er_ctx) @@ -110,7 +110,7 @@ void cn10k_cpt_hw_ctx_clear(struct pci_dev *pdev, DMA_BIDIRECTIONAL); kfree(er_ctx->hw_ctx); } -EXPORT_SYMBOL_NS_GPL(cn10k_cpt_hw_ctx_clear, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(cn10k_cpt_hw_ctx_clear, "CRYPTO_DEV_OCTEONTX2_CPT"); void cn10k_cpt_hw_ctx_set(union cn10k_cpt_hw_ctx *hctx, u16 ctx_sz) { @@ -119,7 +119,7 @@ void cn10k_cpt_hw_ctx_set(union cn10k_cpt_hw_ctx *hctx, u16 ctx_sz) hctx->w0.ctx_sz = ctx_sz; hctx->w0.ctx_push_sz = 1; } -EXPORT_SYMBOL_NS_GPL(cn10k_cpt_hw_ctx_set, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(cn10k_cpt_hw_ctx_set, "CRYPTO_DEV_OCTEONTX2_CPT"); int cn10k_cpt_hw_ctx_init(struct pci_dev *pdev, struct cn10k_cpt_errata_ctx *er_ctx) @@ -149,7 +149,7 @@ int cn10k_cpt_hw_ctx_init(struct pci_dev *pdev, return 0; } -EXPORT_SYMBOL_NS_GPL(cn10k_cpt_hw_ctx_init, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(cn10k_cpt_hw_ctx_init, "CRYPTO_DEV_OCTEONTX2_CPT"); void cn10k_cpt_ctx_flush(struct pci_dev *pdev, u64 cptr, bool inval) { @@ -168,7 +168,7 @@ void cn10k_cpt_ctx_flush(struct pci_dev *pdev, u64 cptr, bool inval) otx2_cpt_read64(lfs->reg_base, lfs->blkaddr, lfs->lf[0].slot, OTX2_CPT_LF_CTX_ERR); } -EXPORT_SYMBOL_NS_GPL(cn10k_cpt_ctx_flush, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(cn10k_cpt_ctx_flush, "CRYPTO_DEV_OCTEONTX2_CPT"); void cptvf_hw_ops_get(struct otx2_cptvf_dev *cptvf) { @@ -177,4 +177,4 @@ void cptvf_hw_ops_get(struct otx2_cptvf_dev *cptvf) else cptvf->lfs.ops = &otx2_hw_ops; } -EXPORT_SYMBOL_NS_GPL(cptvf_hw_ops_get, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(cptvf_hw_ops_get, "CRYPTO_DEV_OCTEONTX2_CPT"); diff --git a/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c b/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c index 5be0103c1fb8175e5addc33f3f9f59675283d54f..b8b7c8a3c0ca567e3dc27820f7bb2ff86bd2a98b 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c @@ -19,7 +19,7 @@ int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev) } return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_mbox_msg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_mbox_msg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev) { @@ -37,13 +37,13 @@ int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev) return otx2_cpt_send_mbox_msg(mbox, pdev); } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_ready_msg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_ready_msg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_send_af_reg_requests(struct otx2_mbox *mbox, struct pci_dev *pdev) { return otx2_cpt_send_mbox_msg(mbox, pdev); } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_af_reg_requests, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_send_af_reg_requests, "CRYPTO_DEV_OCTEONTX2_CPT"); static int otx2_cpt_add_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, u64 reg, @@ -95,7 +95,7 @@ int otx2_cpt_add_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, return 0; } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_add_write_af_reg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_add_write_af_reg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, u64 reg, u64 *val, int blkaddr) @@ -108,7 +108,7 @@ int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, return otx2_cpt_send_mbox_msg(mbox, pdev); } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_read_af_reg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_read_af_reg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, u64 reg, u64 val, int blkaddr) @@ -121,7 +121,7 @@ int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, return otx2_cpt_send_mbox_msg(mbox, pdev); } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_write_af_reg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_write_af_reg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs) { @@ -180,7 +180,7 @@ int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs) return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_detach_rsrcs_msg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_detach_rsrcs_msg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs) { @@ -213,7 +213,7 @@ int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs) } return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_msix_offset_msg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_msix_offset_msg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_sync_mbox_msg(struct otx2_mbox *mbox) { @@ -228,7 +228,7 @@ int otx2_cpt_sync_mbox_msg(struct otx2_mbox *mbox) return otx2_mbox_check_rsp_msgs(mbox, 0); } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_sync_mbox_msg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_sync_mbox_msg, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cpt_lf_reset_msg(struct otx2_cptlfs_info *lfs, int slot) { @@ -254,4 +254,4 @@ int otx2_cpt_lf_reset_msg(struct otx2_cptlfs_info *lfs, int slot) return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cpt_lf_reset_msg, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cpt_lf_reset_msg, "CRYPTO_DEV_OCTEONTX2_CPT"); diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptlf.c b/drivers/crypto/marvell/octeontx2/otx2_cptlf.c index b52728e3c0d13e89e26348c92510b1fc9bc77337..b5d66afcc030b3f0c15681d71d5d0a70f3f2c783 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptlf.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptlf.c @@ -288,8 +288,7 @@ void otx2_cptlf_unregister_misc_interrupts(struct otx2_cptlfs_info *lfs) cptlf_set_misc_intrs(lfs, false); } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_misc_interrupts, - CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_misc_interrupts, "CRYPTO_DEV_OCTEONTX2_CPT"); void otx2_cptlf_unregister_done_interrupts(struct otx2_cptlfs_info *lfs) { @@ -308,8 +307,7 @@ void otx2_cptlf_unregister_done_interrupts(struct otx2_cptlfs_info *lfs) cptlf_set_done_intrs(lfs, false); } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_done_interrupts, - CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_done_interrupts, "CRYPTO_DEV_OCTEONTX2_CPT"); static int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs, int lf_num, int irq_offset, @@ -351,8 +349,7 @@ free_irq: otx2_cptlf_unregister_misc_interrupts(lfs); return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_misc_interrupts, - CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_misc_interrupts, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cptlf_register_done_interrupts(struct otx2_cptlfs_info *lfs) { @@ -375,8 +372,7 @@ free_irq: otx2_cptlf_unregister_done_interrupts(lfs); return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_done_interrupts, - CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_done_interrupts, "CRYPTO_DEV_OCTEONTX2_CPT"); void otx2_cptlf_free_irqs_affinity(struct otx2_cptlfs_info *lfs) { @@ -390,7 +386,7 @@ void otx2_cptlf_free_irqs_affinity(struct otx2_cptlfs_info *lfs) free_cpumask_var(lfs->lf[slot].affinity_mask); } } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_free_irqs_affinity, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_free_irqs_affinity, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cptlf_set_irqs_affinity(struct otx2_cptlfs_info *lfs) { @@ -423,7 +419,7 @@ free_affinity_mask: otx2_cptlf_free_irqs_affinity(lfs); return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_set_irqs_affinity, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_set_irqs_affinity, "CRYPTO_DEV_OCTEONTX2_CPT"); int otx2_cptlf_init(struct otx2_cptlfs_info *lfs, u8 eng_grp_mask, int pri, int lfs_num) @@ -486,7 +482,7 @@ clear_lfs_num: lfs->lfs_num = 0; return ret; } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_init, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_init, "CRYPTO_DEV_OCTEONTX2_CPT"); void otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs) { @@ -498,7 +494,7 @@ void otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs) otx2_cpt_detach_rsrcs_msg(lfs); lfs->lfs_num = 0; } -EXPORT_SYMBOL_NS_GPL(otx2_cptlf_shutdown, CRYPTO_DEV_OCTEONTX2_CPT); +EXPORT_SYMBOL_NS_GPL(otx2_cptlf_shutdown, "CRYPTO_DEV_OCTEONTX2_CPT"); MODULE_AUTHOR("Marvell"); MODULE_DESCRIPTION("Marvell RVU CPT Common module"); diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c index 94d0e73e42de1c9941f3b083d46659831c2cb1af..12971300296d9756dd3dc18c819c3b5f4d1c1b8c 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c @@ -868,7 +868,7 @@ static struct pci_driver otx2_cpt_pci_driver = { module_pci_driver(otx2_cpt_pci_driver); -MODULE_IMPORT_NS(CRYPTO_DEV_OCTEONTX2_CPT); +MODULE_IMPORT_NS("CRYPTO_DEV_OCTEONTX2_CPT"); MODULE_AUTHOR("Marvell"); MODULE_DESCRIPTION(OTX2_CPT_DRV_STRING); diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c index d0b6ee901f62039d45a86906ef5e76462e8fcebb..d84eebdf2fa8475a809dec7ddd7196cd3a7b1f3f 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c @@ -453,7 +453,7 @@ static struct pci_driver otx2_cptvf_pci_driver = { module_pci_driver(otx2_cptvf_pci_driver); -MODULE_IMPORT_NS(CRYPTO_DEV_OCTEONTX2_CPT); +MODULE_IMPORT_NS("CRYPTO_DEV_OCTEONTX2_CPT"); MODULE_AUTHOR("Marvell"); MODULE_DESCRIPTION("Marvell RVU CPT Virtual Function Driver"); diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 432b7cfd12a8e10703f1513ba4553e8821369546..cb14829bb9be4b479ff215f9fe813833774cbc54 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -934,5 +934,5 @@ MODULE_SOFTDEP("pre: cxl_port"); module_exit(cxl_acpi_exit); MODULE_DESCRIPTION("CXL ACPI: Platform Support"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(CXL); -MODULE_IMPORT_NS(ACPI); +MODULE_IMPORT_NS("CXL"); +MODULE_IMPORT_NS("ACPI"); diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c index 2a1f164db98e6592a57fdb52197363833e0f7f2a..8153f8d83a164a20b948517bb3f09e278c80d681 100644 --- a/drivers/cxl/core/cdat.c +++ b/drivers/cxl/core/cdat.c @@ -416,7 +416,7 @@ void cxl_endpoint_parse_cdat(struct cxl_port *port) cxl_qos_class_verify(cxlmd); cxl_memdev_update_perf(cxlmd); } -EXPORT_SYMBOL_NS_GPL(cxl_endpoint_parse_cdat, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_endpoint_parse_cdat, "CXL"); static int cdat_sslbis_handler(union acpi_subtable_headers *header, void *arg, const unsigned long end) @@ -513,7 +513,7 @@ void cxl_switch_parse_cdat(struct cxl_port *port) if (rc) dev_dbg(&port->dev, "Failed to parse SSLBIS: %d\n", rc); } -EXPORT_SYMBOL_NS_GPL(cxl_switch_parse_cdat, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_switch_parse_cdat, "CXL"); static void __cxl_coordinates_combine(struct access_coordinate *out, struct access_coordinate *c1, @@ -545,7 +545,7 @@ void cxl_coordinates_combine(struct access_coordinate *out, __cxl_coordinates_combine(&out[i], &c1[i], &c2[i]); } -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); static void cxl_bandwidth_add(struct access_coordinate *coord, struct access_coordinate *c1, diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index ff0c96ade24146eed95cbb27de1d7d6f2024691a..28edd5822486851912393f066478252b20abc19d 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -73,7 +73,7 @@ int devm_cxl_add_passthrough_decoder(struct cxl_port *port) return add_hdm_decoder(port, &cxlsd->cxld, single_port_map); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_passthrough_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_passthrough_decoder, "CXL"); static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm) { @@ -199,7 +199,7 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port, return cxlhdm; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, "CXL"); static void __cxl_dpa_debug(struct seq_file *file, struct resource *r, int depth) { @@ -221,7 +221,7 @@ void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds) } up_read(&cxl_dpa_rwsem); } -EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, "CXL"); /* * Must be called in a context that synchronizes against this decoder's @@ -358,7 +358,7 @@ int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, "CXL"); resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled) { @@ -738,7 +738,7 @@ void cxl_port_commit_reap(struct cxl_decoder *cxld) device_for_each_child_reverse_from(&port->dev, &cxld->dev, NULL, commit_reap); } -EXPORT_SYMBOL_NS_GPL(cxl_port_commit_reap, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_port_commit_reap, "CXL"); static void cxl_decoder_reset(struct cxl_decoder *cxld) { @@ -1064,4 +1064,4 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm, return 0; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_decoders, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_decoders, "CXL"); diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 5175138c4fb7382426145640d7d04967b02b22dc..548564c770c02c0a4571a00ae3f6de8f63183183 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -281,7 +281,7 @@ int cxl_internal_send_cmd(struct cxl_mailbox *cxl_mbox, return -EIO; return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, "CXL"); static bool cxl_mem_raw_command_allowed(u16 opcode) { @@ -854,7 +854,7 @@ out: kvfree(gsl); return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, "CXL"); void cxl_event_trace_record(const struct cxl_memdev *cxlmd, enum cxl_event_log_type type, @@ -894,7 +894,7 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd, trace_cxl_dram(cxlmd, type, cxlr, hpa, &evt->dram); } } -EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, "CXL"); static void __cxl_event_trace_record(const struct cxl_memdev *cxlmd, enum cxl_event_log_type type, @@ -1063,7 +1063,7 @@ void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status) if (status & CXLDEV_EVENT_STATUS_INFO) cxl_mem_get_records_log(mds, CXL_EVENT_TYPE_INFO); } -EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, "CXL"); /** * cxl_mem_get_partition_info - Get partition info @@ -1155,7 +1155,7 @@ int cxl_dev_state_identify(struct cxl_memdev_state *mds) return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_dev_state_identify, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_dev_state_identify, "CXL"); static int __cxl_mem_sanitize(struct cxl_memdev_state *mds, u16 cmd) { @@ -1306,7 +1306,7 @@ int cxl_mem_create_range_info(struct cxl_memdev_state *mds) mds->active_volatile_bytes, mds->active_persistent_bytes, "pmem"); } -EXPORT_SYMBOL_NS_GPL(cxl_mem_create_range_info, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_mem_create_range_info, "CXL"); int cxl_set_timestamp(struct cxl_memdev_state *mds) { @@ -1333,7 +1333,7 @@ int cxl_set_timestamp(struct cxl_memdev_state *mds) return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_set_timestamp, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_set_timestamp, "CXL"); int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len, struct cxl_region *cxlr) @@ -1384,7 +1384,7 @@ int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len, mutex_unlock(&mds->poison.lock); return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_mem_get_poison, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_mem_get_poison, "CXL"); static void free_poison_buf(void *buf) { @@ -1420,7 +1420,7 @@ int cxl_poison_state_init(struct cxl_memdev_state *mds) mutex_init(&mds->poison.lock); return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_poison_state_init, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_poison_state_init, "CXL"); int cxl_mailbox_init(struct cxl_mailbox *cxl_mbox, struct device *host) { @@ -1433,7 +1433,7 @@ int cxl_mailbox_init(struct cxl_mailbox *cxl_mbox, struct device *host) return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_mailbox_init, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_mailbox_init, "CXL"); struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev) { @@ -1455,7 +1455,7 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev) return mds; } -EXPORT_SYMBOL_NS_GPL(cxl_memdev_state_create, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_memdev_state_create, "CXL"); void __init cxl_mbox_init(void) { diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index 84fefb76dafabc22e6e1a12397381b3f18eea7c5..ae3dfcbe893897aaf315c947d3bdb0741aadf599 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -250,7 +250,7 @@ int cxl_trigger_poison_list(struct cxl_memdev *cxlmd) return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_trigger_poison_list, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_trigger_poison_list, "CXL"); static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa) { @@ -329,7 +329,7 @@ out: return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_inject_poison, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_inject_poison, "CXL"); int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa) { @@ -393,7 +393,7 @@ out: return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_clear_poison, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_clear_poison, "CXL"); static struct attribute *cxl_memdev_attributes[] = { &dev_attr_serial.attr, @@ -537,7 +537,7 @@ void cxl_memdev_update_perf(struct cxl_memdev *cxlmd) sysfs_update_group(&cxlmd->dev.kobj, &cxl_memdev_ram_attribute_group); sysfs_update_group(&cxlmd->dev.kobj, &cxl_memdev_pmem_attribute_group); } -EXPORT_SYMBOL_NS_GPL(cxl_memdev_update_perf, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_memdev_update_perf, "CXL"); static const struct device_type cxl_memdev_type = { .name = "cxl_memdev", @@ -550,7 +550,7 @@ bool is_cxl_memdev(const struct device *dev) { return dev->type == &cxl_memdev_type; } -EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL); +EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL"); /** * set_exclusive_cxl_commands() - atomically disable user cxl commands @@ -569,7 +569,7 @@ void set_exclusive_cxl_commands(struct cxl_memdev_state *mds, CXL_MEM_COMMAND_ID_MAX); up_write(&cxl_memdev_rwsem); } -EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, CXL); +EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL"); /** * clear_exclusive_cxl_commands() - atomically enable user cxl commands @@ -584,7 +584,7 @@ void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds, CXL_MEM_COMMAND_ID_MAX); up_write(&cxl_memdev_rwsem); } -EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, CXL); +EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, "CXL"); static void cxl_memdev_shutdown(struct device *dev) { @@ -1006,7 +1006,7 @@ int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds) return PTR_ERR(fwl); return devm_add_action_or_reset(host, cxl_remove_fw_upload, fwl); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fw_upload, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fw_upload, "CXL"); static const struct file_operations cxl_memdev_fops = { .owner = THIS_MODULE, @@ -1060,7 +1060,7 @@ err: put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_memdev, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_memdev, "CXL"); static void sanitize_teardown_notifier(void *data) { @@ -1105,7 +1105,7 @@ int devm_cxl_sanitize_setup_notifier(struct device *host, return devm_add_action_or_reset(host, sanitize_teardown_notifier, mds); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_sanitize_setup_notifier, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_sanitize_setup_notifier, "CXL"); __init int cxl_memdev_init(void) { diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index 5b46bc46aaa9511957824300c39e2096d6f07dd6..9d58ab9d33c554e05ddfa2610269e6d08bfaa8e9 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -101,7 +101,7 @@ int devm_cxl_port_enumerate_dports(struct cxl_port *port) return ctx.error; return ctx.count; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_port_enumerate_dports, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_port_enumerate_dports, "CXL"); static int cxl_dvsec_mem_range_valid(struct cxl_dev_state *cxlds, int id) { @@ -209,7 +209,7 @@ int cxl_await_media_ready(struct cxl_dev_state *cxlds) return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_await_media_ready, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_await_media_ready, "CXL"); static int cxl_set_mem_enable(struct cxl_dev_state *cxlds, u16 val) { @@ -386,7 +386,7 @@ int cxl_dvsec_rr_decode(struct device *dev, struct cxl_port *port, return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_dvsec_rr_decode, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_dvsec_rr_decode, "CXL"); /** * cxl_hdm_decode_init() - Setup HDM decoding for the endpoint @@ -464,7 +464,7 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm, */ return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_hdm_decode_init, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_hdm_decode_init, "CXL"); #define CXL_DOE_TABLE_ACCESS_REQ_CODE 0x000000ff #define CXL_DOE_TABLE_ACCESS_REQ_CODE_READ 0 @@ -648,7 +648,7 @@ err: devm_kfree(dev, buf); dev_err(dev, "Failed to read/validate CDAT.\n"); } -EXPORT_SYMBOL_NS_GPL(read_cdat_data, CXL); +EXPORT_SYMBOL_NS_GPL(read_cdat_data, "CXL"); static void __cxl_handle_cor_ras(struct cxl_dev_state *cxlds, void __iomem *ras_base) @@ -805,7 +805,7 @@ void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host) cxl_disable_rch_root_ints(dport); } } -EXPORT_SYMBOL_NS_GPL(cxl_dport_init_ras_reporting, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_dport_init_ras_reporting, "CXL"); static void cxl_handle_rdport_cor_ras(struct cxl_dev_state *cxlds, struct cxl_dport *dport) @@ -916,7 +916,7 @@ void cxl_cor_error_detected(struct pci_dev *pdev) cxl_handle_endpoint_cor_ras(cxlds); } } -EXPORT_SYMBOL_NS_GPL(cxl_cor_error_detected, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_cor_error_detected, "CXL"); pci_ers_result_t cxl_error_detected(struct pci_dev *pdev, pci_channel_state_t state) @@ -966,7 +966,7 @@ pci_ers_result_t cxl_error_detected(struct pci_dev *pdev, } return PCI_ERS_RESULT_NEED_RESET; } -EXPORT_SYMBOL_NS_GPL(cxl_error_detected, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_error_detected, "CXL"); static int cxl_flit_size(struct pci_dev *pdev) { @@ -1030,7 +1030,7 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port) return device_for_each_child(&port->dev, port, __cxl_endpoint_decoder_reset_detected); } -EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, "CXL"); int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c) { diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c index c00f3a933164faa524219ee36fca6b5727444033..b3378d3f6acb4c9e3601683119754e3cd6329df2 100644 --- a/drivers/cxl/core/pmem.c +++ b/drivers/cxl/core/pmem.c @@ -49,13 +49,13 @@ struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev) return NULL; return container_of(dev, struct cxl_nvdimm_bridge, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm_bridge, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm_bridge, "CXL"); bool is_cxl_nvdimm_bridge(struct device *dev) { return dev->type == &cxl_nvdimm_bridge_type; } -EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm_bridge, CXL); +EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm_bridge, "CXL"); static int match_nvdimm_bridge(struct device *dev, void *data) { @@ -82,7 +82,7 @@ struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port) return to_cxl_nvdimm_bridge(dev); } -EXPORT_SYMBOL_NS_GPL(cxl_find_nvdimm_bridge, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_find_nvdimm_bridge, "CXL"); static struct lock_class_key cxl_nvdimm_bridge_key; @@ -164,7 +164,7 @@ err: put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, "CXL"); static void cxl_nvdimm_release(struct device *dev) { @@ -188,7 +188,7 @@ bool is_cxl_nvdimm(struct device *dev) { return dev->type == &cxl_nvdimm_type; } -EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm, CXL); +EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm, "CXL"); struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) { @@ -197,7 +197,7 @@ struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) return NULL; return container_of(dev, struct cxl_nvdimm, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm, "CXL"); static struct lock_class_key cxl_nvdimm_key; @@ -293,4 +293,4 @@ err_alloc: return rc; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm, "CXL"); diff --git a/drivers/cxl/core/pmu.c b/drivers/cxl/core/pmu.c index 5d8e06b0ba6e88f383953982cf836c1da8099ec6..b3136d7664aba83257915f6b07a587a7c4c56a83 100644 --- a/drivers/cxl/core/pmu.c +++ b/drivers/cxl/core/pmu.c @@ -65,4 +65,4 @@ err: put_device(&pmu->dev); return rc; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_pmu_add, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_pmu_add, "CXL"); diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index af92c67bc9542d0cede905d6a1f35c695c7f446b..78a5c2c259829c3e1a7671ff61fdd95c6c43cc82 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -437,7 +437,7 @@ struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev) return NULL; return container_of(dev, struct cxl_root_decoder, cxlsd.cxld.dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_root_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_root_decoder, "CXL"); static void cxl_root_decoder_release(struct device *dev) { @@ -471,19 +471,19 @@ bool is_endpoint_decoder(struct device *dev) { return dev->type == &cxl_decoder_endpoint_type; } -EXPORT_SYMBOL_NS_GPL(is_endpoint_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(is_endpoint_decoder, "CXL"); bool is_root_decoder(struct device *dev) { return dev->type == &cxl_decoder_root_type; } -EXPORT_SYMBOL_NS_GPL(is_root_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(is_root_decoder, "CXL"); bool is_switch_decoder(struct device *dev) { return is_root_decoder(dev) || dev->type == &cxl_decoder_switch_type; } -EXPORT_SYMBOL_NS_GPL(is_switch_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(is_switch_decoder, "CXL"); struct cxl_decoder *to_cxl_decoder(struct device *dev) { @@ -493,7 +493,7 @@ struct cxl_decoder *to_cxl_decoder(struct device *dev) return NULL; return container_of(dev, struct cxl_decoder, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, "CXL"); struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev) { @@ -502,7 +502,7 @@ struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev) return NULL; return container_of(dev, struct cxl_endpoint_decoder, cxld.dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_endpoint_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_endpoint_decoder, "CXL"); struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev) { @@ -511,7 +511,7 @@ struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev) return NULL; return container_of(dev, struct cxl_switch_decoder, cxld.dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_switch_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_switch_decoder, "CXL"); static void cxl_ep_release(struct cxl_ep *ep) { @@ -585,7 +585,7 @@ bool is_cxl_port(const struct device *dev) { return dev->type == &cxl_port_type; } -EXPORT_SYMBOL_NS_GPL(is_cxl_port, CXL); +EXPORT_SYMBOL_NS_GPL(is_cxl_port, "CXL"); struct cxl_port *to_cxl_port(const struct device *dev) { @@ -594,7 +594,7 @@ struct cxl_port *to_cxl_port(const struct device *dev) return NULL; return container_of(dev, struct cxl_port, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_port, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_port, "CXL"); static void unregister_port(void *_port) { @@ -942,7 +942,7 @@ struct cxl_port *devm_cxl_add_port(struct device *host, return port; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, "CXL"); struct cxl_root *devm_cxl_add_root(struct device *host, const struct cxl_root_ops *ops) @@ -958,7 +958,7 @@ struct cxl_root *devm_cxl_add_root(struct device *host, cxl_root->ops = ops; return cxl_root; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_root, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_root, "CXL"); struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port) { @@ -974,7 +974,7 @@ struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port) return xa_load(&cxl_root_buses, (unsigned long)port->uport_dev); } -EXPORT_SYMBOL_NS_GPL(cxl_port_to_pci_bus, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_port_to_pci_bus, "CXL"); static void unregister_pci_bus(void *uport_dev) { @@ -995,7 +995,7 @@ int devm_cxl_register_pci_bus(struct device *host, struct device *uport_dev, return rc; return devm_add_action_or_reset(host, unregister_pci_bus, uport_dev); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_register_pci_bus, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_register_pci_bus, "CXL"); static bool dev_is_cxl_root_child(struct device *dev) { @@ -1027,7 +1027,7 @@ struct cxl_root *find_cxl_root(struct cxl_port *port) get_device(&iter->dev); return to_cxl_root(iter); } -EXPORT_SYMBOL_NS_GPL(find_cxl_root, CXL); +EXPORT_SYMBOL_NS_GPL(find_cxl_root, "CXL"); void put_cxl_root(struct cxl_root *cxl_root) { @@ -1036,7 +1036,7 @@ void put_cxl_root(struct cxl_root *cxl_root) put_device(&cxl_root->port.dev); } -EXPORT_SYMBOL_NS_GPL(put_cxl_root, CXL); +EXPORT_SYMBOL_NS_GPL(put_cxl_root, "CXL"); static struct cxl_dport *find_dport(struct cxl_port *port, int id) { @@ -1230,7 +1230,7 @@ struct cxl_dport *devm_cxl_add_dport(struct cxl_port *port, return dport; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_dport, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_dport, "CXL"); /** * devm_cxl_add_rch_dport - append RCH downstream port data to a cxl_port @@ -1264,7 +1264,7 @@ struct cxl_dport *devm_cxl_add_rch_dport(struct cxl_port *port, return dport; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_rch_dport, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_rch_dport, "CXL"); static int add_ep(struct cxl_ep *new) { @@ -1421,7 +1421,7 @@ int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint) cxlmd->depth = endpoint->depth; return devm_add_action_or_reset(dev, delete_endpoint, cxlmd); } -EXPORT_SYMBOL_NS_GPL(cxl_endpoint_autoremove, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_endpoint_autoremove, "CXL"); /* * The natural end of life of a non-root 'cxl_port' is when its parent port goes @@ -1692,21 +1692,21 @@ retry: return 0; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_ports, CXL); +EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_ports, "CXL"); struct cxl_port *cxl_pci_find_port(struct pci_dev *pdev, struct cxl_dport **dport) { return find_cxl_port(pdev->dev.parent, dport); } -EXPORT_SYMBOL_NS_GPL(cxl_pci_find_port, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_pci_find_port, "CXL"); struct cxl_port *cxl_mem_find_port(struct cxl_memdev *cxlmd, struct cxl_dport **dport) { return find_cxl_port(grandparent(&cxlmd->dev), dport); } -EXPORT_SYMBOL_NS_GPL(cxl_mem_find_port, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_mem_find_port, "CXL"); static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd, struct cxl_port *port, int *target_map) @@ -1840,7 +1840,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port, cxlrd->qos_class = CXL_QOS_CLASS_INVALID; return cxlrd; } -EXPORT_SYMBOL_NS_GPL(cxl_root_decoder_alloc, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_root_decoder_alloc, "CXL"); /** * cxl_switch_decoder_alloc - Allocate a switch level decoder @@ -1877,7 +1877,7 @@ struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port, cxld->dev.type = &cxl_decoder_switch_type; return cxlsd; } -EXPORT_SYMBOL_NS_GPL(cxl_switch_decoder_alloc, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_switch_decoder_alloc, "CXL"); /** * cxl_endpoint_decoder_alloc - Allocate an endpoint decoder @@ -1909,7 +1909,7 @@ struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port) cxld->dev.type = &cxl_decoder_endpoint_type; return cxled; } -EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, "CXL"); /** * cxl_decoder_add_locked - Add a decoder with targets @@ -1965,7 +1965,7 @@ int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map) return device_add(dev); } -EXPORT_SYMBOL_NS_GPL(cxl_decoder_add_locked, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_decoder_add_locked, "CXL"); /** * cxl_decoder_add - Add a decoder with targets @@ -1995,7 +1995,7 @@ int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map) guard(device)(&port->dev); return cxl_decoder_add_locked(cxld, target_map); } -EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, "CXL"); static void cxld_unregister(void *dev) { @@ -2013,7 +2013,7 @@ int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld) { return devm_add_action_or_reset(host, cxld_unregister, &cxld->dev); } -EXPORT_SYMBOL_NS_GPL(cxl_decoder_autoremove, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_decoder_autoremove, "CXL"); /** * __cxl_driver_register - register a driver for the cxl bus @@ -2046,13 +2046,13 @@ int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner, return driver_register(&cxl_drv->drv); } -EXPORT_SYMBOL_NS_GPL(__cxl_driver_register, CXL); +EXPORT_SYMBOL_NS_GPL(__cxl_driver_register, "CXL"); void cxl_driver_unregister(struct cxl_driver *cxl_drv) { driver_unregister(&cxl_drv->drv); } -EXPORT_SYMBOL_NS_GPL(cxl_driver_unregister, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_driver_unregister, "CXL"); static int cxl_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) { @@ -2104,19 +2104,19 @@ void cxl_bus_rescan(void) queue_work(cxl_bus_wq, &rescan_work); } -EXPORT_SYMBOL_NS_GPL(cxl_bus_rescan, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_bus_rescan, "CXL"); void cxl_bus_drain(void) { drain_workqueue(cxl_bus_wq); } -EXPORT_SYMBOL_NS_GPL(cxl_bus_drain, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_bus_drain, "CXL"); bool schedule_cxl_memdev_detach(struct cxl_memdev *cxlmd) { return queue_work(cxl_bus_wq, &cxlmd->detach_work); } -EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, CXL); +EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, "CXL"); static void add_latency(struct access_coordinate *c, long latency) { @@ -2242,7 +2242,7 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port, return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_endpoint_get_perf_coordinates, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_endpoint_get_perf_coordinates, "CXL"); int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port, struct access_coordinate *c) @@ -2299,7 +2299,7 @@ struct bus_type cxl_bus_type = { .remove = cxl_bus_remove, .bus_groups = cxl_bus_attribute_groups, }; -EXPORT_SYMBOL_NS_GPL(cxl_bus_type, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_bus_type, "CXL"); static struct dentry *cxl_debugfs; @@ -2307,7 +2307,7 @@ struct dentry *cxl_debugfs_create_dir(const char *dir) { return debugfs_create_dir(dir, cxl_debugfs); } -EXPORT_SYMBOL_NS_GPL(cxl_debugfs_create_dir, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_debugfs_create_dir, "CXL"); static __init int cxl_core_init(void) { @@ -2363,4 +2363,4 @@ subsys_initcall(cxl_core_init); module_exit(cxl_core_exit); MODULE_DESCRIPTION("CXL: Core Compute Express Link support"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 70d0a017e99c85c71f410e405970b2c6cdc47b67..d778996507984a759bbe84e7acac3774e0c7af98 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -2299,7 +2299,7 @@ bool is_cxl_region(struct device *dev) { return dev->type == &cxl_region_type; } -EXPORT_SYMBOL_NS_GPL(is_cxl_region, CXL); +EXPORT_SYMBOL_NS_GPL(is_cxl_region, "CXL"); static struct cxl_region *to_cxl_region(struct device *dev) { @@ -2652,7 +2652,7 @@ bool is_cxl_pmem_region(struct device *dev) { return dev->type == &cxl_pmem_region_type; } -EXPORT_SYMBOL_NS_GPL(is_cxl_pmem_region, CXL); +EXPORT_SYMBOL_NS_GPL(is_cxl_pmem_region, "CXL"); struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev) { @@ -2661,7 +2661,7 @@ struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev) return NULL; return container_of(dev, struct cxl_pmem_region, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_pmem_region, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_pmem_region, "CXL"); struct cxl_poison_context { struct cxl_port *port; @@ -3015,7 +3015,7 @@ struct cxl_dax_region *to_cxl_dax_region(struct device *dev) return NULL; return container_of(dev, struct cxl_dax_region, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_dax_region, CXL); +EXPORT_SYMBOL_NS_GPL(to_cxl_dax_region, "CXL"); static struct lock_class_key cxl_dax_region_key; @@ -3359,7 +3359,7 @@ out: put_device(cxlrd_dev); return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, "CXL"); static int is_system_ram(struct resource *res, void *arg) { @@ -3462,6 +3462,6 @@ void cxl_region_exit(void) cxl_driver_unregister(&cxl_region_driver); } -MODULE_IMPORT_NS(CXL); -MODULE_IMPORT_NS(DEVMEM); +MODULE_IMPORT_NS("CXL"); +MODULE_IMPORT_NS("DEVMEM"); MODULE_ALIAS_CXL(CXL_DEVICE_REGION); diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index 429973a2165bb0bf3e5e2970501d83fc5734d874..59cb35b40c7e5502ab664afa72135c97575e44ac 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -106,7 +106,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, rmap->size = length; } } -EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, "CXL"); /** * cxl_probe_device_regs() - Detect CXL Device register blocks @@ -174,7 +174,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base, rmap->size = length; } } -EXPORT_SYMBOL_NS_GPL(cxl_probe_device_regs, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_probe_device_regs, "CXL"); void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr, resource_size_t length) @@ -232,7 +232,7 @@ int cxl_map_component_regs(const struct cxl_register_map *map, return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, "CXL"); int cxl_map_device_regs(const struct cxl_register_map *map, struct cxl_device_regs *regs) @@ -266,7 +266,7 @@ int cxl_map_device_regs(const struct cxl_register_map *map, return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, "CXL"); static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi, struct cxl_register_map *map) @@ -344,7 +344,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type, map->resource = CXL_RESOURCE_NONE; return -ENODEV; } -EXPORT_SYMBOL_NS_GPL(cxl_find_regblock_instance, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_find_regblock_instance, "CXL"); /** * cxl_find_regblock() - Locate register blocks by type @@ -362,7 +362,7 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type, { return cxl_find_regblock_instance(pdev, type, map, 0); } -EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, "CXL"); /** * cxl_count_regblock() - Count instances of a given regblock type. @@ -385,7 +385,7 @@ int cxl_count_regblock(struct pci_dev *pdev, enum cxl_regloc_type type) count++; } } -EXPORT_SYMBOL_NS_GPL(cxl_count_regblock, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_count_regblock, "CXL"); int cxl_map_pmu_regs(struct cxl_register_map *map, struct cxl_pmu_regs *regs) { @@ -399,7 +399,7 @@ int cxl_map_pmu_regs(struct cxl_register_map *map, struct cxl_pmu_regs *regs) return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_map_pmu_regs, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_map_pmu_regs, "CXL"); static int cxl_map_regblock(struct cxl_register_map *map) { @@ -468,7 +468,7 @@ int cxl_setup_regs(struct cxl_register_map *map) return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_setup_regs, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_setup_regs, "CXL"); u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb) { @@ -560,7 +560,7 @@ int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport) return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_dport_map_rcd_linkcap, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_dport_map_rcd_linkcap, "CXL"); resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri, enum cxl_rcrb which) @@ -633,4 +633,4 @@ resource_size_t cxl_rcd_component_reg_phys(struct device *dev, return CXL_RESOURCE_NONE; return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); } -EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, "CXL"); diff --git a/drivers/cxl/core/suspend.c b/drivers/cxl/core/suspend.c index a5984d96ea1d06a9641ecfc9f0f465f4a74068f4..29aa5cc5e5652a549fc9203d005ae4b6e5eb4b93 100644 --- a/drivers/cxl/core/suspend.c +++ b/drivers/cxl/core/suspend.c @@ -15,10 +15,10 @@ void cxl_mem_active_inc(void) { atomic_inc(&mem_active); } -EXPORT_SYMBOL_NS_GPL(cxl_mem_active_inc, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_mem_active_inc, "CXL"); void cxl_mem_active_dec(void) { atomic_dec(&mem_active); } -EXPORT_SYMBOL_NS_GPL(cxl_mem_active_dec, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_mem_active_dec, "CXL"); diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c index a9fd5cd5a0d2f97f60a4d4d82d3d94848adafb9e..2f03a4d5606ea7834c67c07e3b8c9bf1887f23ea 100644 --- a/drivers/cxl/mem.c +++ b/drivers/cxl/mem.c @@ -252,7 +252,7 @@ module_cxl_driver(cxl_mem_driver); MODULE_DESCRIPTION("CXL: Memory Expansion"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); MODULE_ALIAS_CXL(CXL_DEVICE_MEMORY_EXPANDER); /* * create_endpoint() wants to validate port driver attach immediately after diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index b2cb81f6d9e7d094be771827fe770f7eb3eb0047..0241d1d7133a4b9c3fe3fddfdc0bcc9cf807ee11 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1184,4 +1184,4 @@ module_init(cxl_pci_driver_init); module_exit(cxl_pci_driver_exit); MODULE_DESCRIPTION("CXL: PCI manageability"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index d2d43a4fc05387fdd643d5f7d73612e49b5762bc..f9c95996e937ed495e2fd9ac8547c9e3102ad7cc 100644 --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@ -459,7 +459,7 @@ MODULE_DESCRIPTION("CXL PMEM: Persistent Memory Support"); MODULE_LICENSE("GPL v2"); module_init(cxl_pmem_init); module_exit(cxl_pmem_exit); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); MODULE_ALIAS_CXL(CXL_DEVICE_NVDIMM_BRIDGE); MODULE_ALIAS_CXL(CXL_DEVICE_NVDIMM); MODULE_ALIAS_CXL(CXL_DEVICE_PMEM_REGION); diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c index 9dc394295e1fcd1610813837b2f515b66995eb25..4c83f6a22e584f1f248807c7fa4fe932d6f11d67 100644 --- a/drivers/cxl/port.c +++ b/drivers/cxl/port.c @@ -173,7 +173,7 @@ static ssize_t CDAT_read(struct file *filp, struct kobject *kobj, static BIN_ATTR_ADMIN_RO(CDAT, 0); static umode_t cxl_port_bin_attr_is_visible(struct kobject *kobj, - struct bin_attribute *attr, int i) + const struct bin_attribute *attr, int i) { struct device *dev = kobj_to_dev(kobj); struct cxl_port *port = to_cxl_port(dev); @@ -226,5 +226,5 @@ module_exit(cxl_port_exit); MODULE_DESCRIPTION("CXL: Port enumeration and services"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); MODULE_ALIAS_CXL(CXL_DEVICE_PORT); diff --git a/drivers/dax/cxl.c b/drivers/dax/cxl.c index 9b29e732b39a691fbd8ac0391b477b1584b59568..13cd94d32ff7a1d70af7821c1aecd7490302149d 100644 --- a/drivers/dax/cxl.c +++ b/drivers/dax/cxl.c @@ -46,4 +46,4 @@ MODULE_ALIAS_CXL(CXL_DEVICE_DAX_REGION); MODULE_DESCRIPTION("CXL DAX: direct access to CXL regions"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Intel Corporation"); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); diff --git a/drivers/devfreq/event/exynos-nocp.c b/drivers/devfreq/event/exynos-nocp.c index 5edc522f715c3e1e1cd334cc66dae5f5ab9018a6..6a3efd782ad0dfe99f369677e204a37e7a377a7b 100644 --- a/drivers/devfreq/event/exynos-nocp.c +++ b/drivers/devfreq/event/exynos-nocp.c @@ -284,7 +284,7 @@ static void exynos_nocp_remove(struct platform_device *pdev) static struct platform_driver exynos_nocp_driver = { .probe = exynos_nocp_probe, - .remove_new = exynos_nocp_remove, + .remove = exynos_nocp_remove, .driver = { .name = "exynos-nocp", .of_match_table = exynos_nocp_id_match, diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c index 7002df20a49eef308f5f4d4aa6853e23b510b6cf..88cd4dfe87e127bbdeb1f91ceb2a3659b0186915 100644 --- a/drivers/devfreq/event/exynos-ppmu.c +++ b/drivers/devfreq/event/exynos-ppmu.c @@ -701,7 +701,7 @@ static void exynos_ppmu_remove(struct platform_device *pdev) static struct platform_driver exynos_ppmu_driver = { .probe = exynos_ppmu_probe, - .remove_new = exynos_ppmu_remove, + .remove = exynos_ppmu_remove, .driver = { .name = "exynos-ppmu", .of_match_table = exynos_ppmu_id_match, diff --git a/drivers/devfreq/mtk-cci-devfreq.c b/drivers/devfreq/mtk-cci-devfreq.c index 7ad5225b0381d23ae518e4a6fdbe20363b74c2b6..22fe9e631f8aaf4808afdd4a1a1cf300d026010a 100644 --- a/drivers/devfreq/mtk-cci-devfreq.c +++ b/drivers/devfreq/mtk-cci-devfreq.c @@ -430,7 +430,7 @@ MODULE_DEVICE_TABLE(of, mtk_ccifreq_machines); static struct platform_driver mtk_ccifreq_platdrv = { .probe = mtk_ccifreq_probe, - .remove_new = mtk_ccifreq_remove, + .remove = mtk_ccifreq_remove, .driver = { .name = "mtk-ccifreq", .of_match_table = mtk_ccifreq_machines, diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c index d405cee92c250670e7878ebe1865c2b6b3c32a91..dbdce7636ca5b8d62335cfd0c9cafd6408c74ffe 100644 --- a/drivers/devfreq/rk3399_dmc.c +++ b/drivers/devfreq/rk3399_dmc.c @@ -474,7 +474,7 @@ MODULE_DEVICE_TABLE(of, rk3399dmc_devfreq_of_match); static struct platform_driver rk3399_dmcfreq_driver = { .probe = rk3399_dmcfreq_probe, - .remove_new = rk3399_dmcfreq_remove, + .remove = rk3399_dmcfreq_remove, .driver = { .name = "rk3399-dmc-freq", .pm = &rk3399_dmcfreq_pm, diff --git a/drivers/devfreq/sun8i-a33-mbus.c b/drivers/devfreq/sun8i-a33-mbus.c index bcf654f4ff96b8c7efaa7cd2e6c5ddf9e5665807..7c6ae91ede1f56ad26e7b71bb1675d2b91d38178 100644 --- a/drivers/devfreq/sun8i-a33-mbus.c +++ b/drivers/devfreq/sun8i-a33-mbus.c @@ -495,7 +495,7 @@ static SIMPLE_DEV_PM_OPS(sun8i_a33_mbus_pm_ops, static struct platform_driver sun8i_a33_mbus_driver = { .probe = sun8i_a33_mbus_probe, - .remove_new = sun8i_a33_mbus_remove, + .remove = sun8i_a33_mbus_remove, .driver = { .name = "sun8i-a33-mbus", .of_match_table = sun8i_a33_mbus_of_match, diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 5ad0e9e2e1b93b4095b48ce2c7dd37f8c4701666..7eeee3a382021b0ea533436fe81bee0e3c38ca70 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -703,7 +703,7 @@ err_module: module_put(exp_info->owner); return ERR_PTR(ret); } -EXPORT_SYMBOL_NS_GPL(dma_buf_export, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_export, "DMA_BUF"); /** * dma_buf_fd - returns a file descriptor for the given struct dma_buf @@ -727,7 +727,7 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags) return fd; } -EXPORT_SYMBOL_NS_GPL(dma_buf_fd, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF"); /** * dma_buf_get - returns the struct dma_buf related to an fd @@ -753,7 +753,7 @@ struct dma_buf *dma_buf_get(int fd) return file->private_data; } -EXPORT_SYMBOL_NS_GPL(dma_buf_get, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF"); /** * dma_buf_put - decreases refcount of the buffer @@ -772,7 +772,7 @@ void dma_buf_put(struct dma_buf *dmabuf) fput(dmabuf->file); } -EXPORT_SYMBOL_NS_GPL(dma_buf_put, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF"); static void mangle_sg_table(struct sg_table *sg_table) { @@ -978,7 +978,7 @@ err_unlock: dma_buf_detach(dmabuf, attach); return ERR_PTR(ret); } -EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF"); /** * dma_buf_attach - Wrapper for dma_buf_dynamic_attach @@ -993,7 +993,7 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, { return dma_buf_dynamic_attach(dmabuf, dev, NULL, NULL); } -EXPORT_SYMBOL_NS_GPL(dma_buf_attach, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_attach, "DMA_BUF"); static void __unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sg_table, @@ -1037,7 +1037,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) kfree(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_detach, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF"); /** * dma_buf_pin - Lock down the DMA-buf @@ -1067,7 +1067,7 @@ int dma_buf_pin(struct dma_buf_attachment *attach) return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_pin, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_pin, "DMA_BUF"); /** * dma_buf_unpin - Unpin a DMA-buf @@ -1088,7 +1088,7 @@ void dma_buf_unpin(struct dma_buf_attachment *attach) if (dmabuf->ops->unpin) dmabuf->ops->unpin(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, "DMA_BUF"); /** * dma_buf_map_attachment - Returns the scatterlist table of the attachment; @@ -1176,7 +1176,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, #endif /* CONFIG_DMA_API_DEBUG */ return sg_table; } -EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, "DMA_BUF"); /** * dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment; @@ -1204,7 +1204,7 @@ dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach, return sg_table; } -EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, "DMA_BUF"); /** * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might @@ -1236,7 +1236,7 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, !IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) dma_buf_unpin(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, "DMA_BUF"); /** * dma_buf_unmap_attachment_unlocked - unmaps and decreases usecount of the buffer;might @@ -1261,7 +1261,7 @@ void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach, dma_buf_unmap_attachment(attach, sg_table, direction); dma_resv_unlock(attach->dmabuf->resv); } -EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment_unlocked, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment_unlocked, "DMA_BUF"); /** * dma_buf_move_notify - notify attachments that DMA-buf is moving @@ -1281,7 +1281,7 @@ void dma_buf_move_notify(struct dma_buf *dmabuf) if (attach->importer_ops) attach->importer_ops->move_notify(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, "DMA_BUF"); /** * DOC: cpu access @@ -1429,7 +1429,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_begin_cpu_access, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_begin_cpu_access, "DMA_BUF"); /** * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the @@ -1457,7 +1457,7 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf, return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, "DMA_BUF"); /** @@ -1499,7 +1499,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, return dmabuf->ops->mmap(dmabuf, vma); } -EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, "DMA_BUF"); /** * dma_buf_vmap - Create virtual mapping for the buffer object into kernel @@ -1552,7 +1552,7 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map) return 0; } -EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, "DMA_BUF"); /** * dma_buf_vmap_unlocked - Create virtual mapping for the buffer object into kernel @@ -1579,7 +1579,7 @@ int dma_buf_vmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map) return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_vmap_unlocked, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_vmap_unlocked, "DMA_BUF"); /** * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap. @@ -1603,7 +1603,7 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) iosys_map_clear(&dmabuf->vmap_ptr); } } -EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap, "DMA_BUF"); /** * dma_buf_vunmap_unlocked - Unmap a vmap obtained by dma_buf_vmap. @@ -1619,7 +1619,7 @@ void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map) dma_buf_vunmap(dmabuf, map); dma_resv_unlock(dmabuf->resv); } -EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF); +EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, "DMA_BUF"); #ifdef CONFIG_DEBUG_FS static int dma_buf_debug_show(struct seq_file *s, void *unused) diff --git a/drivers/dma/idxd/Makefile b/drivers/dma/idxd/Makefile index 2b4a0d406e1e713556e9b166f0a09098e9374ea1..9ff9d7b87b649d0bb000e0cb57f86140fe10cc0d 100644 --- a/drivers/dma/idxd/Makefile +++ b/drivers/dma/idxd/Makefile @@ -1,4 +1,4 @@ -ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD +ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"IDXD"' obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o idxd_bus-y := bus.o diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c index a4adb0c179959fcb933ff7f2e9804951fe2d59b2..eff9943f1a42e2f7b1cc41fc1546b6973513bc62 100644 --- a/drivers/dma/idxd/compat.c +++ b/drivers/dma/idxd/compat.c @@ -103,4 +103,4 @@ struct idxd_device_driver dsa_drv = { }; module_idxd_driver(dsa_drv); -MODULE_IMPORT_NS(IDXD); +MODULE_IMPORT_NS("IDXD"); diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index c41ef195eeb9f218935520301f3582b9b6787c7d..5cf419fe6b4645337cf361305ca066d34763b3c2 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -161,7 +161,7 @@ int idxd_wq_alloc_resources(struct idxd_wq *wq) free_hw_descs(wq); return rc; } -EXPORT_SYMBOL_NS_GPL(idxd_wq_alloc_resources, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_wq_alloc_resources, "IDXD"); void idxd_wq_free_resources(struct idxd_wq *wq) { @@ -175,7 +175,7 @@ void idxd_wq_free_resources(struct idxd_wq *wq) dma_free_coherent(dev, wq->compls_size, wq->compls, wq->compls_addr); sbitmap_queue_free(&wq->sbq); } -EXPORT_SYMBOL_NS_GPL(idxd_wq_free_resources, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_wq_free_resources, "IDXD"); int idxd_wq_enable(struct idxd_wq *wq) { @@ -407,7 +407,7 @@ int idxd_wq_init_percpu_ref(struct idxd_wq *wq) reinit_completion(&wq->wq_resurrect); return 0; } -EXPORT_SYMBOL_NS_GPL(idxd_wq_init_percpu_ref, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_wq_init_percpu_ref, "IDXD"); void __idxd_wq_quiesce(struct idxd_wq *wq) { @@ -417,7 +417,7 @@ void __idxd_wq_quiesce(struct idxd_wq *wq) complete_all(&wq->wq_resurrect); wait_for_completion(&wq->wq_dead); } -EXPORT_SYMBOL_NS_GPL(__idxd_wq_quiesce, IDXD); +EXPORT_SYMBOL_NS_GPL(__idxd_wq_quiesce, "IDXD"); void idxd_wq_quiesce(struct idxd_wq *wq) { @@ -425,7 +425,7 @@ void idxd_wq_quiesce(struct idxd_wq *wq) __idxd_wq_quiesce(wq); mutex_unlock(&wq->wq_lock); } -EXPORT_SYMBOL_NS_GPL(idxd_wq_quiesce, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_wq_quiesce, "IDXD"); /* Device control bits */ static inline bool idxd_is_enabled(struct idxd_device *idxd) @@ -1494,7 +1494,7 @@ err_map_portal: err: return rc; } -EXPORT_SYMBOL_NS_GPL(idxd_drv_enable_wq, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_drv_enable_wq, "IDXD"); void idxd_drv_disable_wq(struct idxd_wq *wq) { @@ -1516,7 +1516,7 @@ void idxd_drv_disable_wq(struct idxd_wq *wq) wq->type = IDXD_WQT_NONE; wq->client_count = 0; } -EXPORT_SYMBOL_NS_GPL(idxd_drv_disable_wq, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_drv_disable_wq, "IDXD"); int idxd_device_drv_probe(struct idxd_dev *idxd_dev) { diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 234c1c658ec792fbf37b6564f7ec235b77290644..140f8d772bee13718aa1d32264b264a2e6e7bc0f 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -25,7 +25,7 @@ MODULE_VERSION(IDXD_DRIVER_VERSION); MODULE_DESCRIPTION("Intel Data Streaming Accelerator and In-Memory Analytics Accelerator common driver"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Intel Corporation"); -MODULE_IMPORT_NS(IDXD); +MODULE_IMPORT_NS("IDXD"); static bool sva = true; module_param(sva, bool, 0644); diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c index 94eca25ae9b909af6f662a93bab37349bb747c4a..6db1c5fcedc5800aca536eee264118b230d1a477 100644 --- a/drivers/dma/idxd/submit.c +++ b/drivers/dma/idxd/submit.c @@ -61,7 +61,7 @@ struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype) return __get_desc(wq, idx, cpu); } -EXPORT_SYMBOL_NS_GPL(idxd_alloc_desc, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_alloc_desc, "IDXD"); void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc) { @@ -70,7 +70,7 @@ void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc) desc->cpu = -1; sbitmap_queue_clear(&wq->sbq, desc->id, cpu); } -EXPORT_SYMBOL_NS_GPL(idxd_free_desc, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_free_desc, "IDXD"); static struct idxd_desc *list_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie, struct idxd_desc *desc) @@ -219,4 +219,4 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) percpu_ref_put(&wq->wq_active); return 0; } -EXPORT_SYMBOL_NS_GPL(idxd_submit_desc, IDXD); +EXPORT_SYMBOL_NS_GPL(idxd_submit_desc, "IDXD"); diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index fe89f5c4837f49cc8a8bfca90aa19e9f81dcf658..3e971f9023633087ef91ca7b06f4eb296049093f 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -482,7 +482,7 @@ static const struct dev_pm_ops altr_sdram_pm_ops = { static struct platform_driver altr_sdram_edac_driver = { .probe = altr_sdram_probe, - .remove_new = altr_sdram_remove, + .remove = altr_sdram_remove, .driver = { .name = "altr_sdram_edac", #ifdef CONFIG_PM @@ -816,7 +816,7 @@ static void altr_edac_device_remove(struct platform_device *pdev) static struct platform_driver altr_edac_device_driver = { .probe = altr_edac_device_probe, - .remove_new = altr_edac_device_remove, + .remove = altr_edac_device_remove, .driver = { .name = "altr_edac_device", .of_match_table = altr_edac_device_of_match, diff --git a/drivers/edac/armada_xp_edac.c b/drivers/edac/armada_xp_edac.c index 589bc81f124902f0c9baca3281913c248e65f4f7..d64248fcf4c055c92fbf652b2e77766cf4e77244 100644 --- a/drivers/edac/armada_xp_edac.c +++ b/drivers/edac/armada_xp_edac.c @@ -364,7 +364,7 @@ static void axp_mc_remove(struct platform_device *pdev) static struct platform_driver axp_mc_driver = { .probe = axp_mc_probe, - .remove_new = axp_mc_remove, + .remove = axp_mc_remove, .driver = { .name = "armada_xp_mc_edac", .of_match_table = of_match_ptr(axp_mc_of_match), @@ -579,7 +579,7 @@ static void aurora_l2_remove(struct platform_device *pdev) static struct platform_driver aurora_l2_driver = { .probe = aurora_l2_probe, - .remove_new = aurora_l2_remove, + .remove = aurora_l2_remove, .driver = { .name = "aurora_l2_edac", .of_match_table = of_match_ptr(aurora_l2_of_match), diff --git a/drivers/edac/aspeed_edac.c b/drivers/edac/aspeed_edac.c index 157a480eb761b10e6f7cc0d82e0cdafa889dd77e..dadb8acbee3d6c258fe55c5dddfb075650c289db 100644 --- a/drivers/edac/aspeed_edac.c +++ b/drivers/edac/aspeed_edac.c @@ -387,7 +387,7 @@ static struct platform_driver aspeed_driver = { .of_match_table = aspeed_of_match }, .probe = aspeed_probe, - .remove_new = aspeed_remove + .remove = aspeed_remove }; module_platform_driver(aspeed_driver); diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c index 739132e5ed8af089bf54f8abe36118a4060db2bf..4942a240c30f2593cf21aa44322662eaa84d524e 100644 --- a/drivers/edac/bluefield_edac.c +++ b/drivers/edac/bluefield_edac.c @@ -474,7 +474,7 @@ static struct platform_driver bluefield_edac_mc_driver = { .acpi_match_table = bluefield_mc_acpi_ids, }, .probe = bluefield_edac_mc_probe, - .remove_new = bluefield_edac_mc_remove, + .remove = bluefield_edac_mc_remove, }; module_platform_driver(bluefield_edac_mc_driver); diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index 2000f66fbf5c4628710d0883422a9316f34fd9e2..c2420e2287ff7ff150f70ec3bbf28ba4b7886f53 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c @@ -246,7 +246,7 @@ static struct platform_driver cell_edac_driver = { .name = "cbe-mic", }, .probe = cell_edac_probe, - .remove_new = cell_edac_remove, + .remove = cell_edac_remove, }; static int __init cell_edac_init(void) diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c index eb702bc3aa29a5ed205a322b9e23e88fddb1939c..9c9e4369c04118f2ac3017c8649f241caadf1c10 100644 --- a/drivers/edac/cpc925_edac.c +++ b/drivers/edac/cpc925_edac.c @@ -1027,7 +1027,7 @@ static void cpc925_remove(struct platform_device *pdev) static struct platform_driver cpc925_edac_driver = { .probe = cpc925_probe, - .remove_new = cpc925_remove, + .remove = cpc925_remove, .driver = { .name = "cpc925_edac", } diff --git a/drivers/edac/dmc520_edac.c b/drivers/edac/dmc520_edac.c index 5e52d31db3b8f5a0e7118dd2e2b99caeb0621c4d..64a4d0a07032cc5149dd62a785f0e930bc32bf75 100644 --- a/drivers/edac/dmc520_edac.c +++ b/drivers/edac/dmc520_edac.c @@ -640,7 +640,7 @@ static struct platform_driver dmc520_edac_driver = { }, .probe = dmc520_edac_probe, - .remove_new = dmc520_edac_remove + .remove = dmc520_edac_remove }; module_platform_driver(dmc520_edac_driver); diff --git a/drivers/edac/highbank_l2_edac.c b/drivers/edac/highbank_l2_edac.c index 282ca6535f8f63544427b8f6a0559a6488aa9402..24f163ff323f6a21568d65433b14288612cb3651 100644 --- a/drivers/edac/highbank_l2_edac.c +++ b/drivers/edac/highbank_l2_edac.c @@ -128,7 +128,7 @@ static void highbank_l2_err_remove(struct platform_device *pdev) static struct platform_driver highbank_l2_edac_driver = { .probe = highbank_l2_err_probe, - .remove_new = highbank_l2_err_remove, + .remove = highbank_l2_err_remove, .driver = { .name = "hb_l2_edac", .of_match_table = hb_l2_err_of_match, diff --git a/drivers/edac/highbank_mc_edac.c b/drivers/edac/highbank_mc_edac.c index 1c5b888ab11de3598f6b334c7b2cf2d401751c9f..a8879d72d064a00fa1c6b43a64a6fb8846345b1c 100644 --- a/drivers/edac/highbank_mc_edac.c +++ b/drivers/edac/highbank_mc_edac.c @@ -261,7 +261,7 @@ static void highbank_mc_remove(struct platform_device *pdev) static struct platform_driver highbank_mc_edac_driver = { .probe = highbank_mc_probe, - .remove_new = highbank_mc_remove, + .remove = highbank_mc_remove, .driver = { .name = "hb_mc_edac", .of_match_table = hb_ddr_ctrl_of_match, diff --git a/drivers/edac/layerscape_edac.c b/drivers/edac/layerscape_edac.c index 9a0c92ebbc3c4f812d38bf3a4ebd3e40443a383e..a2caa7fc54122d49c89acb7f1333792b28164d88 100644 --- a/drivers/edac/layerscape_edac.c +++ b/drivers/edac/layerscape_edac.c @@ -28,7 +28,7 @@ MODULE_DEVICE_TABLE(of, fsl_ddr_mc_err_of_match); static struct platform_driver fsl_ddr_mc_err_driver = { .probe = fsl_mc_err_probe, - .remove_new = fsl_mc_err_remove, + .remove = fsl_mc_err_remove, .driver = { .name = "fsl_ddr_mc_err", .of_match_table = fsl_ddr_mc_err_of_match, diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index d0266cbcbeda7781a084ca43f1f1bf7e30fcccf0..a45dc6b35edefe9ff86e6ac924cbfa905d6f0303 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -323,7 +323,7 @@ static const struct platform_device_id mpc85xx_pci_err_match[] = { static struct platform_driver mpc85xx_pci_err_driver = { .probe = mpc85xx_pci_err_probe, - .remove_new = mpc85xx_pci_err_remove, + .remove = mpc85xx_pci_err_remove, .id_table = mpc85xx_pci_err_match, .driver = { .name = "mpc85xx_pci_err", @@ -627,7 +627,7 @@ MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match); static struct platform_driver mpc85xx_l2_err_driver = { .probe = mpc85xx_l2_err_probe, - .remove_new = mpc85xx_l2_err_remove, + .remove = mpc85xx_l2_err_remove, .driver = { .name = "mpc85xx_l2_err", .of_match_table = mpc85xx_l2_err_of_match, @@ -656,7 +656,7 @@ MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match); static struct platform_driver mpc85xx_mc_err_driver = { .probe = fsl_mc_err_probe, - .remove_new = fsl_mc_err_remove, + .remove = fsl_mc_err_remove, .driver = { .name = "mpc85xx_mc_err", .of_match_table = mpc85xx_mc_err_of_match, diff --git a/drivers/edac/npcm_edac.c b/drivers/edac/npcm_edac.c index 2e2133b784e92251dc26f4a3661c5d50505ba039..e60a99eb8cfbb5063e5ad79130d08969b0f5503f 100644 --- a/drivers/edac/npcm_edac.c +++ b/drivers/edac/npcm_edac.c @@ -531,7 +531,7 @@ static struct platform_driver npcm_edac_driver = { .of_match_table = npcm_edac_of_match, }, .probe = edac_probe, - .remove_new = edac_remove, + .remove = edac_remove, }; module_platform_driver(npcm_edac_driver); diff --git a/drivers/edac/octeon_edac-l2c.c b/drivers/edac/octeon_edac-l2c.c index 2adb9c8093f86bcda208070e6f35ba94c3d9f86e..e6b1595a3cb586ad9e6433b310dba20f4c0e68f1 100644 --- a/drivers/edac/octeon_edac-l2c.c +++ b/drivers/edac/octeon_edac-l2c.c @@ -194,7 +194,7 @@ static void octeon_l2c_remove(struct platform_device *pdev) static struct platform_driver octeon_l2c_driver = { .probe = octeon_l2c_probe, - .remove_new = octeon_l2c_remove, + .remove = octeon_l2c_remove, .driver = { .name = "octeon_l2c_edac", } diff --git a/drivers/edac/octeon_edac-lmc.c b/drivers/edac/octeon_edac-lmc.c index 4112c2ee34b86f80a9b401acb0166dfc7bbfdeb6..f7176b95b4feeb4f97dd300b05dfe62941af049f 100644 --- a/drivers/edac/octeon_edac-lmc.c +++ b/drivers/edac/octeon_edac-lmc.c @@ -312,7 +312,7 @@ static void octeon_lmc_edac_remove(struct platform_device *pdev) static struct platform_driver octeon_lmc_edac_driver = { .probe = octeon_lmc_edac_probe, - .remove_new = octeon_lmc_edac_remove, + .remove = octeon_lmc_edac_remove, .driver = { .name = "octeon_lmc_edac", } diff --git a/drivers/edac/octeon_edac-pc.c b/drivers/edac/octeon_edac-pc.c index d9eeb40d2784c7184f373a93a2678137708259ad..aa1219db0b172692e273d95dfa84faeb19c3ebe3 100644 --- a/drivers/edac/octeon_edac-pc.c +++ b/drivers/edac/octeon_edac-pc.c @@ -130,7 +130,7 @@ static void co_cache_error_remove(struct platform_device *pdev) static struct platform_driver co_cache_error_driver = { .probe = co_cache_error_probe, - .remove_new = co_cache_error_remove, + .remove = co_cache_error_remove, .driver = { .name = "octeon_pc_edac", } diff --git a/drivers/edac/octeon_edac-pci.c b/drivers/edac/octeon_edac-pci.c index 4d368af2c5f0c6ae15a54ca5ee922b4028760ae6..c4f3bc33a971484e9c7d153e19c649cb161c58fc 100644 --- a/drivers/edac/octeon_edac-pci.c +++ b/drivers/edac/octeon_edac-pci.c @@ -97,7 +97,7 @@ static void octeon_pci_remove(struct platform_device *pdev) static struct platform_driver octeon_pci_driver = { .probe = octeon_pci_probe, - .remove_new = octeon_pci_remove, + .remove = octeon_pci_remove, .driver = { .name = "octeon_pci_edac", } diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c index a9a8ba067007a9a2fc5bb7f473bc6f7783d62514..04c42c83a2bad5994ad465917fd005cb196f947e 100644 --- a/drivers/edac/qcom_edac.c +++ b/drivers/edac/qcom_edac.c @@ -407,7 +407,7 @@ MODULE_DEVICE_TABLE(platform, qcom_llcc_edac_id_table); static struct platform_driver qcom_llcc_edac_driver = { .probe = qcom_llcc_edac_probe, - .remove_new = qcom_llcc_edac_remove, + .remove = qcom_llcc_edac_remove, .driver = { .name = "qcom_llcc_edac", }, diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index d7416166fd8a424f981ca2f5eace7dd565e8f114..5ed32a3299c44e386215e909dfaf1055e6faacf4 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -1488,7 +1488,7 @@ static struct platform_driver synps_edac_mc_driver = { .of_match_table = synps_edac_match, }, .probe = mc_probe, - .remove_new = mc_remove, + .remove = mc_remove, }; module_platform_driver(synps_edac_mc_driver); diff --git a/drivers/edac/ti_edac.c b/drivers/edac/ti_edac.c index 29723c9592f79e63ad248b9db04b6ebc1fbf876d..39cc2ef9cac4295d372bb182d4b39ea0667520ae 100644 --- a/drivers/edac/ti_edac.c +++ b/drivers/edac/ti_edac.c @@ -322,7 +322,7 @@ static void ti_edac_remove(struct platform_device *pdev) static struct platform_driver ti_edac_driver = { .probe = ti_edac_probe, - .remove_new = ti_edac_remove, + .remove = ti_edac_remove, .driver = { .name = EDAC_MOD_NAME, .of_match_table = ti_edac_of_match, diff --git a/drivers/edac/versal_edac.c b/drivers/edac/versal_edac.c index a556d23e8261c6df566bcccf3b538478ebba659c..5a43b5d43ca28027c829f53aea50588297484c5c 100644 --- a/drivers/edac/versal_edac.c +++ b/drivers/edac/versal_edac.c @@ -1186,7 +1186,7 @@ static struct platform_driver xilinx_ddr_edac_mc_driver = { .of_match_table = xlnx_edac_match, }, .probe = mc_probe, - .remove_new = mc_remove, + .remove = mc_remove, }; module_platform_driver(xilinx_ddr_edac_mc_driver); diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c index fd87f1b2c1453ea76c873e187d443c34d1e96038..699c7d29d80cd63b0187dee8af3da010d9b7a7a4 100644 --- a/drivers/edac/xgene_edac.c +++ b/drivers/edac/xgene_edac.c @@ -1989,7 +1989,7 @@ MODULE_DEVICE_TABLE(of, xgene_edac_of_match); static struct platform_driver xgene_edac_driver = { .probe = xgene_edac_probe, - .remove_new = xgene_edac_remove, + .remove = xgene_edac_remove, .driver = { .name = "xgene-edac", .of_match_table = xgene_edac_of_match, diff --git a/drivers/edac/zynqmp_edac.c b/drivers/edac/zynqmp_edac.c index c9dc78d8c824f5314a85b5ae332f225f4712f613..cdffc9e4194d42d4d11c5218c9f341ac46301a94 100644 --- a/drivers/edac/zynqmp_edac.c +++ b/drivers/edac/zynqmp_edac.c @@ -455,7 +455,7 @@ static struct platform_driver zynqmp_ocm_edac_driver = { .of_match_table = zynqmp_ocm_edac_match, }, .probe = edac_probe, - .remove_new = edac_remove, + .remove = edac_remove, }; module_platform_driver(zynqmp_ocm_edac_driver); diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c index 125016da7fde3f095b3b425a62204fc6aa5b8690..46c40d85c2ac89599ffbe7b6d11b161b295d5564 100644 --- a/drivers/extcon/extcon-adc-jack.c +++ b/drivers/extcon/extcon-adc-jack.c @@ -196,7 +196,7 @@ static SIMPLE_DEV_PM_OPS(adc_jack_pm_ops, static struct platform_driver adc_jack_driver = { .probe = adc_jack_probe, - .remove_new = adc_jack_remove, + .remove = adc_jack_remove, .driver = { .name = "adc-jack", .pm = &adc_jack_pm_ops, diff --git a/drivers/extcon/extcon-intel-cht-wc.c b/drivers/extcon/extcon-intel-cht-wc.c index 93552dc3c895c6d43a0f916ab7dcc9e97aa27f31..8131a3d7d5620dfab07e5256657b9a4276cfc380 100644 --- a/drivers/extcon/extcon-intel-cht-wc.c +++ b/drivers/extcon/extcon-intel-cht-wc.c @@ -627,7 +627,7 @@ MODULE_DEVICE_TABLE(platform, cht_wc_extcon_table); static struct platform_driver cht_wc_extcon_driver = { .probe = cht_wc_extcon_probe, - .remove_new = cht_wc_extcon_remove, + .remove = cht_wc_extcon_remove, .id_table = cht_wc_extcon_table, .driver = { .name = "cht_wcove_pwrsrc", diff --git a/drivers/extcon/extcon-intel-mrfld.c b/drivers/extcon/extcon-intel-mrfld.c index a1f737f13d4991787cf48ea5e81254d5cf7fbf93..9219f4328d70afd9f23d25f7ff2e27290b8d5a74 100644 --- a/drivers/extcon/extcon-intel-mrfld.c +++ b/drivers/extcon/extcon-intel-mrfld.c @@ -275,7 +275,7 @@ static struct platform_driver mrfld_extcon_driver = { .name = "mrfld_bcove_pwrsrc", }, .probe = mrfld_extcon_probe, - .remove_new = mrfld_extcon_remove, + .remove = mrfld_extcon_remove, .id_table = mrfld_extcon_id_table, }; module_platform_driver(mrfld_extcon_driver); diff --git a/drivers/extcon/extcon-max3355.c b/drivers/extcon/extcon-max3355.c index e62ce7a8d1317cac62e720736ae20a55b6562766..b2ee4ff8b04d2bc26dd05fb0dba95438c2ef2eb2 100644 --- a/drivers/extcon/extcon-max3355.c +++ b/drivers/extcon/extcon-max3355.c @@ -127,7 +127,7 @@ MODULE_DEVICE_TABLE(of, max3355_match_table); static struct platform_driver max3355_driver = { .probe = max3355_probe, - .remove_new = max3355_remove, + .remove = max3355_remove, .driver = { .name = "extcon-max3355", .of_match_table = max3355_match_table, diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c index 9849e3b8327edc3eac252c27abc6f0da1008d0d3..2ae9f7f1a67fc2052ed1eb94ed234f79e549dbbc 100644 --- a/drivers/extcon/extcon-max77843.c +++ b/drivers/extcon/extcon-max77843.c @@ -956,7 +956,7 @@ static struct platform_driver max77843_muic_driver = { .of_match_table = of_max77843_muic_dt_match, }, .probe = max77843_muic_probe, - .remove_new = max77843_muic_remove, + .remove = max77843_muic_remove, .id_table = max77843_muic_id, }; diff --git a/drivers/extcon/extcon-rtk-type-c.c b/drivers/extcon/extcon-rtk-type-c.c index 19a01e66373304b2bb9ccd655201797b8278b67d..bdc2b7b3a2465604678945a1eb5c259572697297 100644 --- a/drivers/extcon/extcon-rtk-type-c.c +++ b/drivers/extcon/extcon-rtk-type-c.c @@ -1778,7 +1778,7 @@ static const struct dev_pm_ops extcon_rtk_type_c_pm_ops = { static struct platform_driver extcon_rtk_type_c_driver = { .probe = extcon_rtk_type_c_probe, - .remove_new = extcon_rtk_type_c_remove, + .remove = extcon_rtk_type_c_remove, .driver = { .name = "extcon-rtk-type_c", .of_match_table = extcon_rtk_type_c_match, diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c index 9b61eb99b7dc950086ab5967ff911c26e552d4e0..5e8ad21ad206b842e2b317fac30bc51a20efa0df 100644 --- a/drivers/extcon/extcon-usb-gpio.c +++ b/drivers/extcon/extcon-usb-gpio.c @@ -279,7 +279,7 @@ MODULE_DEVICE_TABLE(platform, usb_extcon_platform_ids); static struct platform_driver usb_extcon_driver = { .probe = usb_extcon_probe, - .remove_new = usb_extcon_remove, + .remove = usb_extcon_remove, .driver = { .name = "extcon-usb-gpio", .pm = &usb_extcon_pm_ops, diff --git a/drivers/extcon/extcon-usbc-cros-ec.c b/drivers/extcon/extcon-usbc-cros-ec.c index 805a47230689d236fa8ca356ef797bf3794846db..1fb627ea8b508f8f116a8e9ba9f03c4e3b1abac6 100644 --- a/drivers/extcon/extcon-usbc-cros-ec.c +++ b/drivers/extcon/extcon-usbc-cros-ec.c @@ -529,7 +529,7 @@ static struct platform_driver extcon_cros_ec_driver = { .of_match_table = of_match_ptr(extcon_cros_ec_of_match), .pm = DEV_PM_OPS, }, - .remove_new = extcon_cros_ec_remove, + .remove = extcon_cros_ec_remove, .probe = extcon_cros_ec_probe, }; diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 1f53ca1f87e39719f13e43a3ba028ff810ce4593..1b5fb2c4ce8682901a954555d8aacf2f19c0dc85 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3333,7 +3333,7 @@ static struct platform_driver scmi_driver = { .dev_groups = versions_groups, }, .probe = scmi_probe, - .remove_new = scmi_remove, + .remove = scmi_remove, }; static struct dentry *scmi_debugfs_init(void) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index f4d47577f83ee71a89ea4baa9a85599895b99e1c..87c323de17b9012f543a06ae07d020ed69611be1 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -1049,7 +1049,7 @@ static struct platform_driver scpi_driver = { .dev_groups = versions_groups, }, .probe = scpi_probe, - .remove_new = scpi_remove, + .remove = scpi_remove, }; module_platform_driver(scpi_driver); diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 419220fa42fd7e66077b1642a94ed2ceea4a1fad..5365e9a4300070c42e1bc998b848e62a4e4c9d53 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -378,7 +378,7 @@ const char *cs_dsp_mem_region_name(unsigned int type) return NULL; } } -EXPORT_SYMBOL_NS_GPL(cs_dsp_mem_region_name, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_mem_region_name, "FW_CS_DSP"); #ifdef CONFIG_DEBUG_FS static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) @@ -519,7 +519,7 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) dsp->debugfs_root = root; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, "FW_CS_DSP"); /** * cs_dsp_cleanup_debugfs() - Removes DSP representation from debugfs @@ -531,17 +531,17 @@ void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) debugfs_remove_recursive(dsp->debugfs_root); dsp->debugfs_root = ERR_PTR(-ENODEV); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, "FW_CS_DSP"); #else void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) { } -EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, "FW_CS_DSP"); void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) { } -EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, "FW_CS_DSP"); static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) @@ -749,7 +749,7 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int return -ETIMEDOUT; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_write_acked_control, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_write_acked_control, "FW_CS_DSP"); static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, unsigned int off, const void *buf, size_t len) @@ -827,7 +827,7 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, return 1; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_write_ctrl, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_write_ctrl, "FW_CS_DSP"); /** * cs_dsp_coeff_lock_and_write_ctrl() - Writes the given buffer to the given coefficient control @@ -926,7 +926,7 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, return ret; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_read_ctrl, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_coeff_read_ctrl, "FW_CS_DSP"); /** * cs_dsp_coeff_lock_and_read_ctrl() - Reads the given coefficient control into the given buffer @@ -1679,7 +1679,7 @@ struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, in return rslt; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_get_ctl, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_get_ctl, "FW_CS_DSP"); static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, const struct cs_dsp_alg_region *alg_region) @@ -1769,7 +1769,7 @@ struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, return NULL; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_find_alg_region, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_find_alg_region, "FW_CS_DSP"); static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, int type, __be32 id, @@ -2404,7 +2404,7 @@ int cs_dsp_adsp1_init(struct cs_dsp *dsp) return cs_dsp_common_init(dsp); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_init, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_init, "FW_CS_DSP"); /** * cs_dsp_adsp1_power_up() - Load and start the named firmware @@ -2496,7 +2496,7 @@ err_mutex: mutex_unlock(&dsp->pwr_lock); return ret; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_power_up, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_power_up, "FW_CS_DSP"); /** * cs_dsp_adsp1_power_down() - Halts the DSP @@ -2528,7 +2528,7 @@ void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) mutex_unlock(&dsp->pwr_lock); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_power_down, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp1_power_down, "FW_CS_DSP"); static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) { @@ -2680,7 +2680,7 @@ int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) return ret; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_set_dspclk, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_set_dspclk, "FW_CS_DSP"); static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) { @@ -2770,7 +2770,7 @@ err_mutex: return ret; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_power_up, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_power_up, "FW_CS_DSP"); /** * cs_dsp_power_down() - Powers-down the DSP @@ -2804,7 +2804,7 @@ void cs_dsp_power_down(struct cs_dsp *dsp) cs_dsp_dbg(dsp, "Shutdown complete\n"); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_power_down, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_power_down, "FW_CS_DSP"); static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) { @@ -2890,7 +2890,7 @@ err: return ret; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_run, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_run, "FW_CS_DSP"); /** * cs_dsp_stop() - Stops the firmware @@ -2929,7 +2929,7 @@ void cs_dsp_stop(struct cs_dsp *dsp) cs_dsp_dbg(dsp, "Execution stopped\n"); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_stop, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_stop, "FW_CS_DSP"); static int cs_dsp_halo_start_core(struct cs_dsp *dsp) { @@ -2991,7 +2991,7 @@ int cs_dsp_adsp2_init(struct cs_dsp *dsp) return cs_dsp_common_init(dsp); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_init, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_init, "FW_CS_DSP"); /** * cs_dsp_halo_init() - Initialise a cs_dsp structure representing a HALO Core DSP @@ -3008,7 +3008,7 @@ int cs_dsp_halo_init(struct cs_dsp *dsp) return cs_dsp_common_init(dsp); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_init, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_init, "FW_CS_DSP"); /** * cs_dsp_remove() - Clean a cs_dsp before deletion @@ -3028,7 +3028,7 @@ void cs_dsp_remove(struct cs_dsp *dsp) cs_dsp_free_ctl_blk(ctl); } } -EXPORT_SYMBOL_NS_GPL(cs_dsp_remove, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_remove, "FW_CS_DSP"); /** * cs_dsp_read_raw_data_block() - Reads a block of data from DSP memory @@ -3065,7 +3065,7 @@ int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int me return 0; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_read_raw_data_block, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_read_raw_data_block, "FW_CS_DSP"); /** * cs_dsp_read_data_word() - Reads a word from DSP memory @@ -3089,7 +3089,7 @@ int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_add return 0; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_read_data_word, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_read_data_word, "FW_CS_DSP"); /** * cs_dsp_write_data_word() - Writes a word to DSP memory @@ -3115,7 +3115,7 @@ int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_ad return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_write_data_word, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_write_data_word, "FW_CS_DSP"); /** * cs_dsp_remove_padding() - Convert unpacked words to packed bytes @@ -3139,7 +3139,7 @@ void cs_dsp_remove_padding(u32 *buf, int nwords) *pack_out++ = (u8)(word >> 16); } } -EXPORT_SYMBOL_NS_GPL(cs_dsp_remove_padding, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_remove_padding, "FW_CS_DSP"); /** * cs_dsp_adsp2_bus_error() - Handle a DSP bus error interrupt @@ -3209,7 +3209,7 @@ void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) error: mutex_unlock(&dsp->pwr_lock); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_bus_error, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_bus_error, "FW_CS_DSP"); /** * cs_dsp_halo_bus_error() - Handle a DSP bus error interrupt @@ -3269,7 +3269,7 @@ void cs_dsp_halo_bus_error(struct cs_dsp *dsp) exit_unlock: mutex_unlock(&dsp->pwr_lock); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_bus_error, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_bus_error, "FW_CS_DSP"); /** * cs_dsp_halo_wdt_expire() - Handle DSP watchdog expiry @@ -3289,7 +3289,7 @@ void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) mutex_unlock(&dsp->pwr_lock); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_wdt_expire, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_halo_wdt_expire, "FW_CS_DSP"); static const struct cs_dsp_ops cs_dsp_adsp1_ops = { .validate_version = cs_dsp_validate_version, @@ -3419,7 +3419,7 @@ int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val) return 0; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_write, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_write, "FW_CS_DSP"); /** * cs_dsp_chunk_flush() - Pad remaining data with zero and commit to chunk @@ -3438,7 +3438,7 @@ int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch) return cs_dsp_chunk_write(ch, CS_DSP_DATA_WORD_BITS - ch->cachebits, 0); } -EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_flush, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_flush, "FW_CS_DSP"); /** * cs_dsp_chunk_read() - Parse data from a DSP memory chunk @@ -3480,7 +3480,7 @@ int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits) return result; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_read, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_read, "FW_CS_DSP"); struct cs_dsp_wseq_op { @@ -3605,7 +3605,7 @@ int cs_dsp_wseq_init(struct cs_dsp *dsp, struct cs_dsp_wseq *wseqs, unsigned int return 0; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_wseq_init, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_wseq_init, "FW_CS_DSP"); static struct cs_dsp_wseq_op *cs_dsp_wseq_find_op(u32 addr, u8 op_code, struct list_head *wseq_ops) @@ -3720,7 +3720,7 @@ op_new_free: return ret; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_wseq_write, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_wseq_write, "FW_CS_DSP"); /** * cs_dsp_wseq_multi_write() - Add or update multiple entries in a write sequence @@ -3752,7 +3752,7 @@ int cs_dsp_wseq_multi_write(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq, return 0; } -EXPORT_SYMBOL_NS_GPL(cs_dsp_wseq_multi_write, FW_CS_DSP); +EXPORT_SYMBOL_NS_GPL(cs_dsp_wseq_multi_write, "FW_CS_DSP"); MODULE_DESCRIPTION("Cirrus Logic DSP Support"); MODULE_AUTHOR("Simon Trimmer "); diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index 552c78f5f05902a20f78ad7671bbb36d5542a7f2..a253b61449459eca31afc6ca780a20c4557659ba 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c @@ -6,7 +6,7 @@ #include #include -MODULE_IMPORT_NS(EFIVAR); +MODULE_IMPORT_NS("EFIVAR"); #define DUMP_NAME_LEN 66 diff --git a/drivers/firmware/efi/embedded-firmware.c b/drivers/firmware/efi/embedded-firmware.c index f5be8e22305be46a57968e4b3b4fb6ba5e8e205d..b49a09d7e6651941ca797060413ab009da6441b2 100644 --- a/drivers/firmware/efi/embedded-firmware.c +++ b/drivers/firmware/efi/embedded-firmware.c @@ -16,9 +16,9 @@ /* Exported for use by lib/test_firmware.c only */ LIST_HEAD(efi_embedded_fw_list); -EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_list, TEST_FIRMWARE); +EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_list, "TEST_FIRMWARE"); bool efi_embedded_fw_checked; -EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_checked, TEST_FIRMWARE); +EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_checked, "TEST_FIRMWARE"); static const struct dmi_system_id * const embedded_fw_table[] = { #ifdef CONFIG_TOUCHSCREEN_DMI diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 4056ba7f3440850f1d6785ec69fd9e49ed2d0a9b..3700e98697676d8e6f04f061f447391503f9abba 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -149,7 +149,7 @@ int efivar_lock(void) } return 0; } -EXPORT_SYMBOL_NS_GPL(efivar_lock, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_lock, "EFIVAR"); /* * efivar_lock() - obtain the efivar lock if it is free @@ -165,7 +165,7 @@ int efivar_trylock(void) } return 0; } -EXPORT_SYMBOL_NS_GPL(efivar_trylock, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_trylock, "EFIVAR"); /* * efivar_unlock() - release the efivar lock @@ -174,7 +174,7 @@ void efivar_unlock(void) { up(&efivars_lock); } -EXPORT_SYMBOL_NS_GPL(efivar_unlock, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_unlock, "EFIVAR"); /* * efivar_get_variable() - retrieve a variable identified by name/vendor @@ -186,7 +186,7 @@ efi_status_t efivar_get_variable(efi_char16_t *name, efi_guid_t *vendor, { return __efivars->ops->get_variable(name, vendor, attr, size, data); } -EXPORT_SYMBOL_NS_GPL(efivar_get_variable, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_get_variable, "EFIVAR"); /* * efivar_get_next_variable() - enumerate the next name/vendor pair @@ -198,7 +198,7 @@ efi_status_t efivar_get_next_variable(unsigned long *name_size, { return __efivars->ops->get_next_variable(name_size, name, vendor); } -EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable, "EFIVAR"); /* * efivar_set_variable_locked() - set a variable identified by name/vendor @@ -230,7 +230,7 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor, return setvar(name, vendor, attr, data_size, data); } -EXPORT_SYMBOL_NS_GPL(efivar_set_variable_locked, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_set_variable_locked, "EFIVAR"); /* * efivar_set_variable() - set a variable identified by name/vendor @@ -252,7 +252,7 @@ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor, efivar_unlock(); return status; } -EXPORT_SYMBOL_NS_GPL(efivar_set_variable, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_set_variable, "EFIVAR"); efi_status_t efivar_query_variable_info(u32 attr, u64 *storage_space, @@ -264,4 +264,4 @@ efi_status_t efivar_query_variable_info(u32 attr, return __efivars->ops->query_variable_info(attr, storage_space, remaining_space, max_variable_size); } -EXPORT_SYMBOL_NS_GPL(efivar_query_variable_info, EFIVAR); +EXPORT_SYMBOL_NS_GPL(efivar_query_variable_info, "EFIVAR"); diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c index 208652a8087cd2463f8b52e155e4fbb96f484944..882db32e51be975a5304cf364feb281578f78627 100644 --- a/drivers/firmware/google/coreboot_table.c +++ b/drivers/firmware/google/coreboot_table.c @@ -220,7 +220,7 @@ MODULE_DEVICE_TABLE(of, coreboot_of_match); static struct platform_driver coreboot_table_driver = { .probe = coreboot_table_probe, - .remove_new = coreboot_table_remove, + .remove = coreboot_table_remove, .driver = { .name = "coreboot_table", .acpi_match_table = ACPI_PTR(cros_coreboot_acpi_match), diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c index 01c8ef14eaec3fa54ebd6ba6e032b37727228db7..ed79e823157afbdbda17e5a5a903312009c119e6 100644 --- a/drivers/firmware/imx/imx-dsp.c +++ b/drivers/firmware/imx/imx-dsp.c @@ -180,7 +180,7 @@ static struct platform_driver imx_dsp_driver = { .name = "imx-dsp", }, .probe = imx_dsp_probe, - .remove_new = imx_dsp_remove, + .remove = imx_dsp_remove, }; builtin_platform_driver(imx_dsp_driver); diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 8e59be3782cbb7532e2f655410bf18e1ba7966f8..55b9cfad8a042b3b21cf703cd5982febf0886669 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -116,7 +116,7 @@ static void __meminit release_firmware_map_entry(struct kobject *kobj) kfree(entry); } -static struct kobj_type __refdata memmap_ktype = { +static const struct kobj_type memmap_ktype = { .release = release_firmware_map_entry, .sysfs_ops = &memmap_attr_ops, .default_groups = def_groups, diff --git a/drivers/firmware/microchip/mpfs-auto-update.c b/drivers/firmware/microchip/mpfs-auto-update.c index 0f7ec88482022c7eef668de24ba6b633dc69a995..38a03698cec957ce5b58169621c67d9a59945170 100644 --- a/drivers/firmware/microchip/mpfs-auto-update.c +++ b/drivers/firmware/microchip/mpfs-auto-update.c @@ -458,7 +458,7 @@ static struct platform_driver mpfs_auto_update_driver = { .name = "mpfs-auto-update", }, .probe = mpfs_auto_update_probe, - .remove_new = mpfs_auto_update_remove, + .remove = mpfs_auto_update_remove, }; module_platform_driver(mpfs_auto_update_driver); diff --git a/drivers/firmware/mtk-adsp-ipc.c b/drivers/firmware/mtk-adsp-ipc.c index a762302978de0f9fa3bdea869e1a99dcdc79cc45..2b79371c61c9bfcace42d24b0cede1b04e1abb34 100644 --- a/drivers/firmware/mtk-adsp-ipc.c +++ b/drivers/firmware/mtk-adsp-ipc.c @@ -95,10 +95,9 @@ static int mtk_adsp_ipc_probe(struct platform_device *pdev) adsp_chan->idx = i; adsp_chan->ch = mbox_request_channel_byname(cl, adsp_mbox_ch_names[i]); if (IS_ERR(adsp_chan->ch)) { - ret = PTR_ERR(adsp_chan->ch); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to request mbox chan %s ret %d\n", - adsp_mbox_ch_names[i], ret); + ret = dev_err_probe(dev, PTR_ERR(adsp_chan->ch), + "Failed to request mbox channel %s\n", + adsp_mbox_ch_names[i]); for (j = 0; j < i; j++) { adsp_chan = &adsp_ipc->chans[j]; @@ -133,7 +132,7 @@ static struct platform_driver mtk_adsp_ipc_driver = { .name = "mtk-adsp-ipc", }, .probe = mtk_adsp_ipc_probe, - .remove_new = mtk_adsp_ipc_remove, + .remove = mtk_adsp_ipc_remove, }; builtin_platform_driver(mtk_adsp_ipc_driver); diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 85c525745b311fd0b8518b36742b8a72f58dcd2b..d58da3e4500a5e230b7da9a75e4d70df7c38c542 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -757,7 +757,7 @@ MODULE_DEVICE_TABLE(acpi, fw_cfg_sysfs_acpi_match); static struct platform_driver fw_cfg_sysfs_driver = { .probe = fw_cfg_sysfs_probe, - .remove_new = fw_cfg_sysfs_remove, + .remove = fw_cfg_sysfs_remove, .driver = { .name = "fw_cfg", .of_match_table = fw_cfg_sysfs_mmio_match, diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 18cc34987108537c1d39d81ff8866b52d0bee5b3..7ecde6921a0ac2992bd40aca24fdc7825a3ebba3 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -406,7 +406,7 @@ static struct platform_driver rpi_firmware_driver = { }, .probe = rpi_firmware_probe, .shutdown = rpi_firmware_shutdown, - .remove_new = rpi_firmware_remove, + .remove = rpi_firmware_remove, }; module_platform_driver(rpi_firmware_driver); diff --git a/drivers/firmware/stratix10-rsu.c b/drivers/firmware/stratix10-rsu.c index e20cee9c2d320abaa81be38d6eb0c257ebaf3486..1ea39a0a76c787c6396300734b636b4b3a0ae04d 100644 --- a/drivers/firmware/stratix10-rsu.c +++ b/drivers/firmware/stratix10-rsu.c @@ -802,7 +802,7 @@ static void stratix10_rsu_remove(struct platform_device *pdev) static struct platform_driver stratix10_rsu_driver = { .probe = stratix10_rsu_probe, - .remove_new = stratix10_rsu_remove, + .remove = stratix10_rsu_remove, .driver = { .name = "stratix10-rsu", .dev_groups = rsu_groups, diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index 528f37417aea48532003125cb8eacebff312e160..c5c78b869561b0c1e9602823ad1f501e98e3ce51 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -1271,7 +1271,7 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev) static struct platform_driver stratix10_svc_driver = { .probe = stratix10_svc_drv_probe, - .remove_new = stratix10_svc_drv_remove, + .remove = stratix10_svc_drv_remove, .driver = { .name = "stratix10-svc", .of_match_table = stratix10_svc_drv_match, diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index cdb565c411198910114b0bc6a67496e9e851cd83..720fa8b5d8e95d9828151a1ed02e5f9a23fc506c 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -2118,6 +2118,6 @@ static struct platform_driver zynqmp_firmware_driver = { .dev_groups = zynqmp_firmware_groups, }, .probe = zynqmp_firmware_probe, - .remove_new = zynqmp_firmware_remove, + .remove = zynqmp_firmware_remove, }; module_platform_driver(zynqmp_firmware_driver); diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c index f4de3fea0b2dcda7bb127c2bfac1dcea376c0d0a..e41492988dd633e2653071daaade86f9dfa984ea 100644 --- a/drivers/fpga/altera-fpga2sdram.c +++ b/drivers/fpga/altera-fpga2sdram.c @@ -152,7 +152,7 @@ MODULE_DEVICE_TABLE(of, altera_fpga_of_match); static struct platform_driver altera_fpga_driver = { .probe = alt_fpga_bridge_probe, - .remove_new = alt_fpga_bridge_remove, + .remove = alt_fpga_bridge_remove, .driver = { .name = "altera_fpga2sdram_bridge", .of_match_table = of_match_ptr(altera_fpga_of_match), diff --git a/drivers/fpga/altera-freeze-bridge.c b/drivers/fpga/altera-freeze-bridge.c index 44061cb16f8770fe87369f5be188460987a0c50a..594693ff786e25f8aa3a57b5d9a8a2bb33da7570 100644 --- a/drivers/fpga/altera-freeze-bridge.c +++ b/drivers/fpga/altera-freeze-bridge.c @@ -262,7 +262,7 @@ static void altera_freeze_br_remove(struct platform_device *pdev) static struct platform_driver altera_freeze_br_driver = { .probe = altera_freeze_br_probe, - .remove_new = altera_freeze_br_remove, + .remove = altera_freeze_br_remove, .driver = { .name = "altera_freeze_br", .of_match_table = altera_freeze_br_of_match, diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c index 6f8e24be19c6df7a653bbe990f2441d07b3f14e3..f2f1250689cb0a876514a5be8432ff85a4612dae 100644 --- a/drivers/fpga/altera-hps2fpga.c +++ b/drivers/fpga/altera-hps2fpga.c @@ -205,7 +205,7 @@ MODULE_DEVICE_TABLE(of, altera_fpga_of_match); static struct platform_driver alt_fpga_bridge_driver = { .probe = alt_fpga_bridge_probe, - .remove_new = alt_fpga_bridge_remove, + .remove = alt_fpga_bridge_remove, .driver = { .name = "altera_hps2fpga_bridge", .of_match_table = of_match_ptr(altera_fpga_of_match), diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c index 6b97c073849ea91e4ec90849371ea1b6ee55e9ca..2fd4f07ed081adc76a7a596eacafa2c3e29ece61 100644 --- a/drivers/fpga/dfl-afu-main.c +++ b/drivers/fpga/dfl-afu-main.c @@ -947,12 +947,12 @@ static const struct attribute_group *afu_dev_groups[] = { }; static struct platform_driver afu_driver = { - .driver = { - .name = DFL_FPGA_FEATURE_DEV_PORT, + .driver = { + .name = DFL_FPGA_FEATURE_DEV_PORT, .dev_groups = afu_dev_groups, }, - .probe = afu_probe, - .remove_new = afu_remove, + .probe = afu_probe, + .remove = afu_remove, }; static int __init afu_init(void) diff --git a/drivers/fpga/dfl-fme-br.c b/drivers/fpga/dfl-fme-br.c index 0b01b389527760933899f232ba33f3d726a3dc11..950c606c59d4466a73dc020fe7c1eacc09269070 100644 --- a/drivers/fpga/dfl-fme-br.c +++ b/drivers/fpga/dfl-fme-br.c @@ -92,11 +92,11 @@ static void fme_br_remove(struct platform_device *pdev) } static struct platform_driver fme_br_driver = { - .driver = { - .name = DFL_FPGA_FME_BRIDGE, + .driver = { + .name = DFL_FPGA_FME_BRIDGE, }, - .probe = fme_br_probe, - .remove_new = fme_br_remove, + .probe = fme_br_probe, + .remove = fme_br_remove, }; module_platform_driver(fme_br_driver); diff --git a/drivers/fpga/dfl-fme-main.c b/drivers/fpga/dfl-fme-main.c index 864924f68f5e2c4f2a87989ad4b96800d0bbe6e0..f8d89a4a6ccbfb5eeba163cdcd7e175130545489 100644 --- a/drivers/fpga/dfl-fme-main.c +++ b/drivers/fpga/dfl-fme-main.c @@ -742,12 +742,12 @@ static const struct attribute_group *fme_dev_groups[] = { }; static struct platform_driver fme_driver = { - .driver = { - .name = DFL_FPGA_FEATURE_DEV_FME, + .driver = { + .name = DFL_FPGA_FEATURE_DEV_FME, .dev_groups = fme_dev_groups, }, - .probe = fme_probe, - .remove_new = fme_remove, + .probe = fme_probe, + .remove = fme_remove, }; module_platform_driver(fme_driver); diff --git a/drivers/fpga/dfl-fme-region.c b/drivers/fpga/dfl-fme-region.c index 71616f8b4982de143fed31bdcd42deddf8367813..c6cd63063c8200df10ca647ec3414e5eeb0db7ba 100644 --- a/drivers/fpga/dfl-fme-region.c +++ b/drivers/fpga/dfl-fme-region.c @@ -71,11 +71,11 @@ static void fme_region_remove(struct platform_device *pdev) } static struct platform_driver fme_region_driver = { - .driver = { - .name = DFL_FPGA_FME_REGION, + .driver = { + .name = DFL_FPGA_FME_REGION, }, - .probe = fme_region_probe, - .remove_new = fme_region_remove, + .probe = fme_region_probe, + .remove = fme_region_remove, }; module_platform_driver(fme_region_driver); diff --git a/drivers/fpga/intel-m10-bmc-sec-update.c b/drivers/fpga/intel-m10-bmc-sec-update.c index 7ac9f9f5af129bcc5674c5891e11a6378e5744ee..10f678b9ed36624b0c5ba7449fc9518c2f12fafd 100644 --- a/drivers/fpga/intel-m10-bmc-sec-update.c +++ b/drivers/fpga/intel-m10-bmc-sec-update.c @@ -759,7 +759,7 @@ MODULE_DEVICE_TABLE(platform, intel_m10bmc_sec_ids); static struct platform_driver intel_m10bmc_sec_driver = { .probe = m10bmc_sec_probe, - .remove_new = m10bmc_sec_remove, + .remove = m10bmc_sec_remove, .driver = { .name = "intel-m10bmc-sec-update", .dev_groups = m10bmc_sec_attr_groups, @@ -771,4 +771,4 @@ module_platform_driver(intel_m10bmc_sec_driver); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("Intel MAX10 BMC Secure Update"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); +MODULE_IMPORT_NS("INTEL_M10_BMC_CORE"); diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c index 8526a5a86f0cbe9e6729528f10b87f4c15078f79..43db4bb77138a8400873e5bb8d17c85e7e9903b6 100644 --- a/drivers/fpga/of-fpga-region.c +++ b/drivers/fpga/of-fpga-region.c @@ -436,7 +436,7 @@ static void of_fpga_region_remove(struct platform_device *pdev) static struct platform_driver of_fpga_region_driver = { .probe = of_fpga_region_probe, - .remove_new = of_fpga_region_remove, + .remove = of_fpga_region_remove, .driver = { .name = "of-fpga-region", .of_match_table = of_match_ptr(fpga_region_of_match), diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c index 4c03513b8f03b5c9c6140abea34b4be650f790ea..0165a3c86932237376dd9f1e3ca2c400e8b9bf03 100644 --- a/drivers/fpga/socfpga-a10.c +++ b/drivers/fpga/socfpga-a10.c @@ -535,7 +535,7 @@ MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match); static struct platform_driver socfpga_a10_fpga_driver = { .probe = socfpga_a10_fpga_probe, - .remove_new = socfpga_a10_fpga_remove, + .remove = socfpga_a10_fpga_remove, .driver = { .name = "socfpga_a10_fpga_manager", .of_match_table = socfpga_a10_fpga_of_match, diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c index 2c0def7d7cbb160c714e27a92c5006a1f91d6a5d..0a295ccf1644a86d6a335c734594d8f1e82c5bf2 100644 --- a/drivers/fpga/stratix10-soc.c +++ b/drivers/fpga/stratix10-soc.c @@ -455,7 +455,7 @@ MODULE_DEVICE_TABLE(of, s10_of_match); static struct platform_driver s10_driver = { .probe = s10_probe, - .remove_new = s10_remove, + .remove = s10_remove, .driver = { .name = "Stratix10 SoC FPGA manager", .of_match_table = of_match_ptr(s10_of_match), diff --git a/drivers/fpga/xilinx-pr-decoupler.c b/drivers/fpga/xilinx-pr-decoupler.c index 788dd2f63a652e79f68a16177372eb25096d4380..822751fad18ae754be51a1b9ea24a554c9273fdc 100644 --- a/drivers/fpga/xilinx-pr-decoupler.c +++ b/drivers/fpga/xilinx-pr-decoupler.c @@ -162,7 +162,7 @@ static void xlnx_pr_decoupler_remove(struct platform_device *pdev) static struct platform_driver xlnx_pr_decoupler_driver = { .probe = xlnx_pr_decoupler_probe, - .remove_new = xlnx_pr_decoupler_remove, + .remove = xlnx_pr_decoupler_remove, .driver = { .name = "xlnx_pr_decoupler", .of_match_table = xlnx_pr_decoupler_of_match, diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 4db3d80e10b090b85944cd4747e4ca2c45c52a56..f7e08f7ea9ef3cca215fbdf30cdcbf4cddbed9ea 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c @@ -642,7 +642,7 @@ MODULE_DEVICE_TABLE(of, zynq_fpga_of_match); static struct platform_driver zynq_fpga_driver = { .probe = zynq_fpga_probe, - .remove_new = zynq_fpga_remove, + .remove = zynq_fpga_remove, .driver = { .name = "zynq_fpga_manager", .of_match_table = of_match_ptr(zynq_fpga_of_match), diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c index 6f5e1bdf7e40e420dbb8523914c5e45d9433dcda..bff897f77fe5fd243f57e650ed94cfcde348032a 100644 --- a/drivers/fsi/fsi-master-aspeed.c +++ b/drivers/fsi/fsi-master-aspeed.c @@ -666,7 +666,7 @@ static struct platform_driver fsi_master_aspeed_driver = { .of_match_table = fsi_master_aspeed_match, }, .probe = fsi_master_aspeed_probe, - .remove_new = fsi_master_aspeed_remove, + .remove = fsi_master_aspeed_remove, }; module_platform_driver(fsi_master_aspeed_driver); diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c index a4c37ff8edd69d8c85d431baa97d3205f408f5bd..9f2fd444ceb604384666c7c8eb92091f90283207 100644 --- a/drivers/fsi/fsi-master-ast-cf.c +++ b/drivers/fsi/fsi-master-ast-cf.c @@ -1434,7 +1434,7 @@ static struct platform_driver fsi_master_acf = { .of_match_table = fsi_master_acf_match, }, .probe = fsi_master_acf_probe, - .remove_new = fsi_master_acf_remove, + .remove = fsi_master_acf_remove, }; module_platform_driver(fsi_master_acf); diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index f761344f487329bfe9795cf2bab051ecbc52703a..69de0b5b9cbd18837eaac96a1ae2d1696a2d0635 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -888,7 +888,7 @@ static struct platform_driver fsi_master_gpio_driver = { .of_match_table = fsi_master_gpio_match, }, .probe = fsi_master_gpio_probe, - .remove_new = fsi_master_gpio_remove, + .remove = fsi_master_gpio_remove, }; module_platform_driver(fsi_master_gpio_driver); diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c index a6d4c8f123a5a93552eed42c35b3924828f4f213..d3e6bf37878a762653d57f00c5fc8db336a9ad3b 100644 --- a/drivers/fsi/fsi-occ.c +++ b/drivers/fsi/fsi-occ.c @@ -740,7 +740,7 @@ static struct platform_driver occ_driver = { .of_match_table = occ_match, }, .probe = occ_probe, - .remove_new = occ_remove, + .remove = occ_remove, }; static int occ_init(void) diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index 4df9becaf3490c837700f7477813ca2a01b015bc..cf5a50102d49160982092df67bca3ad590dbe796 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -22,7 +22,7 @@ #include "gpio-i8255.h" -MODULE_IMPORT_NS(I8255); +MODULE_IMPORT_NS("I8255"); #define DIO48E_EXTENT 16 #define MAX_NUM_DIO48E max_num_isa_dev(DIO48E_EXTENT) @@ -339,4 +339,4 @@ module_isa_driver_with_irq(dio48e_driver, num_dio48e, num_irq); MODULE_AUTHOR("William Breathitt Gray "); MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(I8254); +MODULE_IMPORT_NS("I8254"); diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index f03ccd0f534cffbb8ac3eceb9328df73ba57587a..ffe7e1cb6b238856b9d13b2a278fe6c44b9cc8d3 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -126,4 +126,4 @@ module_isa_driver_with_irq(idio_16_driver, num_idio_16, num_irq); MODULE_AUTHOR("William Breathitt Gray "); MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(GPIO_IDIO_16); +MODULE_IMPORT_NS("GPIO_IDIO_16"); diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index 72755fee647847d643ac209e1d52b0f71e1fac8e..34eb26298e32412c3cf8533b4b5855676f5f98ba 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -420,7 +420,7 @@ static void aspeed_sgpio_irq_print_chip(struct irq_data *d, struct seq_file *p) int offset; irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset); - seq_printf(p, dev_name(gpio->dev)); + seq_puts(p, dev_name(gpio->dev)); } static const struct irq_chip aspeed_sgpio_irq_chip = { diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index 208f95fb585e1ec8e54ed43eb27862ff3cc721d1..40c1bd80f8b0434d5f8457de332b6a4e07242237 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -1049,7 +1049,7 @@ static void aspeed_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) if (rc) return; - seq_printf(p, dev_name(gpio->dev)); + seq_puts(p, dev_name(gpio->dev)); } static const struct irq_chip aspeed_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-elkhartlake.c b/drivers/gpio/gpio-elkhartlake.c index 887c0fe99d3950df5e8d13fa7f1ef4cb3ce87811..95de52d2cc634ab6815fabb1ba2badf1be8f56cb 100644 --- a/drivers/gpio/gpio-elkhartlake.c +++ b/drivers/gpio/gpio-elkhartlake.c @@ -75,4 +75,4 @@ MODULE_AUTHOR("Pandith N "); MODULE_AUTHOR("Raag Jadav "); MODULE_DESCRIPTION("Intel Elkhart Lake PSE GPIO driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(GPIO_TANGIER); +MODULE_IMPORT_NS("GPIO_TANGIER"); diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index ab798c848215ad9241ccb39d82f0e5d27fed09c5..58d2464c07bc360137f3100de4e4147030bb121c 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -249,7 +249,7 @@ static void ep93xx_irq_print_chip(struct irq_data *data, struct seq_file *p) { struct gpio_chip *gc = irq_data_get_irq_chip_data(data); - seq_printf(p, dev_name(gc->parent)); + seq_puts(p, dev_name(gc->parent)); } static const struct irq_chip gpio_eic_irq_chip = { diff --git a/drivers/gpio/gpio-gpio-mm.c b/drivers/gpio/gpio-gpio-mm.c index 43d823a56e59e2e9f64bdc824162edc063c68f08..fb7c510bf2fad4413b5de529437ffc4bac765520 100644 --- a/drivers/gpio/gpio-gpio-mm.c +++ b/drivers/gpio/gpio-gpio-mm.c @@ -18,7 +18,7 @@ #include "gpio-i8255.h" -MODULE_IMPORT_NS(I8255); +MODULE_IMPORT_NS("I8255"); #define GPIOMM_EXTENT 8 #define MAX_NUM_GPIOMM max_num_isa_dev(GPIOMM_EXTENT) diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c index 1bcfc1835dae8c70a28b54b2a0a5ca493e2872bd..0580f6712bea9a4d510bd332645982adbc5c6a32 100644 --- a/drivers/gpio/gpio-hlwd.c +++ b/drivers/gpio/gpio-hlwd.c @@ -210,7 +210,7 @@ static void hlwd_gpio_irq_print_chip(struct irq_data *data, struct seq_file *p) struct hlwd_gpio *hlwd = gpiochip_get_data(irq_data_get_irq_chip_data(data)); - seq_printf(p, dev_name(hlwd->dev)); + seq_puts(p, dev_name(hlwd->dev)); } static const struct irq_chip hlwd_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-i8255.c b/drivers/gpio/gpio-i8255.c index 64ab80fc4a1e5c881352d7a3b01b0ae8ea71c72e..953018bfa2b1e8c463d1f02cbeb45e961181dbd9 100644 --- a/drivers/gpio/gpio-i8255.c +++ b/drivers/gpio/gpio-i8255.c @@ -134,7 +134,7 @@ int devm_i8255_regmap_register(struct device *const dev, return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config)); } -EXPORT_SYMBOL_NS_GPL(devm_i8255_regmap_register, I8255); +EXPORT_SYMBOL_NS_GPL(devm_i8255_regmap_register, "I8255"); MODULE_AUTHOR("William Breathitt Gray"); MODULE_DESCRIPTION("Intel 8255 Programmable Peripheral Interface"); diff --git a/drivers/gpio/gpio-idio-16.c b/drivers/gpio/gpio-idio-16.c index 53b1eb876a1257b84adf110b856dd0aede745451..2c9512589297217176c0450e6eab8adad4d3fe87 100644 --- a/drivers/gpio/gpio-idio-16.c +++ b/drivers/gpio/gpio-idio-16.c @@ -14,7 +14,7 @@ #include "gpio-idio-16.h" -#define DEFAULT_SYMBOL_NAMESPACE GPIO_IDIO_16 +#define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16" #define IDIO_16_DAT_BASE 0x0 #define IDIO_16_OUT_BASE IDIO_16_DAT_BASE diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c index d67b912d884ddb1ffc33fcfa2f513e252ca600b3..503d2441c58f27381bff532cf01fd45f654707f0 100644 --- a/drivers/gpio/gpio-ljca.c +++ b/drivers/gpio/gpio-ljca.c @@ -492,4 +492,4 @@ MODULE_AUTHOR("Zhifeng Wang "); MODULE_AUTHOR("Lixu Zhang "); MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-GPIO driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LJCA); +MODULE_IMPORT_NS("LJCA"); diff --git a/drivers/gpio/gpio-menz127.c b/drivers/gpio/gpio-menz127.c index 3ccd2cb35b9caf2e73f6c7ceace31e0510e0d870..ebe5da4933bce730c70f83c1c0f86fc4a4cc9906 100644 --- a/drivers/gpio/gpio-menz127.c +++ b/drivers/gpio/gpio-menz127.c @@ -201,4 +201,4 @@ MODULE_AUTHOR("Andreas Werner "); MODULE_DESCRIPTION("MEN 16z127 GPIO Controller"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("mcb:16z127"); -MODULE_IMPORT_NS(MCB); +MODULE_IMPORT_NS("MCB"); diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index cd20604f26de5d2629d76c0b9541527e5a4fd8e3..4335a5d8e4f6d5ea1c93eccde4094e6fe85ece0c 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -142,4 +142,4 @@ module_pci_driver(mrfld_gpio_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Merrifield SoC GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(GPIO_TANGIER); +MODULE_IMPORT_NS("GPIO_TANGIER"); diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c index 6abe01bc39c3e1123440bca8034e826b27419f5e..6f3dda6b635fa2c0d51fea16b26f78e1aa3167b4 100644 --- a/drivers/gpio/gpio-mlxbf2.c +++ b/drivers/gpio/gpio-mlxbf2.c @@ -331,7 +331,7 @@ static void mlxbf2_gpio_irq_print_chip(struct irq_data *irqd, struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc); - seq_printf(p, dev_name(gs->dev)); + seq_puts(p, dev_name(gs->dev)); } static const struct irq_chip mlxbf2_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 7ad45340549622e49fc3faa6d2cbc4a19425ad92..54c4bfdccf56812b5f79435a97b6eb90904ca59c 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -715,7 +715,7 @@ static void omap_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) { struct gpio_bank *bank = omap_irq_data_get_bank(d); - seq_printf(p, dev_name(bank->dev)); + seq_puts(p, dev_name(bank->dev)); } static const struct irq_chip omap_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 3f2d33ee20cca9c8cb04956cdd24efab0767ea10..272febc3230e90baf370811f498383b9fb12cc6f 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -815,7 +815,7 @@ static void pca953x_irq_print_chip(struct irq_data *data, struct seq_file *p) { struct gpio_chip *gc = irq_data_get_irq_chip_data(data); - seq_printf(p, dev_name(gc->parent)); + seq_puts(p, dev_name(gc->parent)); } static const struct irq_chip pca953x_irq_chip = { diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c index 64f332c805507645039615e0a89b83175f6bb616..476cea1b5ed774d18511aaf71d8ca2d71bcc9ff0 100644 --- a/drivers/gpio/gpio-pci-idio-16.c +++ b/drivers/gpio/gpio-pci-idio-16.c @@ -112,4 +112,4 @@ module_pci_driver(idio_16_driver); MODULE_AUTHOR("William Breathitt Gray "); MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(GPIO_IDIO_16); +MODULE_IMPORT_NS("GPIO_IDIO_16"); diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index a211a02d4b4a633e81ffda19ca437f52d79f9bf5..1c273727ffa3ac54d0f1e66bd6efb784d2a8604e 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -291,7 +291,7 @@ static void pl061_irq_print_chip(struct irq_data *data, struct seq_file *p) { struct gpio_chip *gc = irq_data_get_irq_chip_data(data); - seq_printf(p, dev_name(gc->parent)); + seq_puts(p, dev_name(gc->parent)); } static const struct irq_chip pl061_irq_chip = { diff --git a/drivers/gpio/gpio-tangier.c b/drivers/gpio/gpio-tangier.c index 4b29abafecf6a466e5a81f6c8eeea70395e84823..a415e6d361731e809d137a92b6c4658b447c26bd 100644 --- a/drivers/gpio/gpio-tangier.c +++ b/drivers/gpio/gpio-tangier.c @@ -459,7 +459,7 @@ int devm_tng_gpio_probe(struct device *dev, struct tng_gpio *gpio) return 0; } -EXPORT_SYMBOL_NS_GPL(devm_tng_gpio_probe, GPIO_TANGIER); +EXPORT_SYMBOL_NS_GPL(devm_tng_gpio_probe, "GPIO_TANGIER"); static int tng_gpio_suspend(struct device *dev) { diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 6d3a39a03f58e22363f69a3c9074021c1107fc32..9ad286adf2632f300ee981185ea32d79ca012df5 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -600,7 +600,7 @@ static void tegra_gpio_irq_print_chip(struct irq_data *d, struct seq_file *s) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - seq_printf(s, dev_name(chip->parent)); + seq_puts(s, dev_name(chip->parent)); } static const struct irq_chip tegra_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index 1ecb733a5e88b4ade2b46f9089d672ec5ce07a60..6895b65c86aff5b92bee2da0ad5f3306653828e6 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -610,7 +610,7 @@ static void tegra186_irq_print_chip(struct irq_data *data, struct seq_file *p) { struct gpio_chip *gc = irq_data_get_irq_chip_data(data); - seq_printf(p, dev_name(gc->parent)); + seq_puts(p, dev_name(gc->parent)); } static const struct irq_chip tegra186_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c index f2e7e8754d95d699c0c2e4aa334e362396c376f4..5e26eb3adabbf4f467a27892882b803c62c43414 100644 --- a/drivers/gpio/gpio-tqmx86.c +++ b/drivers/gpio/gpio-tqmx86.c @@ -275,7 +275,7 @@ static void tqmx86_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - seq_printf(p, gc->label); + seq_puts(p, gc->label); } static const struct irq_chip tqmx86_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-visconti.c b/drivers/gpio/gpio-visconti.c index ebc71ecdb6cf5d0adfbddad5c86f60648d29e79f..5bd965c18a465f29884cbe56711b25d7e755df2d 100644 --- a/drivers/gpio/gpio-visconti.c +++ b/drivers/gpio/gpio-visconti.c @@ -142,7 +142,7 @@ static void visconti_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct visconti_gpio *priv = gpiochip_get_data(gc); - seq_printf(p, dev_name(priv->dev)); + seq_puts(p, dev_name(priv->dev)); } static const struct irq_chip visconti_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c index 0f9d1f61fee360cb5c6ee4c5c1a71c611e98db5c..93544e98ccbd3f8172010658cf82f5692949c772 100644 --- a/drivers/gpio/gpio-xgs-iproc.c +++ b/drivers/gpio/gpio-xgs-iproc.c @@ -198,7 +198,7 @@ static void iproc_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct iproc_gpio_chip *chip = to_iproc_gpio(gc); - seq_printf(p, dev_name(chip->dev)); + seq_puts(p, dev_name(chip->dev)); } static const struct irq_chip iproc_gpio_irq_chip = { diff --git a/drivers/gpio/gpiolib-swnode.c b/drivers/gpio/gpiolib-swnode.c index 51d2475c05c57c7e9922dd534adf15c4bb3d2b1b..f21dbc28cf2c8c2d06d034b7c89d302cc52bb9b5 100644 --- a/drivers/gpio/gpiolib-swnode.c +++ b/drivers/gpio/gpiolib-swnode.c @@ -141,7 +141,7 @@ int swnode_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) const struct software_node swnode_gpio_undefined = { .name = GPIOLIB_SWNODE_UNDEFINED_NAME, }; -EXPORT_SYMBOL_NS_GPL(swnode_gpio_undefined, GPIO_SWNODE); +EXPORT_SYMBOL_NS_GPL(swnode_gpio_undefined, "GPIO_SWNODE"); static int __init swnode_gpio_init(void) { diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c index 3a588fecb0c58362e149a556ea22ae95db3bc03d..f44de9d4b6a17f212bb9911bb3f33df69a349315 100644 --- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c +++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c @@ -330,6 +330,8 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, } list_for_each_entry(tmp_adev, reset_device_list, reset_list) { + amdgpu_set_init_level(tmp_adev, + AMDGPU_INIT_LEVEL_RESET_RECOVERY); dev_info(tmp_adev->dev, "GPU reset succeeded, trying to resume\n"); r = aldebaran_mode2_restore_ip(tmp_adev); @@ -375,6 +377,8 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, tmp_adev); if (!r) { + amdgpu_set_init_level(tmp_adev, + AMDGPU_INIT_LEVEL_DEFAULT); amdgpu_irq_gpu_reset_resume_helper(tmp_adev); r = amdgpu_ib_ring_tests(tmp_adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index d8bc6da5001614e3add6999f8b53df2df42be6a3..4653a8d2823a6d6f645c620ba56caf0769e0d2b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -839,6 +839,7 @@ struct amdgpu_mqd { enum amdgpu_init_lvl_id { AMDGPU_INIT_LEVEL_DEFAULT, AMDGPU_INIT_LEVEL_MINIMAL_XGMI, + AMDGPU_INIT_LEVEL_RESET_RECOVERY, }; struct amdgpu_init_level { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0171d240fcb05e37d9a8a037b4d94e9103a57a36..9095c05e0269f947f60c78a1c8481aa6de191cba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -156,6 +156,11 @@ struct amdgpu_init_level amdgpu_init_default = { .hwini_ip_block_mask = AMDGPU_IP_BLK_MASK_ALL, }; +struct amdgpu_init_level amdgpu_init_recovery = { + .level = AMDGPU_INIT_LEVEL_RESET_RECOVERY, + .hwini_ip_block_mask = AMDGPU_IP_BLK_MASK_ALL, +}; + /* * Minimal blocks needed to be initialized before a XGMI hive can be reset. This * is used for cases like reset on initialization where the entire hive needs to @@ -182,6 +187,9 @@ void amdgpu_set_init_level(struct amdgpu_device *adev, case AMDGPU_INIT_LEVEL_MINIMAL_XGMI: adev->init_lvl = &amdgpu_init_minimal_xgmi; break; + case AMDGPU_INIT_LEVEL_RESET_RECOVERY: + adev->init_lvl = &amdgpu_init_recovery; + break; case AMDGPU_INIT_LEVEL_DEFAULT: fallthrough; default: @@ -3250,7 +3258,7 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) return r; } - if (!amdgpu_in_reset(adev)) + if (!amdgpu_reset_in_recovery(adev)) amdgpu_ras_set_error_query_ready(adev, true); amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE); @@ -4669,8 +4677,8 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) int idx; bool px; - amdgpu_fence_driver_sw_fini(adev); amdgpu_device_ip_fini(adev); + amdgpu_fence_driver_sw_fini(adev); amdgpu_ucode_release(&adev->firmware.gpu_info_fw); adev->accel_working = false; dma_fence_put(rcu_dereference_protected(adev->gang_submit, true)); @@ -5419,7 +5427,7 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context) struct list_head *device_list_handle; bool full_reset, vram_lost = false; struct amdgpu_device *tmp_adev; - int r; + int r, init_level; device_list_handle = reset_context->reset_device_list; @@ -5428,10 +5436,18 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context) full_reset = test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags); + /** + * If it's reset on init, it's default init level, otherwise keep level + * as recovery level. + */ + if (reset_context->method == AMD_RESET_METHOD_ON_INIT) + init_level = AMDGPU_INIT_LEVEL_DEFAULT; + else + init_level = AMDGPU_INIT_LEVEL_RESET_RECOVERY; + r = 0; list_for_each_entry(tmp_adev, device_list_handle, reset_list) { - /* After reset, it's default init level */ - amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_DEFAULT); + amdgpu_set_init_level(tmp_adev, init_level); if (full_reset) { /* post card */ amdgpu_ras_set_fed(tmp_adev, false); @@ -5518,6 +5534,9 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context) out: if (!r) { + /* IP init is complete now, set level as default */ + amdgpu_set_init_level(tmp_adev, + AMDGPU_INIT_LEVEL_DEFAULT); amdgpu_irq_gpu_reset_resume_helper(tmp_adev); r = amdgpu_ib_ring_tests(tmp_adev); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index f57cc72c43cf4b1254a19085cbef507b6db8315f..69a6b6dba0a540b5289d833a829900a42e9280bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -1778,9 +1778,11 @@ int amdgpu_gfx_sysfs_init(struct amdgpu_device *adev) void amdgpu_gfx_sysfs_fini(struct amdgpu_device *adev) { - amdgpu_gfx_sysfs_xcp_fini(adev); - amdgpu_gfx_sysfs_isolation_shader_fini(adev); - amdgpu_gfx_sysfs_reset_mask_fini(adev); + if (adev->dev->kobj.sd) { + amdgpu_gfx_sysfs_xcp_fini(adev); + amdgpu_gfx_sysfs_isolation_shader_fini(adev); + amdgpu_gfx_sysfs_reset_mask_fini(adev); + } } int amdgpu_gfx_cleaner_shader_sw_init(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c index 04eb516745962d09db2faa8fc2cf0ef5c8439287..b6d2eb049f540811f345566286d102c1f7f3faae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c @@ -447,6 +447,8 @@ int amdgpu_jpeg_sysfs_reset_mask_init(struct amdgpu_device *adev) void amdgpu_jpeg_sysfs_reset_mask_fini(struct amdgpu_device *adev) { - if (adev->jpeg.num_jpeg_inst) - device_remove_file(adev->dev, &dev_attr_jpeg_reset_mask); + if (adev->dev->kobj.sd) { + if (adev->jpeg.num_jpeg_inst) + device_remove_file(adev->dev, &dev_attr_jpeg_reset_mask); + } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c index e8adfd0a570a2be072dbbd54a60c9834f7662a45..34b5e22b44e5f2ab4d2a374698009f6901fa6850 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c @@ -137,7 +137,8 @@ void amdgpu_preempt_mgr_fini(struct amdgpu_device *adev) if (ret) return; - device_remove_file(adev->dev, &dev_attr_mem_info_preempt_used); + if (adev->dev->kobj.sd) + device_remove_file(adev->dev, &dev_attr_mem_info_preempt_used); ttm_resource_manager_cleanup(man); ttm_set_driver_manager(&adev->mman.bdev, AMDGPU_PL_PREEMPT, NULL); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 17cf10c0b72be7178ae324ba6b8f9161fecf67a8..448f9e742983f3ef0c5fccc18d85f0c2449aa08e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -4112,7 +4112,7 @@ static umode_t amdgpu_flash_attr_is_visible(struct kobject *kobj, struct attribu } static umode_t amdgpu_bin_flash_attr_is_visible(struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, int idx) { struct device *dev = kobj_to_dev(kobj); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 1bc95b0cdbb8df3507cb525dcfb32b27c59f77ed..4c9fa24dd9726a405935907524ed7bf7862779d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1298,7 +1298,7 @@ int amdgpu_ras_bind_aca(struct amdgpu_device *adev, enum amdgpu_ras_block blk, struct ras_manager *obj; /* in resume phase, no need to create aca fs node */ - if (adev->in_suspend || amdgpu_in_reset(adev)) + if (adev->in_suspend || amdgpu_reset_in_recovery(adev)) return 0; obj = get_ras_manager(adev, blk); @@ -3610,7 +3610,7 @@ static void amdgpu_ras_event_mgr_init(struct amdgpu_device *adev) ras->event_mgr = hive ? &hive->event_mgr : &ras->__event_mgr; /* init event manager with node 0 on xgmi system */ - if (!amdgpu_in_reset(adev)) { + if (!amdgpu_reset_in_recovery(adev)) { if (!hive || adev->gmc.xgmi.node_id == 0) ras_event_mgr_init(ras->event_mgr); } @@ -3825,7 +3825,7 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev, r = amdgpu_ras_feature_enable_on_boot(adev, ras_block, 1); if (r) { - if (adev->in_suspend || amdgpu_in_reset(adev)) { + if (adev->in_suspend || amdgpu_reset_in_recovery(adev)) { /* in resume phase, if fail to enable ras, * clean up all ras fs nodes, and disable ras */ goto cleanup; @@ -3837,7 +3837,7 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev, amdgpu_persistent_edc_harvesting(adev, ras_block); /* in resume phase, no need to create ras fs node */ - if (adev->in_suspend || amdgpu_in_reset(adev)) + if (adev->in_suspend || amdgpu_reset_in_recovery(adev)) return 0; ras_obj = container_of(ras_block, struct amdgpu_ras_block_object, ras_comm); @@ -3967,7 +3967,7 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev) amdgpu_ras_event_mgr_init(adev); if (amdgpu_ras_aca_is_supported(adev)) { - if (amdgpu_in_reset(adev)) { + if (amdgpu_reset_in_recovery(adev)) { if (amdgpu_aca_is_enabled(adev)) r = amdgpu_aca_reset(adev); else diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c index 24dae7cdbe9547ed76b7bcd69ab2a87072235dd9..a0acb65f4b40afbcd9d1a305b4893aa66fadfde7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c @@ -342,3 +342,8 @@ void amdgpu_reset_get_desc(struct amdgpu_reset_context *rst_ctxt, char *buf, strscpy(buf, "unknown", len); } } + +bool amdgpu_reset_in_recovery(struct amdgpu_device *adev) +{ + return (adev->init_lvl->level == AMDGPU_INIT_LEVEL_RESET_RECOVERY); +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h index f8628bc898df45183c6b6bf3155a3c1c82f32d92..4d9b9701139be520c2cfcc94bf6b1a182130959a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h @@ -158,4 +158,6 @@ extern struct amdgpu_reset_handler xgmi_reset_on_init_handler; int amdgpu_reset_do_xgmi_reset_on_init( struct amdgpu_reset_context *reset_context); +bool amdgpu_reset_in_recovery(struct amdgpu_device *adev); + #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index 8c89b69edc20119384e01abd42fe4c8ecb617842..113f0d2426187e75a8d184f466ca32ebeaaa62a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -451,6 +451,8 @@ void amdgpu_sdma_sysfs_reset_mask_fini(struct amdgpu_device *adev) if (!amdgpu_gpu_recovery) return; - if (adev->sdma.num_instances) - device_remove_file(adev->dev, &dev_attr_sdma_reset_mask); + if (adev->dev->kobj.sd) { + if (adev->sdma.num_instances) + device_remove_file(adev->dev, &dev_attr_sdma_reset_mask); + } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9f922ec50ea2dc846b5cdbd931e655ebab86f9fc..c8180cad0abdd8c8aaa61b6376fd0fcf7f84a72b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -61,7 +61,7 @@ #include "amdgpu_res_cursor.h" #include "bif/bif_4_1_d.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); #define AMDGPU_TTM_VRAM_MAX_DW_READ ((size_t)128) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 74fdbf71d95b74d9433e239005f78bb99e25ecfe..599d3ca4e0ef9e20e55ae8a76840705f9f894326 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -214,15 +214,15 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) drm_sched_entity_destroy(&adev->vce.entity); - amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr, - (void **)&adev->vce.cpu_addr); - for (i = 0; i < adev->vce.num_rings; i++) amdgpu_ring_fini(&adev->vce.ring[i]); amdgpu_ucode_release(&adev->vce.fw); mutex_destroy(&adev->vce.idle_mutex); + amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr, + (void **)&adev->vce.cpu_addr); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index aecb78e0519f67e53e3e3643898ba27c12e98757..3e94c3ba1ba2cf494984d1bbb2e5d05e1f68674f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -1283,3 +1283,40 @@ int amdgpu_vcn_psp_update_sram(struct amdgpu_device *adev, int inst_idx, return psp_execute_ip_fw_load(&adev->psp, &ucode); } + +static ssize_t amdgpu_get_vcn_reset_mask(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(ddev); + + if (!adev) + return -ENODEV; + + return amdgpu_show_reset_mask(buf, adev->vcn.supported_reset); +} + +static DEVICE_ATTR(vcn_reset_mask, 0444, + amdgpu_get_vcn_reset_mask, NULL); + +int amdgpu_vcn_sysfs_reset_mask_init(struct amdgpu_device *adev) +{ + int r = 0; + + if (adev->vcn.num_vcn_inst) { + r = device_create_file(adev->dev, &dev_attr_vcn_reset_mask); + if (r) + return r; + } + + return r; +} + +void amdgpu_vcn_sysfs_reset_mask_fini(struct amdgpu_device *adev) +{ + if (adev->dev->kobj.sd) { + if (adev->vcn.num_vcn_inst) + device_remove_file(adev->dev, &dev_attr_vcn_reset_mask); + } +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 765b809d48a2573447c5b4278440f8be74fc8bf1..1e32311c1dff73f83b829dbb78a526fb84f8f89d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -333,6 +333,8 @@ struct amdgpu_vcn { /* IP reg dump */ uint32_t *ip_dump; + + uint32_t supported_reset; }; struct amdgpu_fw_shared_rb_ptrs_struct { @@ -519,5 +521,7 @@ int amdgpu_vcn_ras_sw_init(struct amdgpu_device *adev); int amdgpu_vcn_psp_update_sram(struct amdgpu_device *adev, int inst_idx, enum AMDGPU_UCODE_ID ucode_id); int amdgpu_vcn_save_vcpu_bo(struct amdgpu_device *adev); +int amdgpu_vcn_sysfs_reset_mask_init(struct amdgpu_device *adev); +void amdgpu_vcn_sysfs_reset_mask_fini(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c index 3e6f9dfb61bb31f7d39756257eb78cb5af08884c..110b120d7375d013ffce806e71c1f4ca9a0b17ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c @@ -904,8 +904,10 @@ int amdgpu_vpe_sysfs_reset_mask_init(struct amdgpu_device *adev) void amdgpu_vpe_sysfs_reset_mask_fini(struct amdgpu_device *adev) { - if (adev->vpe.num_instances) - device_remove_file(adev->dev, &dev_attr_vpe_reset_mask); + if (adev->dev->kobj.sd) { + if (adev->vpe.num_instances) + device_remove_file(adev->dev, &dev_attr_vpe_reset_mask); + } } static const struct amdgpu_ring_funcs vpe_ring_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index b47422b0b5b104582290a3c8a40bd9d8f87cc0a5..74b4349e345a6bf1f2fc171b30d4bf224a2a66d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -40,6 +40,11 @@ #define smnPCS_GOPX1_PCS_ERROR_STATUS 0x12200210 #define smnPCS_GOPX1_PCS_ERROR_NONCORRECTABLE_MASK 0x12200218 +#define XGMI_STATE_DISABLE 0xD1 +#define XGMI_STATE_LS0 0x81 +#define XGMI_LINK_ACTIVE 1 +#define XGMI_LINK_INACTIVE 0 + static DEFINE_MUTEX(xgmi_mutex); #define AMDGPU_MAX_XGMI_DEVICE_PER_HIVE 4 @@ -289,6 +294,42 @@ static const struct amdgpu_pcs_ras_field xgmi3x16_pcs_ras_fields[] = { SOC15_REG_FIELD(PCS_XGMI3X16_PCS_ERROR_STATUS, RxCMDPktErr)}, }; +static u32 xgmi_v6_4_get_link_status(struct amdgpu_device *adev, int global_link_num) +{ + const u32 smnpcs_xgmi3x16_pcs_state_hist1 = 0x11a00070; + const int xgmi_inst = 2; + u32 link_inst; + u64 addr; + + link_inst = global_link_num % xgmi_inst; + + addr = (smnpcs_xgmi3x16_pcs_state_hist1 | (link_inst << 20)) + + adev->asic_funcs->encode_ext_smn_addressing(global_link_num / xgmi_inst); + + return RREG32_PCIE_EXT(addr); +} + +int amdgpu_get_xgmi_link_status(struct amdgpu_device *adev, int global_link_num) +{ + u32 xgmi_state_reg_val; + + switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) { + case IP_VERSION(6, 4, 0): + xgmi_state_reg_val = xgmi_v6_4_get_link_status(adev, global_link_num); + break; + default: + return -EOPNOTSUPP; + } + + if ((xgmi_state_reg_val & 0xFF) == XGMI_STATE_DISABLE) + return -ENOLINK; + + if ((xgmi_state_reg_val & 0xFF) == XGMI_STATE_LS0) + return XGMI_LINK_ACTIVE; + + return XGMI_LINK_INACTIVE; +} + /** * DOC: AMDGPU XGMI Support * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h index 8cc7ab38db7c78a3da3ed93dc6c17d2430b1491a..d1282b4c63488bead5bb7b50ec0e012de09acd0b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h @@ -84,5 +84,7 @@ int amdgpu_xgmi_reset_on_init(struct amdgpu_device *adev); int amdgpu_xgmi_request_nps_change(struct amdgpu_device *adev, struct amdgpu_hive_info *hive, int req_nps_mode); +int amdgpu_get_xgmi_link_status(struct amdgpu_device *adev, + int global_link_num); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c index 483a441b46aa1051f78820296095b0a1368b2bc2..621aeca5388033b396e8d3381d19da093f8edac6 100644 --- a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c +++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c @@ -254,8 +254,8 @@ static void df_v3_6_sw_init(struct amdgpu_device *adev) static void df_v3_6_sw_fini(struct amdgpu_device *adev) { - - device_remove_file(adev->dev, &dev_attr_df_cntr_avail); + if (adev->dev->kobj.sd) + device_remove_file(adev->dev, &dev_attr_df_cntr_avail); } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 07f45f1a503adfa425cf11fb6ccca7cf1d30fedd..b6016f11956ec1abfb32c7b29b5e1f5f1c0e3392 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -87,9 +87,14 @@ static void gmc_v7_0_init_golden_registers(struct amdgpu_device *adev) static void gmc_v7_0_mc_stop(struct amdgpu_device *adev) { + struct amdgpu_ip_block *ip_block; u32 blackout; - gmc_v7_0_wait_for_idle((void *)adev); + ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GMC); + if (!ip_block) + return; + + gmc_v7_0_wait_for_idle(ip_block); blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL); if (REG_GET_FIELD(blackout, MC_SHARED_BLACKOUT_CNTL, BLACKOUT_MODE) != 1) { @@ -251,9 +256,14 @@ static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev, */ static void gmc_v7_0_mc_program(struct amdgpu_device *adev) { + struct amdgpu_ip_block *ip_block; u32 tmp; int i, j; + ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GMC); + if (!ip_block) + return; + /* Initialize HDP */ for (i = 0, j = 0; i < 32; i++, j += 0x6) { WREG32((0xb05 + j), 0x00000000); @@ -264,7 +274,7 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev) } WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0); - if (gmc_v7_0_wait_for_idle((void *)adev)) + if (gmc_v7_0_wait_for_idle(ip_block)) dev_warn(adev->dev, "Wait for MC idle timedout !\n"); if (adev->mode_info.num_crtc) { @@ -288,7 +298,7 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev) WREG32(mmMC_VM_AGP_BASE, 0); WREG32(mmMC_VM_AGP_TOP, adev->gmc.agp_end >> 22); WREG32(mmMC_VM_AGP_BOT, adev->gmc.agp_start >> 22); - if (gmc_v7_0_wait_for_idle((void *)adev)) + if (gmc_v7_0_wait_for_idle(ip_block)) dev_warn(adev->dev, "Wait for MC idle timedout !\n"); WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK); @@ -1183,7 +1193,7 @@ static int gmc_v7_0_soft_reset(struct amdgpu_ip_block *ip_block) if (srbm_soft_reset) { gmc_v7_0_mc_stop(adev); - if (gmc_v7_0_wait_for_idle((void *)adev)) + if (gmc_v7_0_wait_for_idle(ip_block)) dev_warn(adev->dev, "Wait for GMC idle timed out !\n"); tmp = RREG32(mmSRBM_SOFT_RESET); diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c index 03b8b7cd5229b98dd84389a33570374bfe41d7fe..7319299f25aeaee0a2f13249785514572a50fc50 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c @@ -604,7 +604,7 @@ static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev) static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); + bool set_clocks = !cancel_delayed_work_sync(&adev->jpeg.idle_work); int cnt = 0; mutex_lock(&adev->vcn.vcn1_jpeg1_workaround); diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c index d6823fb45d3288a3025047534987f434b0c8fada..6e29b69894a57de6b49bd6f5b613caea04990afb 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c @@ -150,7 +150,7 @@ static int jpeg_v2_0_hw_fini(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; - cancel_delayed_work_sync(&adev->vcn.idle_work); + cancel_delayed_work_sync(&adev->jpeg.idle_work); if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS)) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c index 5063a38801d698898777dce1c4ffd2a0fcb04057..9ac421486f05fde3d1b5bca4d8e523c0da2887d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c @@ -211,7 +211,7 @@ static int jpeg_v2_5_hw_fini(struct amdgpu_ip_block *ip_block) struct amdgpu_device *adev = ip_block->adev; int i; - cancel_delayed_work_sync(&adev->vcn.idle_work); + cancel_delayed_work_sync(&adev->jpeg.idle_work); for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { if (adev->jpeg.harvest_config & (1 << i)) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c index 10adbb7cbf5392f8d4e4bd3cf1c09c7bad9ff800..e0df6800502ca8e7ac4f3497a46c9a7543e477d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c @@ -164,7 +164,7 @@ static int jpeg_v3_0_hw_fini(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; - cancel_delayed_work_sync(&adev->vcn.idle_work); + cancel_delayed_work_sync(&adev->jpeg.idle_work); if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS)) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c index 193dfac5dc76bc648dde32026b1d72fade1fb743..eca1963c33b6bf5f109bc965f289ffbfa85854d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c @@ -202,7 +202,7 @@ static int jpeg_v4_0_hw_fini(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; - cancel_delayed_work_sync(&adev->vcn.idle_work); + cancel_delayed_work_sync(&adev->jpeg.idle_work); if (!amdgpu_sriov_vf(adev)) { if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS)) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c index b48e2412e6cc1475f5176eba70cf629a3288aebb..1d9e3b101c3a3225bdb8f181d88746adafc17372 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c @@ -227,7 +227,7 @@ static int jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block *ip_block) struct amdgpu_device *adev = ip_block->adev; int i; - cancel_delayed_work_sync(&adev->vcn.idle_work); + cancel_delayed_work_sync(&adev->jpeg.idle_work); for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { if (adev->jpeg.harvest_config & (1 << i)) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c index 686f9605239d01e55d1bd5c64a31bd2715241625..58fb1e5fa89c481fc5411189762f88bd1b347c81 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c @@ -168,7 +168,7 @@ static int jpeg_v5_0_0_hw_fini(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; - cancel_delayed_work_sync(&adev->vcn.idle_work); + cancel_delayed_work_sync(&adev->jpeg.idle_work); if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS)) diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c index 7a9adfda5814a651f982883ade25e74290614e3d..814ab59fdd4a3a370897ca4ef1413ab70f6ac1d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c @@ -275,6 +275,15 @@ static void nbio_v7_11_init_registers(struct amdgpu_device *adev) if (def != data) WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, data); + switch (adev->ip_versions[NBIO_HWIP][0]) { + case IP_VERSION(7, 11, 0): + case IP_VERSION(7, 11, 1): + case IP_VERSION(7, 11, 2): + case IP_VERSION(7, 11, 3): + data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4) & ~BIT(23); + WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4, data); + break; + } } static void nbio_v7_11_update_medium_grain_clock_gating(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c b/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c index 9b01e074af471e14790416eb56dce53edace03c1..2594467bdd8735dbea28648bfe3065614f757f65 100644 --- a/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c +++ b/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c @@ -220,6 +220,7 @@ sienna_cichlid_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, int r; struct amdgpu_device *tmp_adev = (struct amdgpu_device *)reset_ctl->handle; + amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_RESET_RECOVERY); dev_info(tmp_adev->dev, "GPU reset succeeded, trying to resume\n"); r = sienna_cichlid_mode2_restore_ip(tmp_adev); @@ -237,6 +238,7 @@ sienna_cichlid_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, amdgpu_irq_gpu_reset_resume_helper(tmp_adev); + amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_DEFAULT); r = amdgpu_ib_ring_tests(tmp_adev); if (r) { dev_err(tmp_adev->dev, diff --git a/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c b/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c index e70ebad3f9fac499406deffa23bd66761cd7d001..70569ea906bca7652b4047496c0414781ce67eb3 100644 --- a/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c +++ b/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c @@ -221,6 +221,7 @@ smu_v13_0_10_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, int r; struct amdgpu_device *tmp_adev = (struct amdgpu_device *)reset_ctl->handle; + amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_RESET_RECOVERY); dev_info(tmp_adev->dev, "GPU reset succeeded, trying to resume\n"); r = smu_v13_0_10_mode2_restore_ip(tmp_adev); @@ -234,6 +235,7 @@ smu_v13_0_10_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, amdgpu_irq_gpu_reset_resume_helper(tmp_adev); + amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_DEFAULT); r = amdgpu_ib_ring_tests(tmp_adev); if (r) { dev_err(tmp_adev->dev, diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c index 5512259cac79d9102db865b66d7d0fe99d5c1762..fcc8511e91ee0ffe3edf53cfaba810d3cfb60f2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c @@ -225,6 +225,10 @@ static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block) vcn_v4_0_fw_shared_init(adev, i); } + /* TODO: Add queue reset mask when FW fully supports it */ + adev->vcn.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); + if (amdgpu_sriov_vf(adev)) { r = amdgpu_virt_alloc_mm_table(adev); if (r) @@ -247,6 +251,10 @@ static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block) adev->vcn.ip_dump = ptr; } + r = amdgpu_vcn_sysfs_reset_mask_init(adev); + if (r) + return r; + return 0; } @@ -284,6 +292,7 @@ static int vcn_v4_0_sw_fini(struct amdgpu_ip_block *ip_block) if (r) return r; + amdgpu_vcn_sysfs_reset_mask_fini(adev); r = amdgpu_vcn_sw_fini(adev); kfree(adev->vcn.ip_dump); diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c index cf808a153fce73a349d7254f2590ef9109f26ef0..3f69b9b2bcd07988af54d43fae49cf7d3799eeec 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c @@ -123,6 +123,20 @@ static int vcn_v4_0_3_early_init(struct amdgpu_ip_block *ip_block) return amdgpu_vcn_early_init(adev); } +static int vcn_v4_0_3_fw_shared_init(struct amdgpu_device *adev, int inst_idx) +{ + struct amdgpu_vcn4_fw_shared *fw_shared; + + fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; + fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); + fw_shared->sq.is_enabled = 1; + + if (amdgpu_vcnfw_log) + amdgpu_vcn_fwlog_init(&adev->vcn.inst[inst_idx]); + + return 0; +} + /** * vcn_v4_0_3_sw_init - sw init for VCN block * @@ -155,8 +169,6 @@ static int vcn_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block) return r; for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - volatile struct amdgpu_vcn4_fw_shared *fw_shared; - vcn_inst = GET_INST(VCN, i); ring = &adev->vcn.inst[i].ring_enc[0]; @@ -179,14 +191,13 @@ static int vcn_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block) if (r) return r; - fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; - fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); - fw_shared->sq.is_enabled = true; - - if (amdgpu_vcnfw_log) - amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); + vcn_v4_0_3_fw_shared_init(adev, i); } + /* TODO: Add queue reset mask when FW fully supports it */ + adev->vcn.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); + if (amdgpu_sriov_vf(adev)) { r = amdgpu_virt_alloc_mm_table(adev); if (r) @@ -213,6 +224,10 @@ static int vcn_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block) adev->vcn.ip_dump = ptr; } + r = amdgpu_vcn_sysfs_reset_mask_init(adev); + if (r) + return r; + return 0; } @@ -246,6 +261,7 @@ static int vcn_v4_0_3_sw_fini(struct amdgpu_ip_block *ip_block) if (r) return r; + amdgpu_vcn_sysfs_reset_mask_fini(adev); r = amdgpu_vcn_sw_fini(adev); kfree(adev->vcn.ip_dump); @@ -280,6 +296,8 @@ static int vcn_v4_0_3_hw_init(struct amdgpu_ip_block *ip_block) } } else { for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + struct amdgpu_vcn4_fw_shared *fw_shared; + vcn_inst = GET_INST(VCN, i); ring = &adev->vcn.inst[i].ring_enc[0]; @@ -303,6 +321,11 @@ static int vcn_v4_0_3_hw_init(struct amdgpu_ip_block *ip_block) regVCN_RB1_DB_CTRL); } + /* Re-init fw_shared when RAS fatal error occurred */ + fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; + if (!fw_shared->sq.is_enabled) + vcn_v4_0_3_fw_shared_init(adev, i); + r = amdgpu_ring_test_helper(ring); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c index fe2cc1a80c13ef511b2a4a35f700132fe0631cb7..bd3d2bbdc16bb6e6205fd7e65d90b5ebde3871ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c @@ -170,6 +170,10 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block) amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); } + /* TODO: Add queue reset mask when FW fully supports it */ + adev->vcn.supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) adev->vcn.pause_dpg_mode = vcn_v5_0_0_pause_dpg_mode; @@ -181,6 +185,11 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block) } else { adev->vcn.ip_dump = ptr; } + + r = amdgpu_vcn_sysfs_reset_mask_init(adev); + if (r) + return r; + return 0; } @@ -215,6 +224,7 @@ static int vcn_v5_0_0_sw_fini(struct amdgpu_ip_block *ip_block) if (r) return r; + amdgpu_vcn_sysfs_reset_mask_fini(adev); r = amdgpu_vcn_sw_fini(adev); kfree(adev->vcn.ip_dump); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index 4843dcb9a5f79690167061e9dc0c8b7a67cb11ce..2b0a830f5b294653bb809dbb9e1dab43eebdb8ad 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -125,7 +125,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_node *dev, memset(kq->pq_kernel_addr, 0, queue_size); memset(kq->rptr_kernel, 0, sizeof(*kq->rptr_kernel)); - memset(kq->wptr_kernel, 0, sizeof(*kq->wptr_kernel)); + memset(kq->wptr_kernel, 0, dev->kfd->device_info.doorbell_size); prop.queue_size = queue_size; prop.is_interop = false; @@ -306,12 +306,17 @@ int kq_submit_packet(struct kernel_queue *kq) if (amdgpu_amdkfd_is_fed(kq->dev->adev)) return -EIO; + /* Make sure ring buffer is updated before wptr updated */ + mb(); + if (kq->dev->kfd->device_info.doorbell_size == 8) { *kq->wptr64_kernel = kq->pending_wptr64; + mb(); /* Make sure wptr updated before ring doorbell */ write_kernel_doorbell64(kq->queue->properties.doorbell_ptr, kq->pending_wptr64); } else { *kq->wptr_kernel = kq->pending_wptr; + mb(); /* Make sure wptr updated before ring doorbell */ write_kernel_doorbell(kq->queue->properties.doorbell_ptr, kq->pending_wptr); } diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index df17e79c45c767b32c538798c5098a7be3c25dae..11e3f2f3b1745e6cec5af72f80e48aaf7eebe7d7 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -7,20 +7,21 @@ menu "Display Engine Configuration" config DRM_AMD_DC bool "AMD DC - Enable new display engine" default y - depends on BROKEN || !CC_IS_CLANG || ARM64 || RISCV || SPARC64 || X86_64 + depends on BROKEN || !CC_IS_CLANG || ARM64 || LOONGARCH || RISCV || SPARC64 || X86_64 select SND_HDA_COMPONENT if SND_HDA_CORE # !CC_IS_CLANG: https://github.com/ClangBuiltLinux/linux/issues/1752 - select DRM_AMD_DC_FP if ARCH_HAS_KERNEL_FPU_SUPPORT && !(CC_IS_CLANG && (ARM64 || RISCV)) + select DRM_AMD_DC_FP if ARCH_HAS_KERNEL_FPU_SUPPORT && !(CC_IS_CLANG && (ARM64 || LOONGARCH || RISCV)) help Choose this option if you want to use the new display engine support for AMDGPU. This adds required support for Vega and Raven ASICs. - calculate_bandwidth() is presently broken on all !(X86_64 || SPARC64 || ARM64) - architectures built with Clang (all released versions), whereby the stack - frame gets blown up to well over 5k. This would cause an immediate kernel - panic on most architectures. We'll revert this when the following bug report - has been resolved: https://github.com/llvm/llvm-project/issues/41896. + calculate_bandwidth() is presently broken on all !(X86_64 || SPARC64 || + ARM64 || LOONGARCH || RISCV) architectures built with Clang (all released + versions), whereby the stack frame gets blown up to well over 5k. This + would cause an immediate kernel panic on most architectures. We'll revert + this when the following bug report has been resolved: + https://github.com/llvm/llvm-project/issues/41896. config DRM_AMD_DC_FP def_bool n diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 7872c6cabb14c3aa6819c034c9fd05255b335d0d..1dd26d5df6b95f1f464d58db2674b3ba520e89ab 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3141,7 +3141,10 @@ static void restore_planes_and_stream_state( return; for (i = 0; i < status->plane_count; i++) { + /* refcount will always be valid, restore everything else */ + struct kref refcount = status->plane_states[i]->refcount; *status->plane_states[i] = scratch->plane_states[i]; + status->plane_states[i]->refcount = refcount; } *stream = scratch->stream_state; } @@ -6097,11 +6100,11 @@ struct dc_power_profile dc_get_power_profile_for_dc_state(const struct dc_state { struct dc_power_profile profile = { 0 }; - if (!context || !context->clk_mgr || !context->clk_mgr->ctx || !context->clk_mgr->ctx->dc) + profile.power_level = !context->bw_ctx.bw.dcn.clk.p_state_change_support; + if (!context->clk_mgr || !context->clk_mgr->ctx || !context->clk_mgr->ctx->dc) return profile; struct dc *dc = context->clk_mgr->ctx->dc; - if (dc->res_pool->funcs->get_power_profile) profile.power_level = dc->res_pool->funcs->get_power_profile(context); return profile; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 0419ee7f22a53baabf23b0b5fd6ff388d68ee243..252af83e34a530b876f61825302332129bd92617 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -898,6 +898,9 @@ void hwss_setup_dpp(union block_sequence_params *params) struct dpp *dpp = pipe_ctx->plane_res.dpp; struct dc_plane_state *plane_state = pipe_ctx->plane_state; + if (!plane_state) + return; + if (dpp && dpp->funcs->dpp_setup) { // program the input csc dpp->funcs->dpp_setup(dpp, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 33125b95c3a13258eef4d2bc4a04e51b5862798f..619fad17de55447afaed21e2190f5ae4a4fbcda2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1501,6 +1501,10 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) res = spl_calculate_scaler_params(spl_in, spl_out); // Convert respective out params from SPL to scaler data translate_SPL_out_params_to_pipe_ctx(pipe_ctx, spl_out); + + /* Ignore scaler failure if pipe context plane is phantom plane */ + if (!res && plane_state->is_phantom) + res = true; } else { #endif /* depends on h_active */ @@ -1571,6 +1575,10 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) &plane_state->scaling_quality); } + /* Ignore scaler failure if pipe context plane is phantom plane */ + if (!res && plane_state->is_phantom) + res = true; + if (res && (pipe_ctx->plane_res.scl_data.taps.v_taps != temp.v_taps || pipe_ctx->plane_res.scl_data.taps.h_taps != temp.h_taps || pipe_ctx->plane_res.scl_data.taps.v_taps_c != temp.v_taps_c || diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e143fab00a861c4f578167702c648d2b4b043945..1040519358841dbb6086e5630ce535f2801196d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -55,7 +55,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.309" +#define DC_VER "3.2.310" #define MAX_SURFACES 3 #define MAX_PLANES 6 diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c index 838d72eaa87fbd4abf1ccbe150053b492d5406fd..b363f5360818d881285c64fb27ed3a01e59ba2e3 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c @@ -1392,10 +1392,10 @@ static void dccg35_set_dtbclk_dto( /* The recommended programming sequence to enable DTBCLK DTO to generate * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should - * be set only after DTO is enabled + * be set only after DTO is enabled. + * PIPEx_DTO_SRC_SEL should not be programmed during DTBCLK update since OTG may still be on, and the + * programming is handled in program_pix_clk() regardless, so it can be removed from here. */ - REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], - PIPE_DTO_SRC_SEL[params->otg_inst], 2); } else { switch (params->otg_inst) { case 0: @@ -1412,9 +1412,12 @@ static void dccg35_set_dtbclk_dto( break; } - REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst], - DTBCLK_DTO_ENABLE[params->otg_inst], 0, - PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1); + /** + * PIPEx_DTO_SRC_SEL should not be programmed during DTBCLK update since OTG may still be on, and the + * programming is handled in program_pix_clk() regardless, so it can be removed from here. + */ + REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_ENABLE[params->otg_inst], 0); REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0); REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0); diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c index 92e43a1e4dd46258fc933ce2c46fd36649cd7a8a..601320b1be81717b201e1b24e00d3d81844e04ac 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c @@ -11,6 +11,7 @@ #define DML2_MAX_FMT_420_BUFFER_WIDTH 4096 #define DML_MAX_NUM_OF_SLICES_PER_DSC 4 +#define ALLOW_SDPIF_RATE_LIMIT_PRE_CSTATE const char *dml2_core_internal_bw_type_str(enum dml2_core_internal_bw_type bw_type) { @@ -3886,6 +3887,10 @@ static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch #endif *p->hw_debug5 = false; +#ifdef ALLOW_SDPIF_RATE_LIMIT_PRE_CSTATE + if (p->NumberOfActiveSurfaces > 1) + *p->hw_debug5 = true; +#else for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { if (!(p->mrq_present) && (!(*p->UnboundedRequestEnabled)) && (TotalActiveDPP == 1) && p->display_cfg->plane_descriptors[k].surface.dcc.enable @@ -3901,6 +3906,7 @@ static void CalculateSwathAndDETConfiguration(struct dml2_core_internal_scratch dml2_printf("DML::%s: k=%u hw_debug5 = %u\n", __func__, k, *p->hw_debug5); #endif } +#endif } static enum dml2_odm_mode DecideODMMode(unsigned int HActive, diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c index 6eccf0241d857d89031224900d9063460d76472f..1ed21c1b86a5bb000f071c337aca0a3b716b8a56 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c @@ -258,12 +258,25 @@ static unsigned int find_preferred_pipe_candidates(const struct dc_state *existi * However this condition comes with a caveat. We need to ignore pipes that will * require a change in OPP but still have the same stream id. For example during * an MPC to ODM transiton. + * + * Adding check to avoid pipe select on the head pipe by utilizing dc resource + * helper function resource_get_primary_dpp_pipe and comparing the pipe index. */ if (existing_state) { for (i = 0; i < pipe_count; i++) { if (existing_state->res_ctx.pipe_ctx[i].stream && existing_state->res_ctx.pipe_ctx[i].stream->stream_id == stream_id) { + struct pipe_ctx *head_pipe = + resource_is_pipe_type(&existing_state->res_ctx.pipe_ctx[i], DPP_PIPE) ? + resource_get_primary_dpp_pipe(&existing_state->res_ctx.pipe_ctx[i]) : + NULL; + + // we should always respect the head pipe from selection + if (head_pipe && head_pipe->pipe_idx == i) + continue; if (existing_state->res_ctx.pipe_ctx[i].plane_res.hubp && - existing_state->res_ctx.pipe_ctx[i].plane_res.hubp->opp_id != i) + existing_state->res_ctx.pipe_ctx[i].plane_res.hubp->opp_id != i && + (existing_state->res_ctx.pipe_ctx[i].prev_odm_pipe || + existing_state->res_ctx.pipe_ctx[i].next_odm_pipe)) continue; preferred_pipe_candidates[num_preferred_candidates++] = i; @@ -292,6 +305,14 @@ static unsigned int find_last_resort_pipe_candidates(const struct dc_state *exis */ if (existing_state) { for (i = 0; i < pipe_count; i++) { + struct pipe_ctx *head_pipe = + resource_is_pipe_type(&existing_state->res_ctx.pipe_ctx[i], DPP_PIPE) ? + resource_get_primary_dpp_pipe(&existing_state->res_ctx.pipe_ctx[i]) : + NULL; + + // we should always respect the head pipe from selection + if (head_pipe && head_pipe->pipe_idx == i) + continue; if ((existing_state->res_ctx.pipe_ctx[i].plane_res.hubp && existing_state->res_ctx.pipe_ctx[i].plane_res.hubp->opp_id != i) || existing_state->res_ctx.pipe_ctx[i].stream_res.tg) diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index ebd5df1a36e8bc73f3ce83f3d25beb8b9f234301..d9aaebfa3a0a76bc40df501eb94cde23b3152cf1 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -1093,14 +1093,11 @@ static bool setup_dsc_config( if (!is_dsc_possible) goto done; - // Final decission: can we do DSC or not? - if (is_dsc_possible) { - // Fill out the rest of DSC settings - dsc_cfg->block_pred_enable = dsc_common_caps.is_block_pred_supported; - dsc_cfg->linebuf_depth = dsc_common_caps.lb_bit_depth; - dsc_cfg->version_minor = (dsc_common_caps.dsc_version & 0xf0) >> 4; - dsc_cfg->is_dp = dsc_sink_caps->is_dp; - } + /* Fill out the rest of DSC settings */ + dsc_cfg->block_pred_enable = dsc_common_caps.is_block_pred_supported; + dsc_cfg->linebuf_depth = dsc_common_caps.lb_bit_depth; + dsc_cfg->version_minor = (dsc_common_caps.dsc_version & 0xf0) >> 4; + dsc_cfg->is_dp = dsc_sink_caps->is_dp; done: if (!is_dsc_possible) diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h index 4bd1dda077196175b2d912c68c69664289f9501f..9fbd45c7dfef277077b6bacee6268baaee9d861b 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h @@ -200,6 +200,7 @@ struct dcn_hubbub_registers { uint32_t DCHUBBUB_ARB_FRAC_URG_BW_MALL_B; uint32_t DCHUBBUB_TIMEOUT_DETECTION_CTRL1; uint32_t DCHUBBUB_TIMEOUT_DETECTION_CTRL2; + uint32_t DCHUBBUB_CTRL_STATUS; }; #define HUBBUB_REG_FIELD_LIST_DCN32(type) \ @@ -320,7 +321,12 @@ struct dcn_hubbub_registers { type DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD;\ type DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD;\ type DCHUBBUB_TIMEOUT_DETECTION_EN;\ - type DCHUBBUB_TIMEOUT_TIMER_RESET + type DCHUBBUB_TIMEOUT_TIMER_RESET;\ + type ROB_UNDERFLOW_STATUS;\ + type ROB_OVERFLOW_STATUS;\ + type ROB_OVERFLOW_CLEAR;\ + type DCHUBBUB_HW_DEBUG;\ + type CSTATE_SWATH_CHK_GOOD_MODE #define HUBBUB_STUTTER_REG_FIELD_LIST(type) \ type DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A;\ diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.h index 036bb3e6c957514f6ded123c20f0123b69d68240..46d8f5c70750a3c9f7f808b16eb30bab57138943 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.h @@ -96,6 +96,7 @@ struct dcn20_hubbub { unsigned int det1_size; unsigned int det2_size; unsigned int det3_size; + bool allow_sdpif_rate_limit_when_cstate_req; }; void hubbub2_construct(struct dcn20_hubbub *hubbub, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c index 5d658e9bef6401e99d6f7774d25717bbabb4d3f8..92fab471b183697d8958b167cee5fa9319a56b17 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c @@ -1192,15 +1192,35 @@ static void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst) } } -static void dcn401_program_timeout_thresholds(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs) +static bool dcn401_program_arbiter(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); + bool wm_pending = false; + uint32_t temp; + /* request backpressure and outstanding return threshold (unused)*/ //REG_UPDATE(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD, arb_regs->req_stall_threshold); /* P-State stall threshold */ REG_UPDATE(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD, arb_regs->pstate_stall_threshold); + + if (safe_to_lower || arb_regs->allow_sdpif_rate_limit_when_cstate_req > hubbub2->allow_sdpif_rate_limit_when_cstate_req) { + hubbub2->allow_sdpif_rate_limit_when_cstate_req = arb_regs->allow_sdpif_rate_limit_when_cstate_req; + + /* only update the required bits */ + REG_GET(DCHUBBUB_CTRL_STATUS, DCHUBBUB_HW_DEBUG, &temp); + if (hubbub2->allow_sdpif_rate_limit_when_cstate_req) { + temp |= (1 << 5); + } else { + temp &= ~(1 << 5); + } + REG_UPDATE(DCHUBBUB_CTRL_STATUS, DCHUBBUB_HW_DEBUG, temp); + } else { + wm_pending = true; + } + + return wm_pending; } static const struct hubbub_funcs hubbub4_01_funcs = { @@ -1226,7 +1246,7 @@ static const struct hubbub_funcs hubbub4_01_funcs = { .program_det_segments = dcn401_program_det_segments, .program_compbuf_segments = dcn401_program_compbuf_segments, .wait_for_det_update = dcn401_wait_for_det_update, - .program_timeout_thresholds = dcn401_program_timeout_thresholds, + .program_arbiter = dcn401_program_arbiter, }; void hubbub401_construct(struct dcn20_hubbub *hubbub2, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h index 5f1960722ebddb10b5e3c2a00d9a6a985f2760a8..b1d9ea9d1c3d614d709f92e3d9673deff5db1281 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h @@ -128,7 +128,12 @@ HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD, mask_sh),\ HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD, mask_sh),\ HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_DETECTION_EN, mask_sh),\ - HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_TIMER_RESET, mask_sh) + HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_TIMER_RESET, mask_sh),\ + HUBBUB_SF(DCHUBBUB_CTRL_STATUS, ROB_UNDERFLOW_STATUS, mask_sh),\ + HUBBUB_SF(DCHUBBUB_CTRL_STATUS, ROB_OVERFLOW_STATUS, mask_sh),\ + HUBBUB_SF(DCHUBBUB_CTRL_STATUS, ROB_OVERFLOW_CLEAR, mask_sh),\ + HUBBUB_SF(DCHUBBUB_CTRL_STATUS, DCHUBBUB_HW_DEBUG, mask_sh),\ + HUBBUB_SF(DCHUBBUB_CTRL_STATUS, CSTATE_SWATH_CHK_GOOD_MODE, mask_sh) bool hubbub401_program_urgent_watermarks( struct hubbub *hubbub, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 05424a9af58bdedd4144962a0d091ca3c08b3459..b029ec1b26d36e28f6f653c53d7152c375d9b777 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -1925,9 +1925,9 @@ static void dcn20_program_pipe( dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->hubp_regs.det_size); } - if (pipe_ctx->update_flags.raw || - (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.raw) || - pipe_ctx->stream->update_flags.raw) + if (pipe_ctx->plane_state && (pipe_ctx->update_flags.raw || + pipe_ctx->plane_state->update_flags.raw || + pipe_ctx->stream->update_flags.raw)) dcn20_update_dchubp_dpp(dc, pipe_ctx, context); if (pipe_ctx->plane_state && (pipe_ctx->update_flags.bits.enable || diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index e8cc1bfa73f31adb26865624b952807965f0d9b4..5de11e2837c011295012ff1f43ba5e44eaf6d0cb 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -1488,6 +1488,10 @@ void dcn401_prepare_bandwidth(struct dc *dc, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, false); + /* update timeout thresholds */ + if (hubbub->funcs->program_arbiter) { + dc->wm_optimized_required |= hubbub->funcs->program_arbiter(hubbub, &context->bw_ctx.bw.dcn.arb_regs, false); + } /* decrease compbuf size */ if (hubbub->funcs->program_compbuf_segments) { @@ -1529,6 +1533,10 @@ void dcn401_optimize_bandwidth( &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, true); + /* update timeout thresholds */ + if (hubbub->funcs->program_arbiter) { + hubbub->funcs->program_arbiter(hubbub, &context->bw_ctx.bw.dcn.arb_regs, true); + } if (dc->clk_mgr->dc_mode_softmax_enabled) if (dc->clk_mgr->clks.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 && @@ -1554,11 +1562,6 @@ void dcn401_optimize_bandwidth( pipe_ctx->dlg_regs.min_dst_y_next_start); } } - - /* update timeout thresholds */ - if (hubbub->funcs->program_timeout_thresholds) { - hubbub->funcs->program_timeout_thresholds(hubbub, &context->bw_ctx.bw.dcn.arb_regs); - } } void dcn401_fams2_global_control_lock(struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h index 6c1d41c0f09926da5d8514297164e794ff8322ac..52b745667ef756b9dc8931f0e3a8f0f0ae8fabfc 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -228,7 +228,7 @@ struct hubbub_funcs { void (*program_det_segments)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg); void (*program_compbuf_segments)(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase); void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst); - void (*program_timeout_thresholds)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs); + bool (*program_arbiter)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower); }; struct hubbub { diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h index 7c8d61db153d38f648b5efd333dc755d189e72a3..19568c359669421d6df34810f17e776f13a67389 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h @@ -612,7 +612,8 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context); SR(DCHUBBUB_SDPIF_CFG1), \ SR(DCHUBBUB_MEM_PWR_MODE_CTRL), \ SR(DCHUBBUB_TIMEOUT_DETECTION_CTRL1), \ - SR(DCHUBBUB_TIMEOUT_DETECTION_CTRL2) + SR(DCHUBBUB_TIMEOUT_DETECTION_CTRL2), \ + SR(DCHUBBUB_CTRL_STATUS) /* DCCG */ diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c index 614276200aa08324fd4bdb2e6388001a28526cb1..73a65913cb12476b6ce4db3eb056858e998e0568 100644 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c +++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c @@ -99,7 +99,7 @@ static struct spl_rect calculate_plane_rec_in_timing_active( * * recout_x = 128 + round(plane_x * 2304 / 1920) * recout_w = 128 + round((plane_x + plane_w) * 2304 / 1920) - recout_x - * recout_y = 0 + round(plane_y * 1440 / 1280) + * recout_y = 0 + round(plane_y * 1440 / 1200) * recout_h = 0 + round((plane_y + plane_h) * 1440 / 1200) - recout_y * * NOTE: fixed point division is not error free. To reduce errors @@ -739,14 +739,13 @@ static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in, return SCL_MODE_SCALING_444_RGB_ENABLE; } - /* Bypass YUV if at 1:1 with no ISHARP or if doing 2:1 YUV - * downscale without EASF + /* + * Bypass YUV if Y is 1:1 with no ISHARP + * Do not bypass UV at 1:1 for cositing to be applied */ - if ((!enable_isharp) && (!enable_easf)) { + if (!enable_isharp) { if (data->ratios.horz.value == one && data->ratios.vert.value == one) return SCL_MODE_SCALING_420_LUMA_BYPASS; - if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one) - return SCL_MODE_SCALING_420_CHROMA_BYPASS; } return SCL_MODE_SCALING_420_YCBCR_ENABLE; @@ -933,6 +932,7 @@ static bool spl_get_optimal_number_of_taps( int min_taps_y, min_taps_c; enum lb_memory_config lb_config; bool skip_easf = false; + bool is_ycbcr = spl_dscl_is_video_format(spl_in->basic_in.format); if (spl_scratch->scl_data.viewport.width > spl_scratch->scl_data.h_active && max_downscale_src_width != 0 && @@ -1074,10 +1074,9 @@ static bool spl_get_optimal_number_of_taps( /* Sharpener requires scaler to be enabled, including for 1:1 * Check if ISHARP can be enabled - * If ISHARP is not enabled, for 1:1, set taps to 1 and disable - * EASF - * For case of 2:1 YUV where chroma is 1:1, set taps to 1 if - * EASF is not enabled + * If ISHARP is not enabled, set taps to 1 if ratio is 1:1 + * except for chroma taps. Keep previous taps so it can + * handle cositing */ *enable_isharp = spl_get_isharp_en(spl_in, spl_scratch); @@ -1087,20 +1086,28 @@ static bool spl_get_optimal_number_of_taps( spl_scratch->scl_data.taps.h_taps = 1; spl_scratch->scl_data.taps.v_taps = 1; - if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c)) + if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c) && !is_ycbcr) spl_scratch->scl_data.taps.h_taps_c = 1; - if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c)) + if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c) && !is_ycbcr) spl_scratch->scl_data.taps.v_taps_c = 1; *enable_easf_v = false; *enable_easf_h = false; } else { if ((!*enable_easf_h) && + (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz))) + spl_scratch->scl_data.taps.h_taps = 1; + + if ((!*enable_easf_v) && + (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert))) + spl_scratch->scl_data.taps.v_taps = 1; + + if ((!*enable_easf_h) && !is_ycbcr && (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c))) spl_scratch->scl_data.taps.h_taps_c = 1; - if ((!*enable_easf_v) && + if ((!*enable_easf_v) && !is_ycbcr && (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c))) spl_scratch->scl_data.taps.v_taps_c = 1; } @@ -1111,8 +1118,7 @@ static bool spl_get_optimal_number_of_taps( static void spl_set_black_color_data(enum spl_pixel_format format, struct scl_black_color *scl_black_color) { - bool ycbcr = format >= SPL_PIXEL_FORMAT_VIDEO_BEGIN - && format <= SPL_PIXEL_FORMAT_VIDEO_END; + bool ycbcr = spl_dscl_is_video_format(format); if (ycbcr) { scl_black_color->offset_rgb_y = BLACK_OFFSET_RGB_Y; scl_black_color->offset_rgb_cbcr = BLACK_OFFSET_CBCR; @@ -1746,6 +1752,32 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data, spl_set_blur_scale_data(dscl_prog_data, data); } +/* Calculate recout, scaling ratio, and viewport, then get optimal number of taps */ +static bool spl_calculate_number_of_taps(struct spl_in *spl_in, struct spl_scratch *spl_scratch, struct spl_out *spl_out, + bool *enable_easf_v, bool *enable_easf_h, bool *enable_isharp) +{ + bool res = false; + + memset(spl_scratch, 0, sizeof(struct spl_scratch)); + spl_scratch->scl_data.h_active = spl_in->h_active; + spl_scratch->scl_data.v_active = spl_in->v_active; + + // All SPL calls + /* recout calculation */ + /* depends on h_active */ + spl_calculate_recout(spl_in, spl_scratch, spl_out); + /* depends on pixel format */ + spl_calculate_scaling_ratios(spl_in, spl_scratch, spl_out); + /* depends on scaling ratios and recout, does not calculate offset yet */ + spl_calculate_viewport_size(spl_in, spl_scratch); + + res = spl_get_optimal_number_of_taps( + spl_in->basic_out.max_downscale_src_width, spl_in, + spl_scratch, &spl_in->scaling_quality, enable_easf_v, + enable_easf_h, enable_isharp); + return res; +} + /* Calculate scaler parameters */ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out) { @@ -1760,23 +1792,9 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out) bool enable_isharp = false; const struct spl_scaler_data *data = &spl_scratch.scl_data; - memset(&spl_scratch, 0, sizeof(struct spl_scratch)); - spl_scratch.scl_data.h_active = spl_in->h_active; - spl_scratch.scl_data.v_active = spl_in->v_active; + res = spl_calculate_number_of_taps(spl_in, &spl_scratch, spl_out, + &enable_easf_v, &enable_easf_h, &enable_isharp); - // All SPL calls - /* recout calculation */ - /* depends on h_active */ - spl_calculate_recout(spl_in, &spl_scratch, spl_out); - /* depends on pixel format */ - spl_calculate_scaling_ratios(spl_in, &spl_scratch, spl_out); - /* depends on scaling ratios and recout, does not calculate offset yet */ - spl_calculate_viewport_size(spl_in, &spl_scratch); - - res = spl_get_optimal_number_of_taps( - spl_in->basic_out.max_downscale_src_width, spl_in, - &spl_scratch, &spl_in->scaling_quality, &enable_easf_v, - &enable_easf_h, &enable_isharp); /* * Depends on recout, scaling ratios, h_active and taps * May need to re-check lb size after this in some obscure scenario @@ -1824,3 +1842,20 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out) return res; } + +/* External interface to get number of taps only */ +bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out) +{ + bool res = false; + bool enable_easf_v = false; + bool enable_easf_h = false; + bool enable_isharp = false; + struct spl_scratch spl_scratch; + struct dscl_prog_data *dscl_prog_data = spl_out->dscl_prog_data; + const struct spl_scaler_data *data = &spl_scratch.scl_data; + + res = spl_calculate_number_of_taps(spl_in, &spl_scratch, spl_out, + &enable_easf_v, &enable_easf_h, &enable_isharp); + spl_set_taps_data(dscl_prog_data, data); + return res; +} diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h index 205e59a2a8ee8fb8ebf4df07db860f7fcda40d34..02a2d6725ed58dbf3892e5deb46feb470a4a428a 100644 --- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h +++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.h @@ -13,4 +13,6 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out); +bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out); + #endif /* __DC_SPL_H__ */ diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h index 5ebe4cb40f9db6ff19b05f3275e931b967b73961..c38a01742d6f0e115c0662703b7ab5eb42baf0cb 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h @@ -7571,6 +7571,8 @@ // base address: 0x10100000 #define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0 0xd000 #define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_BASE_IDX 5 +#define regRCC_DEV0_EPF5_STRAP4 0xd284 +#define regRCC_DEV0_EPF5_STRAP4_BASE_IDX 5 // addressBlock: nbio_nbif0_bif_rst_bif_rst_regblk diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h index eb8c556d9c9300dbb4d586b5ab590f3b3316c7bf..3b96f1e5a1802c7d71eafba42fe68ff33ef3d527 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h @@ -50665,6 +50665,19 @@ #define RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_D1_SUPPORT_DEV0_F0_MASK 0x40000000L #define RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_D2_SUPPORT_DEV0_F0_MASK 0x80000000L +//RCC_DEV0_EPF5_STRAP4 +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_64BIT_EN_DEV0_F5__SHIFT 0x14 +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_EN_DEV0_F5__SHIFT 0x15 +#define RCC_DEV0_EPF5_STRAP4__STRAP_FLR_EN_DEV0_F5__SHIFT 0x16 +#define RCC_DEV0_EPF5_STRAP4__STRAP_PME_SUPPORT_DEV0_F5__SHIFT 0x17 +#define RCC_DEV0_EPF5_STRAP4__STRAP_INTERRUPT_PIN_DEV0_F5__SHIFT 0x1c +#define RCC_DEV0_EPF5_STRAP4__STRAP_AUXPWR_SUPPORT_DEV0_F5__SHIFT 0x1f +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_64BIT_EN_DEV0_F5_MASK 0x00100000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_EN_DEV0_F5_MASK 0x00200000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_FLR_EN_DEV0_F5_MASK 0x00400000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_PME_SUPPORT_DEV0_F5_MASK 0x0F800000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_INTERRUPT_PIN_DEV0_F5_MASK 0x70000000L +#define RCC_DEV0_EPF5_STRAP4__STRAP_AUXPWR_SUPPORT_DEV0_F5_MASK 0x80000000L // addressBlock: nbio_nbif0_bif_rst_bif_rst_regblk //HARD_RST_CTRL diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index bb27c0d2a9ae89fe2faa5589fc85ca2806295585..67a5de57394361e2a272be17e0a9daa907c39e8a 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -357,11 +357,22 @@ struct dpm_clocks; struct amdgpu_xcp_metrics { /* Utilization Instantaneous (%) */ - u32 gfx_busy_inst[MAX_XCC]; - u16 jpeg_busy[NUM_JPEG_ENG]; - u16 vcn_busy[NUM_VCN]; + uint32_t gfx_busy_inst[MAX_XCC]; + uint16_t jpeg_busy[NUM_JPEG_ENG]; + uint16_t vcn_busy[NUM_VCN]; /* Utilization Accumulated (%) */ - u64 gfx_busy_acc[MAX_XCC]; + uint64_t gfx_busy_acc[MAX_XCC]; +}; + +struct amdgpu_xcp_metrics_v1_1 { + /* Utilization Instantaneous (%) */ + uint32_t gfx_busy_inst[MAX_XCC]; + uint16_t jpeg_busy[NUM_JPEG_ENG]; + uint16_t vcn_busy[NUM_VCN]; + /* Utilization Accumulated (%) */ + uint64_t gfx_busy_acc[MAX_XCC]; + /* Total App Clock Counter Accumulated */ + uint64_t gfx_below_host_limit_acc[MAX_XCC]; }; struct amd_pm_funcs { @@ -977,6 +988,105 @@ struct gpu_metrics_v1_6 { uint32_t pcie_lc_perf_other_end_recovery; }; +struct gpu_metrics_v1_7 { + struct metrics_table_header common_header; + + /* Temperature (Celsius) */ + uint16_t temperature_hotspot; + uint16_t temperature_mem; + uint16_t temperature_vrsoc; + + /* Power (Watts) */ + uint16_t curr_socket_power; + + /* Utilization (%) */ + uint16_t average_gfx_activity; + uint16_t average_umc_activity; // memory controller + + /* VRAM max bandwidthi (in GB/sec) at max memory clock */ + uint64_t mem_max_bandwidth; + + /* Energy (15.259uJ (2^-16) units) */ + uint64_t energy_accumulator; + + /* Driver attached timestamp (in ns) */ + uint64_t system_clock_counter; + + /* Accumulation cycle counter */ + uint32_t accumulation_counter; + + /* Accumulated throttler residencies */ + uint32_t prochot_residency_acc; + uint32_t ppt_residency_acc; + uint32_t socket_thm_residency_acc; + uint32_t vr_thm_residency_acc; + uint32_t hbm_thm_residency_acc; + + /* Clock Lock Status. Each bit corresponds to clock instance */ + uint32_t gfxclk_lock_status; + + /* Link width (number of lanes) and speed (in 0.1 GT/s) */ + uint16_t pcie_link_width; + uint16_t pcie_link_speed; + + /* XGMI bus width and bitrate (in Gbps) */ + uint16_t xgmi_link_width; + uint16_t xgmi_link_speed; + + /* Utilization Accumulated (%) */ + uint32_t gfx_activity_acc; + uint32_t mem_activity_acc; + + /*PCIE accumulated bandwidth (GB/sec) */ + uint64_t pcie_bandwidth_acc; + + /*PCIE instantaneous bandwidth (GB/sec) */ + uint64_t pcie_bandwidth_inst; + + /* PCIE L0 to recovery state transition accumulated count */ + uint64_t pcie_l0_to_recov_count_acc; + + /* PCIE replay accumulated count */ + uint64_t pcie_replay_count_acc; + + /* PCIE replay rollover accumulated count */ + uint64_t pcie_replay_rover_count_acc; + + /* PCIE NAK sent accumulated count */ + uint32_t pcie_nak_sent_count_acc; + + /* PCIE NAK received accumulated count */ + uint32_t pcie_nak_rcvd_count_acc; + + /* XGMI accumulated data transfer size(KiloBytes) */ + uint64_t xgmi_read_data_acc[NUM_XGMI_LINKS]; + uint64_t xgmi_write_data_acc[NUM_XGMI_LINKS]; + + /* XGMI link status(active/inactive) */ + uint16_t xgmi_link_status[NUM_XGMI_LINKS]; + + uint16_t padding; + + /* PMFW attached timestamp (10ns resolution) */ + uint64_t firmware_timestamp; + + /* Current clocks (Mhz) */ + uint16_t current_gfxclk[MAX_GFX_CLKS]; + uint16_t current_socclk[MAX_CLKS]; + uint16_t current_vclk0[MAX_CLKS]; + uint16_t current_dclk0[MAX_CLKS]; + uint16_t current_uclk; + + /* Number of current partition */ + uint16_t num_partition; + + /* XCP metrics stats */ + struct amdgpu_xcp_metrics_v1_1 xcp_stats[NUM_XCP]; + + /* PCIE other end recovery counter */ + uint32_t pcie_lc_perf_other_end_recovery; +}; + /* * gpu_metrics_v2_0 is not recommended as it's not naturally aligned. * Use gpu_metrics_v2_1 or later instead. diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c index b52ce135d84d4601b5e0e51d21de853c5236a15a..d3ff6a831ed5dcfa143ec80c130ffec860b051c4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c @@ -257,20 +257,18 @@ static int vega12_smu_init(struct pp_hwmgr *hwmgr) priv->smu_tables.entry[TABLE_WATERMARKS].size = sizeof(Watermarks_t); tools_size = 0x19000; - if (tools_size) { - ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, - tools_size, - PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM, - &priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle, - &priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr, - &priv->smu_tables.entry[TABLE_PMSTATUSLOG].table); - if (ret) - goto err1; + ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, + tools_size, + PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle, + &priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr, + &priv->smu_tables.entry[TABLE_PMSTATUSLOG].table); + if (ret) + goto err1; - priv->smu_tables.entry[TABLE_PMSTATUSLOG].version = 0x01; - priv->smu_tables.entry[TABLE_PMSTATUSLOG].size = tools_size; - } + priv->smu_tables.entry[TABLE_PMSTATUSLOG].version = 0x01; + priv->smu_tables.entry[TABLE_PMSTATUSLOG].size = tools_size; /* allocate space for AVFS Fuse table */ ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev, diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 64f9179595766aaa95a2e09dac612e2321ab4752..b8355293518f89e8ea3f1f26ac91551a3d09084c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1704,7 +1704,9 @@ static int smu_smc_hw_setup(struct smu_context *smu) return ret; } - if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN5) + pcie_gen = 4; + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) pcie_gen = 3; else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) pcie_gen = 2; @@ -1717,7 +1719,9 @@ static int smu_smc_hw_setup(struct smu_context *smu) * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 */ - if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X32) + pcie_width = 7; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) pcie_width = 6; else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) pcie_width = 5; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h index 0546b02e198ddea7f3f14ceb73be9f4856db3d2b..29a4583db8734bf6ce57c72d2d2c4e3a7da62166 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h @@ -53,7 +53,7 @@ #define CTF_OFFSET_MEM 5 extern const int decoded_link_speed[5]; -extern const int decoded_link_width[7]; +extern const int decoded_link_width[8]; #define DECODE_GEN_SPEED(gen_speed_idx) (decoded_link_speed[gen_speed_idx]) #define DECODE_LANE_WIDTH(lane_width_idx) (decoded_link_width[lane_width_idx]) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 4b36c230e43a0928d7d640f9c94091724b946893..12125303bb7991b521fcc58b788d5fae0c7a6547 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1344,8 +1344,12 @@ static int arcturus_get_power_limit(struct smu_context *smu, *default_power_limit = power_limit; if (max_power_limit) *max_power_limit = power_limit; + /** + * No lower bound is imposed on the limit. Any unreasonable limit set + * will result in frequent throttling. + */ if (min_power_limit) - *min_power_limit = power_limit; + *min_power_limit = 0; return 0; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index fa30a9e1f27afe65d5f437b726503931238ec706..ab3c93ddce46ff2292de6434455bf52173ae4e02 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -96,7 +96,6 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_14.bin"); #define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0 #define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5 #define LINK_SPEED_MAX 4 - #define SMU_13_0_6_DSCLK_THRESHOLD 140 #define MCA_BANK_IPID(_ip, _hwid, _type) \ @@ -370,7 +369,7 @@ static int smu_v13_0_6_tables_init(struct smu_context *smu) return -ENOMEM; smu_table->metrics_time = 0; - smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_6); + smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_7); smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); if (!smu_table->gpu_metrics_table) { @@ -2321,8 +2320,8 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table { bool per_inst, smu_13_0_6_per_inst, smu_13_0_14_per_inst, apu_per_inst; struct smu_table_context *smu_table = &smu->smu_table; - struct gpu_metrics_v1_6 *gpu_metrics = - (struct gpu_metrics_v1_6 *)smu_table->gpu_metrics_table; + struct gpu_metrics_v1_7 *gpu_metrics = + (struct gpu_metrics_v1_7 *)smu_table->gpu_metrics_table; bool flag = smu_v13_0_6_is_unified_metrics(smu); int ret = 0, xcc_id, inst, i, j, k, idx; struct amdgpu_device *adev = smu->adev; @@ -2341,7 +2340,7 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table metrics_a = (MetricsTableA_t *)metrics_x; - smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 6); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 7); gpu_metrics->temperature_hotspot = SMUQ10_ROUND(GET_METRIC_FIELD(MaxSocketTemperature, flag)); @@ -2448,6 +2447,9 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table SMUQ10_ROUND(GET_METRIC_FIELD(XgmiReadDataSizeAcc, flag)[i]); gpu_metrics->xgmi_write_data_acc[i] = SMUQ10_ROUND(GET_METRIC_FIELD(XgmiWriteDataSizeAcc, flag)[i]); + ret = amdgpu_get_xgmi_link_status(adev, i); + if (ret >= 0) + gpu_metrics->xgmi_link_status[i] = ret; } gpu_metrics->num_partition = adev->xcp_mgr->num_xcps; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index c5d3e25cc967e1ecd3c264bb6a862488407b2b4d..4fd0354bd312f2e225fb1cb121cba43054b35586 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -2147,6 +2147,8 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency; gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK]; + gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK]; + gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK]; gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0]; gpu_metrics->current_dclk0 = metrics->CurrClock[PPCLK_DCLK_0]; gpu_metrics->current_vclk1 = metrics->CurrClock[PPCLK_VCLK_1]; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c index ecb0164d533eea6ccf5da869b0bdab046d3e701d..a87040cb2f2e52ff830c4f60d24dcde078961b90 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c @@ -49,7 +49,7 @@ #define regMP1_SMN_IH_SW_INT_CTRL_mp1_14_0_0_BASE_IDX 0 const int decoded_link_speed[5] = {1, 2, 3, 4, 5}; -const int decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16}; +const int decoded_link_width[8] = {0, 1, 2, 4, 8, 12, 16, 32}; /* * DO NOT use these for err/warn/info/debug messages. * Use dev_err, dev_warn, dev_info and dev_dbg instead. diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c index 59b369eff30fb806f1e717dcde66b7f78a5d53cf..687a0f5ac94f580f5105f65325c4511dbe52c5aa 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c @@ -1173,13 +1173,15 @@ static int smu_v14_0_2_print_clk_levels(struct smu_context *smu, (pcie_table->pcie_gen[i] == 0) ? "2.5GT/s," : (pcie_table->pcie_gen[i] == 1) ? "5.0GT/s," : (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s," : - (pcie_table->pcie_gen[i] == 3) ? "16.0GT/s," : "", + (pcie_table->pcie_gen[i] == 3) ? "16.0GT/s," : + (pcie_table->pcie_gen[i] == 4) ? "32.0GT/s," : "", (pcie_table->pcie_lane[i] == 1) ? "x1" : (pcie_table->pcie_lane[i] == 2) ? "x2" : (pcie_table->pcie_lane[i] == 3) ? "x4" : (pcie_table->pcie_lane[i] == 4) ? "x8" : (pcie_table->pcie_lane[i] == 5) ? "x12" : - (pcie_table->pcie_lane[i] == 6) ? "x16" : "", + (pcie_table->pcie_lane[i] == 6) ? "x16" : + (pcie_table->pcie_lane[i] == 7) ? "x32" : "", pcie_table->clk_freq[i], (gen_speed == DECODE_GEN_SPEED(pcie_table->pcie_gen[i])) && (lane_width == DECODE_LANE_WIDTH(pcie_table->pcie_lane[i])) ? @@ -1463,15 +1465,35 @@ static int smu_v14_0_2_update_pcie_parameters(struct smu_context *smu, struct smu_14_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; struct smu_14_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; + int num_of_levels = pcie_table->num_of_link_levels; uint32_t smu_pcie_arg; int ret, i; - for (i = 0; i < pcie_table->num_of_link_levels; i++) { - if (pcie_table->pcie_gen[i] > pcie_gen_cap) + if (!num_of_levels) + return 0; + + if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) { + if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap) + pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1]; + + if (pcie_table->pcie_lane[num_of_levels - 1] < pcie_width_cap) + pcie_width_cap = pcie_table->pcie_lane[num_of_levels - 1]; + + /* Force all levels to use the same settings */ + for (i = 0; i < num_of_levels; i++) { pcie_table->pcie_gen[i] = pcie_gen_cap; - if (pcie_table->pcie_lane[i] > pcie_width_cap) pcie_table->pcie_lane[i] = pcie_width_cap; + } + } else { + for (i = 0; i < num_of_levels; i++) { + if (pcie_table->pcie_gen[i] > pcie_gen_cap) + pcie_table->pcie_gen[i] = pcie_gen_cap; + if (pcie_table->pcie_lane[i] > pcie_width_cap) + pcie_table->pcie_lane[i] = pcie_width_cap; + } + } + for (i = 0; i < num_of_levels; i++) { smu_pcie_arg = i << 16; smu_pcie_arg |= pcie_table->pcie_gen[i] << 8; smu_pcie_arg |= pcie_table->pcie_lane[i]; @@ -2753,7 +2775,6 @@ static const struct pptable_funcs smu_v14_0_2_ppt_funcs = { .get_unique_id = smu_v14_0_2_get_unique_id, .get_power_limit = smu_v14_0_2_get_power_limit, .set_power_limit = smu_v14_0_2_set_power_limit, - .set_power_source = smu_v14_0_set_power_source, .get_power_profile_mode = smu_v14_0_2_get_power_profile_mode, .set_power_profile_mode = smu_v14_0_2_set_power_profile_mode, .run_btc = smu_v14_0_run_btc, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index f1ab1a6bb46703a6a970e8b6cec6f2adb9019a3c..dbbd3759bff375e3feb3b9c14df18fb7b281f82c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -1081,6 +1081,9 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev) case METRICS_VERSION(1, 6): structure_size = sizeof(struct gpu_metrics_v1_6); break; + case METRICS_VERSION(1, 7): + structure_size = sizeof(struct gpu_metrics_v1_7); + break; case METRICS_VERSION(2, 0): structure_size = sizeof(struct gpu_metrics_v2_0); break; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c index 6d475bb34002ee4936685996ba912e1215512b56..d981d721e7969b55240349a073d755da0d98335b 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c @@ -153,7 +153,7 @@ static const struct dev_pm_ops komeda_pm_ops = { static struct platform_driver komeda_platform_driver = { .probe = komeda_platform_probe, - .remove_new = komeda_platform_remove, + .remove = komeda_platform_remove, .shutdown = komeda_platform_shutdown, .driver = { .name = "komeda", diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index cd4389809d42d3d469b5c02afaaf96c2d5989bc3..191b806624dfa55b033e6bce639a4b8fafd85f78 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -405,7 +405,7 @@ static SIMPLE_DEV_PM_OPS(hdlcd_pm_ops, hdlcd_pm_suspend, hdlcd_pm_resume); static struct platform_driver hdlcd_platform_driver = { .probe = hdlcd_probe, - .remove_new = hdlcd_remove, + .remove = hdlcd_remove, .shutdown = hdlcd_shutdown, .driver = { .name = "hdlcd", diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index 4cb25004b84fec2c83ddaa1ac06179d3c5ebe866..fd2be80f3bf5c06f2133d886f0e23b329d0dc455 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c @@ -988,7 +988,7 @@ static const struct dev_pm_ops malidp_pm_ops = { static struct platform_driver malidp_platform_driver = { .probe = malidp_platform_probe, - .remove_new = malidp_platform_remove, + .remove = malidp_platform_remove, .shutdown = malidp_platform_shutdown, .driver = { .name = "mali-dp", diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index c78687c755a869a8d3eb824dff01b8e5828ea890..0900e4466ffb3f8e3ea4182cca1772626c0bff34 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -1084,7 +1084,7 @@ MODULE_DEVICE_TABLE(platform, armada_lcd_platform_ids); struct platform_driver armada_lcd_platform_driver = { .probe = armada_lcd_probe, - .remove_new = armada_lcd_remove, + .remove = armada_lcd_remove, .driver = { .name = "armada-lcd", .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 5c26f0409478a47678ec14581423666ad116bae3..650e450cc19b83800cf65be49c070121447a61c8 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -250,7 +250,7 @@ MODULE_DEVICE_TABLE(platform, armada_drm_platform_ids); static struct platform_driver armada_drm_platform_driver = { .probe = armada_drm_probe, - .remove_new = armada_drm_remove, + .remove = armada_drm_remove, .shutdown = armada_drm_shutdown, .driver = { .name = "armada-drm", diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 26d10065d5344e726463ab13642b287f33488e84..1a1680d71486d619d7e23e5d144f694e362f699a 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -15,7 +15,7 @@ #include "armada_gem.h" #include "armada_ioctlP.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); static vm_fault_t armada_gem_vm_fault(struct vm_fault *vmf) { diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index 109023815fa2c6d072bda03eef5ec07658e4e2c8..b7e608ba61941dc2665568767d3928abef1cd2e7 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -368,7 +368,7 @@ static void aspeed_gfx_shutdown(struct platform_device *pdev) static struct platform_driver aspeed_gfx_platform_driver = { .probe = aspeed_gfx_probe, - .remove_new = aspeed_gfx_remove, + .remove = aspeed_gfx_remove, .shutdown = aspeed_gfx_shutdown, .driver = { .name = "aspeed_gfx", diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 792dcc19e8e7a30e428f3fc6260ed2060fe519b5..7b209af7cf457a774237c0310bbc45bafdaf2018 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -937,7 +937,7 @@ static const struct of_device_id atmel_hlcdc_dc_of_match[] = { static struct platform_driver atmel_hlcdc_dc_platform_driver = { .probe = atmel_hlcdc_dc_drm_probe, - .remove_new = atmel_hlcdc_dc_drm_remove, + .remove = atmel_hlcdc_dc_drm_remove, .shutdown = atmel_hlcdc_dc_drm_shutdown, .driver = { .name = "atmel-hlcdc-display-controller", diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 7457d38622b0c76928d1b6220bfe7ce76759bb98..c7a0247e06adf3e532f830363b3422a8058513ef 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -1300,7 +1300,7 @@ MODULE_DEVICE_TABLE(of, cdns_dsi_of_match); static struct platform_driver cdns_dsi_platform_driver = { .probe = cdns_dsi_drm_probe, - .remove_new = cdns_dsi_drm_remove, + .remove = cdns_dsi_drm_remove, .driver = { .name = "cdns-dsi", .of_match_table = cdns_dsi_of_match, diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index 41f72d458487fb27a34f2fa475c51de55725bc23..d081850e3c03e982812f64bb62ae922a1828cc7e 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -2656,7 +2656,7 @@ static struct platform_driver mhdp_driver = { .of_match_table = mhdp_ids, }, .probe = cdns_mhdp_probe, - .remove_new = cdns_mhdp_remove, + .remove = cdns_mhdp_remove, }; module_platform_driver(mhdp_driver); diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c index aab9ce7be94c58d899d8a746c3049f867d5931cd..72bc508d4e6e2bf5be535c8856b46465d1ff835e 100644 --- a/drivers/gpu/drm/bridge/display-connector.c +++ b/drivers/gpu/drm/bridge/display-connector.c @@ -427,7 +427,7 @@ MODULE_DEVICE_TABLE(of, display_connector_match); static struct platform_driver display_connector_driver = { .probe = display_connector_probe, - .remove_new = display_connector_remove, + .remove = display_connector_remove, .driver = { .name = "display-connector", .of_match_table = display_connector_match, diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c index 0e4bac7dd04ff199df759537d19b20d26e0dfb1a..0fc8a14fd80062248a43b8b93272101a7ca6158a 100644 --- a/drivers/gpu/drm/bridge/fsl-ldb.c +++ b/drivers/gpu/drm/bridge/fsl-ldb.c @@ -393,7 +393,7 @@ MODULE_DEVICE_TABLE(of, fsl_ldb_match); static struct platform_driver fsl_ldb_driver = { .probe = fsl_ldb_probe, - .remove_new = fsl_ldb_remove, + .remove = fsl_ldb_remove, .driver = { .name = "fsl-ldb", .of_match_table = fsl_ldb_match, diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c index 073e64dc200c892f73f2f9bfd1d3f34704eb5408..0d1ac3edcab41658cf604a8a994026b4bf40cf27 100644 --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c @@ -193,7 +193,7 @@ MODULE_DEVICE_TABLE(of, imx8mp_hdmi_pvi_match); static struct platform_driver imx8mp_hdmi_pvi_driver = { .probe = imx8mp_hdmi_pvi_probe, - .remove_new = imx8mp_hdmi_pvi_remove, + .remove = imx8mp_hdmi_pvi_remove, .driver = { .name = "imx-hdmi-pvi", .of_match_table = imx8mp_hdmi_pvi_match, diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c index 8fcc6d18f4ab9b05b8482f9576ade5f7a93dde56..1e7a789ec289030b87bd46f6104210fd59474dc1 100644 --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -144,7 +144,7 @@ MODULE_DEVICE_TABLE(of, imx8mp_dw_hdmi_of_table); static struct platform_driver imx8mp_dw_hdmi_platform_driver = { .probe = imx8mp_dw_hdmi_probe, - .remove_new = imx8mp_dw_hdmi_remove, + .remove = imx8mp_dw_hdmi_remove, .driver = { .name = "imx8mp-dw-hdmi-tx", .of_match_table = imx8mp_dw_hdmi_of_table, diff --git a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c index c879e37f5811fa30616bf75b4de23abd8ac88f58..dd5823f04c700f7890c4a28cb7ef12ff16b20c18 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c @@ -570,7 +570,7 @@ MODULE_DEVICE_TABLE(of, imx8qm_ldb_dt_ids); static struct platform_driver imx8qm_ldb_driver = { .probe = imx8qm_ldb_probe, - .remove_new = imx8qm_ldb_remove, + .remove = imx8qm_ldb_remove, .driver = { .pm = pm_ptr(&imx8qm_ldb_pm_ops), .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c index b33011f397f0d6d69df59000610a937397ae603f..7bce2305d676714cdec7ce085cb53b25ce42f8e7 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c @@ -706,7 +706,7 @@ MODULE_DEVICE_TABLE(of, imx8qxp_ldb_dt_ids); static struct platform_driver imx8qxp_ldb_driver = { .probe = imx8qxp_ldb_probe, - .remove_new = imx8qxp_ldb_remove, + .remove = imx8qxp_ldb_remove, .driver = { .pm = pm_ptr(&imx8qxp_ldb_pm_ops), .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c index ce43e4069e21b2ecfae2f885fe2dab002a277f22..1812bd106261b802658dfbd9d52ecab7de1036e2 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c @@ -427,7 +427,7 @@ MODULE_DEVICE_TABLE(of, imx8qxp_pc_dt_ids); static struct platform_driver imx8qxp_pc_bridge_driver = { .probe = imx8qxp_pc_bridge_probe, - .remove_new = imx8qxp_pc_bridge_remove, + .remove = imx8qxp_pc_bridge_remove, .driver = { .pm = pm_ptr(&imx8qxp_pc_pm_ops), .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c index 1d11cc1df43c06b3b894466e957561c73ce143e4..4b0715ed6f38c9b6a1d24cb0142ca94cfd6042e1 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c @@ -409,7 +409,7 @@ MODULE_DEVICE_TABLE(of, imx8qxp_pixel_link_dt_ids); static struct platform_driver imx8qxp_pixel_link_bridge_driver = { .probe = imx8qxp_pixel_link_bridge_probe, - .remove_new = imx8qxp_pixel_link_bridge_remove, + .remove = imx8qxp_pixel_link_bridge_remove, .driver = { .of_match_table = imx8qxp_pixel_link_dt_ids, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c index fb7cf4369bb81d5bc5809159705e34b3a5869252..65cf3a6c8ec692488aaf421946c6b2180fcebcc1 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c @@ -467,7 +467,7 @@ MODULE_DEVICE_TABLE(of, imx8qxp_pxl2dpi_dt_ids); static struct platform_driver imx8qxp_pxl2dpi_bridge_driver = { .probe = imx8qxp_pxl2dpi_bridge_probe, - .remove_new = imx8qxp_pxl2dpi_bridge_remove, + .remove = imx8qxp_pxl2dpi_bridge_remove, .driver = { .of_match_table = imx8qxp_pxl2dpi_dt_ids, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c index 2347f8dd632f9e7608fd40d6ea00f278de32a545..bea8346515b8c8ce150040f58d288ac564eeb563 100644 --- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c @@ -904,7 +904,7 @@ MODULE_DEVICE_TABLE(of, imx93_dsi_dt_ids); static struct platform_driver imx93_dsi_driver = { .probe = imx93_dsi_probe, - .remove_new = imx93_dsi_remove, + .remove = imx93_dsi_remove, .driver = { .of_match_table = imx93_dsi_dt_ids, .name = "imx93_mipi_dsi", diff --git a/drivers/gpu/drm/bridge/lvds-codec.c b/drivers/gpu/drm/bridge/lvds-codec.c index 991732c4b62981bbe7559a10a7fa7a51869d2982..389af0233fcdec9af7a4fbfe8d267170fbc4759c 100644 --- a/drivers/gpu/drm/bridge/lvds-codec.c +++ b/drivers/gpu/drm/bridge/lvds-codec.c @@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(of, lvds_codec_match); static struct platform_driver lvds_codec_driver = { .probe = lvds_codec_probe, - .remove_new = lvds_codec_remove, + .remove = lvds_codec_remove, .driver = { .name = "lvds-codec", .of_match_table = lvds_codec_match, diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 5f05647a3beabcfdee458de9135342069f8e18be..1e5b2a37cb8c9a7be4438039502226255cc952bb 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -1211,7 +1211,7 @@ static void nwl_dsi_remove(struct platform_device *pdev) static struct platform_driver nwl_dsi_driver = { .probe = nwl_dsi_probe, - .remove_new = nwl_dsi_remove, + .remove = nwl_dsi_remove, .driver = { .of_match_table = nwl_dsi_dt_ids, .name = DRV_NAME, diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 4416d0be72722e01d3869e7f7626872e167836a6..f8b4fb8357659018ec0db65374ee5d05330639ae 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -2139,7 +2139,7 @@ MODULE_DEVICE_TABLE(of, samsung_dsim_of_match); static struct platform_driver samsung_dsim_driver = { .probe = samsung_dsim_probe, - .remove_new = samsung_dsim_remove, + .remove = samsung_dsim_remove, .driver = { .name = "samsung-dsim", .pm = pm_ptr(&samsung_dsim_pm_ops), diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c index 221e9a4edb40b67ece20277a8df667028fc7654c..cf1f66b7b192c94f2f1abe22767837e638aeef4e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c @@ -645,7 +645,7 @@ static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend, static struct platform_driver snd_dw_hdmi_driver = { .probe = snd_dw_hdmi_probe, - .remove_new = snd_dw_hdmi_remove, + .remove = snd_dw_hdmi_remove, .driver = { .name = DRIVER_NAME, .pm = PM_OPS, diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c index d4614de1ae1ea7153e6346a9f9e50cd70b9f6cee..9549dabde941c604962267f21af04de6f03ff5f2 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c @@ -346,7 +346,7 @@ static const struct dev_pm_ops dw_hdmi_cec_pm = { static struct platform_driver dw_hdmi_cec_driver = { .probe = dw_hdmi_cec_probe, - .remove_new = dw_hdmi_cec_remove, + .remove = dw_hdmi_cec_remove, .driver = { .name = "dw-hdmi-cec", .pm = pm_ptr(&dw_hdmi_cec_pm), diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c index 423762da2ab471b04a3cd4de09cdf4e30be7ac59..ab18f9a3bf2304fbeb3fffc1b0d6b9c8d47ac7c9 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c @@ -181,7 +181,7 @@ static void snd_dw_hdmi_remove(struct platform_device *pdev) static struct platform_driver snd_dw_hdmi_driver = { .probe = snd_dw_hdmi_probe, - .remove_new = snd_dw_hdmi_remove, + .remove = snd_dw_hdmi_remove, .driver = { .name = DRIVER_NAME, }, diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index 26c187d20d973dc65801a3baa59ecf57d20072eb..f1c5a8d0fa90e2eb2ee488b6a5871b005f797ea1 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -225,7 +225,7 @@ static void snd_dw_hdmi_remove(struct platform_device *pdev) static struct platform_driver snd_dw_hdmi_driver = { .probe = snd_dw_hdmi_probe, - .remove_new = snd_dw_hdmi_remove, + .remove = snd_dw_hdmi_remove, .driver = { .name = DRIVER_NAME, }, diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c index 674efc489e3a9fe6d41319b7dc4f9ed7ac0c79c7..bba10cf9b4f96aef69f82403a7642d08c2b9f4b7 100644 --- a/drivers/gpu/drm/bridge/thc63lvd1024.c +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c @@ -230,7 +230,7 @@ MODULE_DEVICE_TABLE(of, thc63_match); static struct platform_driver thc63_driver = { .probe = thc63_probe, - .remove_new = thc63_remove, + .remove = thc63_remove, .driver = { .name = "thc63lvd1024", .of_match_table = thc63_match, diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index b1b1e4d5a24ae1071176738312945b957ccef0d1..107a2c0b96c99edc040ef667914c68e5b9264eba 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -406,7 +406,7 @@ MODULE_DEVICE_TABLE(of, tfp410_match); static struct platform_driver tfp410_platform_driver = { .probe = tfp410_probe, - .remove_new = tfp410_remove, + .remove = tfp410_remove, .driver = { .name = "tfp410-bridge", .of_match_table = tfp410_match, diff --git a/drivers/gpu/drm/bridge/ti-tpd12s015.c b/drivers/gpu/drm/bridge/ti-tpd12s015.c index f9fb35683a273955ce9d7dfd8da29dbf7dc6c6b3..47b74cb25b14fcf4a09137d8b5b7f4ff739eae59 100644 --- a/drivers/gpu/drm/bridge/ti-tpd12s015.c +++ b/drivers/gpu/drm/bridge/ti-tpd12s015.c @@ -195,7 +195,7 @@ MODULE_DEVICE_TABLE(of, tpd12s015_of_match); static struct platform_driver tpd12s015_driver = { .probe = tpd12s015_probe, - .remove_new = tpd12s015_remove, + .remove = tpd12s015_remove, .driver = { .name = "tpd12s015", .of_match_table = tpd12s015_of_match, diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c index d810529ebfb6e8764bad1d1a705bf09b52dec8ff..ec7eac6b595f7eeee0151c524a3998321c7e3ab9 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c @@ -292,7 +292,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux, aux_ep->dev.parent = aux->dev; aux_ep->dev.bus = &dp_aux_bus_type; aux_ep->dev.type = &dp_aux_device_type_type; - aux_ep->dev.of_node = of_node_get(np); + device_set_node(&aux_ep->dev, of_fwnode_handle(of_node_get(np))); dev_set_name(&aux_ep->dev, "aux-%s", dev_name(aux->dev)); ret = device_register(&aux_ep->dev); diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c index 870b90b78bc4eba4f25bb36de50139a528c14787..16988d316a6dc702310fa44c15c92dc67b82802b 100644 --- a/drivers/gpu/drm/drm_gem_dma_helper.c +++ b/drivers/gpu/drm/drm_gem_dma_helper.c @@ -600,5 +600,5 @@ drm_gem_dma_prime_import_sg_table_vmap(struct drm_device *dev, EXPORT_SYMBOL(drm_gem_dma_prime_import_sg_table_vmap); MODULE_DESCRIPTION("DRM DMA memory-management helpers"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index 3bdb6ba37ff42fb6d8fc0715358863e83061de5a..185534f56bab94b5c009e93d28ee88c1903c1343 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -18,7 +18,7 @@ #include "drm_internal.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); #define AFBC_HEADER_SIZE 16 #define AFBC_TH_LAYOUT_ALIGNMENT 8 diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index 8508060a1a95ccd5b617dbaf8666c9bd30b7598e..5ab351409312b5a0de542df2b636278d6186cb7b 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -22,7 +22,7 @@ #include #include -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); /** * DOC: overview @@ -800,5 +800,5 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev, EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table); MODULE_DESCRIPTION("DRM SHMEM memory-management helpers"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 0e3f8adf162f6732fad1b678cc37ca279be0bdac..32a8781cfd67b82ece7b7b94625715171bb41917 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -40,7 +40,7 @@ #include "drm_internal.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); /** * DOC: overview and lifetime rules diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 9b4e2f4b1bc711de6bf65c122d8f4e3591c1c2e2..a46f9e4ac09a63e328f6fd69e986f65a67c88469 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -669,7 +669,7 @@ static void etnaviv_pdev_remove(struct platform_device *pdev) static struct platform_driver etnaviv_platform_driver = { .probe = etnaviv_pdev_probe, - .remove_new = etnaviv_pdev_remove, + .remove = etnaviv_pdev_remove, .driver = { .name = "etnaviv", }, diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 6b98200068e45a76169c9ec6f3614733ee763d2f..42e57d1425540ad4838ab415c2ffd6699ed141f7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -10,7 +10,7 @@ #include "etnaviv_drv.h" #include "etnaviv_gem.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); static struct lock_class_key etnaviv_prime_lock_class; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index c7d59c06ccd18978aca1484f70ea1f7f790a0fd2..2d4c112ce0338cf3d7643eb9be27869e46fb6a3c 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1985,6 +1985,6 @@ struct platform_driver etnaviv_gpu_driver = { .of_match_table = etnaviv_gpu_match, }, .probe = etnaviv_gpu_platform_probe, - .remove_new = etnaviv_gpu_platform_remove, + .remove = etnaviv_gpu_platform_remove, .id_table = gpu_ids, }; diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 0ef7bc8848b0798b125f7a65ff04cf4586f13d71..b9e206303b487e5f3116d053197ef3ff200b6155 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -871,7 +871,7 @@ static void exynos5433_decon_remove(struct platform_device *pdev) struct platform_driver exynos5433_decon_driver = { .probe = exynos5433_decon_probe, - .remove_new = exynos5433_decon_remove, + .remove = exynos5433_decon_remove, .driver = { .name = "exynos5433-decon", .pm = pm_ptr(&exynos5433_decon_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index c65364087faca62cc45aa7d49a9bd249dd1866c8..5170f72b08309d7e0363263776c69d93fca6357d 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -874,7 +874,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(exynos7_decon_pm_ops, exynos7_decon_suspend, struct platform_driver decon_driver = { .probe = decon_probe, - .remove_new = decon_remove, + .remove = decon_remove, .driver = { .name = "exynos-decon", .pm = pm_ptr(&exynos7_decon_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 22142b293279f258f4d2fa398b7af9d9647f8daf..5bcf41e0bd047cc26ff0f42fe4c16841738ae619 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c @@ -279,7 +279,7 @@ MODULE_DEVICE_TABLE(of, exynos_dp_match); struct platform_driver dp_driver = { .probe = exynos_dp_probe, - .remove_new = exynos_dp_remove, + .remove = exynos_dp_remove, .driver = { .name = "exynos-dp", .pm = pm_ptr(&exynos_dp_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 2a466d8179f47cf9c9e90ef028f21fbb75a80e28..1c44f85c5f54b9ea5b8d69784e22eda5277a368b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -363,7 +363,7 @@ static void exynos_drm_platform_shutdown(struct platform_device *pdev) static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, - .remove_new = exynos_drm_platform_remove, + .remove = exynos_drm_platform_remove, .shutdown = exynos_drm_platform_shutdown, .driver = { .name = "exynos-drm", diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index bf16deaae68b62952539a8c2a7b4e41e68e25270..896a03639e2d9b80971d43aff540fc7fb9f005bd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -181,7 +181,7 @@ MODULE_DEVICE_TABLE(of, exynos_dsi_of_match); struct platform_driver dsi_driver = { .probe = samsung_dsim_probe, - .remove_new = samsung_dsim_remove, + .remove = samsung_dsim_remove, .driver = { .name = "exynos-dsi", .pm = &samsung_dsim_pm_ops, diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 4d7ea65b7dd8366a2ca1c24f1c01d94105501b87..b150cfd92f6ee9dd5941c91906c2636f969f50a0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -1408,7 +1408,7 @@ MODULE_DEVICE_TABLE(of, fimc_of_match); struct platform_driver fimc_driver = { .probe = fimc_probe, - .remove_new = fimc_remove, + .remove = fimc_remove, .driver = { .of_match_table = fimc_of_match, .name = "exynos-drm-fimc", diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index f57df8c4813911e05642d54d5e3929ed3d786820..1ad87584b1c2c83a0cb9a32b2cbacb9947191509 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1323,7 +1323,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(exynos_fimd_pm_ops, exynos_fimd_suspend, struct platform_driver fimd_driver = { .probe = fimd_probe, - .remove_new = fimd_remove, + .remove = fimd_remove, .driver = { .name = "exynos4-fb", .pm = pm_ptr(&exynos_fimd_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 3a3b2c00e40070f6ced47da39d627db81d262f70..d32f2474cbaa86459c8ea2a93c5f4eff87431b6a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -1607,7 +1607,7 @@ MODULE_DEVICE_TABLE(of, exynos_g2d_match); struct platform_driver g2d_driver = { .probe = g2d_probe, - .remove_new = g2d_remove, + .remove = g2d_remove, .driver = { .name = "exynos-drm-g2d", .pm = pm_ptr(&g2d_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 638ca96830e9dd9f213242a214ffcca11d9fa5b2..4787fee4696f8e6f9eecaacb1535765c246688c8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -18,7 +18,7 @@ #include "exynos_drm_drv.h" #include "exynos_drm_gem.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); static int exynos_drm_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 1ae90ef1fc2300ecdb1830164d406eb685558be8..e6d516e1976d8d714bb4f58836dcfb94c40a71eb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -1420,7 +1420,7 @@ MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match); struct platform_driver gsc_driver = { .probe = gsc_probe, - .remove_new = gsc_remove, + .remove = gsc_remove, .driver = { .name = "exynos-drm-gsc", .pm = &gsc_pm_ops, diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index d61ec451807c2632800fbaae3a02600206d191cd..b34ec67283370e3fa836c7df06e12e2fba524622 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -460,7 +460,7 @@ MODULE_DEVICE_TABLE(of, exynos_mic_of_match); struct platform_driver mic_driver = { .probe = exynos_mic_probe, - .remove_new = exynos_mic_remove, + .remove = exynos_mic_remove, .driver = { .name = "exynos-mic", .pm = pm_ptr(&exynos_mic_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index 2eb0b701672fa1125c0f9a0598de0e5d16e6e1de..7b0f4a98a70ae612fca9342ebdf12613888c59f1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -451,7 +451,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(rotator_pm_ops, rotator_runtime_suspend, struct platform_driver rotator_driver = { .probe = rotator_probe, - .remove_new = rotator_remove, + .remove = rotator_remove, .driver = { .name = "exynos-rotator", .pm = pm_ptr(&rotator_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos_drm_scaler.c b/drivers/gpu/drm/exynos/exynos_drm_scaler.c index 2788105ac780bc90d395978d7c91d4b8db340021..c8a1b6b0a29c3ad3f3398ec9f8cdec689b875d5b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_scaler.c +++ b/drivers/gpu/drm/exynos/exynos_drm_scaler.c @@ -719,7 +719,7 @@ MODULE_DEVICE_TABLE(of, exynos_scaler_match); struct platform_driver scaler_driver = { .probe = scaler_probe, - .remove_new = scaler_remove, + .remove = scaler_remove, .driver = { .name = "exynos-scaler", .pm = pm_ptr(&scaler_pm_ops), diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 6de0cced6c9d2116d0fb59caf00ee3cae42ecae1..fd388b1dbe68c0a96f36be4fb1a6197a1a598125 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -467,7 +467,7 @@ static void vidi_remove(struct platform_device *pdev) struct platform_driver vidi_driver = { .probe = vidi_probe, - .remove_new = vidi_remove, + .remove = vidi_remove, .driver = { .name = "exynos-drm-vidi", .dev_groups = vidi_groups, diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index c9d4b9146df95bb46cb6bea4849c331616c2b463..466a9e514aa1c8191828e131dea5dd9731a2608d 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2126,7 +2126,7 @@ static const struct dev_pm_ops exynos_hdmi_pm_ops = { struct platform_driver hdmi_driver = { .probe = hdmi_probe, - .remove_new = hdmi_remove, + .remove = hdmi_remove, .driver = { .name = "exynos-hdmi", .pm = &exynos_hdmi_pm_ops, diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 1db955f000449da378922e76effaff0220e38822..a3670d2eaab2bd47f09cbbd67d9ca470280e4c74 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1335,5 +1335,5 @@ struct platform_driver mixer_driver = { .of_match_table = mixer_match_types, }, .probe = mixer_probe, - .remove_new = mixer_remove, + .remove = mixer_remove, }; diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 91a48d774cf7dcdcaa23db5713b1029d868de3af..be1ab673e49eef3f0deb092793a8ab04b48aff41 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -378,7 +378,7 @@ static void fsl_dcu_drm_shutdown(struct platform_device *pdev) static struct platform_driver fsl_dcu_drm_platform_driver = { .probe = fsl_dcu_drm_probe, - .remove_new = fsl_dcu_drm_remove, + .remove = fsl_dcu_drm_remove, .shutdown = fsl_dcu_drm_shutdown, .driver = { .name = "fsl-dcu", diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c index a39cc549c20b5248062b4fde2cdcf7a664632b32..2eea9fb0e76bf3ead8f5914e6ebb65b5b3603b9a 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c @@ -889,7 +889,7 @@ MODULE_DEVICE_TABLE(of, dsi_of_match); static struct platform_driver dsi_driver = { .probe = dsi_probe, - .remove_new = dsi_remove, + .remove = dsi_remove, .driver = { .name = "dw-dsi", .of_match_table = dsi_of_match, diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 86a3a1faff495f724acc2ec25b2010f193d73f86..b3ab944652a6ab3783c638d6d507ed84ada0853b 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -302,7 +302,7 @@ MODULE_DEVICE_TABLE(of, kirin_drm_dt_ids); static struct platform_driver kirin_drm_platform_driver = { .probe = kirin_drm_platform_probe, - .remove_new = kirin_drm_platform_remove, + .remove = kirin_drm_platform_remove, .shutdown = kirin_drm_platform_shutdown, .driver = { .name = "kirin-drm", diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index f6d42ec6949e7fdd0f64d11b9b6727bbb0b8f823..f57e4dba2873cca5f74f63c705993c6a42bf7f00 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -1503,6 +1503,8 @@ static int hdcp2_deauthenticate_port(struct intel_connector *connector) static int hdcp2_authentication_key_exchange(struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); + struct intel_digital_port *dig_port = + intel_attached_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; union { struct hdcp2_ake_init ake_init; @@ -1513,30 +1515,36 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) } msgs; const struct intel_hdcp_shim *shim = hdcp->shim; size_t size; - int ret, i; + int ret, i, max_retries; /* Init for seq_num */ hdcp->seq_num_v = 0; hdcp->seq_num_m = 0; + if (intel_encoder_is_dp(&dig_port->base) || + intel_encoder_is_mst(&dig_port->base)) + max_retries = 10; + else + max_retries = 1; + ret = hdcp2_prepare_ake_init(connector, &msgs.ake_init); if (ret < 0) return ret; /* * Retry the first read and write to downstream at least 10 times - * with a 50ms delay if not hdcp2 capable(dock decides to stop advertising - * hdcp2 capability for some reason). The reason being that - * during suspend resume dock usually keeps the HDCP2 registers inaccesible - * causing AUX error. This wouldn't be a big problem if the userspace - * just kept retrying with some delay while it continues to play low - * value content but most userpace applications end up throwing an error - * when it receives one from KMD. This makes sure we give the dock - * and the sink devices to complete its power cycle and then try HDCP - * authentication. The values of 10 and delay of 50ms was decided based - * on multiple trial and errors. + * with a 50ms delay if not hdcp2 capable for DP/DPMST encoders + * (dock decides to stop advertising hdcp2 capability for some reason). + * The reason being that during suspend resume dock usually keeps the + * HDCP2 registers inaccesible causing AUX error. This wouldn't be a + * big problem if the userspace just kept retrying with some delay while + * it continues to play low value content but most userpace applications + * end up throwing an error when it receives one from KMD. This makes + * sure we give the dock and the sink devices to complete its power cycle + * and then try HDCP authentication. The values of 10 and delay of 50ms + * was decided based on multiple trial and errors. */ - for (i = 0; i < 10; i++) { + for (i = 0; i < max_retries; i++) { if (!intel_hdcp2_get_capability(connector)) { msleep(50); continue; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 1df74f7aa3dcbdda1b5dbff0df8dc07e3fa58a5b..9473050ac84256ceb14a8f792577e5df368c2fb5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -16,7 +16,7 @@ #include "i915_gem_object.h" #include "i915_scatterlist.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); I915_SELFTEST_DECLARE(static bool force_different_devices;) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index ca0fb126b02d6544ea45c5e4a49ce1c9c7c3d48d..b27ff77bfb50193e2ced35e71b4f977e80ad39d7 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -53,8 +53,8 @@ #include "intel_gvt.h" #include "gvt.h" -MODULE_IMPORT_NS(DMA_BUF); -MODULE_IMPORT_NS(I915_GVT); +MODULE_IMPORT_NS("DMA_BUF"); +MODULE_IMPORT_NS("I915_GVT"); /* helper macros copied from vfio-pci */ #define VFIO_PCI_OFFSET_SHIFT 40 diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c index 5a01d60e51861e9ef6e4276db405561d3f7cc076..a5383a2bc64b9d186a965e36423a547592d3d69e 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c +++ b/drivers/gpu/drm/i915/intel_gvt.c @@ -204,7 +204,7 @@ int intel_gvt_set_ops(const struct intel_vgpu_ops *ops) return 0; } -EXPORT_SYMBOL_NS_GPL(intel_gvt_set_ops, I915_GVT); +EXPORT_SYMBOL_NS_GPL(intel_gvt_set_ops, "I915_GVT"); void intel_gvt_clear_ops(const struct intel_vgpu_ops *ops) { @@ -222,7 +222,7 @@ void intel_gvt_clear_ops(const struct intel_vgpu_ops *ops) intel_gvt_ops = NULL; mutex_unlock(&intel_gvt_mutex); } -EXPORT_SYMBOL_NS_GPL(intel_gvt_clear_ops, I915_GVT); +EXPORT_SYMBOL_NS_GPL(intel_gvt_clear_ops, "I915_GVT"); /** * intel_gvt_init - initialize GVT components @@ -284,40 +284,40 @@ void intel_gvt_resume(struct drm_i915_private *dev_priv) * Exported here so that the exports only get created when GVT support is * actually enabled. */ -EXPORT_SYMBOL_NS_GPL(i915_gem_object_alloc, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_object_create_shmem, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_object_init, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_object_ggtt_pin_ww, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_object_pin_map, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_object_set_to_cpu_domain, I915_GVT); -EXPORT_SYMBOL_NS_GPL(__i915_gem_object_flush_map, I915_GVT); -EXPORT_SYMBOL_NS_GPL(__i915_gem_object_set_pages, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_gtt_insert, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_prime_export, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_ww_ctx_init, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_ww_ctx_backoff, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_gem_ww_ctx_fini, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_ppgtt_create, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_request_add, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_request_create, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_request_wait, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_reserve_fence, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_unreserve_fence, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_vm_release, I915_GVT); -EXPORT_SYMBOL_NS_GPL(_i915_vma_move_to_active, I915_GVT); -EXPORT_SYMBOL_NS_GPL(intel_context_create, I915_GVT); -EXPORT_SYMBOL_NS_GPL(__intel_context_do_pin, I915_GVT); -EXPORT_SYMBOL_NS_GPL(__intel_context_do_unpin, I915_GVT); -EXPORT_SYMBOL_NS_GPL(intel_ring_begin, I915_GVT); -EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_get, I915_GVT); +EXPORT_SYMBOL_NS_GPL(i915_gem_object_alloc, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_object_create_shmem, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_object_init, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_object_ggtt_pin_ww, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_object_pin_map, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_object_set_to_cpu_domain, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(__i915_gem_object_flush_map, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(__i915_gem_object_set_pages, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_gtt_insert, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_prime_export, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_ww_ctx_init, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_ww_ctx_backoff, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_gem_ww_ctx_fini, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_ppgtt_create, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_request_add, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_request_create, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_request_wait, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_reserve_fence, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_unreserve_fence, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_vm_release, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(_i915_vma_move_to_active, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(intel_context_create, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(__intel_context_do_pin, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(__intel_context_do_unpin, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(intel_ring_begin, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_get, "I915_GVT"); #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) -EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put, I915_GVT); +EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put, "I915_GVT"); #endif -EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put_unchecked, I915_GVT); -EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_for_reg, I915_GVT); -EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_get, I915_GVT); -EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_put, I915_GVT); -EXPORT_SYMBOL_NS_GPL(shmem_pin_map, I915_GVT); -EXPORT_SYMBOL_NS_GPL(shmem_unpin_map, I915_GVT); -EXPORT_SYMBOL_NS_GPL(__px_dma, I915_GVT); -EXPORT_SYMBOL_NS_GPL(i915_fence_ops, I915_GVT); +EXPORT_SYMBOL_NS_GPL(intel_runtime_pm_put_unchecked, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_for_reg, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_get, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(intel_uncore_forcewake_put, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(shmem_pin_map, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(shmem_unpin_map, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(__px_dma, "I915_GVT"); +EXPORT_SYMBOL_NS_GPL(i915_fence_ops, "I915_GVT"); diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index 955c9a33212acfe697db6c419b2fa88b38e6f2f1..aa51f366626c847f830553da09ab08c2aeef5edb 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -1308,4 +1308,4 @@ int intel_gvt_iterate_mmio_table(struct intel_gvt_mmio_table_iter *iter) err: return ret; } -EXPORT_SYMBOL_NS_GPL(intel_gvt_iterate_mmio_table, I915_GVT); +EXPORT_SYMBOL_NS_GPL(intel_gvt_iterate_mmio_table, "I915_GVT"); diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index 36c0e768698efc66731c281c4eb994f87574ba26..85ee9abd1811c5b9b4ff8e99513061476ee941a6 100644 --- a/drivers/gpu/drm/imagination/pvr_drv.c +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -1485,7 +1485,7 @@ static const struct dev_pm_ops pvr_pm_ops = { static struct platform_driver pvr_driver = { .probe = pvr_probe, - .remove_new = pvr_remove, + .remove = pvr_remove, .driver = { .name = PVR_DRIVER_NAME, .pm = &pvr_pm_ops, @@ -1497,5 +1497,5 @@ module_platform_driver(pvr_driver); MODULE_AUTHOR("Imagination Technologies Ltd."); MODULE_DESCRIPTION(PVR_DRIVER_DESC); MODULE_LICENSE("Dual MIT/GPL"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); MODULE_FIRMWARE("powervr/rogue_33.15.11.3_v1.fw"); diff --git a/drivers/gpu/drm/imx/dcss/dcss-drv.c b/drivers/gpu/drm/imx/dcss/dcss-drv.c index d881f5a347608652b93fe2f77260266688b49d44..19b027cc1dc4a94a9274167d2152c479aa7d83c3 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-drv.c +++ b/drivers/gpu/drm/imx/dcss/dcss-drv.c @@ -112,7 +112,7 @@ MODULE_DEVICE_TABLE(of, dcss_of_match); static struct platform_driver dcss_platform_driver = { .probe = dcss_drv_platform_probe, - .remove_new = dcss_drv_platform_remove, + .remove = dcss_drv_platform_remove, .shutdown = dcss_drv_platform_shutdown, .driver = { .name = "imx-dcss", diff --git a/drivers/gpu/drm/imx/ipuv3/dw_hdmi-imx.c b/drivers/gpu/drm/imx/ipuv3/dw_hdmi-imx.c index 0006ea52b83c5902d48ca859ed89cfeb48edc61e..8333c4bf736988346ece64d7f27020e31ee7ca88 100644 --- a/drivers/gpu/drm/imx/ipuv3/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/ipuv3/dw_hdmi-imx.c @@ -265,7 +265,7 @@ static void dw_hdmi_imx_remove(struct platform_device *pdev) static struct platform_driver dw_hdmi_imx_platform_driver = { .probe = dw_hdmi_imx_probe, - .remove_new = dw_hdmi_imx_remove, + .remove = dw_hdmi_imx_remove, .driver = { .name = "dwhdmi-imx", .of_match_table = dw_hdmi_imx_dt_ids, diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c index ced06bd8eae8b4bb33c90ef35a631aa205766788..5f2c93c3c28866ca79bae47e8a932cd7f240b886 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c @@ -325,7 +325,7 @@ MODULE_DEVICE_TABLE(of, imx_drm_dt_ids); static struct platform_driver imx_drm_pdrv = { .probe = imx_drm_platform_probe, - .remove_new = imx_drm_platform_remove, + .remove = imx_drm_platform_remove, .shutdown = imx_drm_platform_shutdown, .driver = { .name = "imx-drm", diff --git a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c index ff74018ac5cdf4633251b4039b380325e841b242..6be7a57ad03df22a61fb5589393fec539bbbc705 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c @@ -632,7 +632,7 @@ static void imx_ldb_remove(struct platform_device *pdev) static struct platform_driver imx_ldb_driver = { .probe = imx_ldb_probe, - .remove_new = imx_ldb_remove, + .remove = imx_ldb_remove, .driver = { .of_match_table = imx_ldb_dt_ids, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/imx/ipuv3/imx-tve.c b/drivers/gpu/drm/imx/ipuv3/imx-tve.c index d46d07d25f51795b1a569adafb51b9896e0b77d4..3a3c8a195119de7e385aece1bea4518376dae75a 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-tve.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-tve.c @@ -662,7 +662,7 @@ MODULE_DEVICE_TABLE(of, imx_tve_dt_ids); static struct platform_driver imx_tve_driver = { .probe = imx_tve_probe, - .remove_new = imx_tve_remove, + .remove = imx_tve_remove, .driver = { .of_match_table = imx_tve_dt_ids, .name = "imx-tve", diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c index 99db53e167bd020dd2be887fa2aa3117370d0a99..cf7b02b2d52cb734f27578d0190e6a3c68a771c3 100644 --- a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c @@ -449,5 +449,5 @@ struct platform_driver ipu_drm_driver = { .name = "imx-ipuv3-crtc", }, .probe = ipu_drm_probe, - .remove_new = ipu_drm_remove, + .remove = ipu_drm_remove, }; diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c index 70f62e89622e577089a407f09e1cfd35781dde36..9e66eb77b1ebe853599a60df69ce8db94fdffd49 100644 --- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -273,7 +273,7 @@ MODULE_DEVICE_TABLE(of, imx_pd_dt_ids); static struct platform_driver imx_pd_driver = { .probe = imx_pd_probe, - .remove_new = imx_pd_remove, + .remove = imx_pd_remove, .driver = { .of_match_table = imx_pd_dt_ids, .name = "imx-parallel-display", diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c index 3215c4acd6753657ef78a91d9b7449fa2b7b5863..fa7d44623c52c3e7dfc664886d52e53a868fe647 100644 --- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c @@ -527,7 +527,7 @@ static struct platform_driver imx_lcdc_driver = { .of_match_table = imx_lcdc_of_dev_id, }, .probe = imx_lcdc_probe, - .remove_new = imx_lcdc_remove, + .remove = imx_lcdc_remove, .shutdown = imx_lcdc_shutdown, }; module_platform_driver(imx_lcdc_driver); diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 056b70b635549861a37027a3b562f1ee2051733a..8469e1e5e582e6845d8fbc8695b1a291a71d2861 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -1632,7 +1632,7 @@ static struct platform_driver ingenic_drm_driver = { .of_match_table = of_match_ptr(ingenic_drm_of_match), }, .probe = ingenic_drm_probe, - .remove_new = ingenic_drm_remove, + .remove = ingenic_drm_remove, .shutdown = ingenic_drm_shutdown, }; diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c b/drivers/gpu/drm/ingenic/ingenic-ipu.c index 5bd9072352b517df3fbb1354a95313c46922bfd6..26ebf424d63ec21ccee80221745c3e8bcc6b3d7f 100644 --- a/drivers/gpu/drm/ingenic/ingenic-ipu.c +++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c @@ -991,7 +991,7 @@ static struct platform_driver ingenic_ipu_driver = { .of_match_table = ingenic_ipu_of_match, }, .probe = ingenic_ipu_probe, - .remove_new = ingenic_ipu_remove, + .remove = ingenic_ipu_remove, }; struct platform_driver *ingenic_ipu_driver_ptr = &ingenic_ipu_driver; diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c index 0274ab9caa85dd063ac862588e219b1f69c06d82..a3d31de761cb0544004b30f30ec8f497d65032c7 100644 --- a/drivers/gpu/drm/kmb/kmb_drv.c +++ b/drivers/gpu/drm/kmb/kmb_drv.c @@ -622,7 +622,7 @@ static SIMPLE_DEV_PM_OPS(kmb_pm_ops, kmb_pm_suspend, kmb_pm_resume); static struct platform_driver kmb_platform_driver = { .probe = kmb_probe, - .remove_new = kmb_remove, + .remove = kmb_remove, .driver = { .name = "kmb-drm", .pm = &kmb_pm_ops, diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index 10bce18b7c31c7f2ff7a3572139b10dfa397ad85..fb3062c872b317ef27cd321b2638944f8a5dc33a 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -488,7 +488,7 @@ static const struct dev_pm_ops lima_pm_ops = { static struct platform_driver lima_platform_driver = { .probe = lima_pdev_probe, - .remove_new = lima_pdev_remove, + .remove = lima_pdev_remove, .driver = { .name = "lima", .pm = &lima_pm_ops, diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c index e4d90701b29d416665d688dbb0283ed44340fdab..fb9de5e0bc0e80724731712e20345f5a80b6b424 100644 --- a/drivers/gpu/drm/logicvc/logicvc_drm.c +++ b/drivers/gpu/drm/logicvc/logicvc_drm.c @@ -491,7 +491,7 @@ MODULE_DEVICE_TABLE(of, logicvc_drm_of_table); static struct platform_driver logicvc_drm_platform_driver = { .probe = logicvc_drm_probe, - .remove_new = logicvc_drm_remove, + .remove = logicvc_drm_remove, .shutdown = logicvc_drm_shutdown, .driver = { .name = "logicvc-drm", diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index f60bdd7b6c13d13738c5aa9336d454a2891854fc..c4d51f5f038d83a7dafeb50afb75057ee4a4be08 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -483,7 +483,7 @@ static struct platform_driver mcde_driver = { .of_match_table = mcde_of_match, }, .probe = mcde_probe, - .remove_new = mcde_remove, + .remove = mcde_remove, .shutdown = mcde_shutdown, }; diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index e2fad1a048b5423a595efca08c856e8ed2a29dd5..395449a72f0a1dc0d8ee97ecd245ca52f0282402 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -1229,5 +1229,5 @@ struct platform_driver mcde_dsi_driver = { .of_match_table = mcde_dsi_of_match, }, .probe = mcde_dsi_probe, - .remove_new = mcde_dsi_remove, + .remove = mcde_dsi_remove, }; diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c index 2de24844314743fe24d8395c06588ca39aa68750..b42c0d87eba3f29d41b9862bf79b36fb54f86515 100644 --- a/drivers/gpu/drm/mediatek/mtk_cec.c +++ b/drivers/gpu/drm/mediatek/mtk_cec.c @@ -241,7 +241,7 @@ MODULE_DEVICE_TABLE(of, mtk_cec_of_ids); struct platform_driver mtk_cec_driver = { .probe = mtk_cec_probe, - .remove_new = mtk_cec_remove, + .remove = mtk_cec_remove, .driver = { .name = "mediatek-cec", .of_match_table = mtk_cec_of_ids, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c index 59fb9a08d54bd23da88766309c7f1c16a1768470..abc9e5525d039d9d0cc6ba9feb284a47cca52d38 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c @@ -218,7 +218,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_aal_driver_dt_match); struct platform_driver mtk_disp_aal_driver = { .probe = mtk_disp_aal_probe, - .remove_new = mtk_disp_aal_remove, + .remove = mtk_disp_aal_remove, .driver = { .name = "mediatek-disp-aal", .of_match_table = mtk_disp_aal_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c index 9b75727e0861c02f9d96564ca8be062c1c72c622..10d60d2c2a568ebbe09f90e8f42a73e4c2366662 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c @@ -209,7 +209,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match); struct platform_driver mtk_disp_ccorr_driver = { .probe = mtk_disp_ccorr_probe, - .remove_new = mtk_disp_ccorr_remove, + .remove = mtk_disp_ccorr_remove, .driver = { .name = "mediatek-disp-ccorr", .of_match_table = mtk_disp_ccorr_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index 2fd5e7dc9e247c0b3a47c1fac9ba35ad6678dc38..dd8433a38282a9ba1bcc3a4ddd01dd89738ccb60 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -159,7 +159,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_color_driver_dt_match); struct platform_driver mtk_disp_color_driver = { .probe = mtk_disp_color_probe, - .remove_new = mtk_disp_color_remove, + .remove = mtk_disp_color_remove, .driver = { .name = "mediatek-disp-color", .of_match_table = mtk_disp_color_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c index f0b38817ba6c74daf62ad736de055daa4c6e367c..b17b11d93846f2019d8c4afb294375333e22dc42 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c @@ -329,7 +329,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_gamma_driver_dt_match); struct platform_driver mtk_disp_gamma_driver = { .probe = mtk_disp_gamma_probe, - .remove_new = mtk_disp_gamma_remove, + .remove = mtk_disp_gamma_remove, .driver = { .name = "mediatek-disp-gamma", .of_match_table = mtk_disp_gamma_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index 435e5d9c8520ed0c04b483ce2d5295c445573e47..563b1b248fbbb38ef03bb3e3ceecdd265961df60 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -370,7 +370,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match); struct platform_driver mtk_disp_merge_driver = { .probe = mtk_disp_merge_probe, - .remove_new = mtk_disp_merge_remove, + .remove = mtk_disp_merge_remove, .driver = { .name = "mediatek-disp-merge", .of_match_table = mtk_disp_merge_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index e0c0bb01f65ae006828a9a94e945dac62c56763c..f731d4fbe8b62269b06873eb341581f7a5ef7eb8 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -746,7 +746,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match); struct platform_driver mtk_disp_ovl_driver = { .probe = mtk_disp_ovl_probe, - .remove_new = mtk_disp_ovl_remove, + .remove = mtk_disp_ovl_remove, .driver = { .name = "mediatek-disp-ovl", .of_match_table = mtk_disp_ovl_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c index 187855d835903f10bea8450e0a996d7af795a589..fa0e95dd29a0130b1fba2af5e5f87e7988cd31f5 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c @@ -665,7 +665,7 @@ static void mtk_disp_ovl_adaptor_remove(struct platform_device *pdev) struct platform_driver mtk_disp_ovl_adaptor_driver = { .probe = mtk_disp_ovl_adaptor_probe, - .remove_new = mtk_disp_ovl_adaptor_remove, + .remove = mtk_disp_ovl_adaptor_remove, .driver = { .name = "mediatek-disp-ovl-adaptor", }, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 07243f3722604a2d92516b1b1a3c1343f2e50bba..bf47790e4d6be5d60070c63c15c75fa201cc4b27 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -417,7 +417,7 @@ MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match); struct platform_driver mtk_disp_rdma_driver = { .probe = mtk_disp_rdma_probe, - .remove_new = mtk_disp_rdma_remove, + .remove = mtk_disp_rdma_remove, .driver = { .name = "mediatek-disp-rdma", .of_match_table = mtk_disp_rdma_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 1cc916b164713d71461a0b2ad370032a14604be6..36713c176cfcf1af2d365280700d06f4c1239e09 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -2899,7 +2899,7 @@ MODULE_DEVICE_TABLE(of, mtk_dp_of_match); static struct platform_driver mtk_dp_driver = { .probe = mtk_dp_probe, - .remove_new = mtk_dp_remove, + .remove = mtk_dp_remove, .driver = { .name = "mediatek-drm-dp", .of_match_table = mtk_dp_of_match, diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 20a9d589fd75ddc1be54f2e8ce50ba81ed706eba..1864eb02dbf50af09c65064834a8b27ca56c3528 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -1108,7 +1108,7 @@ MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids); struct platform_driver mtk_dpi_driver = { .probe = mtk_dpi_probe, - .remove_new = mtk_dpi_remove, + .remove = mtk_dpi_remove, .driver = { .name = "mediatek-dpi", .of_match_table = mtk_dpi_of_ids, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 9a8ef8558da921c75c1ab1986795bbc0a394899d..0829ceb9967ca5d03509c52a559494d58776077b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -1251,7 +1251,7 @@ static const struct dev_pm_ops mtk_drm_pm_ops = { static struct platform_driver mtk_drm_platform_driver = { .probe = mtk_drm_probe, - .remove_new = mtk_drm_remove, + .remove = mtk_drm_remove, .shutdown = mtk_drm_shutdown, .driver = { .name = "mediatek-drm", diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 33ceeb8d69251d8dde823eed4c59ec4eca5b70f1..e61b9bc68e9a362a7ade29188a7aa398b084545a 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -1301,7 +1301,7 @@ MODULE_DEVICE_TABLE(of, mtk_dsi_of_match); struct platform_driver mtk_dsi_driver = { .probe = mtk_dsi_probe, - .remove_new = mtk_dsi_remove, + .remove = mtk_dsi_remove, .driver = { .name = "mtk-dsi", .of_match_table = mtk_dsi_of_match, diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c index 0f22e7d337cb6779939a12c14e4dd31e5a4f2769..96832d0cca37c1037364450f869987bfbb4a1774 100644 --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c @@ -388,7 +388,7 @@ MODULE_DEVICE_TABLE(of, mtk_ethdr_driver_dt_match); struct platform_driver mtk_ethdr_driver = { .probe = mtk_ethdr_probe, - .remove_new = mtk_ethdr_remove, + .remove = mtk_ethdr_remove, .driver = { .name = "mediatek-disp-ethdr", .of_match_table = mtk_ethdr_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 7687f673964ec7df0d76328a43ed76d71b192350..70dc1d4460adfc04b5c40263d11184aae826c658 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1795,7 +1795,7 @@ MODULE_DEVICE_TABLE(of, mtk_hdmi_of_ids); static struct platform_driver mtk_hdmi_driver = { .probe = mtk_hdmi_probe, - .remove_new = mtk_hdmi_remove, + .remove = mtk_hdmi_remove, .driver = { .name = "mediatek-drm-hdmi", .of_match_table = mtk_hdmi_of_ids, diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c index 8e60631d4cd2a1031c3b06d470f8d968bc213762..07db6806784442f802c1a78a02aff3c556c1cda2 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c @@ -331,7 +331,7 @@ MODULE_DEVICE_TABLE(of, mtk_hdmi_ddc_match); struct platform_driver mtk_hdmi_ddc_driver = { .probe = mtk_hdmi_ddc_probe, - .remove_new = mtk_hdmi_ddc_remove, + .remove = mtk_hdmi_ddc_remove, .driver = { .name = "mediatek-hdmi-ddc", .of_match_table = mtk_hdmi_ddc_match, diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c index 7c1a8c7968337f992157c6225a8d0e16e6377ab7..fc69ee38ce7d6a245a7460cfde8de426e83b2e80 100644 --- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c @@ -341,7 +341,7 @@ MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match); struct platform_driver mtk_mdp_rdma_driver = { .probe = mtk_mdp_rdma_probe, - .remove_new = mtk_mdp_rdma_remove, + .remove = mtk_mdp_rdma_remove, .driver = { .name = "mediatek-mdp-rdma", .of_match_table = mtk_mdp_rdma_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_padding.c b/drivers/gpu/drm/mediatek/mtk_padding.c index 4bebd13a07bd7291dcc1877822c40b158e18b44d..b4e3e5a3428b6f5a28786e8310ea50fe9edeeef5 100644 --- a/drivers/gpu/drm/mediatek/mtk_padding.c +++ b/drivers/gpu/drm/mediatek/mtk_padding.c @@ -146,7 +146,7 @@ MODULE_DEVICE_TABLE(of, mtk_padding_driver_dt_match); struct platform_driver mtk_padding_driver = { .probe = mtk_padding_probe, - .remove_new = mtk_padding_remove, + .remove = mtk_padding_remove, .driver = { .name = "mediatek-disp-padding", .of_match_table = mtk_padding_driver_dt_match, diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 7cace75a38af9c90edc88067bf0d87911b877cdf..0f5a1a54544e669d24c4cb0a6cc4122bd2c327fe 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -559,7 +559,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = { static struct platform_driver meson_drm_platform_driver = { .probe = meson_drv_probe, - .remove_new = meson_drv_remove, + .remove = meson_drv_remove, .shutdown = meson_drv_shutdown, .driver = { .name = "meson-drm", diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index b75db829b1daf01339f05e189b9903ca833b223c..0d7c68b29dfff43ef276734368b15da9ee497919 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -856,7 +856,7 @@ MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table); static struct platform_driver meson_dw_hdmi_platform_driver = { .probe = meson_dw_hdmi_probe, - .remove_new = meson_dw_hdmi_remove, + .remove = meson_dw_hdmi_remove, .driver = { .name = DRIVER_NAME, .of_match_table = meson_dw_hdmi_of_table, diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c index a10cff3ca1fef2cf9501b063bf4a98e03decdcc7..66c73c512b0e68ff0e9dbbfaba5f8bf2d347e6b1 100644 --- a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c +++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c @@ -345,7 +345,7 @@ MODULE_DEVICE_TABLE(of, meson_dw_mipi_dsi_of_table); static struct platform_driver meson_dw_mipi_dsi_platform_driver = { .probe = meson_dw_mipi_dsi_probe, - .remove_new = meson_dw_mipi_dsi_remove, + .remove = meson_dw_mipi_dsi_remove, .driver = { .name = DRIVER_NAME, .of_match_table = meson_dw_mipi_dsi_of_table, diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 9ffe91920fbfb4841b28aabec9fbde94539fdd83..236b25c094cd5d462f4b6653de7b7910985cccb6 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -393,7 +393,7 @@ static const struct dev_pm_ops adreno_pm_ops = { static struct platform_driver adreno_driver = { .probe = adreno_probe, - .remove_new = adreno_remove, + .remove = adreno_remove, .shutdown = adreno_shutdown, .driver = { .name = "adreno", diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index ca4847b2b73876c59dedff1e3ec4188ea70860a7..8b251f87a0520da0807b9b7aed17493990e41627 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1494,7 +1494,7 @@ MODULE_DEVICE_TABLE(of, dpu_dt_match); static struct platform_driver dpu_driver = { .probe = dpu_dev_probe, - .remove_new = dpu_dev_remove, + .remove = dpu_dev_remove, .shutdown = msm_kms_shutdown, .driver = { .name = "msm_dpu", diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 6e4e74f9d63d6774eb2fa002febd4ea5224c32ef..c469e66cfc11870ac11e15a847f854e891283f87 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -568,7 +568,7 @@ MODULE_DEVICE_TABLE(of, mdp4_dt_match); static struct platform_driver mdp4_platform_driver = { .probe = mdp4_probe, - .remove_new = mdp4_remove, + .remove = mdp4_remove, .shutdown = msm_kms_shutdown, .driver = { .name = "mdp4", diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 374704cce65634ab6b673e17d1ef9dd65c7fdc94..3fcca7a3d82e7aaa74379b19763c22eb43c953dd 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -908,7 +908,7 @@ MODULE_DEVICE_TABLE(of, mdp5_dt_match); static struct platform_driver mdp5_driver = { .probe = mdp5_dev_probe, - .remove_new = mdp5_dev_remove, + .remove = mdp5_dev_remove, .shutdown = msm_kms_shutdown, .driver = { .name = "msm_mdp", diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index aba925aab7ad7c6652e81004043864c1cb3ac370..aff51bb973ebe0835c96420d16547ebae0c6c0f2 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1397,7 +1397,7 @@ static const struct dev_pm_ops msm_dp_pm_ops = { static struct platform_driver msm_dp_display_driver = { .probe = msm_dp_display_probe, - .remove_new = msm_dp_display_remove, + .remove = msm_dp_display_remove, .driver = { .name = "msm-dp-display", .of_match_table = msm_dp_dt_match, diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index efd7c23b662fffea212beb641b87d7394f29fa65..2962158776135d6e3c5b119bf4341c135c8f5248 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -207,7 +207,7 @@ static const struct dev_pm_ops dsi_pm_ops = { static struct platform_driver dsi_driver = { .probe = dsi_dev_probe, - .remove_new = dsi_dev_remove, + .remove = dsi_dev_remove, .driver = { .name = "msm_dsi", .of_match_table = dt_match, diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 0bfee41c2e71a04f8e5c0734ccaae2ab675aa161..37b3809c6bdd7c35aca6b475cb1f41c0ab4d3e6d 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -561,7 +561,7 @@ static const struct of_device_id msm_hdmi_dt_match[] = { static struct platform_driver msm_hdmi_driver = { .probe = msm_hdmi_dev_probe, - .remove_new = msm_hdmi_dev_remove, + .remove = msm_hdmi_dev_remove, .driver = { .name = "hdmi_msm", .of_match_table = msm_hdmi_dt_match, diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 95b3f7535d840ee7b544055342bca60fa55a5026..03120c54ced686dcd2ddfe809dd9c9011f608235 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -203,7 +203,7 @@ static const struct of_device_id msm_hdmi_phy_dt_match[] = { static struct platform_driver msm_hdmi_phy_platform_driver = { .probe = msm_hdmi_phy_probe, - .remove_new = msm_hdmi_phy_remove, + .remove = msm_hdmi_phy_remove, .driver = { .name = "msm_hdmi_phy", .of_match_table = msm_hdmi_phy_dt_match, diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c2dd8ef6d6dc69edf499e7aab250277aa92f462b..ffbcc97b5018b5a6d102296603c6c4768c694d6c 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1111,7 +1111,7 @@ static void msm_pdev_remove(struct platform_device *pdev) static struct platform_driver msm_platform_driver = { .probe = msm_pdev_probe, - .remove_new = msm_pdev_remove, + .remove = msm_pdev_remove, .driver = { .name = "msm", }, diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index b7bd899ead44bf86998e7295bccb31a334fa6811..76b6ae35a3cb5da5047e4e5628b2aab6d3e12cfc 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -740,7 +740,7 @@ MODULE_DEVICE_TABLE(of, mdss_dt_match); static struct platform_driver mdss_platform_driver = { .probe = mdss_probe, - .remove_new = mdss_remove, + .remove = mdss_remove, .driver = { .name = "msm-mdss", .of_match_table = mdss_dt_match, diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c index 58ccad9c425d82b99f4b65f9751fafc99bd6bd4d..51ae0b51b1e8d4914990c39781175077c4c05909 100644 --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c @@ -368,7 +368,7 @@ static const struct dev_pm_ops lcdif_pm_ops = { static struct platform_driver lcdif_platform_driver = { .probe = lcdif_probe, - .remove_new = lcdif_remove, + .remove = lcdif_remove, .shutdown = lcdif_shutdown, .driver = { .name = "imx-lcdif", diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index 34a98717b72ce4ed089a9482a8957bc215370455..6b95e4eb3e4e23b475d4fb6b5c900a478dc15caa 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -417,7 +417,7 @@ static const struct dev_pm_ops mxsfb_pm_ops = { static struct platform_driver mxsfb_platform_driver = { .probe = mxsfb_probe, - .remove_new = mxsfb_remove, + .remove = mxsfb_remove, .shutdown = mxsfb_shutdown, .driver = { .name = "mxsfb", diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c index 829fdc6e4031e3c8c2af5c58b9eab9a7fe4d26a4..a5ce8eb4a3be7a20988ea5515e8b58b1801e5842 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.c +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c @@ -86,5 +86,5 @@ struct platform_driver nouveau_platform_driver = { .of_match_table = of_match_ptr(nouveau_platform_match), }, .probe = nouveau_platform_probe, - .remove_new = nouveau_platform_remove, + .remove = nouveau_platform_remove, }; diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 9344855c4887827227a3f39cfc6d248de6f72dc2..533f70e8a4a6491fc2496644cdbd796ed4997cf4 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -4766,7 +4766,7 @@ static const struct dev_pm_ops dispc_pm_ops = { struct platform_driver omap_dispchw_driver = { .probe = dispc_probe, - .remove_new = dispc_remove, + .remove = dispc_remove, .driver = { .name = "omapdss_dispc", .pm = &dispc_pm_ops, diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index ea63c64d3a1abea20820c282cafc75c4c6b7d573..59d20eb8a7e0fdcc13060d00980452bc80c54eb2 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5093,7 +5093,7 @@ static const struct dev_pm_ops dsi_pm_ops = { struct platform_driver omap_dsihw_driver = { .probe = dsi_probe, - .remove_new = dsi_remove, + .remove = dsi_remove, .driver = { .name = "omapdss_dsi", .pm = &dsi_pm_ops, diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 988888e164d7b3e9a87cf340cb12dfebe30d64e8..7b2df3185de4576269e54b1dbaf7a30d0c611d22 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1606,7 +1606,7 @@ static const struct dev_pm_ops dss_pm_ops = { struct platform_driver omap_dsshw_driver = { .probe = dss_probe, - .remove_new = dss_remove, + .remove = dss_remove, .shutdown = dss_shutdown, .driver = { .name = "omapdss_dss", diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 9b8747d83ee877046ed9d0dfae626a4f3bccb6b2..4435f0027c78d75067be42b1c097db2980828ed8 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -852,7 +852,7 @@ static const struct of_device_id hdmi_of_match[] = { struct platform_driver omapdss_hdmi4hw_driver = { .probe = hdmi4_probe, - .remove_new = hdmi4_remove, + .remove = hdmi4_remove, .driver = { .name = "omapdss_hdmi", .of_match_table = hdmi_of_match, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index c7ae2235ae99b0f9b6cb3f9cbb70a74488907723..a8c740df3146eb9dd2b64b2520cfd07e46bc2539 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -819,7 +819,7 @@ static const struct of_device_id hdmi_of_match[] = { struct platform_driver omapdss_hdmi5hw_driver = { .probe = hdmi5_probe, - .remove_new = hdmi5_remove, + .remove = hdmi5_remove, .driver = { .name = "omapdss_hdmi5", .of_match_table = hdmi_of_match, diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index f163d52a7c7daec8e732ed3a37d5e0e60c7b1401..aaeef603682c25773f2f809d8ac04f64cba5fb21 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -912,7 +912,7 @@ static const struct of_device_id venc_of_match[] = { struct platform_driver omap_venchw_driver = { .probe = venc_probe, - .remove_new = venc_remove, + .remove = venc_remove, .driver = { .name = "omapdss_venc", .pm = &venc_pm_ops, diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index fcd600024136693b3c02662e6347ee8b72cfe9ea..3fff32c000a6fce7a9d9bc2f279e42df22dd6840 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c @@ -1210,7 +1210,7 @@ static const struct of_device_id dmm_of_match[] = { struct platform_driver omap_dmm_driver = { .probe = omap_dmm_probe, - .remove_new = omap_dmm_remove, + .remove = omap_dmm_remove, .driver = { .name = DMM_DRIVER_NAME, .of_match_table = of_match_ptr(dmm_of_match), diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 1796cd20a8776172dca9208896ca1d1320ec5b48..e273761216065e61475e441b36d442e233f5b87f 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -857,7 +857,7 @@ static struct platform_driver pdev = { .pm = &omapdrm_pm_ops, }, .probe = pdev_probe, - .remove_new = pdev_remove, + .remove = pdev_remove, .shutdown = pdev_shutdown, }; diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c index 36f9ee4baad3734b2f47e86fea165de08544c05f..30cf1cdc1aa3c8aa94ad6eaa55f8bff6a22e3c52 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c +++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c @@ -11,7 +11,7 @@ #include "omap_drv.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); /* ----------------------------------------------------------------------------- * DMABUF Export diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 8566e9cf2f82a126a4e2400339ba42d35fe2171c..94a46241dece254b4be98e0acb6c5d1ff1a63bf6 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -2049,7 +2049,7 @@ static struct platform_driver panel_edp_platform_driver = { .pm = &panel_edp_pm_ops, }, .probe = panel_edp_platform_probe, - .remove_new = panel_edp_platform_remove, + .remove = panel_edp_platform_remove, .shutdown = panel_edp_platform_shutdown, }; diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c index 1b8e3156914c1dd3e0eac49503e16a71a85fa1f0..ba6c015aabba9e03a37058e0fcf7cb39d1595d70 100644 --- a/drivers/gpu/drm/panel/panel-lvds.c +++ b/drivers/gpu/drm/panel/panel-lvds.c @@ -246,7 +246,7 @@ MODULE_DEVICE_TABLE(of, panel_lvds_of_table); static struct platform_driver panel_lvds_driver = { .probe = panel_lvds_probe, - .remove_new = panel_lvds_remove, + .remove = panel_lvds_remove, .driver = { .name = "panel-lvds", .of_match_table = panel_lvds_of_table, diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c index 8a3fe531c6418c5b6def98b08d363d57d78407a6..7d1b421ea9ddfcf84850a2fc589f7a43e24fc167 100644 --- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c +++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c @@ -297,7 +297,7 @@ static struct platform_driver seiko_panel_platform_driver = { .of_match_table = platform_of_match, }, .probe = seiko_panel_platform_probe, - .remove_new = seiko_panel_remove, + .remove = seiko_panel_remove, }; module_platform_driver(seiko_panel_platform_driver); diff --git a/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c index 76bd9e81082768a3544fe3b6b974db2f1b341484..a9673a52b861553792c9814da54a08043eb773e8 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c @@ -207,7 +207,7 @@ MODULE_DEVICE_TABLE(of, ls037v7dw01_of_match); static struct platform_driver ls037v7dw01_driver = { .probe = ls037v7dw01_probe, - .remove_new = ls037v7dw01_remove, + .remove = ls037v7dw01_remove, .driver = { .name = "panel-sharp-ls037v7dw01", .of_match_table = ls037v7dw01_of_match, diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 06381c62820975beca1ca3d598cb3e715d98a7aa..222c170dde8be261e98ff41168ef8a3a42c167c8 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -5120,7 +5120,7 @@ static struct platform_driver panel_simple_platform_driver = { .pm = &panel_simple_pm_ops, }, .probe = panel_simple_platform_probe, - .remove_new = panel_simple_platform_remove, + .remove = panel_simple_platform_remove, .shutdown = panel_simple_platform_shutdown, }; diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 04d615df52590c1477569e663bb7961af2cfe10a..ee3864476eb90e3658fbc3b9a4771d50dcec84bf 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -866,7 +866,7 @@ MODULE_DEVICE_TABLE(of, dt_match); static struct platform_driver panfrost_driver = { .probe = panfrost_probe, - .remove_new = panfrost_remove, + .remove = panfrost_remove, .driver = { .name = "panfrost", .pm = pm_ptr(&panfrost_pm_ops), diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index ac7e53f6e3f013d3db4d41d2de30ecbfdd4881b4..0b3fbee3d37a8aed4ffcc297be32068a1b35a6dd 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -1589,7 +1589,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(panthor_pm_ops, static struct platform_driver panthor_driver = { .probe = panthor_probe, - .remove_new = panthor_remove, + .remove = panthor_remove, .driver = { .name = "panthor", .pm = pm_ptr(&panthor_pm_ops), diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index 47aa06a9a94221555a4828f41a57cbe03d637ee1..5b69cc8011b42b4686c02f97a2b451a63d6c346d 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -760,16 +760,20 @@ static int radeon_audio_component_get_eld(struct device *kdev, int port, if (!rdev->audio.enabled || !rdev->mode_info.mode_config_initialized) return 0; - list_for_each_entry(encoder, &rdev_to_drm(rdev)->mode_config.encoder_list, head) { + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + const struct drm_connector_helper_funcs *connector_funcs = + connector->helper_private; + encoder = connector_funcs->best_encoder(connector); + + if (!encoder) + continue; + if (!radeon_encoder_is_digital(encoder)) continue; radeon_encoder = to_radeon_encoder(encoder); dig = radeon_encoder->enc_priv; if (!dig->pin || dig->pin->id != port) continue; - connector = radeon_get_connector_for_encoder(encoder); - if (!connector) - continue; *enabled = true; ret = drm_eld_size(connector->eld); memcpy(buf, connector->eld, min(max_bytes, ret)); diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index f9c73c55f04f76ed5c78e9169004f8a7dea6004e..f9996304d9431358224bea27d78b1478af22d60d 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1255,16 +1255,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) goto exit; } } - - if (dret && radeon_connector->hpd.hpd != RADEON_HPD_NONE && - !radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && - connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) { - DRM_DEBUG_KMS("EDID is readable when HPD disconnected\n"); - schedule_delayed_work(&rdev->hotplug_work, msecs_to_jiffies(1000)); - ret = connector_status_disconnected; - goto exit; - } - if (dret) { radeon_connector->detected_by_load = false; radeon_connector_free_edid(connector); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 23d6d1a2586d1525beea55a00b6a4708f4913e99..5e958cc223f44bf563327e9e04d686e25882ccdc 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -248,10 +248,9 @@ int radeon_cik_support = 1; MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)"); module_param_named(cik_support, radeon_cik_support, int, 0444); -static struct pci_device_id pciidlist[] = { +static const struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; - MODULE_DEVICE_TABLE(pci, pciidlist); static const struct drm_driver kms_driver; diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 69d0c12fa419fdb86dfe4433e0e29c4a8dc9646e..616d25c8c2de7f579fb2045591f7d7498ff70689 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -219,8 +219,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, if (old_mem->mem_type == TTM_PL_TT && new_mem->mem_type == TTM_PL_SYSTEM) { radeon_ttm_tt_unbind(bo->bdev, bo->ttm); - ttm_resource_free(bo, &bo->resource); - ttm_bo_assign_mem(bo, new_mem); + ttm_bo_move_null(bo, new_mem); goto out; } if (rdev->ring[radeon_copy_ring_index(rdev)].ready && diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c b/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c index 26a2f5ad8ee5d4ecc8cb6698e16e373a5045bf3d..79b67c406bd69d78ea2701ff92cd9a7cd59327b0 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c @@ -201,7 +201,7 @@ MODULE_DEVICE_TABLE(of, rcar_cmm_of_table); static struct platform_driver rcar_cmm_platform_driver = { .probe = rcar_cmm_probe, - .remove_new = rcar_cmm_remove, + .remove = rcar_cmm_remove, .driver = { .name = "rcar-cmm", .of_match_table = rcar_cmm_of_table, diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c index 4e0bafc86f505b8eb36bfc4f183a7b8b2f45a725..f9ecc334c024ea0205f5b280435dab0bd53da172 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c @@ -729,7 +729,7 @@ error: static struct platform_driver rcar_du_platform_driver = { .probe = rcar_du_probe, - .remove_new = rcar_du_remove, + .remove = rcar_du_remove, .shutdown = rcar_du_shutdown, .driver = { .name = "rcar-du", diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c index 119d69d20b230184c01d5b3fe38a6ac5a2b65375..c0176e5de9a8737e896390a4274a8dcd9a5fd768 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c @@ -108,7 +108,7 @@ MODULE_DEVICE_TABLE(of, rcar_dw_hdmi_of_table); static struct platform_driver rcar_dw_hdmi_platform_driver = { .probe = rcar_dw_hdmi_probe, - .remove_new = rcar_dw_hdmi_remove, + .remove = rcar_dw_hdmi_remove, .driver = { .name = "rcar-dw-hdmi", .of_match_table = rcar_dw_hdmi_of_table, diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c b/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c index 92ba43a6fe38753dcbcaff277e8b86ea83d000e2..e8d64583e3bdb9b0cb35622b1bbe6d9fc88daadf 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c @@ -1018,7 +1018,7 @@ static const struct dev_pm_ops rcar_lvds_pm_ops = { static struct platform_driver rcar_lvds_platform_driver = { .probe = rcar_lvds_probe, - .remove_new = rcar_lvds_remove, + .remove = rcar_lvds_remove, .driver = { .name = "rcar-lvds", .pm = &rcar_lvds_pm_ops, diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c index 2dba7c5ffd2c62953e56b4ef23367f1033d7ec26..8180625d5866d1035d792290d9fcd9aeaaa86702 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c @@ -1088,7 +1088,7 @@ MODULE_DEVICE_TABLE(of, rcar_mipi_dsi_of_table); static struct platform_driver rcar_mipi_dsi_platform_driver = { .probe = rcar_mipi_dsi_probe, - .remove_new = rcar_mipi_dsi_remove, + .remove = rcar_mipi_dsi_remove, .driver = { .name = "rcar-mipi-dsi", .of_match_table = rcar_mipi_dsi_of_table, diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c index bbd7003335da495c9123e340cede795888966d7f..b069efd8ffc39d621373fc3d3ba914a342dc8c33 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c @@ -173,7 +173,7 @@ error: static struct platform_driver rzg2l_du_platform_driver = { .probe = rzg2l_du_probe, - .remove_new = rzg2l_du_remove, + .remove = rzg2l_du_remove, .shutdown = rzg2l_du_shutdown, .driver = { .name = "rzg2l-du", diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c index 10febea473cde974f2c4f85930cd3521c1eda6bf..fa7a1ae22aa3d9bbe7995edef040ac69d922ca2d 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c @@ -798,7 +798,7 @@ MODULE_DEVICE_TABLE(of, rzg2l_mipi_dsi_of_table); static struct platform_driver rzg2l_mipi_dsi_platform_driver = { .probe = rzg2l_mipi_dsi_probe, - .remove_new = rzg2l_mipi_dsi_remove, + .remove = rzg2l_mipi_dsi_remove, .driver = { .name = "rzg2l-mipi-dsi", .pm = &rzg2l_mipi_pm_ops, diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c index 8d3effe3f59820914949a38e000ee780fa19e049..76ee3e16077c4270de6b0475b1cb055658a16163 100644 --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c @@ -282,7 +282,7 @@ static const struct of_device_id shmob_drm_of_table[] __maybe_unused = { static struct platform_driver shmob_drm_platform_driver = { .probe = shmob_drm_probe, - .remove_new = shmob_drm_remove, + .remove = shmob_drm_remove, .shutdown = shmob_drm_shutdown, .driver = { .name = "shmob-drm", diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index d3341edfe4f4f152d02c6fffbedf7af61e740737..546d13f19f9b372bf3fba90f76b30af5c764f9e8 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -470,7 +470,7 @@ MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids); struct platform_driver rockchip_dp_driver = { .probe = rockchip_dp_probe, - .remove_new = rockchip_dp_remove, + .remove = rockchip_dp_remove, .driver = { .name = "rockchip-dp", .pm = pm_ptr(&rockchip_dp_pm_ops), diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index b04538907f956cbf7732c9177c477951eaa32276..ff9d95e2c4d4d5b6dc2682f8750e94cd1e7cf556 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -1254,7 +1254,7 @@ static const struct dev_pm_ops cdn_dp_pm_ops = { struct platform_driver cdn_dp_driver = { .probe = cdn_dp_probe, - .remove_new = cdn_dp_remove, + .remove = cdn_dp_remove, .shutdown = cdn_dp_shutdown, .driver = { .name = "cdn-dp", diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 58a44af0e9ad598db3d939ebd502cc4d2b1696d1..1b64b6e39cc8d925961b17af250e278461ae6cc6 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -1709,7 +1709,7 @@ MODULE_DEVICE_TABLE(of, dw_mipi_dsi_rockchip_dt_ids); struct platform_driver dw_mipi_dsi_rockchip_driver = { .probe = dw_mipi_dsi_rockchip_probe, - .remove_new = dw_mipi_dsi_rockchip_remove, + .remove = dw_mipi_dsi_rockchip_remove, .driver = { .of_match_table = dw_mipi_dsi_rockchip_dt_ids, .pm = &dw_mipi_dsi_rockchip_pm_ops, diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 96e1097f993dc11530f6697dc3f677e4ba91f064..42bda4ffbbbda9955410d8ad6195eff669abce75 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -666,7 +666,7 @@ static const struct dev_pm_ops dw_hdmi_rockchip_pm = { struct platform_driver dw_hdmi_rockchip_pltfm_driver = { .probe = dw_hdmi_rockchip_probe, - .remove_new = dw_hdmi_rockchip_remove, + .remove = dw_hdmi_rockchip_remove, .driver = { .name = "dwhdmi-rockchip", .pm = &dw_hdmi_rockchip_pm, diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index 9c796ee4c303a9a9075b251f681bf14de2dbb9a4..c8b362cc2b95fd490029a9c0552ad9fbc5631d17 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -82,7 +82,7 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) * comment in rk_hdptx_phy_power_on() from * drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c */ - phy_set_bus_width(hdmi->phy, rate / 100); + phy_set_bus_width(hdmi->phy, div_u64(rate, 100)); } } diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c index 42ef62aa0a1e078d4b1db93eb20c7cc21054df28..b58e2a29294bdceefffa90e20a28121d3fe71c48 100644 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -1017,7 +1017,7 @@ MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids); struct platform_driver inno_hdmi_driver = { .probe = inno_hdmi_probe, - .remove_new = inno_hdmi_remove, + .remove = inno_hdmi_remove, .driver = { .name = "innohdmi-rockchip", .of_match_table = inno_hdmi_dt_ids, diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c index 784de990da1b2c076a7067dcebb6c4a1273a5d5c..b0fc8ace2e4140a4ba9058b4f767a37be95f7419 100644 --- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c +++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c @@ -858,7 +858,7 @@ MODULE_DEVICE_TABLE(of, rk3066_hdmi_dt_ids); struct platform_driver rk3066_hdmi_driver = { .probe = rk3066_hdmi_probe, - .remove_new = rk3066_hdmi_remove, + .remove = rk3066_hdmi_remove, .driver = { .name = "rockchip-rk3066-hdmi", .of_match_table = rk3066_hdmi_dt_ids, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 585355de696b7f1ce2c7980525dd8d84aefa7d72..32d8394c4c49964090bcf2af5981d594f602eb04 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -500,7 +500,7 @@ MODULE_DEVICE_TABLE(of, rockchip_drm_dt_ids); static struct platform_driver rockchip_drm_platform_driver = { .probe = rockchip_drm_platform_probe, - .remove_new = rockchip_drm_platform_remove, + .remove = rockchip_drm_platform_remove, .shutdown = rockchip_drm_platform_shutdown, .driver = { .name = "rockchip-drm", diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c index 9a01aa450741713293988c23677d7402e19b9915..aba733736ff7437712fa395f704f326e6b0793dc 100644 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -746,7 +746,7 @@ static void rockchip_lvds_remove(struct platform_device *pdev) struct platform_driver rockchip_lvds_driver = { .probe = rockchip_lvds_probe, - .remove_new = rockchip_lvds_remove, + .remove = rockchip_lvds_remove, .driver = { .name = "rockchip-lvds", .of_match_table = rockchip_lvds_dt_ids, diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index 18efb3fe1c000f691131dabccb2d6965763c8e07..f9d87a0abc8b02df6be4cf5e3f773336256b01e0 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -501,7 +501,7 @@ static void vop2_remove(struct platform_device *pdev) struct platform_driver vop2_platform_driver = { .probe = vop2_probe, - .remove_new = vop2_remove, + .remove = vop2_remove, .driver = { .name = "rockchip-vop2", .of_match_table = vop2_dt_match, diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index e2c6ba26f4377d2916db143c777ab7fed20f623f..8998967f0c0076f5129d2a3c15f46f6a01180d51 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -1284,7 +1284,7 @@ static void vop_remove(struct platform_device *pdev) struct platform_driver vop_platform_driver = { .probe = vop_probe, - .remove_new = vop_remove, + .remove = vop_remove, .driver = { .name = "rockchip-vop", .of_match_table = vop_driver_dt_match, diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index f2ccab9c06d9f52976e2ff45e52daddbba26645a..941a2eb44c57eba72040658f939aaed9a266fec9 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -123,4 +123,4 @@ module_i2c_driver(ssd130x_i2c_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Javier Martinez Canillas "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(DRM_SSD130X); +MODULE_IMPORT_NS("DRM_SSD130X"); diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 84bfde31d1724a2c7e2cb52e847fe934813fda3b..08334be386946eec2b7fcfc71190b5c1e5cf0d3e 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -192,4 +192,4 @@ module_spi_driver(ssd130x_spi_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Javier Martinez Canillas "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(DRM_SSD130X); +MODULE_IMPORT_NS("DRM_SSD130X"); diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 29b2f82d81f8941d4b3272856546d06c56d31b53..486d8f5282f93fed8fa70b94d9f93e86299c5dad 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -209,7 +209,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .family_id = SSD133X_FAMILY, } }; -EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); +EXPORT_SYMBOL_NS_GPL(ssd130x_variants, "DRM_SSD130X"); struct ssd130x_crtc_state { struct drm_crtc_state base; diff --git a/drivers/gpu/drm/sprd/sprd_dpu.c b/drivers/gpu/drm/sprd/sprd_dpu.c index deb3bb96e2a8a9cf2cd0b6b5cfd5ae218ed4a317..cb2816985305fd19eac27413c214681a5a1e9ffa 100644 --- a/drivers/gpu/drm/sprd/sprd_dpu.c +++ b/drivers/gpu/drm/sprd/sprd_dpu.c @@ -866,7 +866,7 @@ static void sprd_dpu_remove(struct platform_device *pdev) struct platform_driver sprd_dpu_driver = { .probe = sprd_dpu_probe, - .remove_new = sprd_dpu_remove, + .remove = sprd_dpu_remove, .driver = { .name = "sprd-dpu-drv", .of_match_table = dpu_match_table, diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c index a74cd0caf64503ffcdae5ffb422632ea487cbfa4..bc1c747d3ea49fa679f9a3b9ff9c33c64dc757d7 100644 --- a/drivers/gpu/drm/sprd/sprd_drm.c +++ b/drivers/gpu/drm/sprd/sprd_drm.c @@ -163,7 +163,7 @@ MODULE_DEVICE_TABLE(of, drm_match_table); static struct platform_driver sprd_drm_driver = { .probe = sprd_drm_probe, - .remove_new = sprd_drm_remove, + .remove = sprd_drm_remove, .shutdown = sprd_drm_shutdown, .driver = { .name = "sprd-drm-drv", diff --git a/drivers/gpu/drm/sprd/sprd_dsi.c b/drivers/gpu/drm/sprd/sprd_dsi.c index 44a7a579660fd16b63ec81f704133f2515ecc41e..8fc26479bb6bce0aa94914f49d0986a7e19326c1 100644 --- a/drivers/gpu/drm/sprd/sprd_dsi.c +++ b/drivers/gpu/drm/sprd/sprd_dsi.c @@ -1060,7 +1060,7 @@ static void sprd_dsi_remove(struct platform_device *pdev) struct platform_driver sprd_dsi_driver = { .probe = sprd_dsi_probe, - .remove_new = sprd_dsi_remove, + .remove = sprd_dsi_remove, .driver = { .name = "sprd-dsi-drv", .of_match_table = dsi_match_table, diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c index 33487a1fed8f57f311398e5984c43b6629aa2fc3..063f82d23d80c4ba83624a0066a18416a2b37351 100644 --- a/drivers/gpu/drm/sti/sti_compositor.c +++ b/drivers/gpu/drm/sti/sti_compositor.c @@ -269,7 +269,7 @@ struct platform_driver sti_compositor_driver = { .of_match_table = compositor_of_match, }, .probe = sti_compositor_probe, - .remove_new = sti_compositor_remove, + .remove = sti_compositor_remove, }; MODULE_AUTHOR("Benjamin Gaignard "); diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index 65f180c8e8e206beae5de8557d64d6c374517d4b..61ceff9aee7e62a510ffcd1a3bcc8060e1ce3136 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c @@ -270,7 +270,7 @@ MODULE_DEVICE_TABLE(of, sti_dt_ids); static struct platform_driver sti_platform_driver = { .probe = sti_platform_probe, - .remove_new = sti_platform_remove, + .remove = sti_platform_remove, .shutdown = sti_platform_shutdown, .driver = { .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c index 68b8197b3dd16713a49d97f91498b686fdda21ec..c6c2abaa1891cd3ea025805b50d275ec314512c3 100644 --- a/drivers/gpu/drm/sti/sti_dvo.c +++ b/drivers/gpu/drm/sti/sti_dvo.c @@ -585,7 +585,7 @@ struct platform_driver sti_dvo_driver = { .of_match_table = dvo_of_match, }, .probe = sti_dvo_probe, - .remove_new = sti_dvo_remove, + .remove = sti_dvo_remove, }; MODULE_AUTHOR("Benjamin Gaignard "); diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c index f18faad974aa2eda58c1e49537f8337db119d4b7..b12863bea95559c4f874eb94cea8938609d435d4 100644 --- a/drivers/gpu/drm/sti/sti_hda.c +++ b/drivers/gpu/drm/sti/sti_hda.c @@ -810,7 +810,7 @@ struct platform_driver sti_hda_driver = { .of_match_table = hda_of_match, }, .probe = sti_hda_probe, - .remove_new = sti_hda_remove, + .remove = sti_hda_remove, }; MODULE_AUTHOR("Benjamin Gaignard "); diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 847470f747c0efad61c2ebdc3fb3746a7a13a863..21b46a6465f08afbcaa8fb95f9cf320c85b4bb83 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -1492,7 +1492,7 @@ struct platform_driver sti_hdmi_driver = { .of_match_table = hdmi_of_match, }, .probe = sti_hdmi_probe, - .remove_new = sti_hdmi_remove, + .remove = sti_hdmi_remove, }; MODULE_AUTHOR("Benjamin Gaignard "); diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index 5793cf2cb8972c3d00453813d8c3a968bddca649..0f658709c9d0d398c4eed65202443db9d0b41f8c 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c @@ -1420,7 +1420,7 @@ struct platform_driver sti_hqvdp_driver = { .of_match_table = hqvdp_of_match, }, .probe = sti_hqvdp_probe, - .remove_new = sti_hqvdp_remove, + .remove = sti_hqvdp_remove, }; MODULE_AUTHOR("Benjamin Gaignard "); diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c index e714c232026c6e88a3b61f7034c54d20fe24e830..af6c06f448c4819def8cc0d0836e30f991529690 100644 --- a/drivers/gpu/drm/sti/sti_tvout.c +++ b/drivers/gpu/drm/sti/sti_tvout.c @@ -889,7 +889,7 @@ struct platform_driver sti_tvout_driver = { .of_match_table = tvout_of_match, }, .probe = sti_tvout_probe, - .remove_new = sti_tvout_remove, + .remove = sti_tvout_remove, }; MODULE_AUTHOR("Benjamin Gaignard "); diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 478dc129d5c289b9647c5474f9edfa6d0c2e7040..bf090a354989419792160c5e03ca6394bc7368b2 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, drv_dt_ids); static struct platform_driver stm_drm_platform_driver = { .probe = stm_drm_platform_probe, - .remove_new = stm_drm_platform_remove, + .remove = stm_drm_platform_remove, .shutdown = stm_drm_platform_shutdown, .driver = { .name = "stm32-display", diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c index b20123854c4ad7b3a2cc973a26fc10fd433e8d09..2c7bc064bc66c6a58903a207cbe8091a14231c2b 100644 --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -783,7 +783,7 @@ static const struct dev_pm_ops dw_mipi_dsi_stm_pm_ops = { static struct platform_driver dw_mipi_dsi_stm_driver = { .probe = dw_mipi_dsi_stm_probe, - .remove_new = dw_mipi_dsi_stm_remove, + .remove = dw_mipi_dsi_stm_remove, .driver = { .of_match_table = dw_mipi_dsi_stm_dt_ids, .name = "stm32-display-dsi", diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index e89eb96d31317738dc007b0b9e4e5d99c78f5e67..2dded3b828df0f3451949ccd47c98a2b8752b6e2 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -1028,7 +1028,7 @@ MODULE_DEVICE_TABLE(of, sun4i_backend_of_table); static struct platform_driver sun4i_backend_platform_driver = { .probe = sun4i_backend_probe, - .remove_new = sun4i_backend_remove, + .remove = sun4i_backend_remove, .driver = { .name = "sun4i-backend", .of_match_table = sun4i_backend_of_table, diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 3f880d8a5666a420c6339ee4c5ad25aefe477793..5eccf58f2e17828594001a4b47a71595e2eb6ebd 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -443,7 +443,7 @@ MODULE_DEVICE_TABLE(of, sun4i_drv_of_table); static struct platform_driver sun4i_drv_platform_driver = { .probe = sun4i_drv_probe, - .remove_new = sun4i_drv_remove, + .remove = sun4i_drv_remove, .shutdown = sun4i_drv_shutdown, .driver = { .name = "sun4i-drm", diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.c b/drivers/gpu/drm/sun4i/sun4i_frontend.c index 280d444dbb6686c06dd3fa65cfdce6dbd85d5101..5ab1604f12dde88cf696a6b70be3853e0aef892a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_frontend.c +++ b/drivers/gpu/drm/sun4i/sun4i_frontend.c @@ -717,7 +717,7 @@ MODULE_DEVICE_TABLE(of, sun4i_frontend_of_table); static struct platform_driver sun4i_frontend_driver = { .probe = sun4i_frontend_probe, - .remove_new = sun4i_frontend_remove, + .remove = sun4i_frontend_remove, .driver = { .name = "sun4i-frontend", .of_match_table = sun4i_frontend_of_table, diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index b3649449de3026784ae2f3466906403a0b6e3b47..453f19f16ab7204fd2abce9be2809b94ceeed040 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -741,7 +741,7 @@ MODULE_DEVICE_TABLE(of, sun4i_hdmi_of_table); static struct platform_driver sun4i_hdmi_driver = { .probe = sun4i_hdmi_probe, - .remove_new = sun4i_hdmi_remove, + .remove = sun4i_hdmi_remove, .driver = { .name = "sun4i-hdmi", .of_match_table = sun4i_hdmi_of_table, diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index a1a2c845ade0ca465e48116d6954d82d8fc3e256..960e83c8291da336ace1d87dc3c4ce9b3114c999 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -1568,7 +1568,7 @@ EXPORT_SYMBOL(sun4i_tcon_of_table); static struct platform_driver sun4i_tcon_platform_driver = { .probe = sun4i_tcon_probe, - .remove_new = sun4i_tcon_remove, + .remove = sun4i_tcon_remove, .driver = { .name = "sun4i-tcon", .of_match_table = sun4i_tcon_of_table, diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c index ec65d9d59de7dc1a44e039743f95362c423070f3..cce4e38789b989a2261139073cdd508e0b7d2cb4 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tv.c +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c @@ -559,7 +559,7 @@ MODULE_DEVICE_TABLE(of, sun4i_tv_of_table); static struct platform_driver sun4i_tv_platform_driver = { .probe = sun4i_tv_probe, - .remove_new = sun4i_tv_remove, + .remove = sun4i_tv_remove, .driver = { .name = "sun4i-tve", .of_match_table = sun4i_tv_of_table, diff --git a/drivers/gpu/drm/sun4i/sun6i_drc.c b/drivers/gpu/drm/sun4i/sun6i_drc.c index 0d342f43fa93e460eb4fac628eb1e50c9140eac7..310c7e0daedec3c2d67293293904cf675f17b442 100644 --- a/drivers/gpu/drm/sun4i/sun6i_drc.c +++ b/drivers/gpu/drm/sun4i/sun6i_drc.c @@ -112,7 +112,7 @@ MODULE_DEVICE_TABLE(of, sun6i_drc_of_table); static struct platform_driver sun6i_drc_platform_driver = { .probe = sun6i_drc_probe, - .remove_new = sun6i_drc_remove, + .remove = sun6i_drc_remove, .driver = { .name = "sun6i-drc", .of_match_table = sun6i_drc_of_table, diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index 4abf4f1020074e0d259a6a31d2f3d2c40a101130..c35b70d83e53b7397c6e38dde45824bd49fdf099 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -1244,7 +1244,7 @@ MODULE_DEVICE_TABLE(of, sun6i_dsi_of_table); static struct platform_driver sun6i_dsi_platform_driver = { .probe = sun6i_dsi_probe, - .remove_new = sun6i_dsi_remove, + .remove = sun6i_dsi_remove, .driver = { .name = "sun6i-mipi-dsi", .of_match_table = sun6i_dsi_of_table, diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 4727dfaa8fb98c096c35d277824ab87921754630..96532709c2a7ed525347a420523fbeeadfdde8ec 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -264,7 +264,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dw_hdmi_dt_ids); static struct platform_driver sun8i_dw_hdmi_pltfm_driver = { .probe = sun8i_dw_hdmi_probe, - .remove_new = sun8i_dw_hdmi_remove, + .remove = sun8i_dw_hdmi_remove, .driver = { .name = "sun8i-dw-hdmi", .of_match_table = sun8i_dw_hdmi_dt_ids, diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index bd0fe2c6624e677e4b83263c8fd1c9466f849a5d..8b41d33baa30968cf0836db060cbd78aea8605a7 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -775,7 +775,7 @@ MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table); static struct platform_driver sun8i_mixer_platform_driver = { .probe = sun8i_mixer_probe, - .remove_new = sun8i_mixer_remove, + .remove = sun8i_mixer_remove, .driver = { .name = "sun8i-mixer", .of_match_table = sun8i_mixer_of_table, diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c index a1ca3916f42bcc63b9ac7643e788d962ef360ca8..8adda578c51ba4db490ef9332b3dbcf671350fce 100644 --- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c @@ -299,7 +299,7 @@ EXPORT_SYMBOL(sun8i_tcon_top_of_table); static struct platform_driver sun8i_tcon_top_platform_driver = { .probe = sun8i_tcon_top_probe, - .remove_new = sun8i_tcon_top_remove, + .remove = sun8i_tcon_top_remove, .driver = { .name = "sun8i-tcon-top", .of_match_table = sun8i_tcon_top_of_table, diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index be61c9d1a4f0e8289ba83cb82edb9f30b95f187c..430b2eededb2b5a3aa0c71022240076c027f5d90 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -3286,5 +3286,5 @@ struct platform_driver tegra_dc_driver = { .of_match_table = tegra_dc_of_match, }, .probe = tegra_dc_probe, - .remove_new = tegra_dc_remove, + .remove = tegra_dc_remove, }; diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index ae12d001a04bfbe98504b6435dc9b9d964f7f4aa..2cd8dcb959c054fd1f8713d61f3073e4ae1e0683 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -697,7 +697,7 @@ struct platform_driver tegra_dpaux_driver = { .pm = pm_ptr(&tegra_dpaux_pm_ops), }, .probe = tegra_dpaux_probe, - .remove_new = tegra_dpaux_remove, + .remove = tegra_dpaux_remove, }; struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index db606e151afc81e26eaacb36a90389acc3b5a1aa..4a8cd9ed0a9414b2f40b716fa8c02aff038a53e0 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -1713,5 +1713,5 @@ struct platform_driver tegra_dsi_driver = { .of_match_table = tegra_dsi_of_match, }, .probe = tegra_dsi_probe, - .remove_new = tegra_dsi_remove, + .remove = tegra_dsi_remove, }; diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index d275404ad0e9898fd312a13237f4ccd325ef130e..ace3e5a805cf7475ba67ce675d2b5dab826e9e15 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -22,7 +22,7 @@ #include "drm.h" #include "gem.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); static unsigned int sg_dma_count_chunks(struct scatterlist *sgl, unsigned int nents) { diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c index a160d01f26e1db485704cfac31d216b3df55445e..21f4dd0fa6aff7c58ffbd01409c268c38186cb96 100644 --- a/drivers/gpu/drm/tegra/gr2d.c +++ b/drivers/gpu/drm/tegra/gr2d.c @@ -394,5 +394,5 @@ struct platform_driver tegra_gr2d_driver = { .pm = &tegra_gr2d_pm, }, .probe = gr2d_probe, - .remove_new = gr2d_remove, + .remove = gr2d_remove, }; diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index caee824832b3bf2f292a251126e43d837ae1092f..42e9656ab80c91bb8e3606ec68139bacbf5da482 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -605,5 +605,5 @@ struct platform_driver tegra_gr3d_driver = { .pm = &tegra_gr3d_pm, }, .probe = gr3d_probe, - .remove_new = gr3d_remove, + .remove = gr3d_remove, }; diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 6bf2dae82ca0510ae36304c077946114fb570390..e705f8590c133a66285cbbce41461c98642ab746 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -1919,5 +1919,5 @@ struct platform_driver tegra_hdmi_driver = { .of_match_table = tegra_hdmi_of_match, }, .probe = tegra_hdmi_probe, - .remove_new = tegra_hdmi_remove, + .remove = tegra_hdmi_remove, }; diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index e0c2019a591b18338172119d7e8064819f7b66c5..fa6140fc37fb16df4b150e5ae9d8148f8f446cd7 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -1218,5 +1218,5 @@ struct platform_driver tegra_display_hub_driver = { .of_match_table = tegra_display_hub_of_match, }, .probe = tegra_display_hub_probe, - .remove_new = tegra_display_hub_remove, + .remove = tegra_display_hub_remove, }; diff --git a/drivers/gpu/drm/tegra/nvdec.c b/drivers/gpu/drm/tegra/nvdec.c index 4860790666af51de98a34942c61856bf3c766c8b..2d9a0a3f6c381d600189078036b0a5eb3d89d461 100644 --- a/drivers/gpu/drm/tegra/nvdec.c +++ b/drivers/gpu/drm/tegra/nvdec.c @@ -566,7 +566,7 @@ struct platform_driver tegra_nvdec_driver = { .pm = &nvdec_pm_ops }, .probe = nvdec_probe, - .remove_new = nvdec_remove, + .remove = nvdec_remove, }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index bad3b8fcc72692eaf89fe82e1a0c70abc00a6b79..802d2db7007afed483dd426f49c47e0e0987ac29 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -4040,5 +4040,5 @@ struct platform_driver tegra_sor_driver = { .pm = &tegra_sor_pm_ops, }, .probe = tegra_sor_probe, - .remove_new = tegra_sor_remove, + .remove = tegra_sor_remove, }; diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 73c356f1c90123d0053b2a4778adb1f870e379b7..332c9b563d3f4400cbf2e408914e0a8f5d395dc6 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -553,7 +553,7 @@ struct platform_driver tegra_vic_driver = { .pm = &vic_pm_ops }, .probe = vic_probe, - .remove_new = vic_remove, + .remove = vic_remove, }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 2428b9aaa0033468d681da892fb01e13086272a6..7c8fd6407d82461cb92ae6d2eaf3859f9982ef49 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -252,7 +252,7 @@ MODULE_DEVICE_TABLE(of, tidss_of_table); static struct platform_driver tidss_platform_driver = { .probe = tidss_probe, - .remove_new = tidss_remove, + .remove = tidss_remove, .shutdown = tidss_shutdown, .driver = { .name = "tidss", diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 8c9f3705aa6cfaf3481c76cd9b752ee865b9b2d6..6f0df8d6b90c1df352b280cf53751034462bb4d2 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -590,7 +590,7 @@ MODULE_DEVICE_TABLE(of, tilcdc_of_match); static struct platform_driver tilcdc_platform_driver = { .probe = tilcdc_pdev_probe, - .remove_new = tilcdc_pdev_remove, + .remove = tilcdc_pdev_remove, .shutdown = tilcdc_pdev_shutdown, .driver = { .name = "tilcdc", diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 5f2d1b6f9ee9e3508e95f908ce2748cafe128235..262f290d85d918553501071a5fc464d2a7cde16c 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -390,7 +390,7 @@ static const struct of_device_id panel_of_match[] = { static struct platform_driver panel_driver = { .probe = panel_probe, - .remove_new = panel_remove, + .remove = panel_remove, .driver = { .name = "tilcdc-panel", .of_match_table = panel_of_match, diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c index 81abedec435db804179dbf16ca2600413b506c4f..0cc68042a6d6b03b68b1c3d19dd30a785165d49c 100644 --- a/drivers/gpu/drm/tiny/arcpgu.c +++ b/drivers/gpu/drm/tiny/arcpgu.c @@ -423,7 +423,7 @@ MODULE_DEVICE_TABLE(of, arcpgu_of_table); static struct platform_driver arcpgu_platform_driver = { .probe = arcpgu_probe, - .remove_new = arcpgu_remove, + .remove = arcpgu_remove, .driver = { .name = "arcpgu", .of_match_table = arcpgu_of_table, diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c index 220c1244b3c0bb4eae569e18d08fbb012ad16e1e..9898eab5e9e2c583a13a8e4f493b9dc46e08828e 100644 --- a/drivers/gpu/drm/tiny/ofdrm.c +++ b/drivers/gpu/drm/tiny/ofdrm.c @@ -1398,7 +1398,7 @@ static struct platform_driver ofdrm_platform_driver = { .of_match_table = ofdrm_of_match_display, }, .probe = ofdrm_probe, - .remove_new = ofdrm_remove, + .remove = ofdrm_remove, }; module_platform_driver(ofdrm_platform_driver); diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index 3182d32f1b8f73136fe83717a484d34a620529e3..4d4f05dee244c1d5f0c57bebd50a3313d7d6c550 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -1066,7 +1066,7 @@ static struct platform_driver simpledrm_platform_driver = { .of_match_table = simpledrm_of_match_table, }, .probe = simpledrm_probe, - .remove_new = simpledrm_remove, + .remove = simpledrm_remove, }; module_platform_driver(simpledrm_platform_driver); diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c index b30340a2141d0523695e3951fc659d146fa42c31..c341aee37dd958db2e0fa1d8d393b94020776f44 100644 --- a/drivers/gpu/drm/tve200/tve200_drv.c +++ b/drivers/gpu/drm/tve200/tve200_drv.c @@ -267,7 +267,7 @@ static struct platform_driver tve200_driver = { .of_match_table = tve200_of_match, }, .probe = tve200_probe, - .remove_new = tve200_remove, + .remove = tve200_remove, .shutdown = tve200_shutdown, }; drm_module_platform_driver(tve200_driver); diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index fb35c5c3f1a7a8728b653c63aff3270043357a05..bee51c942a56882c6ce619e75880104d93a61685 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -391,7 +391,7 @@ static void v3d_platform_drm_remove(struct platform_device *pdev) static struct platform_driver v3d_platform_driver = { .probe = v3d_platform_drm_probe, - .remove_new = v3d_platform_drm_remove, + .remove = v3d_platform_drm_remove, .driver = { .name = "v3d", .of_match_table = v3d_of_match, diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 575900ee67a5f445cf3ca5b271ba03d1c5f20ad5..ee82a959d2799fa3066f8cc1e273ce38e463e734 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1465,7 +1465,7 @@ static void vc4_crtc_dev_remove(struct platform_device *pdev) struct platform_driver vc4_crtc_driver = { .probe = vc4_crtc_dev_probe, - .remove_new = vc4_crtc_dev_remove, + .remove = vc4_crtc_dev_remove, .driver = { .name = "vc4_crtc", .of_match_table = vc4_crtc_dt_match, diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index a382dc4654bdd211fea2d4b64eaec0c9b95726cb..960550c166d9d2e7fe0d44ab3a43ae4260c435a7 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c @@ -395,7 +395,7 @@ static void vc4_dpi_dev_remove(struct platform_device *pdev) struct platform_driver vc4_dpi_driver = { .probe = vc4_dpi_dev_probe, - .remove_new = vc4_dpi_dev_remove, + .remove = vc4_dpi_dev_remove, .driver = { .name = "vc4_dpi", .of_match_table = vc4_dpi_dt_match, diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index d47e5967592f30fda3daf0c9cbfd8e3f626af776..2c60d37275b044ad1cc7d4bafe490132489bf206 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -471,7 +471,7 @@ MODULE_DEVICE_TABLE(of, vc4_of_match); static struct platform_driver vc4_platform_driver = { .probe = vc4_platform_drm_probe, - .remove_new = vc4_platform_drm_remove, + .remove = vc4_platform_drm_remove, .shutdown = vc4_platform_drm_shutdown, .driver = { .name = "vc4-drm", diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index f5ccc1bf7a63700bfbfbb51db1b4b173438780c3..5eb293bdb363d81341b20c11b8041bdb34663a1b 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1841,7 +1841,7 @@ static void vc4_dsi_dev_remove(struct platform_device *pdev) struct platform_driver vc4_dsi_driver = { .probe = vc4_dsi_dev_probe, - .remove_new = vc4_dsi_dev_remove, + .remove = vc4_dsi_dev_remove, .driver = { .name = "vc4_dsi", .of_match_table = vc4_dsi_dt_match, diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 62b82b1eeb3694d1685969c49b2760cbbddc840e..e3818c48c9b8c8a861bb79c2ca7441540b26f216 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -3422,7 +3422,7 @@ static const struct dev_pm_ops vc4_hdmi_pm_ops = { struct platform_driver vc4_hdmi_driver = { .probe = vc4_hdmi_dev_probe, - .remove_new = vc4_hdmi_dev_remove, + .remove = vc4_hdmi_dev_remove, .driver = { .name = "vc4_hdmi", .of_match_table = vc4_hdmi_dt_match, diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 1edf6e3fa7e6412f4f7af42cd697be08ab829e0d..70623e6b91e9f5ba2e9052da437c362c32c0ac60 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -1153,7 +1153,7 @@ static const struct of_device_id vc4_hvs_dt_match[] = { struct platform_driver vc4_hvs_driver = { .probe = vc4_hvs_dev_probe, - .remove_new = vc4_hvs_dev_remove, + .remove = vc4_hvs_dev_remove, .driver = { .name = "vc4_hvs", .of_match_table = vc4_hvs_dt_match, diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index ffe1f7d1b911d35b0b3d50f4ae55634786b8bebd..3e38a1d2d55ec7a88cb08246c825fb6cf60ca949 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -585,7 +585,7 @@ static const struct of_device_id vc4_txp_dt_match[] = { struct platform_driver vc4_txp_driver = { .probe = vc4_txp_probe, - .remove_new = vc4_txp_remove, + .remove = vc4_txp_remove, .driver = { .name = "vc4_txp", .of_match_table = vc4_txp_dt_match, diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index 2423826c89eb6c4695378b5fe0d4671569b45dcf..bb09df5000bdaec4c2fb9d3b0745b4aaef4d9a9b 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -534,7 +534,7 @@ const struct of_device_id vc4_v3d_dt_match[] = { struct platform_driver vc4_v3d_driver = { .probe = vc4_v3d_dev_probe, - .remove_new = vc4_v3d_dev_remove, + .remove = vc4_v3d_dev_remove, .driver = { .name = "vc4_v3d", .of_match_table = vc4_v3d_dt_match, diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index eb64e881051e6dc62e0dd9e966d3864f7fce521a..06d702e879b053f8ee12ad7b3b3ab9dd44f9b97c 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -848,7 +848,7 @@ static void vc4_vec_dev_remove(struct platform_device *pdev) struct platform_driver vc4_vec_driver = { .probe = vc4_vec_dev_probe, - .remove_new = vc4_vec_dev_remove, + .remove = vc4_vec_dev_remove, .driver = { .name = "vc4_vec", .of_match_table = vc4_vec_dt_match, diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c index a17e62867f3b33cd1aafade244d387b43bb66b51..36d46b79562a3cc781a7323bc29f14bc7f6f7d54 100644 --- a/drivers/gpu/drm/vmwgfx/ttm_object.c +++ b/drivers/gpu/drm/vmwgfx/ttm_object.c @@ -54,7 +54,7 @@ #include #include -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); #define VMW_TTM_OBJECT_REF_HT_ORDER 10 diff --git a/drivers/gpu/drm/xe/tests/xe_live_test_mod.c b/drivers/gpu/drm/xe/tests/xe_live_test_mod.c index 5f14737c8210d2580253f3c2a94f7a97d32cfadc..0d36ab864ec02a0c507ff8183c42175c1da824be 100644 --- a/drivers/gpu/drm/xe/tests/xe_live_test_mod.c +++ b/drivers/gpu/drm/xe/tests/xe_live_test_mod.c @@ -18,4 +18,4 @@ kunit_test_suite(xe_mocs_test_suite); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("xe live kunit tests"); -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); diff --git a/drivers/gpu/drm/xe/tests/xe_test_mod.c b/drivers/gpu/drm/xe/tests/xe_test_mod.c index 875f3e6f965e0c7925df5beb962987790f1df2d0..93081bcf2ab001028aed96b10a21ddc109ca8c9a 100644 --- a/drivers/gpu/drm/xe/tests/xe_test_mod.c +++ b/drivers/gpu/drm/xe/tests/xe_test_mod.c @@ -7,4 +7,4 @@ MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("xe kunit tests"); -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index d2679c5d976b066ada22dfeb9b89a5c53bdf5e84..0b0cd6aa1d9fb4663454c0d921096a021dbf1de6 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -23,6 +23,7 @@ #include "xe_guc_submit.h" #include "xe_hw_engine.h" #include "xe_module.h" +#include "xe_pm.h" #include "xe_sched_job.h" #include "xe_vm.h" @@ -158,8 +159,11 @@ static void xe_devcoredump_deferred_snap_work(struct work_struct *work) { struct xe_devcoredump_snapshot *ss = container_of(work, typeof(*ss), work); struct xe_devcoredump *coredump = container_of(ss, typeof(*coredump), snapshot); + struct xe_device *xe = coredump_to_xe(coredump); unsigned int fw_ref; + xe_pm_runtime_get(xe); + /* keep going if fw fails as we still want to save the memory and SW data */ fw_ref = xe_force_wake_get(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL); if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) @@ -168,6 +172,8 @@ static void xe_devcoredump_deferred_snap_work(struct work_struct *work) xe_guc_exec_queue_snapshot_capture_delayed(ss->ge); xe_force_wake_put(gt_to_fw(ss->gt), fw_ref); + xe_pm_runtime_put(xe); + /* Calculate devcoredump size */ ss->read.size = __xe_devcoredump_read(NULL, INT_MAX, coredump); diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 0e2dd691bdae9c9addfe357dcb9eb87b436dd128..06d6db8b50f93fc5b4dae7a4962463dc79965508 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -350,7 +350,8 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, INIT_LIST_HEAD(&xe->pinned.external_vram); INIT_LIST_HEAD(&xe->pinned.evicted); - xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0); + xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", + WQ_MEM_RECLAIM); xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0); xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0); xe->destroy_wq = alloc_workqueue("xe-destroy-wq", 0, 0); diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c index 68f309f5e9815346009f1869086d3d2faff50fda..c5b95470fa3241fcff5084998429d25b2752fea5 100644 --- a/drivers/gpu/drm/xe/xe_dma_buf.c +++ b/drivers/gpu/drm/xe/xe_dma_buf.c @@ -20,7 +20,7 @@ #include "xe_ttm_vram_mgr.h" #include "xe_vm.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); static int xe_dma_buf_attach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 9a8564ea06b598fc225d4281012412665266c69f..6f4a9812b4f4a73d791afb3a83b12b0f36a578c5 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -767,17 +767,19 @@ static void disable_scheduling_deregister(struct xe_guc *guc, struct xe_exec_queue *q) { MAKE_SCHED_CONTEXT_ACTION(q, DISABLE); - struct xe_device *xe = guc_to_xe(guc); int ret; set_min_preemption_timeout(guc, q); smp_rmb(); - ret = wait_event_timeout(guc->ct.wq, !exec_queue_pending_enable(q) || - xe_guc_read_stopped(guc), HZ * 5); + ret = wait_event_timeout(guc->ct.wq, + (!exec_queue_pending_enable(q) && + !exec_queue_pending_disable(q)) || + xe_guc_read_stopped(guc), + HZ * 5); if (!ret) { struct xe_gpu_scheduler *sched = &q->guc->sched; - drm_warn(&xe->drm, "Pending enable failed to respond"); + xe_gt_warn(q->gt, "Pending enable/disable failed to respond\n"); xe_sched_submission_start(sched); xe_gt_reset_async(q->gt); xe_sched_tdr_queue_imm(sched); @@ -1099,7 +1101,8 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) * modifying state */ ret = wait_event_timeout(guc->ct.wq, - !exec_queue_pending_enable(q) || + (!exec_queue_pending_enable(q) && + !exec_queue_pending_disable(q)) || xe_guc_read_stopped(guc), HZ * 5); if (!ret || xe_guc_read_stopped(guc)) goto trigger_reset; @@ -1328,8 +1331,8 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg) if (guc_exec_queue_allowed_to_change_state(q) && !exec_queue_suspended(q) && exec_queue_enabled(q)) { - wait_event(guc->ct.wq, q->guc->resume_time != RESUME_PENDING || - xe_guc_read_stopped(guc)); + wait_event(guc->ct.wq, (q->guc->resume_time != RESUME_PENDING || + xe_guc_read_stopped(guc)) && !exec_queue_pending_disable(q)); if (!xe_guc_read_stopped(guc)) { s64 since_resume_ms = @@ -1866,16 +1869,29 @@ static void handle_sched_done(struct xe_guc *guc, struct xe_exec_queue *q, xe_gt_assert(guc_to_gt(guc), runnable_state == 0); xe_gt_assert(guc_to_gt(guc), exec_queue_pending_disable(q)); - clear_exec_queue_pending_disable(q); if (q->guc->suspend_pending) { suspend_fence_signal(q); + clear_exec_queue_pending_disable(q); } else { if (exec_queue_banned(q) || check_timeout) { smp_wmb(); wake_up_all(&guc->ct.wq); } - if (!check_timeout) + if (!check_timeout && exec_queue_destroyed(q)) { + /* + * Make sure to clear the pending_disable only + * after sampling the destroyed state. We want + * to ensure we don't trigger the unregister too + * early with something intending to only + * disable scheduling. The caller doing the + * destroy must wait for an ongoing + * pending_disable before marking as destroyed. + */ + clear_exec_queue_pending_disable(q); deregister_exec_queue(guc, q); + } else { + clear_exec_queue_pending_disable(q); + } } } } diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c index cfd31ae49cc1f71b9bbd51a27bc2fc67db410736..1b97d90aaddaf46103a5326f29671b5385d94008 100644 --- a/drivers/gpu/drm/xe/xe_migrate.c +++ b/drivers/gpu/drm/xe/xe_migrate.c @@ -209,7 +209,8 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, num_entries * XE_PAGE_SIZE, ttm_bo_type_kernel, XE_BO_FLAG_VRAM_IF_DGFX(tile) | - XE_BO_FLAG_PINNED); + XE_BO_FLAG_PINNED | + XE_BO_FLAG_PAGETABLE); if (IS_ERR(bo)) return PTR_ERR(bo); @@ -1350,6 +1351,7 @@ __xe_migrate_update_pgtables(struct xe_migrate *m, /* For sysmem PTE's, need to map them in our hole.. */ if (!IS_DGFX(xe)) { + u16 pat_index = xe->pat.idx[XE_CACHE_WB]; u32 ptes, ofs; ppgtt_ofs = NUM_KERNEL_PDE - 1; @@ -1409,7 +1411,7 @@ __xe_migrate_update_pgtables(struct xe_migrate *m, pt_bo->update_index = current_update; addr = vm->pt_ops->pte_encode_bo(pt_bo, 0, - XE_CACHE_WB, 0); + pat_index, 0); bb->cs[bb->len++] = lower_32_bits(addr); bb->cs[bb->len++] = upper_32_bits(addr); } diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index e6640283893f04914b7da11c3e8bfe49e3805ee4..6b7f77425c7f9f78b32757ba8532886847502a2c 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -174,7 +174,7 @@ static const struct xe_graphics_desc graphics_xelpg = { GENMASK(XE_HW_ENGINE_CCS3, XE_HW_ENGINE_CCS0) static const struct xe_graphics_desc graphics_xe2 = { - .name = "Xe2_LPG / Xe2_HPG", + .name = "Xe2_LPG / Xe2_HPG / Xe3_LPG", XE2_GFX_FEATURES, }; diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c index a90480c6aecf563a2eab9007b6af9a5a04f2c123..42f5bebd09e50c1b9bd3f3eae55245f530b7bed3 100644 --- a/drivers/gpu/drm/xe/xe_sync.c +++ b/drivers/gpu/drm/xe/xe_sync.c @@ -87,8 +87,12 @@ static void user_fence_worker(struct work_struct *w) drm_dbg(&ufence->xe->drm, "mmget_not_zero() failed, ufence wasn't signaled\n"); } - wake_up_all(&ufence->xe->ufence_wq); + /* + * Wake up waiters only after updating the ufence state, allowing the UMD + * to safely reuse the same ufence without encountering -EBUSY errors. + */ WRITE_ONCE(ufence->signalled, 1); + wake_up_all(&ufence->xe->ufence_wq); user_fence_put(ufence); } diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c index f5781939de9c357778b36b2592b88df5c91ca38f..07c4d184e7a1fbda476fa3a1b99f379068be0b9b 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c @@ -320,7 +320,7 @@ MODULE_DEVICE_TABLE(of, zynqmp_dpsub_of_match); static struct platform_driver zynqmp_dpsub_driver = { .probe = zynqmp_dpsub_probe, - .remove_new = zynqmp_dpsub_remove, + .remove = zynqmp_dpsub_remove, .shutdown = zynqmp_dpsub_shutdown, .driver = { .name = "zynqmp-dpsub", diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index be2ad7203d7b96111284ab4b00bcbb97c1d317fb..7b1d091f3c090c0cd0f01ef49647de232930312f 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -769,7 +769,7 @@ static struct platform_driver tegra_host1x_driver = { .pm = &host1x_pm_ops, }, .probe = host1x_probe, - .remove_new = host1x_remove, + .remove = host1x_remove, }; static struct platform_driver * const drivers[] = { diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 3535be9daa1f39ab00ddfda4898f6f97c6308dab..947323f4a234339fb79eeb08cf0865f42ef21521 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -1467,7 +1467,7 @@ static struct platform_driver imx_ipu_driver = { .of_match_table = imx_ipu_dt_ids, }, .probe = ipu_probe, - .remove_new = ipu_remove, + .remove = ipu_remove, }; static struct platform_driver * const drivers[] = { diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c index 41bd5dbd7356c0cfe073cd3a917c6160910f6a33..7aac70368b008064aab03f92adeffda4e30fe524 100644 --- a/drivers/gpu/ipu-v3/ipu-pre.c +++ b/drivers/gpu/ipu-v3/ipu-pre.c @@ -374,7 +374,7 @@ static const struct of_device_id ipu_pre_dt_ids[] = { struct platform_driver ipu_pre_drv = { .probe = ipu_pre_probe, - .remove_new = ipu_pre_remove, + .remove = ipu_pre_remove, .driver = { .name = "imx-ipu-pre", .of_match_table = ipu_pre_dt_ids, diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c index afb2d72e9175f39ae4228cf9af6d285e39d56920..d38d3ba54d722baf32e9048fe67bf62a6923c8b0 100644 --- a/drivers/gpu/ipu-v3/ipu-prg.c +++ b/drivers/gpu/ipu-v3/ipu-prg.c @@ -469,7 +469,7 @@ static const struct of_device_id ipu_prg_dt_ids[] = { struct platform_driver ipu_prg_drv = { .probe = ipu_prg_probe, - .remove_new = ipu_prg_remove, + .remove = ipu_prg_remove, .driver = { .name = "imx-ipu-prg", .pm = &prg_pm_ops, diff --git a/drivers/greybus/interface.c b/drivers/greybus/interface.c index d022bfb5e95d74cfe1fb1b6a10d02911f995f4c1..a0f3e942272155ebb613ea705b7eb36d08f521d2 100644 --- a/drivers/greybus/interface.c +++ b/drivers/greybus/interface.c @@ -780,7 +780,7 @@ const struct device_type greybus_interface_type = { * The position of interface within the Endo is encoded in "interface_id" * argument. * - * Returns a pointer to the new interfce or a null pointer if a + * Returns a pointer to the new interface or a null pointer if a * failure occurs due to memory exhaustion. */ struct gb_interface *gb_interface_create(struct gb_module *module, diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c index 961b7f35aa673618abbb7bf2edc18cd3ef7c90f4..2e96ec6a3073da6ab706debdb5a1066cf7b2ccc2 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -19,7 +19,7 @@ #include #include "hid_bpf_dispatch.h" -struct hid_ops *hid_ops; +const struct hid_ops *hid_ops; EXPORT_SYMBOL(hid_ops); u8 * @@ -352,7 +352,6 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz, { struct hid_report_enum *report_enum; struct hid_report *report; - struct hid_device *hdev; u32 report_len; /* check arguments */ @@ -371,9 +370,7 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz, if (*buf__sz < 1) return -EINVAL; - hdev = (struct hid_device *)ctx->hid; /* discard const */ - - report_enum = hdev->report_enum + rtype; + report_enum = ctx->hid->report_enum + rtype; report = hid_ops->hid_get_report(report_enum, buf); if (!report) return -EINVAL; @@ -402,7 +399,6 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, enum hid_report_type rtype, enum hid_class_request reqtype) { struct hid_bpf_ctx_kern *ctx_kern; - struct hid_device *hdev; size_t size = buf__sz; u8 *dma_data; int ret; @@ -429,13 +425,11 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, return -EINVAL; } - hdev = (struct hid_device *)ctx->hid; /* discard const */ - dma_data = kmemdup(buf, size, GFP_KERNEL); if (!dma_data) return -ENOMEM; - ret = hid_ops->hid_hw_raw_request(hdev, + ret = hid_ops->hid_hw_raw_request(ctx->hid, dma_data[0], dma_data, size, @@ -464,7 +458,6 @@ __bpf_kfunc int hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz) { struct hid_bpf_ctx_kern *ctx_kern; - struct hid_device *hdev; size_t size = buf__sz; u8 *dma_data; int ret; @@ -478,13 +471,11 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz) if (ret) return ret; - hdev = (struct hid_device *)ctx->hid; /* discard const */ - dma_data = kmemdup(buf, size, GFP_KERNEL); if (!dma_data) return -ENOMEM; - ret = hid_ops->hid_hw_output_report(hdev, dma_data, size, (u64)(long)ctx, true); + ret = hid_ops->hid_hw_output_report(ctx->hid, dma_data, size, (u64)(long)ctx, true); kfree(dma_data); return ret; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 98bef39642a9e3008e60a60fa887b8328ccd50f5..33a19197332488bd232dcee510d9da9ffec770bc 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -3064,7 +3064,7 @@ int hid_check_keys_pressed(struct hid_device *hid) EXPORT_SYMBOL_GPL(hid_check_keys_pressed); #ifdef CONFIG_HID_BPF -static struct hid_ops __hid_ops = { +static const struct hid_ops __hid_ops = { .hid_get_report = hid_get_report, .hid_hw_raw_request = __hid_hw_raw_request, .hid_hw_output_report = __hid_hw_output_report, diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c index 22683ec819aacae22844f22017473dd7fd83e06b..0f292b5d3e26d27b769a9044d04dd71c5d363af2 100644 --- a/drivers/hid/hid-google-hammer.c +++ b/drivers/hid/hid-google-hammer.c @@ -284,7 +284,7 @@ MODULE_DEVICE_TABLE(of, cbas_ec_of_match); static struct platform_driver cbas_ec_driver = { .probe = cbas_ec_probe, - .remove_new = cbas_ec_remove, + .remove = cbas_ec_remove, .driver = { .name = "cbas_ec", .acpi_match_table = ACPI_PTR(cbas_ec_acpi_ids), diff --git a/drivers/hid/hid-sensor-custom.c b/drivers/hid/hid-sensor-custom.c index 617ae240396d58077198d98117b2cb5c1ec95225..761760668f6d90d886ee18f1983e0e301f374c04 100644 --- a/drivers/hid/hid-sensor-custom.c +++ b/drivers/hid/hid-sensor-custom.c @@ -1065,7 +1065,7 @@ static struct platform_driver hid_sensor_custom_platform_driver = { .name = KBUILD_MODNAME, }, .probe = hid_sensor_custom_probe, - .remove_new = hid_sensor_custom_remove, + .remove = hid_sensor_custom_remove, }; module_platform_driver(hid_sensor_custom_platform_driver); diff --git a/drivers/hid/hid-uclogic-rdesc-test.c b/drivers/hid/hid-uclogic-rdesc-test.c index d6b18213f45f2c3d2813e0e635c989726127119b..066df622b6f2e49ea01ea07a8b006801ffa2181f 100644 --- a/drivers/hid/hid-uclogic-rdesc-test.c +++ b/drivers/hid/hid-uclogic-rdesc-test.c @@ -9,7 +9,7 @@ #include #include "./hid-uclogic-rdesc.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); struct uclogic_template_case { const char *name; diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 43664a24176fca008977b860537817b4941b950e..4e87380d3edd6b845e57baffc41ad0bee2993b8c 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -414,7 +414,19 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state) i2c_hid_dbg(ihid, "%s\n", __func__); + /* + * Some STM-based devices need 400µs after a rising clock edge to wake + * from deep sleep, in which case the first request will fail due to + * the address not being acknowledged. Try after a short sleep to see + * if the device came alive on the bus. Certain Weida Tech devices also + * need this. + */ ret = i2c_hid_set_power_command(ihid, power_state); + if (ret && power_state == I2C_HID_PWR_ON) { + usleep_range(400, 500); + ret = i2c_hid_set_power_command(ihid, I2C_HID_PWR_ON); + } + if (ret) dev_err(&ihid->client->dev, "failed to change power setting.\n"); @@ -976,14 +988,6 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid) enable_irq(client->irq); - /* Make sure the device is awake on the bus */ - ret = i2c_hid_probe_address(ihid); - if (ret < 0) { - dev_err(&client->dev, "nothing at address after resume: %d\n", - ret); - return -ENXIO; - } - /* On Goodix 27c6:0d42 wait extra time before device wakeup. * It's not clear why but if we send wakeup too early, the device will * never trigger input interrupts. diff --git a/drivers/hid/surface-hid/surface_kbd.c b/drivers/hid/surface-hid/surface_kbd.c index 383200d9121ae8be1bc347d427d3b0220e72e818..0be01b5e7425854a5b9a7be14e31c6aab28c80b8 100644 --- a/drivers/hid/surface-hid/surface_kbd.c +++ b/drivers/hid/surface-hid/surface_kbd.c @@ -284,7 +284,7 @@ MODULE_DEVICE_TABLE(acpi, surface_kbd_match); static struct platform_driver surface_kbd_driver = { .probe = surface_kbd_probe, - .remove_new = surface_kbd_remove, + .remove = surface_kbd_remove, .driver = { .name = "surface_keyboard", .acpi_match_table = surface_kbd_match, diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 2bc45b24075c3fe4b70ef222bbd21a4ee11eeb21..9843b52bd017a02a0dfdac4f5b7e2e29062b26e3 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2241,7 +2241,8 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix) if (hid_is_usb(wacom->hdev)) { struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent); struct usb_device *dev = interface_to_usbdev(intf); - product_name = dev->product; + if (dev->product != NULL) + product_name = dev->product; } if (wacom->hdev->bus == BUS_I2C) { diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c index 15cb759151e66991524c594ded1fc4212e973972..eeacc427fd6590e2c33bdba77ebf59d945d785d4 100644 --- a/drivers/hsi/controllers/omap_ssi_core.c +++ b/drivers/hsi/controllers/omap_ssi_core.c @@ -607,7 +607,7 @@ MODULE_DEVICE_TABLE(of, omap_ssi_of_match); static struct platform_driver ssi_pdriver = { .probe = ssi_probe, - .remove_new = ssi_remove, + .remove = ssi_remove, .driver = { .name = "omap_ssi", .pm = DEV_PM_OPS, diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index f0b3eca7376e44bb778c3cd7596ffdda44eb64b0..aeb92b803a177a8e7a54e29eb8b7a119d8202a0c 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c @@ -1385,7 +1385,7 @@ MODULE_DEVICE_TABLE(of, omap_ssi_port_of_match); struct platform_driver ssi_port_pdriver = { .probe = ssi_port_probe, - .remove_new = ssi_port_remove, + .remove = ssi_port_remove, .driver = { .name = "omap_ssi_port", .of_match_table = omap_ssi_port_of_match, diff --git a/drivers/hte/hte-tegra194-test.c b/drivers/hte/hte-tegra194-test.c index df631b5100d230b0eade7dc5d3b0078ee2538a07..f890b79723af36544dd7819576ec1b4be34f071c 100644 --- a/drivers/hte/hte-tegra194-test.c +++ b/drivers/hte/hte-tegra194-test.c @@ -226,7 +226,7 @@ static void tegra_hte_test_remove(struct platform_device *pdev) static struct platform_driver tegra_hte_test_driver = { .probe = tegra_hte_test_probe, - .remove_new = tegra_hte_test_remove, + .remove = tegra_hte_test_remove, .driver = { .name = "tegra_hte_test", .of_match_table = tegra_hte_test_of_match, diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 9b15f7daf5059750e17ea3607b52dee967c1c059..6d89d37b069add5f26a408d6291ca441394d7d2d 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -2560,7 +2560,7 @@ static const struct dev_pm_ops vmbus_bus_pm = { static struct platform_driver vmbus_platform_driver = { .probe = vmbus_platform_driver_probe, - .remove_new = vmbus_platform_driver_remove, + .remove = vmbus_platform_driver_remove, .driver = { .name = "vmbus", .acpi_match_table = ACPI_PTR(vmbus_acpi_device_ids), diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 49b366254529fe6c03e8af6870ebd269cdcfd70c..bbb9cc44e29fbc635706db5bed21f3b8a1cd4987 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -1074,7 +1074,7 @@ hwmon_device_register_for_thermal(struct device *dev, const char *name, return __hwmon_device_register(dev, name, drvdata, NULL, NULL); } -EXPORT_SYMBOL_NS_GPL(hwmon_device_register_for_thermal, HWMON_THERMAL); +EXPORT_SYMBOL_NS_GPL(hwmon_device_register_for_thermal, "HWMON_THERMAL"); /** * hwmon_device_register - register w/ hwmon diff --git a/drivers/hwmon/intel-m10-bmc-hwmon.c b/drivers/hwmon/intel-m10-bmc-hwmon.c index e221f2c1f33238db349f053774e07172e7cacf0e..aa01a4bedc21b518616e2ca2574a17a1fb209e48 100644 --- a/drivers/hwmon/intel-m10-bmc-hwmon.c +++ b/drivers/hwmon/intel-m10-bmc-hwmon.c @@ -787,4 +787,4 @@ MODULE_DEVICE_TABLE(platform, intel_m10bmc_hwmon_ids); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("Intel MAX 10 BMC hardware monitor"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); +MODULE_IMPORT_NS("INTEL_M10_BMC_CORE"); diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c index ee04795b98aabe70f7900da4d3217433943a26cf..c243b51837d2fb6e85296220807fa252f85f7fbc 100644 --- a/drivers/hwmon/nct6775-core.c +++ b/drivers/hwmon/nct6775-core.c @@ -57,7 +57,7 @@ #include "nct6775.h" #undef DEFAULT_SYMBOL_NAMESPACE -#define DEFAULT_SYMBOL_NAMESPACE HWMON_NCT6775 +#define DEFAULT_SYMBOL_NAMESPACE "HWMON_NCT6775" #define USE_ALTERNATE diff --git a/drivers/hwmon/nct6775-i2c.c b/drivers/hwmon/nct6775-i2c.c index aff69fa50461e3681a053ef3b6611ee4dc37d48d..ba71d776a2911b44ab44a00e35317d0ee089b350 100644 --- a/drivers/hwmon/nct6775-i2c.c +++ b/drivers/hwmon/nct6775-i2c.c @@ -184,4 +184,4 @@ module_i2c_driver(nct6775_i2c_driver); MODULE_AUTHOR("Zev Weiss "); MODULE_DESCRIPTION("I2C driver for NCT6775F and compatible chips"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(HWMON_NCT6775); +MODULE_IMPORT_NS("HWMON_NCT6775"); diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c index 1218a3b449a801da121a960ab5726932dd8bf260..0a040364b5127eb0206b468fa4fb16fe21a6eef0 100644 --- a/drivers/hwmon/nct6775-platform.c +++ b/drivers/hwmon/nct6775-platform.c @@ -1622,7 +1622,7 @@ static void __exit sensors_nct6775_platform_exit(void) MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("Platform driver for NCT6775F and compatible chips"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(HWMON_NCT6775); +MODULE_IMPORT_NS("HWMON_NCT6775"); module_init(sensors_nct6775_platform_init); module_exit(sensors_nct6775_platform_exit); diff --git a/drivers/hwmon/peci/cputemp.c b/drivers/hwmon/peci/cputemp.c index 5a682195b98f4c37b5801c64ea55b57bbb9933b1..c7112dbf008b77ff53f0d72ddfe1f05da3c342d7 100644 --- a/drivers/hwmon/peci/cputemp.c +++ b/drivers/hwmon/peci/cputemp.c @@ -607,4 +607,4 @@ MODULE_AUTHOR("Jae Hyun Yoo "); MODULE_AUTHOR("Iwona Winiarska "); MODULE_DESCRIPTION("PECI cputemp driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PECI_CPU); +MODULE_IMPORT_NS("PECI_CPU"); diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c index 4a72e9712408e27349140f14fcb48e098f72a91e..d6762259dd69c1a0dceefc7239231609b1d57130 100644 --- a/drivers/hwmon/peci/dimmtemp.c +++ b/drivers/hwmon/peci/dimmtemp.c @@ -666,4 +666,4 @@ MODULE_AUTHOR("Jae Hyun Yoo "); MODULE_AUTHOR("Iwona Winiarska "); MODULE_DESCRIPTION("PECI dimmtemp driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PECI_CPU); +MODULE_IMPORT_NS("PECI_CPU"); diff --git a/drivers/hwmon/pmbus/acbel-fsg032.c b/drivers/hwmon/pmbus/acbel-fsg032.c index e0c55fd8f3a6dc1cd84bb23fcd5893c053cf2a4b..9f07fb4abaffd44834f3861f7e1d3780e48c5c0c 100644 --- a/drivers/hwmon/pmbus/acbel-fsg032.c +++ b/drivers/hwmon/pmbus/acbel-fsg032.c @@ -120,4 +120,4 @@ module_i2c_driver(acbel_fsg032_driver); MODULE_AUTHOR("Lakshmi Yadlapati"); MODULE_DESCRIPTION("PMBus driver for AcBel Power System power supplies"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/adm1266.c b/drivers/hwmon/pmbus/adm1266.c index 2c4d94cc872943d5088563d03ce7022fde6a118d..d90f8f80be8e0045dbef594612a796f24637e9d1 100644 --- a/drivers/hwmon/pmbus/adm1266.c +++ b/drivers/hwmon/pmbus/adm1266.c @@ -509,4 +509,4 @@ module_i2c_driver(adm1266_driver); MODULE_AUTHOR("Alexandru Tachici "); MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1266"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 59ffc08289bdf734a5a2232ba0a922587b15bee7..127593e10a03f2a490daaf304d7f44b0ca229a67 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -866,4 +866,4 @@ module_i2c_driver(adm1275_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/adp1050.c b/drivers/hwmon/pmbus/adp1050.c index 20f22730fc01898ef868e45851b758fa5cf8f95e..ef46c880b168bd0378030fda2397d075221f3723 100644 --- a/drivers/hwmon/pmbus/adp1050.c +++ b/drivers/hwmon/pmbus/adp1050.c @@ -53,4 +53,4 @@ module_i2c_driver(adp1050_driver); MODULE_AUTHOR("Radu Sabau "); MODULE_DESCRIPTION("Analog Devices ADP1050 HWMON PMBus Driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/bel-pfe.c b/drivers/hwmon/pmbus/bel-pfe.c index 7c5f4b10a7c14ec3a8166be883d0a8a7f05ac8eb..ddf9d9a2958c4fdd31d46f4eefd4fe60d2838967 100644 --- a/drivers/hwmon/pmbus/bel-pfe.c +++ b/drivers/hwmon/pmbus/bel-pfe.c @@ -129,4 +129,4 @@ module_i2c_driver(pfe_pmbus_driver); MODULE_AUTHOR("Tao Ren "); MODULE_DESCRIPTION("PMBus driver for BEL PFE Family Power Supplies"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/bpa-rs600.c b/drivers/hwmon/pmbus/bpa-rs600.c index 0dce26c355565815130e975295118b095d5a2caf..6c3875ba37a08179550e32c72965f7d8bb895c14 100644 --- a/drivers/hwmon/pmbus/bpa-rs600.c +++ b/drivers/hwmon/pmbus/bpa-rs600.c @@ -205,4 +205,4 @@ module_i2c_driver(bpa_rs600_driver); MODULE_AUTHOR("Chris Packham"); MODULE_DESCRIPTION("PMBus driver for BluTek BPA-RS600"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/delta-ahe50dc-fan.c b/drivers/hwmon/pmbus/delta-ahe50dc-fan.c index 4dd3b6686d6a44288f3f368daa6c09d20e2cd780..3850eaea75da2a4be91a21d40ad80f25f6dbfe5f 100644 --- a/drivers/hwmon/pmbus/delta-ahe50dc-fan.c +++ b/drivers/hwmon/pmbus/delta-ahe50dc-fan.c @@ -127,4 +127,4 @@ module_i2c_driver(ahe50dc_fan_driver); MODULE_AUTHOR("Zev Weiss "); MODULE_DESCRIPTION("Driver for Delta AHE-50DC power shelf fan control module"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/dps920ab.c b/drivers/hwmon/pmbus/dps920ab.c index 04e0d598a6e54442e37292e7d5964a9d5ae59d14..cc5aac9dfdb3c867fb32d7510ce7c1dc0794251d 100644 --- a/drivers/hwmon/pmbus/dps920ab.c +++ b/drivers/hwmon/pmbus/dps920ab.c @@ -203,4 +203,4 @@ module_i2c_driver(dps920ab_driver); MODULE_AUTHOR("Robert Marko "); MODULE_DESCRIPTION("PMBus driver for Delta DPS920AB PSU"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/fsp-3y.c b/drivers/hwmon/pmbus/fsp-3y.c index 72a7c261ef068db4166591bbad3cbbb3f9c98d0d..a4dc09e2ef75acf06233b86d84821c3bc8e7cd62 100644 --- a/drivers/hwmon/pmbus/fsp-3y.c +++ b/drivers/hwmon/pmbus/fsp-3y.c @@ -291,4 +291,4 @@ module_i2c_driver(fsp3y_driver); MODULE_AUTHOR("Václav Kubernát"); MODULE_DESCRIPTION("PMBus driver for FSP/3Y-Power power supplies"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c index 1ba4c5e95820f23243b70f7d6c5bc15993637ac3..d05ef7a968a965290b58fa0a0b156810b5bbf2fb 100644 --- a/drivers/hwmon/pmbus/ibm-cffps.c +++ b/drivers/hwmon/pmbus/ibm-cffps.c @@ -614,4 +614,4 @@ module_i2c_driver(ibm_cffps_driver); MODULE_AUTHOR("Eddie James"); MODULE_DESCRIPTION("PMBus driver for IBM Common Form Factor power supplies"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/inspur-ipsps.c b/drivers/hwmon/pmbus/inspur-ipsps.c index 3e3cc9a0f116e771b559e7d03a0ff702b368b5d5..074e0f164ee1c9d308e6a6d34209f48895d1a30f 100644 --- a/drivers/hwmon/pmbus/inspur-ipsps.c +++ b/drivers/hwmon/pmbus/inspur-ipsps.c @@ -224,4 +224,4 @@ module_i2c_driver(ipsps_driver); MODULE_AUTHOR("John Wang"); MODULE_DESCRIPTION("PMBus driver for Inspur Power System power supplies"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/ir35221.c b/drivers/hwmon/pmbus/ir35221.c index 503be59c6c7f195726c79dd7b869c0065a782c1e..46d8f334d49a453e8a8abac9fa053b54409b5001 100644 --- a/drivers/hwmon/pmbus/ir35221.c +++ b/drivers/hwmon/pmbus/ir35221.c @@ -145,4 +145,4 @@ module_i2c_driver(ir35221_driver); MODULE_AUTHOR("Samuel Mendoza-Jonas "); MODULE_DESCRIPTION("PMBus driver for Infineon IR36021"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/ir38064.c b/drivers/hwmon/pmbus/ir38064.c index d4bcc9c39774ec5bd0ae8fc0e85e102302c51d85..7b4188e8bf48303039c77c9d33b83cf926fd01c8 100644 --- a/drivers/hwmon/pmbus/ir38064.c +++ b/drivers/hwmon/pmbus/ir38064.c @@ -87,4 +87,4 @@ module_i2c_driver(ir38064_driver); MODULE_AUTHOR("Maxim Sloyko "); MODULE_DESCRIPTION("PMBus driver for Infineon IR38064 and compatible chips"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/irps5401.c b/drivers/hwmon/pmbus/irps5401.c index f0bdf55c95bf4d9f5a4cd12b1e85a1fe8119eb95..43674c64841d5cb968241ae44f56057d215c7690 100644 --- a/drivers/hwmon/pmbus/irps5401.c +++ b/drivers/hwmon/pmbus/irps5401.c @@ -63,4 +63,4 @@ module_i2c_driver(irps5401_driver); MODULE_AUTHOR("Robert Hancock"); MODULE_DESCRIPTION("PMBus driver for Infineon IRPS5401"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c index 97cc951a13a4948edd1f76b38cc9cfb778eafe84..2af921039309a6aacf1bcd4830dd729c2e407fd0 100644 --- a/drivers/hwmon/pmbus/isl68137.c +++ b/drivers/hwmon/pmbus/isl68137.c @@ -532,4 +532,4 @@ module_i2c_driver(isl68137_driver); MODULE_AUTHOR("Maxim Sloyko "); MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index c36c124d1a2d86f502f66a89165d54e3942258ce..40b0dda32ea6f06c1867834e6b77dea71974a7f7 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -569,4 +569,4 @@ module_i2c_driver(lm25066_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/lt7182s.c b/drivers/hwmon/pmbus/lt7182s.c index aebd97af274172bf320b3e350c19a6cf997ed017..9d6d50f39bd6531ae84f361cc069bfe80748d33a 100644 --- a/drivers/hwmon/pmbus/lt7182s.c +++ b/drivers/hwmon/pmbus/lt7182s.c @@ -192,4 +192,4 @@ module_i2c_driver(lt7182s_driver); MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("PMBus driver for Analog Devices LT7182S"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index a6eb4d4b5487e049ce36f38374dea802618d4eff..4c306943383ab368ad5f9700c1e09bc873822e44 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -952,4 +952,4 @@ module_i2c_driver(ltc2978_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for LTC2978 and compatible chips"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/ltc3815.c b/drivers/hwmon/pmbus/ltc3815.c index f58a8cedb0d7e3f25f747fbac818288a6ca0ccbe..824c16a75e2c01f797030be6354cec6a69498ca0 100644 --- a/drivers/hwmon/pmbus/ltc3815.c +++ b/drivers/hwmon/pmbus/ltc3815.c @@ -208,4 +208,4 @@ module_i2c_driver(ltc3815_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for LTC3815"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max15301.c b/drivers/hwmon/pmbus/max15301.c index f5367a7bc0f519c17f92bd20c7fc75c88a04512a..50dfd477772ffe680446b5c0bf31d45a70042d27 100644 --- a/drivers/hwmon/pmbus/max15301.c +++ b/drivers/hwmon/pmbus/max15301.c @@ -97,4 +97,4 @@ module_i2c_driver(max15301_driver); MODULE_AUTHOR("Erik Rosen "); MODULE_DESCRIPTION("PMBus driver for Maxim MAX15301"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max16064.c b/drivers/hwmon/pmbus/max16064.c index 98e2b5dd58414d0d94bb235cde84fa9df3321861..eb84915c2a83de87f24d636d3359e7895ed4d7a9 100644 --- a/drivers/hwmon/pmbus/max16064.c +++ b/drivers/hwmon/pmbus/max16064.c @@ -111,4 +111,4 @@ module_i2c_driver(max16064_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max16601.c b/drivers/hwmon/pmbus/max16601.c index 3ab2195046007a5c9e9611616322eaf10f17ec58..d696e506aafba3c0a6c6a70250775bfbcc76b4eb 100644 --- a/drivers/hwmon/pmbus/max16601.c +++ b/drivers/hwmon/pmbus/max16601.c @@ -366,4 +366,4 @@ module_i2c_driver(max16601_driver); MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("PMBus driver for Maxim MAX16601"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max20730.c b/drivers/hwmon/pmbus/max20730.c index d56ec24764fdd6672d9ed18bf6b61606de363fc7..95869d198ecf0a1f171d82a59e4fbc4696a390ee 100644 --- a/drivers/hwmon/pmbus/max20730.c +++ b/drivers/hwmon/pmbus/max20730.c @@ -787,4 +787,4 @@ module_i2c_driver(max20730_driver); MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("PMBus driver for Maxim MAX20710 / MAX20730 / MAX20734 / MAX20743"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max20751.c b/drivers/hwmon/pmbus/max20751.c index 8f23c1eb559e89fb26866016bf0a92f8a0223983..ac8c431221338becad83548d6c18bf73cf779444 100644 --- a/drivers/hwmon/pmbus/max20751.c +++ b/drivers/hwmon/pmbus/max20751.c @@ -51,4 +51,4 @@ module_i2c_driver(max20751_driver); MODULE_AUTHOR("Guenter Roeck "); MODULE_DESCRIPTION("PMBus driver for Maxim MAX20751"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max31785.c b/drivers/hwmon/pmbus/max31785.c index 09218dba89658e0fc590239539f0f6da6f56329d..1f94d38a163719d73d25044d2269ae91f045d448 100644 --- a/drivers/hwmon/pmbus/max31785.c +++ b/drivers/hwmon/pmbus/max31785.c @@ -549,4 +549,4 @@ module_i2c_driver(max31785_driver); MODULE_AUTHOR("Andrew Jeffery "); MODULE_DESCRIPTION("PMBus driver for the Maxim MAX31785"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index fe7f6b1b09851e725c0d6f2f5616f9aa470d9339..c9dda33831ff24e7b5e2fd1956a65e6bd2bfcbb9 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c @@ -529,4 +529,4 @@ module_i2c_driver(max34440_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c index 5d5b6aeefa804d2d1705ac70eec20756d8cfba1e..b3a2a7492bbfcf2147215c39e795f5e58ba3e606 100644 --- a/drivers/hwmon/pmbus/max8688.c +++ b/drivers/hwmon/pmbus/max8688.c @@ -191,4 +191,4 @@ module_i2c_driver(max8688_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp2856.c b/drivers/hwmon/pmbus/mp2856.c index 41bb866670912827b759e0569286b971904cee5a..e83c70a3583f80a4e7246a045935f712b6adeab2 100644 --- a/drivers/hwmon/pmbus/mp2856.c +++ b/drivers/hwmon/pmbus/mp2856.c @@ -463,4 +463,4 @@ module_i2c_driver(mp2856_driver); MODULE_AUTHOR("Peter Yin "); MODULE_DESCRIPTION("PMBus driver for MPS MP2856/MP2857 device"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp2888.c b/drivers/hwmon/pmbus/mp2888.c index 3b45f126b611ce9663dd927f779f920ab4da9375..772a623ca7d0a1788549bad144ba3e99df210487 100644 --- a/drivers/hwmon/pmbus/mp2888.c +++ b/drivers/hwmon/pmbus/mp2888.c @@ -404,4 +404,4 @@ module_i2c_driver(mp2888_driver); MODULE_AUTHOR("Vadim Pasternak "); MODULE_DESCRIPTION("PMBus driver for MPS MP2888 device"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp2891.c b/drivers/hwmon/pmbus/mp2891.c index 94ab4ae5fba0b486f95d48668a33d4fcdeed6108..f8f4c91ec23ccde85ad84f21fbb05f303df06185 100644 --- a/drivers/hwmon/pmbus/mp2891.c +++ b/drivers/hwmon/pmbus/mp2891.c @@ -597,4 +597,4 @@ module_i2c_driver(mp2891_driver); MODULE_AUTHOR("Noah Wang "); MODULE_DESCRIPTION("PMBus driver for MPS MP2891"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp2975.c b/drivers/hwmon/pmbus/mp2975.c index 280bb12f762c3dc1d08350a1cf49395ef9c6b6d4..c31982d851962318427c5393340a8a372a3ce950 100644 --- a/drivers/hwmon/pmbus/mp2975.c +++ b/drivers/hwmon/pmbus/mp2975.c @@ -1101,4 +1101,4 @@ module_i2c_driver(mp2975_driver); MODULE_AUTHOR("Vadim Pasternak "); MODULE_DESCRIPTION("PMBus driver for MPS MP2975 device"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp2993.c b/drivers/hwmon/pmbus/mp2993.c index 63691dac2281d89274a31f812c372a9be4b65cd6..81c84fc8ed47d2bfe46bc0d1e4adbc94386fddaf 100644 --- a/drivers/hwmon/pmbus/mp2993.c +++ b/drivers/hwmon/pmbus/mp2993.c @@ -258,4 +258,4 @@ module_i2c_driver(mp2993_driver); MODULE_AUTHOR("Noah Wang "); MODULE_DESCRIPTION("PMBus driver for MPS MP2993"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp5023.c b/drivers/hwmon/pmbus/mp5023.c index 21acb7fd9a1afe6c346b4a2eda7df9a6962710b2..c466d67e9a8f90ce09ec8d2b43741b166a679580 100644 --- a/drivers/hwmon/pmbus/mp5023.c +++ b/drivers/hwmon/pmbus/mp5023.c @@ -64,4 +64,4 @@ module_i2c_driver(mp5023_driver); MODULE_AUTHOR("Howard Chiu "); MODULE_DESCRIPTION("PMBus driver for MPS MP5023 HSC"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp5920.c b/drivers/hwmon/pmbus/mp5920.c index f6d7527ade7d909fdaef3326b9bca66514c975bb..319ae2721bcf4569976ee5cd951c4b7fde836a73 100644 --- a/drivers/hwmon/pmbus/mp5920.c +++ b/drivers/hwmon/pmbus/mp5920.c @@ -87,4 +87,4 @@ MODULE_AUTHOR("Tony Ao "); MODULE_AUTHOR("Alex Vdovydchenko "); MODULE_DESCRIPTION("PMBus driver for MP5920 HSC"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp5990.c b/drivers/hwmon/pmbus/mp5990.c index 5d1d5eac89daa931bcd992de0cb05fce87abba20..4ce381a394807e786a2aa10dd75588840cb8fbc5 100644 --- a/drivers/hwmon/pmbus/mp5990.c +++ b/drivers/hwmon/pmbus/mp5990.c @@ -176,4 +176,4 @@ module_i2c_driver(mp5990_driver); MODULE_AUTHOR("Peter Yin "); MODULE_DESCRIPTION("PMBus driver for MP5990 HSC"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mp9941.c b/drivers/hwmon/pmbus/mp9941.c index 8ab5fc4d409260e16c8c9acc312345d70b3fb2db..42ca6748777afdc126deb76693ecd55530e09f77 100644 --- a/drivers/hwmon/pmbus/mp9941.c +++ b/drivers/hwmon/pmbus/mp9941.c @@ -316,4 +316,4 @@ module_i2c_driver(mp9941_driver); MODULE_AUTHOR("Noah Wang "); MODULE_DESCRIPTION("PMBus driver for MPS MP9941"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mpq7932.c b/drivers/hwmon/pmbus/mpq7932.c index 2dcb6da853bd342731932e69b2c384d22bc93b50..c1e2d0cb2fd086726ba3897affccaf273bfcb912 100644 --- a/drivers/hwmon/pmbus/mpq7932.c +++ b/drivers/hwmon/pmbus/mpq7932.c @@ -164,4 +164,4 @@ module_i2c_driver(mpq7932_regulator_driver); MODULE_AUTHOR("Saravanan Sekar "); MODULE_DESCRIPTION("MPQ7932 PMIC regulator driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/mpq8785.c b/drivers/hwmon/pmbus/mpq8785.c index 0d16491cd7706fe1732aa311ebb5df769056b014..331c274ca89226c7b71d3a4ddeda2fcfd9174586 100644 --- a/drivers/hwmon/pmbus/mpq8785.c +++ b/drivers/hwmon/pmbus/mpq8785.c @@ -87,4 +87,4 @@ module_i2c_driver(mpq8785_driver); MODULE_AUTHOR("Charles Hsu "); MODULE_DESCRIPTION("PMBus driver for MPS MPQ8785"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/pim4328.c b/drivers/hwmon/pmbus/pim4328.c index 31d9ae06379a1ae000342c5686e852d4131e5861..aa98284bbdd847f47e8e440cb4b2e4fb92ed95de 100644 --- a/drivers/hwmon/pmbus/pim4328.c +++ b/drivers/hwmon/pmbus/pim4328.c @@ -230,4 +230,4 @@ module_i2c_driver(pim4328_driver); MODULE_AUTHOR("Erik Rosen "); MODULE_DESCRIPTION("PMBus driver for PIM4006, PIM4328, PIM4820 power interface modules"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/pli1209bc.c b/drivers/hwmon/pmbus/pli1209bc.c index 178e0cdb7887efcd6d24f137baa4367d8ede0a6c..569b61dc1a32a6534926e0aa2c3ac5dc4d9b3c7c 100644 --- a/drivers/hwmon/pmbus/pli1209bc.c +++ b/drivers/hwmon/pmbus/pli1209bc.c @@ -145,4 +145,4 @@ module_i2c_driver(pli1209bc_driver); MODULE_AUTHOR("Marcello Sylvester Bauer "); MODULE_DESCRIPTION("PMBus driver for Vicor PLI1209BC"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/pm6764tr.c b/drivers/hwmon/pmbus/pm6764tr.c index 23f15b608dcf1282a5642a2504f89e514ec6915a..c96c0aecb920a80ccbb8af47e9e0db3a71156e9d 100644 --- a/drivers/hwmon/pmbus/pm6764tr.c +++ b/drivers/hwmon/pmbus/pm6764tr.c @@ -73,4 +73,4 @@ module_i2c_driver(pm6764tr_driver); MODULE_AUTHOR("Charles Hsu"); MODULE_DESCRIPTION("PMBus driver for ST PM6764TR"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c index ec40c5c599543a77c0820a34b17426b3b9f951ee..77cf268e7d2d6d689ae11078da46e93b829bdc17 100644 --- a/drivers/hwmon/pmbus/pmbus.c +++ b/drivers/hwmon/pmbus/pmbus.c @@ -261,4 +261,4 @@ module_i2c_driver(pmbus_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("Generic PMBus driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index a0109296a9949bfe3a351cbb13787011ed54254b..a1375cb6b648c15835c1dde611af2df6b31e774b 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -150,7 +150,7 @@ void pmbus_clear_cache(struct i2c_client *client) for (sensor = data->sensors; sensor; sensor = sensor->next) sensor->data = -ENODATA; } -EXPORT_SYMBOL_NS_GPL(pmbus_clear_cache, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_clear_cache, "PMBUS"); void pmbus_set_update(struct i2c_client *client, u8 reg, bool update) { @@ -161,7 +161,7 @@ void pmbus_set_update(struct i2c_client *client, u8 reg, bool update) if (sensor->reg == reg) sensor->update = update; } -EXPORT_SYMBOL_NS_GPL(pmbus_set_update, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_set_update, "PMBUS"); /* Some chips need a delay between accesses. */ static void pmbus_wait(struct i2c_client *client) @@ -236,7 +236,7 @@ int pmbus_set_page(struct i2c_client *client, int page, int phase) return 0; } -EXPORT_SYMBOL_NS_GPL(pmbus_set_page, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_set_page, "PMBUS"); int pmbus_write_byte(struct i2c_client *client, int page, u8 value) { @@ -252,7 +252,7 @@ int pmbus_write_byte(struct i2c_client *client, int page, u8 value) return rv; } -EXPORT_SYMBOL_NS_GPL(pmbus_write_byte, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_write_byte, "PMBUS"); /* * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if @@ -287,7 +287,7 @@ int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, return rv; } -EXPORT_SYMBOL_NS_GPL(pmbus_write_word_data, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_write_word_data, "PMBUS"); static int pmbus_write_virt_reg(struct i2c_client *client, int page, int reg, @@ -393,7 +393,7 @@ int pmbus_update_fan(struct i2c_client *client, int page, int id, return _pmbus_write_word_data(client, page, pmbus_fan_command_registers[id], command); } -EXPORT_SYMBOL_NS_GPL(pmbus_update_fan, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_update_fan, "PMBUS"); int pmbus_read_word_data(struct i2c_client *client, int page, int phase, u8 reg) { @@ -409,7 +409,7 @@ int pmbus_read_word_data(struct i2c_client *client, int page, int phase, u8 reg) return rv; } -EXPORT_SYMBOL_NS_GPL(pmbus_read_word_data, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_read_word_data, "PMBUS"); static int pmbus_read_virt_reg(struct i2c_client *client, int page, int reg) { @@ -472,7 +472,7 @@ int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) return rv; } -EXPORT_SYMBOL_NS_GPL(pmbus_read_byte_data, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_read_byte_data, "PMBUS"); int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) { @@ -488,7 +488,7 @@ int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) return rv; } -EXPORT_SYMBOL_NS_GPL(pmbus_write_byte_data, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_write_byte_data, "PMBUS"); int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, u8 mask, u8 value) @@ -507,7 +507,7 @@ int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, return rv; } -EXPORT_SYMBOL_NS_GPL(pmbus_update_byte_data, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_update_byte_data, "PMBUS"); static int pmbus_read_block_data(struct i2c_client *client, int page, u8 reg, char *data_buf) @@ -578,14 +578,14 @@ int pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, { return pmbus_get_fan_rate(client, page, id, mode, false); } -EXPORT_SYMBOL_NS_GPL(pmbus_get_fan_rate_device, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_get_fan_rate_device, "PMBUS"); int pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, enum pmbus_fan_mode mode) { return pmbus_get_fan_rate(client, page, id, mode, true); } -EXPORT_SYMBOL_NS_GPL(pmbus_get_fan_rate_cached, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_get_fan_rate_cached, "PMBUS"); static void pmbus_clear_fault_page(struct i2c_client *client, int page) { @@ -600,7 +600,7 @@ void pmbus_clear_faults(struct i2c_client *client) for (i = 0; i < data->info->pages; i++) pmbus_clear_fault_page(client, i); } -EXPORT_SYMBOL_NS_GPL(pmbus_clear_faults, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_clear_faults, "PMBUS"); static int pmbus_check_status_cml(struct i2c_client *client) { @@ -655,13 +655,13 @@ bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg) { return pmbus_check_register(client, _pmbus_read_byte_data, page, reg); } -EXPORT_SYMBOL_NS_GPL(pmbus_check_byte_register, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_check_byte_register, "PMBUS"); bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) { return pmbus_check_register(client, __pmbus_read_word_data, page, reg); } -EXPORT_SYMBOL_NS_GPL(pmbus_check_word_register, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_check_word_register, "PMBUS"); static bool __maybe_unused pmbus_check_block_register(struct i2c_client *client, int page, int reg) @@ -685,7 +685,7 @@ const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client) return data->info; } -EXPORT_SYMBOL_NS_GPL(pmbus_get_driver_info, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_get_driver_info, "PMBUS"); static int pmbus_get_status(struct i2c_client *client, int page, int reg) { @@ -3217,7 +3217,7 @@ const struct regulator_ops pmbus_regulator_ops = { .set_voltage = pmbus_regulator_set_voltage, .list_voltage = pmbus_regulator_list_voltage, }; -EXPORT_SYMBOL_NS_GPL(pmbus_regulator_ops, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_regulator_ops, "PMBUS"); static int pmbus_regulator_register(struct pmbus_data *data) { @@ -3743,7 +3743,7 @@ int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info) return 0; } -EXPORT_SYMBOL_NS_GPL(pmbus_do_probe, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_do_probe, "PMBUS"); struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client) { @@ -3751,7 +3751,7 @@ struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client) return data->debugfs; } -EXPORT_SYMBOL_NS_GPL(pmbus_get_debugfs_dir, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_get_debugfs_dir, "PMBUS"); int pmbus_lock_interruptible(struct i2c_client *client) { @@ -3759,7 +3759,7 @@ int pmbus_lock_interruptible(struct i2c_client *client) return mutex_lock_interruptible(&data->update_lock); } -EXPORT_SYMBOL_NS_GPL(pmbus_lock_interruptible, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_lock_interruptible, "PMBUS"); void pmbus_unlock(struct i2c_client *client) { @@ -3767,7 +3767,7 @@ void pmbus_unlock(struct i2c_client *client) mutex_unlock(&data->update_lock); } -EXPORT_SYMBOL_NS_GPL(pmbus_unlock, PMBUS); +EXPORT_SYMBOL_NS_GPL(pmbus_unlock, "PMBUS"); static int __init pmbus_core_init(void) { diff --git a/drivers/hwmon/pmbus/pxe1610.c b/drivers/hwmon/pmbus/pxe1610.c index 5ac476d3cdd2a9c8715895be5c6810c72e155213..6a4a978eca7e89df1241245dbd01c52d76dba623 100644 --- a/drivers/hwmon/pmbus/pxe1610.c +++ b/drivers/hwmon/pmbus/pxe1610.c @@ -148,4 +148,4 @@ module_i2c_driver(pxe1610_driver); MODULE_AUTHOR("Vijay Khemka "); MODULE_DESCRIPTION("PMBus driver for Infineon PXE1610, PXE1110 and PXM1310"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/q54sj108a2.c b/drivers/hwmon/pmbus/q54sj108a2.c index a235c1cdf4fec54b820a78ddeb73057019b10943..4d7086d83aa3668acb17a10ea08d86965583b597 100644 --- a/drivers/hwmon/pmbus/q54sj108a2.c +++ b/drivers/hwmon/pmbus/q54sj108a2.c @@ -421,4 +421,4 @@ module_i2c_driver(q54sj108a2_driver); MODULE_AUTHOR("Xiao.Ma "); MODULE_DESCRIPTION("PMBus driver for Delta Q54SJ108A2 series modules"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/stpddc60.c b/drivers/hwmon/pmbus/stpddc60.c index 34d0f06f48452b2ab65a7b5302b00112458c4c65..5cb905ed8ae5f0de23c487c8f8e3b7af11dcdb77 100644 --- a/drivers/hwmon/pmbus/stpddc60.c +++ b/drivers/hwmon/pmbus/stpddc60.c @@ -246,4 +246,4 @@ module_i2c_driver(stpddc60_driver); MODULE_AUTHOR("Erik Rosen "); MODULE_DESCRIPTION("PMBus driver for ST STPDDC60"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/tda38640.c b/drivers/hwmon/pmbus/tda38640.c index 044d5fbdf9eb93839b2fdb0b33ca92f380f01a85..07fe58c244850064b48c7f12e3680102053fed03 100644 --- a/drivers/hwmon/pmbus/tda38640.c +++ b/drivers/hwmon/pmbus/tda38640.c @@ -221,4 +221,4 @@ module_i2c_driver(tda38640_driver); MODULE_AUTHOR("Patrick Rudolph "); MODULE_DESCRIPTION("PMBus driver for Infineon TDA38640"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/tps40422.c b/drivers/hwmon/pmbus/tps40422.c index d99b9850ea36c1ec1923401745bdb78a3aef09bd..7c9fedaa068c0b57feebb18f139a8c9ff2facdce 100644 --- a/drivers/hwmon/pmbus/tps40422.c +++ b/drivers/hwmon/pmbus/tps40422.c @@ -51,4 +51,4 @@ module_i2c_driver(tps40422_driver); MODULE_AUTHOR("Zhu Laiwen "); MODULE_DESCRIPTION("PMBus driver for TI TPS40422"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c index 5c9466244d70d19bf5f6dab0034fe1b3cf2681d2..63524dff5e7553cdd71bfdef476ebb5abd4ddce7 100644 --- a/drivers/hwmon/pmbus/tps53679.c +++ b/drivers/hwmon/pmbus/tps53679.c @@ -308,4 +308,4 @@ module_i2c_driver(tps53679_driver); MODULE_AUTHOR("Vadim Pasternak "); MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/tps546d24.c b/drivers/hwmon/pmbus/tps546d24.c index 520ca37269f77e9afa62fd54472fe6158f5e791f..44d7a6df1dbdfc9506359ea530842fbd2f07726b 100644 --- a/drivers/hwmon/pmbus/tps546d24.c +++ b/drivers/hwmon/pmbus/tps546d24.c @@ -68,4 +68,4 @@ module_i2c_driver(tps546d24_driver); MODULE_AUTHOR("Duke Du "); MODULE_DESCRIPTION("PMBus driver for TI tps546d24"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c index 5d3d1773bf520d58440908523456b08552986d63..9b0eadc81a2eeae94de9449a227ee9fe92f9d549 100644 --- a/drivers/hwmon/pmbus/ucd9000.c +++ b/drivers/hwmon/pmbus/ucd9000.c @@ -642,4 +642,4 @@ module_i2c_driver(ucd9000_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/ucd9200.c b/drivers/hwmon/pmbus/ucd9200.c index 7920d1c06df0dccf158644a25818c49fa1b5e4a5..f68adaf4a110e006ae168e4d2f97eece8ec38700 100644 --- a/drivers/hwmon/pmbus/ucd9200.c +++ b/drivers/hwmon/pmbus/ucd9200.c @@ -209,4 +209,4 @@ module_i2c_driver(ucd9200_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/xdp710.c b/drivers/hwmon/pmbus/xdp710.c index dd107e83f61254ad376b51b7bc9ee2d7504e8c09..660bbfe16e1e9d8df254cefe10193fefc1dae82e 100644 --- a/drivers/hwmon/pmbus/xdp710.c +++ b/drivers/hwmon/pmbus/xdp710.c @@ -128,4 +128,4 @@ module_i2c_driver(xdp710_driver); MODULE_AUTHOR("Peter Yin "); MODULE_DESCRIPTION("PMBus driver for XDP710 HSC"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/xdpe12284.c b/drivers/hwmon/pmbus/xdpe12284.c index facb1201aa430100e878b69ff13a6a06cd8ccfa0..f3aa6339d60d0ff73a5a51ba9e65eb5e99922bcc 100644 --- a/drivers/hwmon/pmbus/xdpe12284.c +++ b/drivers/hwmon/pmbus/xdpe12284.c @@ -194,4 +194,4 @@ module_i2c_driver(xdpe122_driver); MODULE_AUTHOR("Vadim Pasternak "); MODULE_DESCRIPTION("PMBus driver for Infineon XDPE122 family"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/xdpe152c4.c b/drivers/hwmon/pmbus/xdpe152c4.c index 7f3b31d4f033f5dae3f7bdf088a5281601f6533c..67a3d5fe1dafadfee45f1cbcb36690a31e1cb44e 100644 --- a/drivers/hwmon/pmbus/xdpe152c4.c +++ b/drivers/hwmon/pmbus/xdpe152c4.c @@ -72,4 +72,4 @@ module_i2c_driver(xdpe152_driver); MODULE_AUTHOR("Greg Schwendimann "); MODULE_DESCRIPTION("PMBus driver for Infineon XDPE152 family"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c index 7920a16203e1379fa28b404241fc41f4af18775b..97be69630cfbb46497a7876d9c8cd05adbf4253b 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c @@ -420,4 +420,4 @@ module_i2c_driver(zl6100_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PMBUS); +MODULE_IMPORT_NS("PMBUS"); diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 1edca1092f29b0077b4b5ff7f606b763719e5b2c..5a2d8c3e0d80a93b4fee270bbd299d72a0691cbd 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -131,7 +131,7 @@ static void u8500_hsem_remove(struct platform_device *pdev) static struct platform_driver u8500_hsem_driver = { .probe = u8500_hsem_probe, - .remove_new = u8500_hsem_remove, + .remove = u8500_hsem_remove, .driver = { .name = "u8500_hsem", }, diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index bfea880d6dfbf1ffd56d763d5566eab0e25080f9..275cc0d9f505fb0c1b2847da94fdfd468c49c6c4 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -689,7 +689,7 @@ MODULE_DEVICE_TABLE(acpi, catu_acpi_ids); static struct platform_driver catu_platform_driver = { .probe = catu_platform_probe, - .remove_new = catu_platform_remove, + .remove = catu_platform_remove, .driver = { .name = "coresight-catu-platform", .acpi_match_table = ACPI_PTR(catu_acpi_ids), diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index 75962dae9aa1854abd84cf1b19b3d523038c0199..342c3aaf414dd88e36b1c1adb944b6ddc872d50d 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -763,7 +763,7 @@ static const struct dev_pm_ops debug_dev_pm_ops = { static struct platform_driver debug_platform_driver = { .probe = debug_platform_probe, - .remove_new = debug_platform_remove, + .remove = debug_platform_remove, .driver = { .name = "coresight-debug-platform", .acpi_match_table = ACPI_PTR(debug_platform_ids), diff --git a/drivers/hwtracing/coresight/coresight-dummy.c b/drivers/hwtracing/coresight/coresight-dummy.c index bb85fa663ffcadf929609f3c61021a9d0100e146..02ef2b945a0c125911530e72c42e5f84671e0fcc 100644 --- a/drivers/hwtracing/coresight/coresight-dummy.c +++ b/drivers/hwtracing/coresight/coresight-dummy.c @@ -144,7 +144,7 @@ static const struct of_device_id dummy_match[] = { static struct platform_driver dummy_driver = { .probe = dummy_probe, - .remove_new = dummy_remove, + .remove = dummy_remove, .driver = { .name = "coresight-dummy", .of_match_table = dummy_match, diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 66d44a404ad0cd1f0529f4bc7afa7d71c2e5190f..dd8c74f893dbdfe1a35d811ef2dc476b81ce07ae 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -2399,7 +2399,7 @@ MODULE_DEVICE_TABLE(acpi, etm4x_acpi_ids); static struct platform_driver etm4_platform_driver = { .probe = etm4_probe_platform_dev, - .remove_new = etm4_remove_platform_dev, + .remove = etm4_remove_platform_dev, .driver = { .name = "coresight-etm4x", .of_match_table = etm4_sysreg_match, diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 5a819c8970fbf576d5a9267612623fbd93044b74..33efe1acbef754caf521ab94f1282103b9ea1744 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -377,7 +377,7 @@ MODULE_DEVICE_TABLE(acpi, funnel_acpi_ids); static struct platform_driver funnel_driver = { .probe = funnel_platform_probe, - .remove_new = funnel_platform_remove, + .remove = funnel_platform_remove, .driver = { .name = "coresight-funnel", /* THIS_MODULE is taken care of by platform_driver_register() */ diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 3e55be9c84186111a56894d837cc0f3a925f1858..0fba87de6d1af3a42a16c973ffcc82cdb7d43094 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -389,7 +389,7 @@ MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids); static struct platform_driver replicator_driver = { .probe = replicator_platform_probe, - .remove_new = replicator_platform_remove, + .remove = replicator_platform_remove, .driver = { .name = "coresight-replicator", /* THIS_MODULE is taken care of by platform_driver_register() */ diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index cb3e04755c99291dc4307e73b3cee34d3058ddb1..b581a30a1cd98d21dbacc4c94850fd412dbe7ae1 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -1036,7 +1036,7 @@ MODULE_DEVICE_TABLE(acpi, stm_acpi_ids); static struct platform_driver stm_platform_driver = { .probe = stm_platform_probe, - .remove_new = stm_platform_remove, + .remove = stm_platform_remove, .driver = { .name = "coresight-stm-platform", .acpi_match_table = ACPI_PTR(stm_acpi_ids), diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 3a482fd2cb225baa4819b47a9f353739219b752c..e9876252a789cb3e1eb41627a5800b6630ea0532 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -730,7 +730,7 @@ MODULE_DEVICE_TABLE(acpi, tmc_acpi_ids); static struct platform_driver tmc_platform_driver = { .probe = tmc_platform_probe, - .remove_new = tmc_platform_remove, + .remove = tmc_platform_remove, .driver = { .name = "coresight-tmc-platform", .acpi_match_table = ACPI_PTR(tmc_acpi_ids), diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index b048e146fbb10813c020ee148058befb615ace50..97ef36f03ec20716fbf4e058398e873671bde0c4 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -307,7 +307,7 @@ MODULE_DEVICE_TABLE(acpi, tpiu_acpi_ids); static struct platform_driver tpiu_platform_driver = { .probe = tpiu_platform_probe, - .remove_new = tpiu_platform_remove, + .remove = tpiu_platform_remove, .driver = { .name = "coresight-tpiu-platform", .acpi_match_table = ACPI_PTR(tpiu_acpi_ids), diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 96a32b2136699402aaee09517132afb5b1a100cd..919804b12a67a4439aedb536fd61bebb51d52a2a 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -1562,7 +1562,7 @@ static struct platform_driver arm_trbe_driver = { .suppress_bind_attrs = true, }, .probe = arm_trbe_device_probe, - .remove_new = arm_trbe_device_remove, + .remove = arm_trbe_device_remove, }; static int __init arm_trbe_init(void) diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c index ef7f560f0ffabbe76155f073a4c8720caeedd408..dc3c9504dd7cd2429ddd22f9fe830d3426e919d3 100644 --- a/drivers/hwtracing/coresight/ultrasoc-smb.c +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c @@ -600,7 +600,7 @@ static struct platform_driver smb_driver = { .suppress_bind_attrs = true, }, .probe = smb_probe, - .remove_new = smb_remove, + .remove = smb_remove, }; module_platform_driver(smb_driver); diff --git a/drivers/hwtracing/intel_th/acpi.c b/drivers/hwtracing/intel_th/acpi.c index 503620e9fd1054a40e772dd834c625a8b3a4b7be..d229324978bd1c5bbf56a8b097bb9e390dac91a4 100644 --- a/drivers/hwtracing/intel_th/acpi.c +++ b/drivers/hwtracing/intel_th/acpi.c @@ -69,7 +69,7 @@ static void intel_th_acpi_remove(struct platform_device *pdev) static struct platform_driver intel_th_acpi_driver = { .probe = intel_th_acpi_probe, - .remove_new = intel_th_acpi_remove, + .remove = intel_th_acpi_remove, .driver = { .name = DRIVER_NAME, .acpi_match_table = intel_th_acpi_ids, diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index af95d6e7f00438b64a5deea72e2d66757b8c5ffd..d27de18de46fe194d3d3d506bf1deb997ffdd81e 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -9,6 +9,7 @@ i2c-core-y := i2c-core-base.o i2c-core-smbus.o i2c-core-$(CONFIG_ACPI) += i2c-core-acpi.o i2c-core-$(CONFIG_I2C_SLAVE) += i2c-core-slave.o i2c-core-$(CONFIG_OF) += i2c-core-of.o +i2c-core-$(CONFIG_OF_DYNAMIC) += i2c-core-of-prober.o obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o diff --git a/drivers/i2c/busses/i2c-amd-asf-plat.c b/drivers/i2c/busses/i2c-amd-asf-plat.c index ba47df5370c72e0af6c84e84ce071c20b4dca803..7512614bf4b7339e39e952e29f9b57fefaa3d595 100644 --- a/drivers/i2c/busses/i2c-amd-asf-plat.c +++ b/drivers/i2c/busses/i2c-amd-asf-plat.c @@ -364,6 +364,6 @@ static struct platform_driver amd_asf_driver = { }; module_platform_driver(amd_asf_driver); -MODULE_IMPORT_NS(PIIX4_SMBUS); +MODULE_IMPORT_NS("PIIX4_SMBUS"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AMD Alert Standard Format Driver"); diff --git a/drivers/i2c/busses/i2c-cgbc.c b/drivers/i2c/busses/i2c-cgbc.c index eba0b205de1183951b598adaf2f6ac807d09b8ab..f054d167ac47600fda88434967499ba7158474b2 100644 --- a/drivers/i2c/busses/i2c-cgbc.c +++ b/drivers/i2c/busses/i2c-cgbc.c @@ -395,7 +395,7 @@ static struct platform_driver cgbc_i2c_driver = { .name = "cgbc-i2c", }, .probe = cgbc_i2c_probe, - .remove_new = cgbc_i2c_remove, + .remove = cgbc_i2c_remove, }; module_platform_driver(cgbc_i2c_driver); diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index 857783d458fbd5bb44f7ede4ca4b6d17ba0e1227..183a35038eef91fb450d0dc98a58d6c8e4071863 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -29,7 +29,7 @@ #include #include -#define DEFAULT_SYMBOL_NAMESPACE I2C_DW_COMMON +#define DEFAULT_SYMBOL_NAMESPACE "I2C_DW_COMMON" #include "i2c-designware-core.h" diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index eca8998d640fb0dfcb52c23b172701c486ed97e5..c8cbe5b1aeb19775617e8db9caf01eb9c685cafc 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -22,7 +22,7 @@ #include #include -#define DEFAULT_SYMBOL_NAMESPACE I2C_DW +#define DEFAULT_SYMBOL_NAMESPACE "I2C_DW" #include "i2c-designware-core.h" @@ -1094,4 +1094,4 @@ EXPORT_SYMBOL_GPL(i2c_dw_probe_master); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus master adapter"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(I2C_DW_COMMON); +MODULE_IMPORT_NS("I2C_DW_COMMON"); diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 38265c3dc4543fc82e9c593591e7558eb38680f0..8e0267c7cc294ee0ffe49d733b010b6c24544a5f 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -368,5 +368,5 @@ module_pci_driver(dw_i2c_driver); MODULE_AUTHOR("Baruch Siach "); MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(I2C_DW); -MODULE_IMPORT_NS(I2C_DW_COMMON); +MODULE_IMPORT_NS("I2C_DW"); +MODULE_IMPORT_NS("I2C_DW_COMMON"); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 3e12aab6bf2dafbff0c0ecaf6ea04c214586289a..d6e1ee935399d7a04feb2e5dce240d927d257b8f 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -397,5 +397,5 @@ module_exit(dw_i2c_exit_driver); MODULE_AUTHOR("Baruch Siach "); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(I2C_DW); -MODULE_IMPORT_NS(I2C_DW_COMMON); +MODULE_IMPORT_NS("I2C_DW"); +MODULE_IMPORT_NS("I2C_DW_COMMON"); diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index fad568e3523b91c483845017e9f1dc0eb9de3a0f..dc2b788eac5bdceff66351f96729174aab0c0c6c 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -16,7 +16,7 @@ #include #include -#define DEFAULT_SYMBOL_NAMESPACE I2C_DW +#define DEFAULT_SYMBOL_NAMESPACE "I2C_DW" #include "i2c-designware-core.h" @@ -282,4 +282,4 @@ EXPORT_SYMBOL_GPL(i2c_dw_probe_slave); MODULE_AUTHOR("Luis Oliveira "); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus slave adapter"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(I2C_DW_COMMON); +MODULE_IMPORT_NS("I2C_DW_COMMON"); diff --git a/drivers/i2c/busses/i2c-ljca.c b/drivers/i2c/busses/i2c-ljca.c index 1dc516ef0fddc58c1a2b5646d031bf9bfbae3e81..93274f0c2d72166bf017f65af797f418743b6a57 100644 --- a/drivers/i2c/busses/i2c-ljca.c +++ b/drivers/i2c/busses/i2c-ljca.c @@ -340,4 +340,4 @@ MODULE_AUTHOR("Zhifeng Wang "); MODULE_AUTHOR("Lixu Zhang "); MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-I2C driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LJCA); +MODULE_IMPORT_NS("LJCA"); diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 9402fa3811c5254e7b0751df56fc10258dd6a2c0..dd75916157f0519a17fb3d45432d7cf1373bd22a 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -195,7 +195,7 @@ int piix4_sb800_region_request(struct device *dev, struct sb800_mmio_cfg *mmio_c return 0; } -EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_request, PIIX4_SMBUS); +EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_request, "PIIX4_SMBUS"); void piix4_sb800_region_release(struct device *dev, struct sb800_mmio_cfg *mmio_cfg) { @@ -208,7 +208,7 @@ void piix4_sb800_region_release(struct device *dev, struct sb800_mmio_cfg *mmio_ release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); } -EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_release, PIIX4_SMBUS); +EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_release, "PIIX4_SMBUS"); static bool piix4_sb800_use_mmio(struct pci_dev *PIIX4_dev) { @@ -591,7 +591,7 @@ int piix4_transaction(struct i2c_adapter *piix4_adapter, unsigned short piix4_sm inb_p(SMBHSTDAT1)); return result; } -EXPORT_SYMBOL_NS_GPL(piix4_transaction, PIIX4_SMBUS); +EXPORT_SYMBOL_NS_GPL(piix4_transaction, "PIIX4_SMBUS"); /* Return negative errno on error. */ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, @@ -767,7 +767,7 @@ int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg) return (smba_en_lo & piix4_port_mask_sb800); } -EXPORT_SYMBOL_NS_GPL(piix4_sb800_port_sel, PIIX4_SMBUS); +EXPORT_SYMBOL_NS_GPL(piix4_sb800_port_sel, "PIIX4_SMBUS"); /* * Handles access to multiple SMBus ports on the SB800. diff --git a/drivers/i2c/i2c-atr.c b/drivers/i2c/i2c-atr.c index f21475ae592183a45b5e46a20e7a0699fb88132c..b7c10ced5a4393cd7a1a2d7448755872a063895d 100644 --- a/drivers/i2c/i2c-atr.c +++ b/drivers/i2c/i2c-atr.c @@ -547,7 +547,7 @@ err_destroy_mutex: return ERR_PTR(ret); } -EXPORT_SYMBOL_NS_GPL(i2c_atr_new, I2C_ATR); +EXPORT_SYMBOL_NS_GPL(i2c_atr_new, "I2C_ATR"); void i2c_atr_delete(struct i2c_atr *atr) { @@ -562,7 +562,7 @@ void i2c_atr_delete(struct i2c_atr *atr) mutex_destroy(&atr->lock); kfree(atr); } -EXPORT_SYMBOL_NS_GPL(i2c_atr_delete, I2C_ATR); +EXPORT_SYMBOL_NS_GPL(i2c_atr_delete, "I2C_ATR"); int i2c_atr_add_adapter(struct i2c_atr *atr, u32 chan_id, struct device *adapter_parent, @@ -657,7 +657,7 @@ err_fwnode_put: kfree(chan); return ret; } -EXPORT_SYMBOL_NS_GPL(i2c_atr_add_adapter, I2C_ATR); +EXPORT_SYMBOL_NS_GPL(i2c_atr_add_adapter, "I2C_ATR"); void i2c_atr_del_adapter(struct i2c_atr *atr, u32 chan_id) { @@ -690,19 +690,19 @@ void i2c_atr_del_adapter(struct i2c_atr *atr, u32 chan_id) kfree(chan->orig_addrs); kfree(chan); } -EXPORT_SYMBOL_NS_GPL(i2c_atr_del_adapter, I2C_ATR); +EXPORT_SYMBOL_NS_GPL(i2c_atr_del_adapter, "I2C_ATR"); void i2c_atr_set_driver_data(struct i2c_atr *atr, void *data) { atr->priv = data; } -EXPORT_SYMBOL_NS_GPL(i2c_atr_set_driver_data, I2C_ATR); +EXPORT_SYMBOL_NS_GPL(i2c_atr_set_driver_data, "I2C_ATR"); void *i2c_atr_get_driver_data(struct i2c_atr *atr) { return atr->priv; } -EXPORT_SYMBOL_NS_GPL(i2c_atr_get_driver_data, I2C_ATR); +EXPORT_SYMBOL_NS_GPL(i2c_atr_get_driver_data, "I2C_ATR"); MODULE_AUTHOR("Luca Ceresoli "); MODULE_AUTHOR("Tomi Valkeinen "); diff --git a/drivers/i2c/i2c-core-of-prober.c b/drivers/i2c/i2c-core-of-prober.c new file mode 100644 index 0000000000000000000000000000000000000000..0a66267e483633ff6b3a53d1b0f3974406cae131 --- /dev/null +++ b/drivers/i2c/i2c-core-of-prober.c @@ -0,0 +1,415 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Linux I2C core OF component prober code + * + * Copyright (C) 2024 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Some devices, such as Google Hana Chromebooks, are produced by multiple + * vendors each using their preferred components. Such components are all + * in the device tree. Instead of having all of them enabled and having each + * driver separately try and probe its device while fighting over shared + * resources, they can be marked as "fail-needs-probe" and have a prober + * figure out which one is actually used beforehand. + * + * This prober assumes such drop-in parts are on the same I2C bus, have + * non-conflicting addresses, and can be directly probed by seeing which + * address responds. + * + * TODO: + * - Support I2C muxes + */ + +static struct device_node *i2c_of_probe_get_i2c_node(struct device *dev, const char *type) +{ + struct device_node *node __free(device_node) = of_find_node_by_name(NULL, type); + if (!node) { + dev_err(dev, "Could not find %s device node\n", type); + return NULL; + } + + struct device_node *i2c_node __free(device_node) = of_get_parent(node); + if (!of_node_name_eq(i2c_node, "i2c")) { + dev_err(dev, "%s device isn't on I2C bus\n", type); + return NULL; + } + + if (!of_device_is_available(i2c_node)) { + dev_err(dev, "I2C controller not available\n"); + return NULL; + } + + return no_free_ptr(i2c_node); +} + +static int i2c_of_probe_enable_node(struct device *dev, struct device_node *node) +{ + int ret; + + dev_dbg(dev, "Enabling %pOF\n", node); + + struct of_changeset *ocs __free(kfree) = kzalloc(sizeof(*ocs), GFP_KERNEL); + if (!ocs) + return -ENOMEM; + + of_changeset_init(ocs); + ret = of_changeset_update_prop_string(ocs, node, "status", "okay"); + if (ret) + return ret; + + ret = of_changeset_apply(ocs); + if (ret) { + /* ocs needs to be explicitly cleaned up before being freed. */ + of_changeset_destroy(ocs); + } else { + /* + * ocs is intentionally kept around as it needs to + * exist as long as the change is applied. + */ + void *ptr __always_unused = no_free_ptr(ocs); + } + + return ret; +} + +static const struct i2c_of_probe_ops i2c_of_probe_dummy_ops; + +/** + * i2c_of_probe_component() - probe for devices of "type" on the same i2c bus + * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages. + * @cfg: Pointer to the &struct i2c_of_probe_cfg containing callbacks and other options + * for the prober. + * @ctx: Context data for callbacks. + * + * Probe for possible I2C components of the same "type" (&i2c_of_probe_cfg->type) + * on the same I2C bus that have their status marked as "fail-needs-probe". + * + * Assumes that across the entire device tree the only instances of nodes + * with "type" prefixed node names (not including the address portion) are + * the ones that need handling for second source components. In other words, + * if "type" is "touchscreen", then all device nodes named "touchscreen*" + * are the ones that need probing. There cannot be another "touchscreen*" + * node that is already enabled. + * + * Assumes that for each "type" of component, only one actually exists. In + * other words, only one matching and existing device will be enabled. + * + * Context: Process context only. Does non-atomic I2C transfers. + * Should only be used from a driver probe function, as the function + * can return -EPROBE_DEFER if the I2C adapter or other resources + * are unavailable. + * Return: 0 on success or no-op, error code otherwise. + * A no-op can happen when it seems like the device tree already + * has components of the type to be probed already enabled. This + * can happen when the device tree had not been updated to mark + * the status of the to-be-probed components as "fail-needs-probe". + * Or this function was already run with the same parameters and + * succeeded in enabling a component. The latter could happen if + * the user had multiple types of components to probe, and one of + * them down the list caused a deferred probe. This is expected + * behavior. + */ +int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cfg, void *ctx) +{ + const struct i2c_of_probe_ops *ops; + const char *type; + struct i2c_adapter *i2c; + int ret; + + ops = cfg->ops ?: &i2c_of_probe_dummy_ops; + type = cfg->type; + + struct device_node *i2c_node __free(device_node) = i2c_of_probe_get_i2c_node(dev, type); + if (!i2c_node) + return -ENODEV; + + /* + * If any devices of the given "type" are already enabled then this function is a no-op. + * Either the device tree hasn't been modified to work with this probe function, or the + * function had already run before and enabled some component. + */ + for_each_child_of_node_with_prefix(i2c_node, node, type) + if (of_device_is_available(node)) + return 0; + + i2c = of_get_i2c_adapter_by_node(i2c_node); + if (!i2c) + return dev_err_probe(dev, -EPROBE_DEFER, "Couldn't get I2C adapter\n"); + + /* Grab and enable resources */ + ret = 0; + if (ops->enable) + ret = ops->enable(dev, i2c_node, ctx); + if (ret) + goto out_put_i2c_adapter; + + for_each_child_of_node_with_prefix(i2c_node, node, type) { + union i2c_smbus_data data; + u32 addr; + + if (of_property_read_u32(node, "reg", &addr)) + continue; + if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0) + continue; + + /* Found a device that is responding */ + if (ops->cleanup_early) + ops->cleanup_early(dev, ctx); + ret = i2c_of_probe_enable_node(dev, node); + break; + } + + if (ops->cleanup) + ops->cleanup(dev, ctx); +out_put_i2c_adapter: + i2c_put_adapter(i2c); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_component, "I2C_OF_PROBER"); + +static int i2c_of_probe_simple_get_supply(struct device *dev, struct device_node *node, + struct i2c_of_probe_simple_ctx *ctx) +{ + const char *supply_name; + struct regulator *supply; + + /* + * It's entirely possible for the component's device node to not have the + * regulator supplies. While it does not make sense from a hardware perspective, + * the supplies could be always on or otherwise not modeled in the device tree, + * but the device would still work. + */ + supply_name = ctx->opts->supply_name; + if (!supply_name) + return 0; + + supply = of_regulator_get_optional(dev, node, supply_name); + if (IS_ERR(supply)) { + return dev_err_probe(dev, PTR_ERR(supply), + "Failed to get regulator supply \"%s\" from %pOF\n", + supply_name, node); + } + + ctx->supply = supply; + + return 0; +} + +static void i2c_of_probe_simple_put_supply(struct i2c_of_probe_simple_ctx *ctx) +{ + regulator_put(ctx->supply); + ctx->supply = NULL; +} + +static int i2c_of_probe_simple_enable_regulator(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + int ret; + + if (!ctx->supply) + return 0; + + dev_dbg(dev, "Enabling regulator supply \"%s\"\n", ctx->opts->supply_name); + + ret = regulator_enable(ctx->supply); + if (ret) + return ret; + + if (ctx->opts->post_power_on_delay_ms) + msleep(ctx->opts->post_power_on_delay_ms); + + return 0; +} + +static void i2c_of_probe_simple_disable_regulator(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + if (!ctx->supply) + return; + + dev_dbg(dev, "Disabling regulator supply \"%s\"\n", ctx->opts->supply_name); + + regulator_disable(ctx->supply); +} + +static int i2c_of_probe_simple_get_gpiod(struct device *dev, struct device_node *node, + struct i2c_of_probe_simple_ctx *ctx) +{ + struct fwnode_handle *fwnode = of_fwnode_handle(node); + struct gpio_desc *gpiod; + const char *con_id; + + /* NULL signals no GPIO needed */ + if (!ctx->opts->gpio_name) + return 0; + + /* An empty string signals an unnamed GPIO */ + if (!ctx->opts->gpio_name[0]) + con_id = NULL; + else + con_id = ctx->opts->gpio_name; + + gpiod = fwnode_gpiod_get_index(fwnode, con_id, 0, GPIOD_ASIS, "i2c-of-prober"); + if (IS_ERR(gpiod)) + return PTR_ERR(gpiod); + + ctx->gpiod = gpiod; + + return 0; +} + +static void i2c_of_probe_simple_put_gpiod(struct i2c_of_probe_simple_ctx *ctx) +{ + gpiod_put(ctx->gpiod); + ctx->gpiod = NULL; +} + +static int i2c_of_probe_simple_set_gpio(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + int ret; + + if (!ctx->gpiod) + return 0; + + dev_dbg(dev, "Configuring GPIO\n"); + + ret = gpiod_direction_output(ctx->gpiod, ctx->opts->gpio_assert_to_enable); + if (ret) + return ret; + + if (ctx->opts->post_gpio_config_delay_ms) + msleep(ctx->opts->post_gpio_config_delay_ms); + + return 0; +} + +static void i2c_of_probe_simple_disable_gpio(struct device *dev, struct i2c_of_probe_simple_ctx *ctx) +{ + gpiod_set_value(ctx->gpiod, !ctx->opts->gpio_assert_to_enable); +} + +/** + * i2c_of_probe_simple_enable - Simple helper for I2C OF prober to get and enable resources + * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages + * @bus_node: Pointer to the &struct device_node of the I2C adapter. + * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. + * + * If &i2c_of_probe_simple_opts->supply_name is given, request the named regulator supply. + * If &i2c_of_probe_simple_opts->gpio_name is given, request the named GPIO. Or if it is + * the empty string, request the unnamed GPIO. + * If a regulator supply was found, enable that regulator. + * If a GPIO line was found, configure the GPIO line to output and set value + * according to given options. + * + * Return: %0 on success or no-op, or a negative error number on failure. + */ +int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node, void *data) +{ + struct i2c_of_probe_simple_ctx *ctx = data; + struct device_node *node; + const char *compat; + int ret; + + dev_dbg(dev, "Requesting resources for components under I2C bus %pOF\n", bus_node); + + if (!ctx || !ctx->opts) + return -EINVAL; + + compat = ctx->opts->res_node_compatible; + if (!compat) + return -EINVAL; + + node = of_get_compatible_child(bus_node, compat); + if (!node) + return dev_err_probe(dev, -ENODEV, "No device compatible with \"%s\" found\n", + compat); + + ret = i2c_of_probe_simple_get_supply(dev, node, ctx); + if (ret) + goto out_put_node; + + ret = i2c_of_probe_simple_get_gpiod(dev, node, ctx); + if (ret) + goto out_put_supply; + + ret = i2c_of_probe_simple_enable_regulator(dev, ctx); + if (ret) + goto out_put_gpiod; + + ret = i2c_of_probe_simple_set_gpio(dev, ctx); + if (ret) + goto out_disable_regulator; + + return 0; + +out_disable_regulator: + i2c_of_probe_simple_disable_regulator(dev, ctx); +out_put_gpiod: + i2c_of_probe_simple_put_gpiod(ctx); +out_put_supply: + i2c_of_probe_simple_put_supply(ctx); +out_put_node: + of_node_put(node); + return ret; +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_enable, "I2C_OF_PROBER"); + +/** + * i2c_of_probe_simple_cleanup_early - \ + * Simple helper for I2C OF prober to release GPIOs before component is enabled + * @dev: Pointer to the &struct device of the caller; unused. + * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. + * + * GPIO descriptors are exclusive and have to be released before the + * actual driver probes so that the latter can acquire them. + */ +void i2c_of_probe_simple_cleanup_early(struct device *dev, void *data) +{ + struct i2c_of_probe_simple_ctx *ctx = data; + + i2c_of_probe_simple_put_gpiod(ctx); +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_cleanup_early, "I2C_OF_PROBER"); + +/** + * i2c_of_probe_simple_cleanup - Clean up and release resources for I2C OF prober simple helpers + * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages + * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context. + * + * * If a GPIO line was found and not yet released, set its value to the opposite of that + * set in i2c_of_probe_simple_enable() and release it. + * * If a regulator supply was found, disable that regulator and release it. + */ +void i2c_of_probe_simple_cleanup(struct device *dev, void *data) +{ + struct i2c_of_probe_simple_ctx *ctx = data; + + /* GPIO operations here are no-ops if i2c_of_probe_simple_cleanup_early was called. */ + i2c_of_probe_simple_disable_gpio(dev, ctx); + i2c_of_probe_simple_put_gpiod(ctx); + + i2c_of_probe_simple_disable_regulator(dev, ctx); + i2c_of_probe_simple_put_supply(ctx); +} +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_cleanup, "I2C_OF_PROBER"); + +struct i2c_of_probe_ops i2c_of_probe_simple_ops = { + .enable = i2c_of_probe_simple_enable, + .cleanup_early = i2c_of_probe_simple_cleanup_early, + .cleanup = i2c_of_probe_simple_cleanup, +}; +EXPORT_SYMBOL_NS_GPL(i2c_of_probe_simple_ops, "I2C_OF_PROBER"); diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 0a6bdc6df1723cc1017abae5e4870072dabf7ea6..e73afbefe2225f9669cbc67168219a038c453245 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -122,7 +122,7 @@ EXPORT_SYMBOL(i2c_smbus_read_byte); s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter, client->addr, client->flags, - I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); + I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); } EXPORT_SYMBOL(i2c_smbus_write_byte); diff --git a/drivers/i3c/master/ast2600-i3c-master.c b/drivers/i3c/master/ast2600-i3c-master.c index 84942dbb6f8028cc5d02717912e6174fa0228afe..e05e83812c712c0110dd39ebc271cef252bc11ad 100644 --- a/drivers/i3c/master/ast2600-i3c-master.c +++ b/drivers/i3c/master/ast2600-i3c-master.c @@ -174,7 +174,7 @@ MODULE_DEVICE_TABLE(of, ast2600_i3c_master_of_match); static struct platform_driver ast2600_i3c_driver = { .probe = ast2600_i3c_probe, - .remove_new = ast2600_i3c_remove, + .remove = ast2600_i3c_remove, .driver = { .name = "ast2600-i3c-master", .of_match_table = ast2600_i3c_master_of_match, diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index 5b5c2e4bdc51601a125486d274db6d8f6bdbbf80..d4b80eb8cecdf4304ce40ca7a58ad64d3adb5490 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -1783,7 +1783,7 @@ MODULE_DEVICE_TABLE(acpi, amd_i3c_device_match); static struct platform_driver dw_i3c_driver = { .probe = dw_i3c_probe, - .remove_new = dw_i3c_remove, + .remove = dw_i3c_remove, .driver = { .name = "dw-i3c-master", .of_match_table = dw_i3c_master_of_match, diff --git a/drivers/i3c/master/i3c-master-cdns.c b/drivers/i3c/master/i3c-master-cdns.c index fe4d59833ad5f4e77a32b7f195b8c8e32af895d8..06c0592487d313734e168dd1857a16d3292e9dd7 100644 --- a/drivers/i3c/master/i3c-master-cdns.c +++ b/drivers/i3c/master/i3c-master-cdns.c @@ -1676,7 +1676,7 @@ static void cdns_i3c_master_remove(struct platform_device *pdev) static struct platform_driver cdns_i3c_master = { .probe = cdns_i3c_master_probe, - .remove_new = cdns_i3c_master_remove, + .remove = cdns_i3c_master_remove, .driver = { .name = "cdns-i3c-master", .of_match_table = cdns_i3c_master_of_ids, diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c index e6e482a259b4cdeee6bdcacbda51e97d1057d0bf..648c501407ced8dc8cd47b7a9df9f87aba677b04 100644 --- a/drivers/i3c/master/mipi-i3c-hci/core.c +++ b/drivers/i3c/master/mipi-i3c-hci/core.c @@ -844,7 +844,7 @@ MODULE_DEVICE_TABLE(acpi, i3c_hci_acpi_match); static struct platform_driver i3c_hci_driver = { .probe = i3c_hci_probe, - .remove_new = i3c_hci_remove, + .remove = i3c_hci_remove, .driver = { .name = "mipi-i3c-hci", .of_match_table = of_match_ptr(i3c_hci_of_match), diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index c1ee3828e7eec065ccac6e1fb18055bb50d6134b..d6057d8c7dec4ea90e1e9206290f0c1d75f749ad 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -1966,7 +1966,7 @@ MODULE_DEVICE_TABLE(of, svc_i3c_master_of_match_tbl); static struct platform_driver svc_i3c_master = { .probe = svc_i3c_master_probe, - .remove_new = svc_i3c_master_remove, + .remove = svc_i3c_master_remove, .driver = { .name = "silvaco-i3c-master", .of_match_table = svc_i3c_master_of_match_tbl, diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c index d054721859b3b5f0c5840b17679b6fb1884305da..8601b9a8b8e75c012fd33e54fa3432359470d163 100644 --- a/drivers/iio/accel/adis16201.c +++ b/drivers/iio/accel/adis16201.c @@ -300,4 +300,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); MODULE_DESCRIPTION("Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:adis16201"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c index 0035e4f4db63ff46ad6e096fdc0c5edd757a9827..41ffd92f27fdca1fb58bc234cff19a81cadbb069 100644 --- a/drivers/iio/accel/adis16209.c +++ b/drivers/iio/accel/adis16209.c @@ -310,4 +310,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); MODULE_DESCRIPTION("Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:adis16209"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_core.c index 4de0a41bd679674dfff8ffa2940635675fdff2ce..46cca10e776f07f47f6f1c7f9cdfc121b2da82da 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -32,19 +32,19 @@ const struct regmap_access_table adxl312_readable_regs_table = { .yes_ranges = adxl312_readable_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl312_readable_regs_table, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl312_readable_regs_table, "IIO_ADXL313"); const struct regmap_access_table adxl313_readable_regs_table = { .yes_ranges = adxl313_readable_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl313_readable_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, "IIO_ADXL313"); const struct regmap_access_table adxl314_readable_regs_table = { .yes_ranges = adxl312_readable_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl314_readable_regs_table, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl314_readable_regs_table, "IIO_ADXL313"); static int adxl312_check_id(struct device *dev, struct adxl313_data *data) @@ -121,7 +121,7 @@ const struct adxl313_chip_info adxl31x_chip_info[] = { .check_id = &adxl312_check_id, }, }; -EXPORT_SYMBOL_NS_GPL(adxl31x_chip_info, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl31x_chip_info, "IIO_ADXL313"); static const struct regmap_range adxl312_writable_reg_range[] = { regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), @@ -144,19 +144,19 @@ const struct regmap_access_table adxl312_writable_regs_table = { .yes_ranges = adxl312_writable_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl312_writable_regs_table, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl312_writable_regs_table, "IIO_ADXL313"); const struct regmap_access_table adxl313_writable_regs_table = { .yes_ranges = adxl313_writable_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl313_writable_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, "IIO_ADXL313"); const struct regmap_access_table adxl314_writable_regs_table = { .yes_ranges = adxl312_writable_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl314_writable_regs_table, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl314_writable_regs_table, "IIO_ADXL313"); static const int adxl313_odr_freqs[][2] = { [0] = { 6, 250000 }, @@ -417,7 +417,7 @@ int adxl313_core_probe(struct device *dev, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, IIO_ADXL313); +EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, "IIO_ADXL313"); MODULE_AUTHOR("Lucas Stankus "); MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer core driver"); diff --git a/drivers/iio/accel/adxl313_i2c.c b/drivers/iio/accel/adxl313_i2c.c index a4cf0cf2c5aaa89a6e191c75c90c4d8b3f53ad78..dfa51860cd83d60b06500dbbc574763c56fc3cf4 100644 --- a/drivers/iio/accel/adxl313_i2c.c +++ b/drivers/iio/accel/adxl313_i2c.c @@ -92,4 +92,4 @@ module_i2c_driver(adxl313_i2c_driver); MODULE_AUTHOR("Lucas Stankus "); MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer I2C driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADXL313); +MODULE_IMPORT_NS("IIO_ADXL313"); diff --git a/drivers/iio/accel/adxl313_spi.c b/drivers/iio/accel/adxl313_spi.c index 6f8d73f6e5a939b3ee433a58582f3ea2b78a6173..ebc5d09f108d16f263065d8b14671b7fb1ee8b14 100644 --- a/drivers/iio/accel/adxl313_spi.c +++ b/drivers/iio/accel/adxl313_spi.c @@ -119,4 +119,4 @@ module_spi_driver(adxl313_spi_driver); MODULE_AUTHOR("Lucas Stankus "); MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADXL313); +MODULE_IMPORT_NS("IIO_ADXL313"); diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 006ce66c0aa38850acff83b14cec2c43bb76cd21..b1efab0f6404ba870f5a17622776fecc081dd461 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -248,7 +248,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(adxl345_core_probe, IIO_ADXL345); +EXPORT_SYMBOL_NS_GPL(adxl345_core_probe, "IIO_ADXL345"); MODULE_AUTHOR("Eva Rachel Retuya "); MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer core driver"); diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c index 4065b8f7c8a8aeb744cd054b6b906bb74f54b697..cb23fb11fcd7d8e8595a620cd28e3abb55e6dae5 100644 --- a/drivers/iio/accel/adxl345_i2c.c +++ b/drivers/iio/accel/adxl345_i2c.c @@ -74,4 +74,4 @@ module_i2c_driver(adxl345_i2c_driver); MODULE_AUTHOR("Eva Rachel Retuya "); MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer I2C driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADXL345); +MODULE_IMPORT_NS("IIO_ADXL345"); diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c index 57e16b44170214ba88035b3e71ea0d7015bd169a..968e7b390d4bb6719f6487ac310b12ff1a2a58e3 100644 --- a/drivers/iio/accel/adxl345_spi.c +++ b/drivers/iio/accel/adxl345_spi.c @@ -88,4 +88,4 @@ module_spi_driver(adxl345_spi_driver); MODULE_AUTHOR("Eva Rachel Retuya "); MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADXL345); +MODULE_IMPORT_NS("IIO_ADXL345"); diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index eabaefa92f19d1fce587204e0992a9d2a9e61dd8..e8cd21fa77a6987363ce30de00d3767352101469 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -72,7 +72,7 @@ const struct regmap_access_table adxl355_readable_regs_tbl = { .yes_ranges = adxl355_read_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl355_read_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl355_readable_regs_tbl, IIO_ADXL355); +EXPORT_SYMBOL_NS_GPL(adxl355_readable_regs_tbl, "IIO_ADXL355"); static const struct regmap_range adxl355_write_reg_range[] = { regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_RESET_REG), @@ -82,7 +82,7 @@ const struct regmap_access_table adxl355_writeable_regs_tbl = { .yes_ranges = adxl355_write_reg_range, .n_yes_ranges = ARRAY_SIZE(adxl355_write_reg_range), }; -EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355); +EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, "IIO_ADXL355"); const struct adxl355_chip_info adxl35x_chip_info[] = { [ADXL355] = { @@ -136,7 +136,7 @@ const struct adxl355_chip_info adxl35x_chip_info[] = { }, }, }; -EXPORT_SYMBOL_NS_GPL(adxl35x_chip_info, IIO_ADXL355); +EXPORT_SYMBOL_NS_GPL(adxl35x_chip_info, "IIO_ADXL355"); enum adxl355_op_mode { ADXL355_MEASUREMENT, @@ -643,7 +643,7 @@ static irqreturn_t adxl355_trigger_handler(int irq, void *p) * The acceleration data is 24 bits and big endian. It has to be saved * in 32 bits, hence, it is saved in the 2nd byte of the 4 byte buffer. * The buf array is 14 bytes as it includes 3x4=12 bytes for - * accelaration data of x, y, and z axis. It also includes 2 bytes for + * acceleration data of x, y, and z axis. It also includes 2 bytes for * temperature data. */ ret = regmap_bulk_read(data->regmap, ADXL355_XDATA3_REG, @@ -801,7 +801,7 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(adxl355_core_probe, IIO_ADXL355); +EXPORT_SYMBOL_NS_GPL(adxl355_core_probe, "IIO_ADXL355"); MODULE_AUTHOR("Puranjay Mohan "); MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer core driver"); diff --git a/drivers/iio/accel/adxl355_i2c.c b/drivers/iio/accel/adxl355_i2c.c index 32398cde9608e226c8ee21147a7785ff5aef0e66..1a512c7b792b6fb83ef34b6989ba5a46845a04dc 100644 --- a/drivers/iio/accel/adxl355_i2c.c +++ b/drivers/iio/accel/adxl355_i2c.c @@ -67,4 +67,4 @@ module_i2c_driver(adxl355_i2c_driver); MODULE_AUTHOR("Puranjay Mohan "); MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer I2C driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADXL355); +MODULE_IMPORT_NS("IIO_ADXL355"); diff --git a/drivers/iio/accel/adxl355_spi.c b/drivers/iio/accel/adxl355_spi.c index 5153ac815e4b0940af5f885442a8164c3e0ee14b..869e3e57d6f728c3608bf0c50222446ab83cd859 100644 --- a/drivers/iio/accel/adxl355_spi.c +++ b/drivers/iio/accel/adxl355_spi.c @@ -70,4 +70,4 @@ module_spi_driver(adxl355_spi_driver); MODULE_AUTHOR("Puranjay Mohan "); MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADXL355); +MODULE_IMPORT_NS("IIO_ADXL355"); diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index e790a66d86c79f7de9650ea47f11c8990825fd42..a48ac0d7bd96b11f666150f8a402529ee30c98fa 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -1073,7 +1073,7 @@ static int adxl367_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { enum adxl367_activity_type act; @@ -1475,7 +1475,7 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(adxl367_probe, IIO_ADXL367); +EXPORT_SYMBOL_NS_GPL(adxl367_probe, "IIO_ADXL367"); MODULE_AUTHOR("Cosmin Tanislav "); MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer driver"); diff --git a/drivers/iio/accel/adxl367_i2c.c b/drivers/iio/accel/adxl367_i2c.c index deb82a43ec36fb8745c0c408e3b027501d3fb752..80f0b642b9b0a593ff8c7565c42aebf1675f83fe 100644 --- a/drivers/iio/accel/adxl367_i2c.c +++ b/drivers/iio/accel/adxl367_i2c.c @@ -83,7 +83,7 @@ static struct i2c_driver adxl367_i2c_driver = { module_i2c_driver(adxl367_i2c_driver); -MODULE_IMPORT_NS(IIO_ADXL367); +MODULE_IMPORT_NS("IIO_ADXL367"); MODULE_AUTHOR("Cosmin Tanislav "); MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer I2C driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/accel/adxl367_spi.c b/drivers/iio/accel/adxl367_spi.c index b70117265791519d63eb9777518df9bea46ee46c..49d7c8fbe8edc8ee21daf2acb005e39cc613fb7a 100644 --- a/drivers/iio/accel/adxl367_spi.c +++ b/drivers/iio/accel/adxl367_spi.c @@ -160,7 +160,7 @@ static struct spi_driver adxl367_spi_driver = { module_spi_driver(adxl367_spi_driver); -MODULE_IMPORT_NS(IIO_ADXL367); +MODULE_IMPORT_NS("IIO_ADXL367"); MODULE_AUTHOR("Cosmin Tanislav "); MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer SPI driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index ef8dd557877bd44570e84579b1af89e6b02cc523..8ba5fbe6e1f50f634d2cc74d64dd427f37ade345 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -940,7 +940,7 @@ static int adxl372_read_event_config(struct iio_dev *indio_dev, const struct iio static int adxl372_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct adxl372_state *st = iio_priv(indio_dev); @@ -1176,7 +1176,7 @@ bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg) { return (reg == ADXL372_FIFO_DATA); } -EXPORT_SYMBOL_NS_GPL(adxl372_readable_noinc_reg, IIO_ADXL372); +EXPORT_SYMBOL_NS_GPL(adxl372_readable_noinc_reg, "IIO_ADXL372"); int adxl372_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) @@ -1260,7 +1260,7 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(adxl372_probe, IIO_ADXL372); +EXPORT_SYMBOL_NS_GPL(adxl372_probe, "IIO_ADXL372"); MODULE_AUTHOR("Stefan Popa "); MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer driver"); diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c index 3571cfde1c0e7c1bc79db5236c7bf8a2707a9a8d..43d5fd921be7b9d531976a81aff4bc1068361718 100644 --- a/drivers/iio/accel/adxl372_i2c.c +++ b/drivers/iio/accel/adxl372_i2c.c @@ -67,4 +67,4 @@ module_i2c_driver(adxl372_i2c_driver); MODULE_AUTHOR("Stefan Popa "); MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer I2C driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ADXL372); +MODULE_IMPORT_NS("IIO_ADXL372"); diff --git a/drivers/iio/accel/adxl372_spi.c b/drivers/iio/accel/adxl372_spi.c index 787699773f96f9ab1777ccba17e4be455cf388f8..1ab1997a55b1f828a1cc2b3be2243c6efb35ea6f 100644 --- a/drivers/iio/accel/adxl372_spi.c +++ b/drivers/iio/accel/adxl372_spi.c @@ -58,4 +58,4 @@ module_spi_driver(adxl372_spi_driver); MODULE_AUTHOR("Stefan Popa "); MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer SPI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ADXL372); +MODULE_IMPORT_NS("IIO_ADXL372"); diff --git a/drivers/iio/accel/adxl380.c b/drivers/iio/accel/adxl380.c index f80527d899be4d99310d4d1a950749ce29c9b7ed..90340f134722a3bd852d4daebab7b7c9e855f94b 100644 --- a/drivers/iio/accel/adxl380.c +++ b/drivers/iio/accel/adxl380.c @@ -194,7 +194,7 @@ const struct adxl380_chip_info adxl380_chip_info = { .temp_offset = 25 * 102 / 10 - 470, }; -EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, IIO_ADXL380); +EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380"); const struct adxl380_chip_info adxl382_chip_info = { .name = "adxl382", @@ -211,7 +211,7 @@ const struct adxl380_chip_info adxl382_chip_info = { */ .temp_offset = 25 * 102 / 10 - 570, }; -EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, IIO_ADXL380); +EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380"); static const unsigned int adxl380_th_reg_high_addr[2] = { [ADXL380_ACTIVITY] = ADXL380_THRESH_ACT_H_REG, @@ -263,7 +263,7 @@ bool adxl380_readable_noinc_reg(struct device *dev, unsigned int reg) { return reg == ADXL380_FIFO_DATA; } -EXPORT_SYMBOL_NS_GPL(adxl380_readable_noinc_reg, IIO_ADXL380); +EXPORT_SYMBOL_NS_GPL(adxl380_readable_noinc_reg, "IIO_ADXL380"); static int adxl380_set_measure_en(struct adxl380_state *st, bool en) { @@ -1181,7 +1181,7 @@ static int adxl380_read_raw(struct iio_dev *indio_dev, ret = adxl380_read_chn(st, chan->address); iio_device_release_direct_mode(indio_dev); - if (ret) + if (ret < 0) return ret; *val = sign_extend32(ret >> chan->scan_type.shift, @@ -1386,7 +1386,7 @@ static int adxl380_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct adxl380_state *st = iio_priv(indio_dev); enum adxl380_axis axis; @@ -1719,7 +1719,6 @@ static int adxl380_config_irq(struct iio_dev *indio_dev) { struct adxl380_state *st = iio_priv(indio_dev); unsigned long irq_flag; - struct irq_data *desc; u32 irq_type; u8 polarity; int ret; @@ -1737,11 +1736,7 @@ static int adxl380_config_irq(struct iio_dev *indio_dev) st->int_map[1] = ADXL380_INT1_MAP1_REG; } - desc = irq_get_irq_data(st->irq); - if (!desc) - return dev_err_probe(st->dev, -EINVAL, "Could not find IRQ %d\n", st->irq); - - irq_type = irqd_get_trigger_type(desc); + irq_type = irq_get_trigger_type(st->irq); if (irq_type == IRQ_TYPE_LEVEL_HIGH) { polarity = 0; irq_flag = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; @@ -1897,7 +1892,7 @@ int adxl380_probe(struct device *dev, struct regmap *regmap, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(adxl380_probe, IIO_ADXL380); +EXPORT_SYMBOL_NS_GPL(adxl380_probe, "IIO_ADXL380"); MODULE_AUTHOR("Ramona Gradinariu "); MODULE_AUTHOR("Antoniu Miclaus "); diff --git a/drivers/iio/accel/adxl380_i2c.c b/drivers/iio/accel/adxl380_i2c.c index 1dc1e77be815de27eb8be3f5fc600449ed6b10d2..b4f86f97236148b0df8666d48010054eef727071 100644 --- a/drivers/iio/accel/adxl380_i2c.c +++ b/drivers/iio/accel/adxl380_i2c.c @@ -61,4 +61,4 @@ MODULE_AUTHOR("Ramona Gradinariu "); MODULE_AUTHOR("Antoniu Miclaus "); MODULE_DESCRIPTION("Analog Devices ADXL380 3-axis accelerometer I2C driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ADXL380); +MODULE_IMPORT_NS("IIO_ADXL380"); diff --git a/drivers/iio/accel/adxl380_spi.c b/drivers/iio/accel/adxl380_spi.c index e7b5778cb6cfe9f78dc9e4277f6c9b0fe2361fd3..6edd0d211ffad91c377baa02457aee5a1a5919ab 100644 --- a/drivers/iio/accel/adxl380_spi.c +++ b/drivers/iio/accel/adxl380_spi.c @@ -63,4 +63,4 @@ MODULE_AUTHOR("Ramona Gradinariu "); MODULE_AUTHOR("Antoniu Miclaus "); MODULE_DESCRIPTION("Analog Devices ADXL380 3-axis accelerometer SPI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ADXL380); +MODULE_IMPORT_NS("IIO_ADXL380"); diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 2445a0f7bc2baee2a27ee3ec0364ccadb768ea1f..128db14ba726a3ada82a43cfcea04c8fc1bfee76 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -144,7 +145,7 @@ struct bma180_data { /* Ensure timestamp is naturally aligned */ struct { s16 chan[4]; - s64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; }; diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index fcbd695e46549fe715407daad65189f691d1117e..009e6243c6cba9e1e8b56a88cf7a3823883bfdb1 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index e4fe36768216dab5af1721c4e31ce18828c231e5..ae806ed60271a7da3a45cf4b9c10eff671e2c946 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -115,7 +115,7 @@ struct bma400_data { struct { __le16 buff[3]; u8 temperature; - s64 ts __aligned(8); + aligned_s64 ts; } buffer __aligned(IIO_DMA_MINALIGN); __le16 status; __be16 duration; @@ -194,7 +194,7 @@ const struct regmap_config bma400_regmap_config = { .writeable_reg = bma400_is_writable_reg, .volatile_reg = bma400_is_volatile_reg, }; -EXPORT_SYMBOL_NS(bma400_regmap_config, IIO_BMA400); +EXPORT_SYMBOL_NS(bma400_regmap_config, "IIO_BMA400"); static const struct iio_mount_matrix * bma400_accel_get_mount_matrix(const struct iio_dev *indio_dev, @@ -1293,7 +1293,7 @@ static int bma400_disable_adv_interrupt(struct bma400_data *data) static int bma400_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct bma400_data *data = iio_priv(indio_dev); int ret; @@ -1763,7 +1763,7 @@ int bma400_probe(struct device *dev, struct regmap *regmap, int irq, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400); +EXPORT_SYMBOL_NS(bma400_probe, "IIO_BMA400"); MODULE_AUTHOR("Dan Robertson "); MODULE_AUTHOR("Jagath Jog J "); diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index c1c72f577295a87a3e17286355e6efbf10498213..24a390c3ae66d152fa3c30639270423809c0e5e6 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -53,4 +53,4 @@ module_i2c_driver(bma400_i2c_driver); MODULE_AUTHOR("Dan Robertson "); MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor (I2C)"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_BMA400); +MODULE_IMPORT_NS("IIO_BMA400"); diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c index 765d8c4a4c4ddff9ffdf2c90954793b407f7ab6d..d386f643515bac595c99d5897f40ea8b79812931 100644 --- a/drivers/iio/accel/bma400_spi.c +++ b/drivers/iio/accel/bma400_spi.c @@ -112,4 +112,4 @@ module_spi_driver(bma400_spi_driver); MODULE_AUTHOR("Dan Robertson "); MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor (SPI)"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_BMA400); +MODULE_IMPORT_NS("IIO_BMA400"); diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 0f32c1e92b4dc121bb85516acef4941b0421f100..744a034bb8b5f27a9184e33db5c90ebcd3e08fbe 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -203,7 +203,7 @@ const struct regmap_config bmc150_regmap_conf = { .val_bits = 8, .max_register = 0x3f, }; -EXPORT_SYMBOL_NS_GPL(bmc150_regmap_conf, IIO_BMC150); +EXPORT_SYMBOL_NS_GPL(bmc150_regmap_conf, "IIO_BMC150"); static int bmc150_accel_set_mode(struct bmc150_accel_data *data, enum bmc150_power_modes mode, @@ -804,7 +804,7 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct bmc150_accel_data *data = iio_priv(indio_dev); int ret; @@ -1760,7 +1760,7 @@ err_disable_regulators: return ret; } -EXPORT_SYMBOL_NS_GPL(bmc150_accel_core_probe, IIO_BMC150); +EXPORT_SYMBOL_NS_GPL(bmc150_accel_core_probe, "IIO_BMC150"); void bmc150_accel_core_remove(struct device *dev) { @@ -1783,7 +1783,7 @@ void bmc150_accel_core_remove(struct device *dev) regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); } -EXPORT_SYMBOL_NS_GPL(bmc150_accel_core_remove, IIO_BMC150); +EXPORT_SYMBOL_NS_GPL(bmc150_accel_core_remove, "IIO_BMC150"); #ifdef CONFIG_PM_SLEEP static int bmc150_accel_suspend(struct device *dev) @@ -1858,7 +1858,7 @@ const struct dev_pm_ops bmc150_accel_pm_ops = { SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend, bmc150_accel_runtime_resume, NULL) }; -EXPORT_SYMBOL_NS_GPL(bmc150_accel_pm_ops, IIO_BMC150); +EXPORT_SYMBOL_NS_GPL(bmc150_accel_pm_ops, "IIO_BMC150"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c index 1c2e40369839a3f4667cac5761ef7ed27b7d94d4..0d4ce6c389317209f1b3cdf5cec913dafc876023 100644 --- a/drivers/iio/accel/bmc150-accel-i2c.c +++ b/drivers/iio/accel/bmc150-accel-i2c.c @@ -291,4 +291,4 @@ module_i2c_driver(bmc150_accel_driver); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("BMC150 I2C accelerometer driver"); -MODULE_IMPORT_NS(IIO_BMC150); +MODULE_IMPORT_NS("IIO_BMC150"); diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c index a6b9f599eb7bdcf8aaa7fb2e8933884c0329c716..70b3642656abcd6120807ae8f34a4e65a78dc884 100644 --- a/drivers/iio/accel/bmc150-accel-spi.c +++ b/drivers/iio/accel/bmc150-accel-spi.c @@ -81,4 +81,4 @@ module_spi_driver(bmc150_accel_driver); MODULE_AUTHOR("Markus Pargmann "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("BMC150 SPI accelerometer driver"); -MODULE_IMPORT_NS(IIO_BMC150); +MODULE_IMPORT_NS("IIO_BMC150"); diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h index 7775c5edaeefd464ead77e9ced917b89f576feea..7a7baf52e5955b4cdaef86aeacf479459b76fe94 100644 --- a/drivers/iio/accel/bmc150-accel.h +++ b/drivers/iio/accel/bmc150-accel.h @@ -6,6 +6,7 @@ #include #include #include +#include #include struct regmap; @@ -69,7 +70,7 @@ struct bmc150_accel_data { */ struct { __le16 channels[3]; - s64 ts __aligned(8); + aligned_s64 ts; } scan; u8 bw_bits; u32 slope_dur; diff --git a/drivers/iio/accel/bmi088-accel-core.c b/drivers/iio/accel/bmi088-accel-core.c index fc1c1613d673b5b53a57e0b5065eb97a5edb61d8..9206fbdbf520c9c3c19a944ae77beec444b0ab6a 100644 --- a/drivers/iio/accel/bmi088-accel-core.c +++ b/drivers/iio/accel/bmi088-accel-core.c @@ -147,7 +147,7 @@ const struct regmap_config bmi088_regmap_conf = { .volatile_table = &bmi088_volatile_table, .cache_type = REGCACHE_RBTREE, }; -EXPORT_SYMBOL_NS_GPL(bmi088_regmap_conf, IIO_BMI088); +EXPORT_SYMBOL_NS_GPL(bmi088_regmap_conf, "IIO_BMI088"); static int bmi088_accel_power_up(struct bmi088_accel_data *data) { @@ -587,7 +587,7 @@ int bmi088_accel_core_probe(struct device *dev, struct regmap *regmap, return ret; } -EXPORT_SYMBOL_NS_GPL(bmi088_accel_core_probe, IIO_BMI088); +EXPORT_SYMBOL_NS_GPL(bmi088_accel_core_probe, "IIO_BMI088"); void bmi088_accel_core_remove(struct device *dev) @@ -601,7 +601,7 @@ void bmi088_accel_core_remove(struct device *dev) pm_runtime_set_suspended(dev); bmi088_accel_power_down(data); } -EXPORT_SYMBOL_NS_GPL(bmi088_accel_core_remove, IIO_BMI088); +EXPORT_SYMBOL_NS_GPL(bmi088_accel_core_remove, "IIO_BMI088"); static int bmi088_accel_runtime_suspend(struct device *dev) { diff --git a/drivers/iio/accel/bmi088-accel-i2c.c b/drivers/iio/accel/bmi088-accel-i2c.c index 17e9156bbe89e252b82830d421fe80186096d5ed..bd22bd0d3c250da8e2e161685cf0a8d7926eb42c 100644 --- a/drivers/iio/accel/bmi088-accel-i2c.c +++ b/drivers/iio/accel/bmi088-accel-i2c.c @@ -67,4 +67,4 @@ module_i2c_driver(bmi088_accel_driver); MODULE_AUTHOR("Jun Yan "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("BMI088 accelerometer driver (I2C)"); -MODULE_IMPORT_NS(IIO_BMI088); +MODULE_IMPORT_NS("IIO_BMI088"); diff --git a/drivers/iio/accel/bmi088-accel-spi.c b/drivers/iio/accel/bmi088-accel-spi.c index df1adc059aa94b9d1a782891e0fa6d497c000fbd..c9d51a74c07fbbc214d704eb804a09d85ac08929 100644 --- a/drivers/iio/accel/bmi088-accel-spi.c +++ b/drivers/iio/accel/bmi088-accel-spi.c @@ -94,4 +94,4 @@ module_spi_driver(bmi088_accel_driver); MODULE_AUTHOR("Niek van Agt "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("BMI088 accelerometer driver (SPI)"); -MODULE_IMPORT_NS(IIO_BMI088); +MODULE_IMPORT_NS("IIO_BMI088"); diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index acadabec4df7ad1c838e9721cbc814a4fa69554c..65aac60f12451076c00241bc1bbce9af72e86639 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -163,7 +164,7 @@ struct fxls8962af_data { const struct fxls8962af_chip_info *chip_info; struct { __le16 channels[3]; - s64 ts __aligned(8); + aligned_s64 ts; } scan; int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */ struct iio_mount_matrix orientation; @@ -179,7 +180,7 @@ const struct regmap_config fxls8962af_i2c_regmap_conf = { .val_bits = 8, .max_register = FXLS8962AF_MAX_REG, }; -EXPORT_SYMBOL_NS_GPL(fxls8962af_i2c_regmap_conf, IIO_FXLS8962AF); +EXPORT_SYMBOL_NS_GPL(fxls8962af_i2c_regmap_conf, "IIO_FXLS8962AF"); const struct regmap_config fxls8962af_spi_regmap_conf = { .reg_bits = 8, @@ -187,7 +188,7 @@ const struct regmap_config fxls8962af_spi_regmap_conf = { .val_bits = 8, .max_register = FXLS8962AF_MAX_REG, }; -EXPORT_SYMBOL_NS_GPL(fxls8962af_spi_regmap_conf, IIO_FXLS8962AF); +EXPORT_SYMBOL_NS_GPL(fxls8962af_spi_regmap_conf, "IIO_FXLS8962AF"); enum { fxls8962af_idx_x, @@ -616,7 +617,7 @@ static int fxls8962af_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct fxls8962af_data *data = iio_priv(indio_dev); u8 enable_event, enable_bits; @@ -1103,8 +1104,7 @@ static int fxls8962af_irq_setup(struct iio_dev *indio_dev, int irq) if (ret) return ret; - irq_type = irqd_get_trigger_type(irq_get_irq_data(irq)); - + irq_type = irq_get_trigger_type(irq); switch (irq_type) { case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: @@ -1220,7 +1220,7 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq) return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, IIO_FXLS8962AF); +EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, "IIO_FXLS8962AF"); static int fxls8962af_runtime_suspend(struct device *dev) { diff --git a/drivers/iio/accel/fxls8962af-i2c.c b/drivers/iio/accel/fxls8962af-i2c.c index 160124673308307f11303ac484118be8a07f86b4..2e1bb43ef2a14267d1051a67177947e25ffe4773 100644 --- a/drivers/iio/accel/fxls8962af-i2c.c +++ b/drivers/iio/accel/fxls8962af-i2c.c @@ -55,4 +55,4 @@ module_i2c_driver(fxls8962af_driver); MODULE_AUTHOR("Sean Nyekjaer "); MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_FXLS8962AF); +MODULE_IMPORT_NS("IIO_FXLS8962AF"); diff --git a/drivers/iio/accel/fxls8962af-spi.c b/drivers/iio/accel/fxls8962af-spi.c index a0d192211839f8e0638bbdfec74942db6cbc7fee..46fc6e002714f6893c5e22b11de315465a26a17f 100644 --- a/drivers/iio/accel/fxls8962af-spi.c +++ b/drivers/iio/accel/fxls8962af-spi.c @@ -55,4 +55,4 @@ module_spi_driver(fxls8962af_driver); MODULE_AUTHOR("Sean Nyekjaer "); MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_FXLS8962AF); +MODULE_IMPORT_NS("IIO_FXLS8962AF"); diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 9b7a73a4c48a520e6c65388006c2df17f1608c8d..078fab2abb68bfcfd073b2cc9443f7a2ae85cc5a 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -28,7 +28,7 @@ struct accel_3d_state { /* Ensure timestamp is naturally aligned */ struct { u32 accel_val[3]; - s64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -328,6 +328,7 @@ static int accel_3d_parse_report(struct platform_device *pdev, /* Function to initialize the processing for usage id */ static int hid_accel_3d_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret = 0; const char *name; struct iio_dev *indio_dev; @@ -335,8 +336,6 @@ static int hid_accel_3d_probe(struct platform_device *pdev) const struct iio_chan_spec *channel_spec; int channel_size; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct accel_3d_state)); if (indio_dev == NULL) @@ -424,7 +423,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_accel_3d_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct accel_3d_state *accel_state = iio_priv(indio_dev); @@ -452,11 +451,11 @@ static struct platform_driver hid_accel_3d_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_accel_3d_probe, - .remove_new = hid_accel_3d_remove, + .remove = hid_accel_3d_remove, }; module_platform_driver(hid_accel_3d_platform_driver); MODULE_DESCRIPTION("HID Sensor Accel 3D"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/accel/kionix-kx022a-i2c.c b/drivers/iio/accel/kionix-kx022a-i2c.c index 8a1d4fc28ddd5a93eb6c3237365fa6f4830dddd4..b39a43ecadffb0045c596aaa4ebe30e363057e1b 100644 --- a/drivers/iio/accel/kionix-kx022a-i2c.c +++ b/drivers/iio/accel/kionix-kx022a-i2c.c @@ -65,4 +65,4 @@ module_i2c_driver(kx022a_i2c_driver); MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver"); MODULE_AUTHOR("Matti Vaittinen "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_KX022A); +MODULE_IMPORT_NS("IIO_KX022A"); diff --git a/drivers/iio/accel/kionix-kx022a-spi.c b/drivers/iio/accel/kionix-kx022a-spi.c index f798b964d0b59ea7399b8625c2dd7edac221e1fb..c38a47806a0006cf0e80f8a6f3207864dc998422 100644 --- a/drivers/iio/accel/kionix-kx022a-spi.c +++ b/drivers/iio/accel/kionix-kx022a-spi.c @@ -65,4 +65,4 @@ module_spi_driver(kx022a_spi_driver); MODULE_DESCRIPTION("ROHM/Kionix kx022A accelerometer driver"); MODULE_AUTHOR("Matti Vaittinen "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_KX022A); +MODULE_IMPORT_NS("IIO_KX022A"); diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c index 53d59a04ae15e93487d66dbf174c58933a7b19d6..670bac21965bdeb743a7cfc258d7decf9ba85bea 100644 --- a/drivers/iio/accel/kionix-kx022a.c +++ b/drivers/iio/accel/kionix-kx022a.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -292,7 +293,7 @@ struct kx022a_data { __le16 buffer[8] __aligned(IIO_DMA_MINALIGN); struct { __le16 channels[3]; - s64 ts __aligned(8); + aligned_s64 ts; } scan; }; @@ -594,7 +595,7 @@ static int kx022a_get_axis(struct kx022a_data *data, if (ret) return ret; - *val = le16_to_cpu(data->buffer[0]); + *val = (s16)le16_to_cpu(data->buffer[0]); return IIO_VAL_INT; } @@ -1175,7 +1176,7 @@ const struct kx022a_chip_info kx022a_chip_info = { .xout_l = KX022A_REG_XOUT_L, .get_fifo_bytes_available = kx022a_get_fifo_bytes_available, }; -EXPORT_SYMBOL_NS_GPL(kx022a_chip_info, IIO_KX022A); +EXPORT_SYMBOL_NS_GPL(kx022a_chip_info, "IIO_KX022A"); const struct kx022a_chip_info kx132_chip_info = { .name = "kx132-1211", @@ -1201,7 +1202,7 @@ const struct kx022a_chip_info kx132_chip_info = { .xout_l = KX132_REG_XOUT_L, .get_fifo_bytes_available = kx132_get_fifo_bytes_available, }; -EXPORT_SYMBOL_NS_GPL(kx132_chip_info, IIO_KX022A); +EXPORT_SYMBOL_NS_GPL(kx132_chip_info, "IIO_KX022A"); /* * Despite the naming, KX132ACR-LBZ is not similar to KX132-1211 but it is @@ -1233,7 +1234,7 @@ const struct kx022a_chip_info kx132acr_chip_info = { .xout_l = KX022A_REG_XOUT_L, .get_fifo_bytes_available = kx022a_get_fifo_bytes_available, }; -EXPORT_SYMBOL_NS_GPL(kx132acr_chip_info, IIO_KX022A); +EXPORT_SYMBOL_NS_GPL(kx132acr_chip_info, "IIO_KX022A"); int kx022a_probe_internal(struct device *dev, const struct kx022a_chip_info *chip_info) { @@ -1371,7 +1372,7 @@ int kx022a_probe_internal(struct device *dev, const struct kx022a_chip_info *chi return ret; } -EXPORT_SYMBOL_NS_GPL(kx022a_probe_internal, IIO_KX022A); +EXPORT_SYMBOL_NS_GPL(kx022a_probe_internal, "IIO_KX022A"); MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver"); MODULE_AUTHOR("Matti Vaittinen "); diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index b76df88163232775bd7c652fbf79087b53905225..f2496cad8ec25fd4df029348737d76e4e0e3440d 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -4,13 +4,15 @@ * Copyright (c) 2014, Intel Corporation. */ -#include #include #include #include #include +#include +#include #include #include +#include #include #include #include @@ -168,14 +170,73 @@ #define KXCJK1013_DEFAULT_WAKE_THRES 1 -enum kx_chipset { - KXCJK1013, - KXCJ91008, - KXTJ21009, - KXTF9, - KX0221020, - KX0231025, - KX_MAX_CHIPS /* this must be last */ +/* Refer to section 4 of the specification */ +struct kx_odr_start_up_time { + int odr_bits; + int usec; +}; + +/* KXCJK-1013 */ +static const struct kx_odr_start_up_time kxcjk1013_odr_start_up_times[] = { + { 0x08, 100000 }, + { 0x09, 100000 }, + { 0x0A, 100000 }, + { 0x0B, 100000 }, + { 0x00, 80000 }, + { 0x01, 41000 }, + { 0x02, 21000 }, + { 0x03, 11000 }, + { 0x04, 6400 }, + { 0x05, 3900 }, + { 0x06, 2700 }, + { 0x07, 2100 }, + { } +}; + +/* KXCTJ2-1009 */ +static const struct kx_odr_start_up_time kxtj21009_odr_start_up_times[] = { + { 0x08, 1240000 }, + { 0x09, 621000 }, + { 0x0A, 309000 }, + { 0x0B, 151000 }, + { 0x00, 80000 }, + { 0x01, 41000 }, + { 0x02, 21000 }, + { 0x03, 11000 }, + { 0x04, 6000 }, + { 0x05, 4000 }, + { 0x06, 3000 }, + { 0x07, 2000 }, + { } +}; + +/* KXTF9 */ +static const struct kx_odr_start_up_time kxtf9_odr_start_up_times[] = { + { 0x01, 81000 }, + { 0x02, 41000 }, + { 0x03, 21000 }, + { 0x04, 11000 }, + { 0x05, 5100 }, + { 0x06, 2700 }, + { } +}; + +/* KX023-1025 */ +static const struct kx_odr_start_up_time kx0231025_odr_start_up_times[] = { + /* First 4 are not in datasheet, taken from KXCTJ2-1009 */ + { 0x08, 1240000 }, + { 0x09, 621000 }, + { 0x0A, 309000 }, + { 0x0B, 151000 }, + { 0x00, 81000 }, + { 0x01, 40000 }, + { 0x02, 22000 }, + { 0x03, 12000 }, + { 0x04, 7000 }, + { 0x05, 4400 }, + { 0x06, 3000 }, + { 0x07, 3000 }, + { } }; enum kx_acpi_type { @@ -234,6 +295,55 @@ static const struct kx_chipset_regs kx0231025_regs = { .wake_thres = KX023_REG_ATH, }; +struct kx_chipset_info { + const struct kx_chipset_regs *regs; + const struct kx_odr_start_up_time *times; + enum kx_acpi_type acpi_type; +}; + +static const struct kx_chipset_info kxcjk1013_info = { + .regs = &kxcjk1013_regs, + .times = pm_ptr(kxcjk1013_odr_start_up_times), +}; + +static const struct kx_chipset_info kxcj91008_info = { + .regs = &kxcjk1013_regs, + .times = pm_ptr(kxcjk1013_odr_start_up_times), +}; + +static const struct kx_chipset_info kxcj91008_kiox010a_info = { + .regs = &kxcjk1013_regs, + .times = pm_ptr(kxcjk1013_odr_start_up_times), + .acpi_type = ACPI_KIOX010A, +}; + +static const struct kx_chipset_info kxcj91008_kiox020a_info = { + .regs = &kxcjk1013_regs, + .times = pm_ptr(kxcjk1013_odr_start_up_times), + .acpi_type = ACPI_GENERIC, +}; + +static const struct kx_chipset_info kxcj91008_smo8500_info = { + .regs = &kxcjk1013_regs, + .times = pm_ptr(kxcjk1013_odr_start_up_times), + .acpi_type = ACPI_SMO8500, +}; + +static const struct kx_chipset_info kxtj21009_info = { + .regs = &kxcjk1013_regs, + .times = pm_ptr(kxtj21009_odr_start_up_times), +}; + +static const struct kx_chipset_info kxtf9_info = { + .regs = &kxtf9_regs, + .times = pm_ptr(kxtf9_odr_start_up_times), +}; + +static const struct kx_chipset_info kx0231025_info = { + .regs = &kx0231025_regs, + .times = pm_ptr(kx0231025_odr_start_up_times), +}; + enum kxcjk1013_axis { AXIS_X, AXIS_Y, @@ -250,7 +360,7 @@ struct kxcjk1013_data { /* Ensure timestamp naturally aligned */ struct { s16 chans[AXIS_MAX]; - s64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; u8 odr_bits; u8 range; @@ -261,9 +371,7 @@ struct kxcjk1013_data { int ev_enable_state; bool motion_trigger_on; int64_t timestamp; - enum kx_chipset chipset; - enum kx_acpi_type acpi_type; - const struct kx_chipset_regs *regs; + const struct kx_chipset_info *info; }; enum kxcjk1013_mode { @@ -314,83 +422,6 @@ static const struct kx_odr_map kxtf9_samp_freq_table[] = { static const char *const kxtf9_samp_freq_avail = "25 50 100 200 400 800"; -/* Refer to section 4 of the specification */ -static __maybe_unused const struct { - int odr_bits; - int usec; -} odr_start_up_times[KX_MAX_CHIPS][12] = { - /* KXCJK-1013 */ - { - {0x08, 100000}, - {0x09, 100000}, - {0x0A, 100000}, - {0x0B, 100000}, - {0, 80000}, - {0x01, 41000}, - {0x02, 21000}, - {0x03, 11000}, - {0x04, 6400}, - {0x05, 3900}, - {0x06, 2700}, - {0x07, 2100}, - }, - /* KXCJ9-1008 */ - { - {0x08, 100000}, - {0x09, 100000}, - {0x0A, 100000}, - {0x0B, 100000}, - {0, 80000}, - {0x01, 41000}, - {0x02, 21000}, - {0x03, 11000}, - {0x04, 6400}, - {0x05, 3900}, - {0x06, 2700}, - {0x07, 2100}, - }, - /* KXCTJ2-1009 */ - { - {0x08, 1240000}, - {0x09, 621000}, - {0x0A, 309000}, - {0x0B, 151000}, - {0, 80000}, - {0x01, 41000}, - {0x02, 21000}, - {0x03, 11000}, - {0x04, 6000}, - {0x05, 4000}, - {0x06, 3000}, - {0x07, 2000}, - }, - /* KXTF9 */ - { - {0x01, 81000}, - {0x02, 41000}, - {0x03, 21000}, - {0x04, 11000}, - {0x05, 5100}, - {0x06, 2700}, - }, - /* KX023-1025 */ - { - /* First 4 are not in datasheet, taken from KXCTJ2-1009 */ - {0x08, 1240000}, - {0x09, 621000}, - {0x0A, 309000}, - {0x0B, 151000}, - {0, 81000}, - {0x01, 40000}, - {0x02, 22000}, - {0x03, 12000}, - {0x04, 7000}, - {0x05, 4400}, - {0x06, 3000}, - {0x07, 3000}, - }, -}; - static const struct { u16 scale; u8 gsel_0; @@ -424,30 +455,15 @@ static int kiox010a_dsm(struct device *dev, int fn_index) return 0; } -static const struct acpi_device_id kx_acpi_match[] = { - {"KXCJ1013", KXCJK1013}, - {"KXCJ1008", KXCJ91008}, - {"KXCJ9000", KXCJ91008}, - {"KIOX0008", KXCJ91008}, - {"KIOX0009", KXTJ21009}, - {"KIOX000A", KXCJ91008}, - {"KIOX010A", KXCJ91008}, /* KXCJ91008 in the display of a yoga 2-in-1 */ - {"KIOX020A", KXCJ91008}, /* KXCJ91008 in the base of a yoga 2-in-1 */ - {"KXTJ1009", KXTJ21009}, - {"KXJ2109", KXTJ21009}, - {"SMO8500", KXCJ91008}, - { } -}; -MODULE_DEVICE_TABLE(acpi, kx_acpi_match); - #endif static int kxcjk1013_set_mode(struct kxcjk1013_data *data, enum kxcjk1013_mode mode) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); return ret; @@ -458,7 +474,7 @@ static int kxcjk1013_set_mode(struct kxcjk1013_data *data, else ret |= KXCJK1013_REG_CTRL1_BIT_PC1; - ret = i2c_smbus_write_byte_data(data->client, data->regs->ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); return ret; @@ -470,9 +486,10 @@ static int kxcjk1013_set_mode(struct kxcjk1013_data *data, static int kxcjk1013_get_mode(struct kxcjk1013_data *data, enum kxcjk1013_mode *mode) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); return ret; @@ -488,9 +505,10 @@ static int kxcjk1013_get_mode(struct kxcjk1013_data *data, static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); return ret; @@ -501,7 +519,7 @@ static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index) ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3); ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4); - ret = i2c_smbus_write_byte_data(data->client, data->regs->ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); return ret; @@ -514,10 +532,11 @@ static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index) static int kxcjk1013_chip_init(struct kxcjk1013_data *data) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; #ifdef CONFIG_ACPI - if (data->acpi_type == ACPI_KIOX010A) { + if (data->info->acpi_type == ACPI_KIOX010A) { /* Make sure the kbd and touchpad on 2-in-1s using 2 KXCJ91008-s work */ kiox010a_dsm(&data->client->dev, KIOX010A_SET_LAPTOP_MODE); } @@ -535,7 +554,7 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) if (ret < 0) return ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); return ret; @@ -544,7 +563,7 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) /* Set 12 bit mode */ ret |= KXCJK1013_REG_CTRL1_BIT_RES; - ret = i2c_smbus_write_byte_data(data->client, data->regs->ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_ctrl\n"); return ret; @@ -555,7 +574,7 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) if (ret < 0) return ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->data_ctrl); + ret = i2c_smbus_read_byte_data(data->client, regs->data_ctrl); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_data_ctrl\n"); return ret; @@ -564,7 +583,7 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) data->odr_bits = ret; /* Set up INT polarity */ - ret = i2c_smbus_read_byte_data(data->client, data->regs->int_ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->int_ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n"); return ret; @@ -575,14 +594,14 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) else ret &= ~KXCJK1013_REG_INT_CTRL1_BIT_IEA; - ret = i2c_smbus_write_byte_data(data->client, data->regs->int_ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->int_ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n"); return ret; } - /* On KX023 and KX022, route all used interrupts to INT1 for now */ - if ((data->chipset == KX0231025 || data->chipset == KX0221020) && data->client->irq > 0) { + /* On KX023, route all used interrupts to INT1 for now */ + if (data->info == &kx0231025_info && data->client->irq > 0) { ret = i2c_smbus_write_byte_data(data->client, KX023_REG_INC4, KX023_REG_INC4_DRDY1 | KX023_REG_INC4_WUFI1); @@ -601,20 +620,17 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) return 0; } -#ifdef CONFIG_PM static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data) { - int i; - int idx = data->chipset; + const struct kx_odr_start_up_time *times; - for (i = 0; i < ARRAY_SIZE(odr_start_up_times[idx]); ++i) { - if (odr_start_up_times[idx][i].odr_bits == data->odr_bits) - return odr_start_up_times[idx][i].usec; + for (times = data->info->times; times->usec; times++) { + if (times->odr_bits == data->odr_bits) + return times->usec; } return KXCJK1013_MAX_STARTUP_TIME_US; } -#endif static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on) { @@ -639,18 +655,17 @@ static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on) static int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; - ret = i2c_smbus_write_byte_data(data->client, data->regs->wake_timer, - data->wake_dur); + ret = i2c_smbus_write_byte_data(data->client, regs->wake_timer, data->wake_dur); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_wake_timer\n"); return ret; } - ret = i2c_smbus_write_byte_data(data->client, data->regs->wake_thres, - data->wake_thres); + ret = i2c_smbus_write_byte_data(data->client, regs->wake_thres, data->wake_thres); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_wake_thres\n"); return ret; @@ -662,6 +677,7 @@ static int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data) static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data, bool status) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; enum kxcjk1013_mode store_mode; @@ -678,7 +694,7 @@ static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data, if (ret < 0) return ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->int_ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->int_ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n"); return ret; @@ -689,13 +705,13 @@ static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data, else ret &= ~KXCJK1013_REG_INT_CTRL1_BIT_IEN; - ret = i2c_smbus_write_byte_data(data->client, data->regs->int_ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->int_ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n"); return ret; } - ret = i2c_smbus_read_byte_data(data->client, data->regs->ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); return ret; @@ -706,7 +722,7 @@ static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data, else ret &= ~KXCJK1013_REG_CTRL1_BIT_WUFE; - ret = i2c_smbus_write_byte_data(data->client, data->regs->ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); return ret; @@ -724,6 +740,7 @@ static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data, static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data, bool status) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; enum kxcjk1013_mode store_mode; @@ -736,7 +753,7 @@ static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data, if (ret < 0) return ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->int_ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->int_ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n"); return ret; @@ -747,13 +764,13 @@ static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data, else ret &= ~KXCJK1013_REG_INT_CTRL1_BIT_IEN; - ret = i2c_smbus_write_byte_data(data->client, data->regs->int_ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->int_ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n"); return ret; } - ret = i2c_smbus_read_byte_data(data->client, data->regs->ctrl1); + ret = i2c_smbus_read_byte_data(data->client, regs->ctrl1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); return ret; @@ -764,7 +781,7 @@ static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data, else ret &= ~KXCJK1013_REG_CTRL1_BIT_DRDY; - ret = i2c_smbus_write_byte_data(data->client, data->regs->ctrl1, ret); + ret = i2c_smbus_write_byte_data(data->client, regs->ctrl1, ret); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); return ret; @@ -811,6 +828,7 @@ static int kxcjk1013_convert_odr_value(const struct kx_odr_map *map, static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) { + const struct kx_chipset_regs *regs = data->info->regs; int ret; enum kxcjk1013_mode store_mode; const struct kx_odr_map *odr_setting; @@ -819,7 +837,7 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) if (ret < 0) return ret; - if (data->chipset == KXTF9) + if (data->info == &kxtf9_info) odr_setting = kxcjk1013_find_odr_value(kxtf9_samp_freq_table, ARRAY_SIZE(kxtf9_samp_freq_table), val, val2); @@ -836,7 +854,7 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) if (ret < 0) return ret; - ret = i2c_smbus_write_byte_data(data->client, data->regs->data_ctrl, + ret = i2c_smbus_write_byte_data(data->client, regs->data_ctrl, odr_setting->odr_bits); if (ret < 0) { dev_err(&data->client->dev, "Error writing data_ctrl\n"); @@ -845,7 +863,7 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) data->odr_bits = odr_setting->odr_bits; - ret = i2c_smbus_write_byte_data(data->client, data->regs->wuf_ctrl, + ret = i2c_smbus_write_byte_data(data->client, regs->wuf_ctrl, odr_setting->wuf_bits); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_ctrl2\n"); @@ -863,7 +881,7 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) static int kxcjk1013_get_odr(struct kxcjk1013_data *data, int *val, int *val2) { - if (data->chipset == KXTF9) + if (data->info == &kxtf9_info) return kxcjk1013_convert_odr_value(kxtf9_samp_freq_table, ARRAY_SIZE(kxtf9_samp_freq_table), data->odr_bits, val, val2); @@ -1063,7 +1081,7 @@ static int kxcjk1013_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct kxcjk1013_data *data = iio_priv(indio_dev); int ret; @@ -1130,7 +1148,7 @@ static ssize_t kxcjk1013_get_samp_freq_avail(struct device *dev, struct kxcjk1013_data *data = iio_priv(indio_dev); const char *str; - if (data->chipset == KXTF9) + if (data->info == &kxtf9_info) str = kxtf9_samp_freq_avail; else str = kxcjk1013_samp_freq_avail; @@ -1207,7 +1225,7 @@ static const struct iio_buffer_setup_ops kxcjk1013_buffer_setup_ops = { .postdisable = kxcjk1013_buffer_postdisable, }; -static const struct iio_info kxcjk1013_info = { +static const struct iio_info kxcjk1013_iio_info = { .attrs = &kxcjk1013_attrs_group, .read_raw = kxcjk1013_read_raw, .write_raw = kxcjk1013_write_raw, @@ -1247,9 +1265,10 @@ static void kxcjk1013_trig_reen(struct iio_trigger *trig) { struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct kxcjk1013_data *data = iio_priv(indio_dev); + const struct kx_chipset_regs *regs = data->info->regs; int ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->int_rel); + ret = i2c_smbus_read_byte_data(data->client, regs->int_rel); if (ret < 0) dev_err(&data->client->dev, "Error reading reg_int_rel\n"); } @@ -1301,8 +1320,9 @@ static const struct iio_trigger_ops kxcjk1013_trigger_ops = { static void kxcjk1013_report_motion_event(struct iio_dev *indio_dev) { struct kxcjk1013_data *data = iio_priv(indio_dev); + const struct kx_chipset_regs *regs = data->info->regs; - int ret = i2c_smbus_read_byte_data(data->client, data->regs->int_src2); + int ret = i2c_smbus_read_byte_data(data->client, regs->int_src2); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_int_src2\n"); return; @@ -1367,16 +1387,17 @@ static irqreturn_t kxcjk1013_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; struct kxcjk1013_data *data = iio_priv(indio_dev); + const struct kx_chipset_regs *regs = data->info->regs; int ret; - ret = i2c_smbus_read_byte_data(data->client, data->regs->int_src1); + ret = i2c_smbus_read_byte_data(data->client, regs->int_src1); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_int_src1\n"); goto ack_intr; } if (ret & KXCJK1013_REG_INT_SRC1_BIT_WUFS) { - if (data->chipset == KXTF9) + if (data->info == &kxtf9_info) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, @@ -1392,7 +1413,7 @@ ack_intr: if (data->dready_trigger_on) return IRQ_HANDLED; - ret = i2c_smbus_read_byte_data(data->client, data->regs->int_rel); + ret = i2c_smbus_read_byte_data(data->client, regs->int_rel); if (ret < 0) dev_err(&data->client->dev, "Error reading reg_int_rel\n"); @@ -1417,31 +1438,6 @@ static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private) return IRQ_HANDLED; } -static const char *kxcjk1013_match_acpi_device(struct device *dev, - enum kx_chipset *chipset, - enum kx_acpi_type *acpi_type, - const char **label) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - - if (strcmp(id->id, "SMO8500") == 0) { - *acpi_type = ACPI_SMO8500; - } else if (strcmp(id->id, "KIOX010A") == 0) { - *acpi_type = ACPI_KIOX010A; - *label = "accel-display"; - } else if (strcmp(id->id, "KIOX020A") == 0) { - *label = "accel-base"; - } - - *chipset = (enum kx_chipset)id->driver_data; - - return dev_name(dev); -} - static int kxcjk1013_probe(struct i2c_client *client) { const struct i2c_device_id *id = i2c_client_get_device_id(client); @@ -1449,6 +1445,7 @@ static int kxcjk1013_probe(struct i2c_client *client) struct kxcjk1013_data *data; struct iio_dev *indio_dev; struct kxcjk_1013_platform_data *pdata; + const void *ddata = NULL; const char *name; int ret; @@ -1489,32 +1486,18 @@ static int kxcjk1013_probe(struct i2c_client *client) msleep(20); if (id) { - data->chipset = (enum kx_chipset)(id->driver_data); name = id->name; - } else if (ACPI_HANDLE(&client->dev)) { - name = kxcjk1013_match_acpi_device(&client->dev, - &data->chipset, - &data->acpi_type, - &indio_dev->label); - } else - return -ENODEV; - - switch (data->chipset) { - case KXCJK1013: - case KXCJ91008: - case KXTJ21009: - data->regs = &kxcjk1013_regs; - break; - case KXTF9: - data->regs = &kxtf9_regs; - break; - case KX0221020: - case KX0231025: - data->regs = &kx0231025_regs; - break; - default: - return -EINVAL; + data->info = (const struct kx_chipset_info *)(id->driver_data); + } else { + name = iio_get_acpi_device_name_and_data(&client->dev, &ddata); + data->info = ddata; + if (data->info == &kxcj91008_kiox010a_info) + indio_dev->label = "accel-display"; + else if (data->info == &kxcj91008_kiox020a_info) + indio_dev->label = "accel-base"; } + if (!name) + return -ENODEV; ret = kxcjk1013_chip_init(data); if (ret < 0) @@ -1527,9 +1510,9 @@ static int kxcjk1013_probe(struct i2c_client *client) indio_dev->available_scan_masks = kxcjk1013_scan_masks; indio_dev->name = name; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->info = &kxcjk1013_info; + indio_dev->info = &kxcjk1013_iio_info; - if (client->irq > 0 && data->acpi_type != ACPI_SMO8500) { + if (client->irq > 0 && data->info->acpi_type != ACPI_SMO8500) { ret = devm_request_threaded_irq(&client->dev, client->irq, kxcjk1013_data_rdy_trig_poll, kxcjk1013_event_handler, @@ -1637,7 +1620,6 @@ static void kxcjk1013_remove(struct i2c_client *client) mutex_unlock(&data->mutex); } -#ifdef CONFIG_PM_SLEEP static int kxcjk1013_suspend(struct device *dev) { struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); @@ -1665,9 +1647,7 @@ static int kxcjk1013_resume(struct device *dev) return ret; } -#endif -#ifdef CONFIG_PM static int kxcjk1013_runtime_suspend(struct device *dev) { struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); @@ -1701,44 +1681,56 @@ static int kxcjk1013_runtime_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops kxcjk1013_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(kxcjk1013_suspend, kxcjk1013_resume) - SET_RUNTIME_PM_OPS(kxcjk1013_runtime_suspend, - kxcjk1013_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(kxcjk1013_suspend, kxcjk1013_resume) + RUNTIME_PM_OPS(kxcjk1013_runtime_suspend, kxcjk1013_runtime_resume, NULL) }; static const struct i2c_device_id kxcjk1013_id[] = { - {"kxcjk1013", KXCJK1013}, - {"kxcj91008", KXCJ91008}, - {"kxtj21009", KXTJ21009}, - {"kxtf9", KXTF9}, - {"kx022-1020", KX0221020}, - {"kx023-1025", KX0231025}, - {"SMO8500", KXCJ91008}, - {} + { "kxcjk1013", (kernel_ulong_t)&kxcjk1013_info }, + { "kxcj91008", (kernel_ulong_t)&kxcj91008_info }, + { "kxtj21009", (kernel_ulong_t)&kxtj21009_info }, + { "kxtf9", (kernel_ulong_t)&kxtf9_info }, + { "kx023-1025", (kernel_ulong_t)&kx0231025_info }, + { } }; - MODULE_DEVICE_TABLE(i2c, kxcjk1013_id); static const struct of_device_id kxcjk1013_of_match[] = { - { .compatible = "kionix,kxcjk1013", }, - { .compatible = "kionix,kxcj91008", }, - { .compatible = "kionix,kxtj21009", }, - { .compatible = "kionix,kxtf9", }, - { .compatible = "kionix,kx022-1020", }, - { .compatible = "kionix,kx023-1025", }, + { .compatible = "kionix,kxcjk1013", &kxcjk1013_info }, + { .compatible = "kionix,kxcj91008", &kxcj91008_info }, + { .compatible = "kionix,kxtj21009", &kxtj21009_info }, + { .compatible = "kionix,kxtf9", &kxtf9_info }, + { .compatible = "kionix,kx023-1025", &kx0231025_info }, { } }; MODULE_DEVICE_TABLE(of, kxcjk1013_of_match); +static const struct acpi_device_id kx_acpi_match[] = { + { "KIOX0008", (kernel_ulong_t)&kxcj91008_info }, + { "KIOX0009", (kernel_ulong_t)&kxtj21009_info }, + { "KIOX000A", (kernel_ulong_t)&kxcj91008_info }, + /* KXCJ91008 in the display of a yoga 2-in-1 */ + { "KIOX010A", (kernel_ulong_t)&kxcj91008_kiox010a_info }, + /* KXCJ91008 in the base of a yoga 2-in-1 */ + { "KIOX020A", (kernel_ulong_t)&kxcj91008_kiox020a_info }, + { "KXCJ1008", (kernel_ulong_t)&kxcj91008_info }, + { "KXCJ1013", (kernel_ulong_t)&kxcjk1013_info }, + { "KXCJ9000", (kernel_ulong_t)&kxcj91008_info }, + { "KXJ2109", (kernel_ulong_t)&kxtj21009_info }, + { "KXTJ1009", (kernel_ulong_t)&kxtj21009_info }, + { "SMO8500", (kernel_ulong_t)&kxcj91008_smo8500_info }, + { } +}; +MODULE_DEVICE_TABLE(acpi, kx_acpi_match); + static struct i2c_driver kxcjk1013_driver = { .driver = { .name = KXCJK1013_DRV_NAME, - .acpi_match_table = ACPI_PTR(kx_acpi_match), + .acpi_match_table = kx_acpi_match, .of_match_table = kxcjk1013_of_match, - .pm = &kxcjk1013_pm_ops, + .pm = pm_ptr(&kxcjk1013_pm_ops), }, .probe = kxcjk1013_probe, .remove = kxcjk1013_remove, diff --git a/drivers/iio/accel/kxsd9-i2c.c b/drivers/iio/accel/kxsd9-i2c.c index c4c7e2d4e98ad992fc447355b159ccc2d5966073..3857d2edf25075381a8872bc973861ab500f9e13 100644 --- a/drivers/iio/accel/kxsd9-i2c.c +++ b/drivers/iio/accel/kxsd9-i2c.c @@ -62,4 +62,4 @@ module_i2c_driver(kxsd9_i2c_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("KXSD9 accelerometer I2C interface"); -MODULE_IMPORT_NS(IIO_KXSD9); +MODULE_IMPORT_NS("IIO_KXSD9"); diff --git a/drivers/iio/accel/kxsd9-spi.c b/drivers/iio/accel/kxsd9-spi.c index 4414670dfb436be30a93364b1055a6b33868e727..a05f4467d94a4a8bc0a0139183600ecc444a8fc9 100644 --- a/drivers/iio/accel/kxsd9-spi.c +++ b/drivers/iio/accel/kxsd9-spi.c @@ -63,4 +63,4 @@ module_spi_driver(kxsd9_spi_driver); MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Kionix KXSD9 SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_KXSD9); +MODULE_IMPORT_NS("IIO_KXSD9"); diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c index 70dfd6e354dbbbfd8af15d7ef99d1e29a861350b..0ededf8cfdca6bf390ace701ca11433a92549758 100644 --- a/drivers/iio/accel/kxsd9.c +++ b/drivers/iio/accel/kxsd9.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -215,7 +216,7 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p) */ struct { __be16 chan[4]; - s64 ts __aligned(8); + aligned_s64 ts; } hw_values; int ret; @@ -473,7 +474,7 @@ err_power_down: return ret; } -EXPORT_SYMBOL_NS(kxsd9_common_probe, IIO_KXSD9); +EXPORT_SYMBOL_NS(kxsd9_common_probe, "IIO_KXSD9"); void kxsd9_common_remove(struct device *dev) { @@ -487,7 +488,7 @@ void kxsd9_common_remove(struct device *dev) pm_runtime_disable(dev); kxsd9_power_down(st); } -EXPORT_SYMBOL_NS(kxsd9_common_remove, IIO_KXSD9); +EXPORT_SYMBOL_NS(kxsd9_common_remove, "IIO_KXSD9"); static int kxsd9_runtime_suspend(struct device *dev) { diff --git a/drivers/iio/accel/mma7455_core.c b/drivers/iio/accel/mma7455_core.c index a34195b3215ddb883eaa8340b4ab045923669019..30746621052c7e09990828355a537c3e455cebf8 100644 --- a/drivers/iio/accel/mma7455_core.c +++ b/drivers/iio/accel/mma7455_core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "mma7455.h" @@ -58,7 +59,7 @@ struct mma7455_data { */ struct { __le16 channels[3]; - s64 ts __aligned(8); + aligned_s64 ts; } scan; }; @@ -238,7 +239,7 @@ const struct regmap_config mma7455_core_regmap = { .val_bits = 8, .max_register = MMA7455_REG_TW, }; -EXPORT_SYMBOL_NS_GPL(mma7455_core_regmap, IIO_MMA7455); +EXPORT_SYMBOL_NS_GPL(mma7455_core_regmap, "IIO_MMA7455"); int mma7455_core_probe(struct device *dev, struct regmap *regmap, const char *name) @@ -293,7 +294,7 @@ int mma7455_core_probe(struct device *dev, struct regmap *regmap, return 0; } -EXPORT_SYMBOL_NS_GPL(mma7455_core_probe, IIO_MMA7455); +EXPORT_SYMBOL_NS_GPL(mma7455_core_probe, "IIO_MMA7455"); void mma7455_core_remove(struct device *dev) { @@ -306,7 +307,7 @@ void mma7455_core_remove(struct device *dev) regmap_write(mma7455->regmap, MMA7455_REG_MCTL, MMA7455_MCTL_MODE_STANDBY); } -EXPORT_SYMBOL_NS_GPL(mma7455_core_remove, IIO_MMA7455); +EXPORT_SYMBOL_NS_GPL(mma7455_core_remove, "IIO_MMA7455"); MODULE_AUTHOR("Joachim Eastwood "); MODULE_DESCRIPTION("Freescale MMA7455L core accelerometer driver"); diff --git a/drivers/iio/accel/mma7455_i2c.c b/drivers/iio/accel/mma7455_i2c.c index 36a357c8e9ed598ee5ffc28caba642be866bf925..2ff8eb1f9ce9602918a1590e4ebcb9e9169b70ee 100644 --- a/drivers/iio/accel/mma7455_i2c.c +++ b/drivers/iio/accel/mma7455_i2c.c @@ -59,4 +59,4 @@ module_i2c_driver(mma7455_i2c_driver); MODULE_AUTHOR("Joachim Eastwood "); MODULE_DESCRIPTION("Freescale MMA7455L I2C accelerometer driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MMA7455); +MODULE_IMPORT_NS("IIO_MMA7455"); diff --git a/drivers/iio/accel/mma7455_spi.c b/drivers/iio/accel/mma7455_spi.c index fcdde2e8a84b2aa70ebe852aa67bbcee6d59718c..aca02e83f789d30cd31e4e28ac79800fd144894c 100644 --- a/drivers/iio/accel/mma7455_spi.c +++ b/drivers/iio/accel/mma7455_spi.c @@ -47,4 +47,4 @@ module_spi_driver(mma7455_spi_driver); MODULE_AUTHOR("Joachim Eastwood "); MODULE_DESCRIPTION("Freescale MMA7455L SPI accelerometer driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MMA7455); +MODULE_IMPORT_NS("IIO_MMA7455"); diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 62e6369e22696cfc8082ffe9d27a5b38d280c752..962d289065ab7bb3da5ae102cb5ee2cb96662af5 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -32,6 +32,7 @@ #include #include #include +#include #define MMA8452_STATUS 0x00 #define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0)) @@ -115,7 +116,7 @@ struct mma8452_data { /* Ensure correct alignment of time stamp when present */ struct { __be16 channels[3]; - s64 ts __aligned(8); + aligned_s64 ts; } buffer; }; @@ -973,7 +974,7 @@ static int mma8452_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct mma8452_data *data = iio_priv(indio_dev); int val, ret; diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index fa1799b0b0dff35ccd811c4abee3883249c184da..1b96687da01a695d9fce7ff7fd9afcd4d9b5fbbb 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -4,11 +4,11 @@ * Copyright (c) 2014, Intel Corporation. */ -#include #include #include +#include +#include #include -#include #include #include #include @@ -45,7 +45,7 @@ enum mma9551_tilt_axis { struct mma9551_data { struct i2c_client *client; struct mutex mutex; - int event_enabled[3]; + bool event_enabled[3]; int irqs[MMA9551_GPIO_COUNT]; }; @@ -162,7 +162,7 @@ static int mma9551_read_event_config(struct iio_dev *indio_dev, static int mma9551_config_incli_event(struct iio_dev *indio_dev, enum iio_modifier axis, - int state) + bool state) { struct mma9551_data *data = iio_priv(indio_dev); enum mma9551_tilt_axis mma_axis; @@ -174,7 +174,7 @@ static int mma9551_config_incli_event(struct iio_dev *indio_dev, if (data->event_enabled[mma_axis] == state) return 0; - if (state == 0) { + if (!state) { ret = mma9551_gpio_config(data->client, (enum mma9551_gpio_pin)mma_axis, MMA9551_APPID_NONE, 0, 0); @@ -225,7 +225,7 @@ static int mma9551_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct mma9551_data *data = iio_priv(indio_dev); int ret; @@ -435,17 +435,6 @@ static int mma9551_gpio_probe(struct iio_dev *indio_dev) return 0; } -static const char *mma9551_match_acpi_device(struct device *dev) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - - return dev_name(dev); -} - static int mma9551_probe(struct i2c_client *client) { const struct i2c_device_id *id = i2c_client_get_device_id(client); @@ -464,8 +453,8 @@ static int mma9551_probe(struct i2c_client *client) if (id) name = id->name; - else if (ACPI_HANDLE(&client->dev)) - name = mma9551_match_acpi_device(&client->dev); + else + name = iio_get_acpi_device_name(&client->dev); ret = mma9551_init(data); if (ret < 0) @@ -618,4 +607,4 @@ MODULE_AUTHOR("Irina Tirdea "); MODULE_AUTHOR("Vlad Dogaru "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver"); -MODULE_IMPORT_NS(IIO_MMA9551); +MODULE_IMPORT_NS("IIO_MMA9551"); diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c index b898f865fb87591641767732aeec02afdaa881a8..3e7d9b79ed0ee9c05e0c2e8b0791e356a3692b18 100644 --- a/drivers/iio/accel/mma9551_core.c +++ b/drivers/iio/accel/mma9551_core.c @@ -219,7 +219,7 @@ int mma9551_read_config_byte(struct i2c_client *client, u8 app_id, return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, reg, NULL, 0, val, 1); } -EXPORT_SYMBOL_NS(mma9551_read_config_byte, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_config_byte, "IIO_MMA9551"); /** * mma9551_write_config_byte() - write 1 configuration byte @@ -244,7 +244,7 @@ int mma9551_write_config_byte(struct i2c_client *client, u8 app_id, return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg, &val, 1, NULL, 0); } -EXPORT_SYMBOL_NS(mma9551_write_config_byte, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_write_config_byte, "IIO_MMA9551"); /** * mma9551_read_status_byte() - read 1 status byte @@ -269,7 +269,7 @@ int mma9551_read_status_byte(struct i2c_client *client, u8 app_id, return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, reg, NULL, 0, val, 1); } -EXPORT_SYMBOL_NS(mma9551_read_status_byte, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_status_byte, "IIO_MMA9551"); /** * mma9551_read_config_word() - read 1 config word @@ -303,7 +303,7 @@ int mma9551_read_config_word(struct i2c_client *client, u8 app_id, return 0; } -EXPORT_SYMBOL_NS(mma9551_read_config_word, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_config_word, "IIO_MMA9551"); /** * mma9551_write_config_word() - write 1 config word @@ -330,7 +330,7 @@ int mma9551_write_config_word(struct i2c_client *client, u8 app_id, return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg, (u8 *)&v, 2, NULL, 0); } -EXPORT_SYMBOL_NS(mma9551_write_config_word, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_write_config_word, "IIO_MMA9551"); /** * mma9551_read_status_word() - read 1 status word @@ -364,7 +364,7 @@ int mma9551_read_status_word(struct i2c_client *client, u8 app_id, return 0; } -EXPORT_SYMBOL_NS(mma9551_read_status_word, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_status_word, "IIO_MMA9551"); /** * mma9551_read_config_words() - read multiple config words @@ -403,7 +403,7 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id, return 0; } -EXPORT_SYMBOL_NS(mma9551_read_config_words, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_config_words, "IIO_MMA9551"); /** * mma9551_read_status_words() - read multiple status words @@ -442,7 +442,7 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id, return 0; } -EXPORT_SYMBOL_NS(mma9551_read_status_words, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_status_words, "IIO_MMA9551"); /** * mma9551_write_config_words() - write multiple config words @@ -477,7 +477,7 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id, return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0); } -EXPORT_SYMBOL_NS(mma9551_write_config_words, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_write_config_words, "IIO_MMA9551"); /** * mma9551_update_config_bits() - update bits in register @@ -513,7 +513,7 @@ int mma9551_update_config_bits(struct i2c_client *client, u8 app_id, return mma9551_write_config_byte(client, app_id, reg, tmp); } -EXPORT_SYMBOL_NS(mma9551_update_config_bits, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_update_config_bits, "IIO_MMA9551"); /** * mma9551_gpio_config() - configure gpio @@ -592,7 +592,7 @@ int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin, return ret; } -EXPORT_SYMBOL_NS(mma9551_gpio_config, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_gpio_config, "IIO_MMA9551"); /** * mma9551_read_version() - read device version information @@ -622,7 +622,7 @@ int mma9551_read_version(struct i2c_client *client) return 0; } -EXPORT_SYMBOL_NS(mma9551_read_version, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_version, "IIO_MMA9551"); /** * mma9551_set_device_state() - sets HW power mode @@ -652,7 +652,7 @@ int mma9551_set_device_state(struct i2c_client *client, bool enable) MMA9551_SLEEP_CFG_FLEEN : MMA9551_SLEEP_CFG_SNCEN); } -EXPORT_SYMBOL_NS(mma9551_set_device_state, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_set_device_state, "IIO_MMA9551"); /** * mma9551_set_power_state() - sets runtime PM state @@ -686,7 +686,7 @@ int mma9551_set_power_state(struct i2c_client *client, bool on) return 0; } -EXPORT_SYMBOL_NS(mma9551_set_power_state, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_set_power_state, "IIO_MMA9551"); /** * mma9551_sleep() - sleep @@ -705,7 +705,7 @@ void mma9551_sleep(int freq) else msleep_interruptible(sleep_val); } -EXPORT_SYMBOL_NS(mma9551_sleep, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_sleep, "IIO_MMA9551"); /** * mma9551_read_accel_chan() - read accelerometer channel @@ -761,7 +761,7 @@ out_poweroff: mma9551_set_power_state(client, false); return ret; } -EXPORT_SYMBOL_NS(mma9551_read_accel_chan, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_accel_chan, "IIO_MMA9551"); /** * mma9551_read_accel_scale() - read accelerometer scale @@ -779,7 +779,7 @@ int mma9551_read_accel_scale(int *val, int *val2) return IIO_VAL_INT_PLUS_MICRO; } -EXPORT_SYMBOL_NS(mma9551_read_accel_scale, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_read_accel_scale, "IIO_MMA9551"); /** * mma9551_app_reset() - reset application @@ -798,7 +798,7 @@ int mma9551_app_reset(struct i2c_client *client, u32 app_mask) MMA9551_RSC_OFFSET(app_mask), MMA9551_RSC_VAL(app_mask)); } -EXPORT_SYMBOL_NS(mma9551_app_reset, IIO_MMA9551); +EXPORT_SYMBOL_NS(mma9551_app_reset, "IIO_MMA9551"); MODULE_AUTHOR("Irina Tirdea "); MODULE_AUTHOR("Vlad Dogaru "); diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 86543f34ef17cfe9ed092930b07c2418e0bf373a..00e224efc8ed2d03d08a22fb0eb51b7dc1b1ddcc 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -4,11 +4,11 @@ * Copyright (c) 2014, Intel Corporation. */ -#include #include #include +#include +#include #include -#include #include #include #include @@ -725,7 +725,8 @@ static int mma9553_read_event_config(struct iio_dev *indio_dev, static int mma9553_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, + bool state) { struct mma9553_data *data = iio_priv(indio_dev); struct mma9553_event *event; @@ -1030,9 +1031,9 @@ static irqreturn_t mma9553_event_handler(int irq, void *private) if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) { data->stepcnt = stepcnt; iio_push_event(indio_dev, - IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, - IIO_EV_DIR_NONE, - IIO_EV_TYPE_CHANGE, 0, 0, 0), + IIO_UNMOD_EVENT_CODE(IIO_STEPS, 0, + IIO_EV_TYPE_CHANGE, + IIO_EV_DIR_NONE), data->timestamp); } @@ -1041,20 +1042,18 @@ static irqreturn_t mma9553_event_handler(int irq, void *private) /* ev_activity can be NULL if activity == ACTIVITY_UNKNOWN */ if (ev_prev_activity && ev_prev_activity->enabled) iio_push_event(indio_dev, - IIO_EVENT_CODE(IIO_ACTIVITY, 0, - ev_prev_activity->info->mod, - IIO_EV_DIR_FALLING, - IIO_EV_TYPE_THRESH, 0, 0, - 0), + IIO_MOD_EVENT_CODE(IIO_ACTIVITY, 0, + ev_prev_activity->info->mod, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), data->timestamp); if (ev_activity && ev_activity->enabled) iio_push_event(indio_dev, - IIO_EVENT_CODE(IIO_ACTIVITY, 0, - ev_activity->info->mod, - IIO_EV_DIR_RISING, - IIO_EV_TYPE_THRESH, 0, 0, - 0), + IIO_MOD_EVENT_CODE(IIO_ACTIVITY, 0, + ev_activity->info->mod, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), data->timestamp); } mutex_unlock(&data->mutex); @@ -1062,17 +1061,6 @@ static irqreturn_t mma9553_event_handler(int irq, void *private) return IRQ_HANDLED; } -static const char *mma9553_match_acpi_device(struct device *dev) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - - return dev_name(dev); -} - static int mma9553_probe(struct i2c_client *client) { const struct i2c_device_id *id = i2c_client_get_device_id(client); @@ -1091,9 +1079,9 @@ static int mma9553_probe(struct i2c_client *client) if (id) name = id->name; - else if (ACPI_HANDLE(&client->dev)) - name = mma9553_match_acpi_device(&client->dev); else + name = iio_get_acpi_device_name(&client->dev); + if (!name) return -ENOSYS; mutex_init(&data->mutex); @@ -1256,4 +1244,4 @@ module_i2c_driver(mma9553_driver); MODULE_AUTHOR("Irina Tirdea "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MMA9553L pedometer platform driver"); -MODULE_IMPORT_NS(IIO_MMA9551); +MODULE_IMPORT_NS("IIO_MMA9551"); diff --git a/drivers/iio/accel/msa311.c b/drivers/iio/accel/msa311.c index 57025354c7cd585b792f21ad6a45c72b092a7d52..e7fb860f32337ca9bc82547fbf2133b8a07da5ce 100644 --- a/drivers/iio/accel/msa311.c +++ b/drivers/iio/accel/msa311.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -893,7 +894,7 @@ static irqreturn_t msa311_buffer_thread(int irq, void *p) __le16 axis; struct { __le16 channels[MSA311_SI_Z + 1]; - s64 ts __aligned(8); + aligned_s64 ts; } buf; memset(&buf, 0, sizeof(buf)); diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index fc54a2a4693c0a0aef155631064c8b016fff41dd..cb5c4e354fc044bacd6a468a2f544bdac62b987c 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -69,7 +70,7 @@ struct mxc4005_data { /* Ensure timestamp is naturally aligned */ struct { __be16 chans[3]; - s64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; bool trigger_enabled; unsigned int control; diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c index 87c54e41f6ccd2f9311653b757b2d794df1dd5d4..3fb0f386c3db603714a746c28be36ee78d1b2a6a 100644 --- a/drivers/iio/accel/sca3000.c +++ b/drivers/iio/accel/sca3000.c @@ -1158,7 +1158,7 @@ error_ret: return ret; } -static int sca3000_freefall_set_state(struct iio_dev *indio_dev, int state) +static int sca3000_freefall_set_state(struct iio_dev *indio_dev, bool state) { struct sca3000_state *st = iio_priv(indio_dev); int ret; @@ -1181,7 +1181,7 @@ static int sca3000_freefall_set_state(struct iio_dev *indio_dev, int state) } static int sca3000_motion_detect_set_state(struct iio_dev *indio_dev, int axis, - int state) + bool state) { struct sca3000_state *st = iio_priv(indio_dev); int ret, ctrlval; @@ -1253,7 +1253,7 @@ static int sca3000_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct sca3000_state *st = iio_priv(indio_dev); int ret; diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c index 7ca9d0d543e04c3fddd178e8e8afd5222b99d23d..3e572af2ec039bb31209fd798fcc43bd84052d48 100644 --- a/drivers/iio/accel/ssp_accel_sensor.c +++ b/drivers/iio/accel/ssp_accel_sensor.c @@ -141,4 +141,4 @@ module_platform_driver(ssp_accel_driver); MODULE_AUTHOR("Karol Wrona "); MODULE_DESCRIPTION("Samsung sensorhub accelerometers driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_SSP_SENSORS); +MODULE_IMPORT_NS("IIO_SSP_SENSORS"); diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 0e371efbda705f4273631ad6be73456e8a56c37a..99cb661fabb2d9cc1943fa8d0a6f3becb71126e6 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -1490,7 +1490,7 @@ const struct st_sensor_settings *st_accel_get_settings(const char *name) return &st_accel_sensors_settings[index]; } -EXPORT_SYMBOL_NS(st_accel_get_settings, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_accel_get_settings, "IIO_ST_SENSORS"); int st_accel_common_probe(struct iio_dev *indio_dev) { @@ -1544,9 +1544,9 @@ int st_accel_common_probe(struct iio_dev *indio_dev) return devm_iio_device_register(parent, indio_dev); } -EXPORT_SYMBOL_NS(st_accel_common_probe, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_accel_common_probe, "IIO_ST_SENSORS"); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics accelerometers driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 329a4d6fb2ec0b10121daea088e102b681760a75..ab4fdba75a0a904970f7280dd31ee5acc8ad20a8 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -216,4 +216,4 @@ module_i2c_driver(st_accel_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics accelerometers i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index 825adab371059d4a1bc0d376403aca0868a34e72..6146754fe47f706aff8760e39cf1d7f32678fcd5 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -184,4 +184,4 @@ module_spi_driver(st_accel_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics accelerometers spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index abead190254b5a39ab78e4d87ef8cbaed160247a..471c154c3631b03bcdba01004dd172e7b3578e89 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -105,7 +106,7 @@ struct stk8312_data { /* Ensure timestamp is naturally aligned */ struct { s8 chans[3]; - s64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; }; diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index a32a77324e92d08a5a07dc62756f78a046b27604..cab592a68622566408834cd401283378081ab7b4 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -94,7 +95,7 @@ struct stk8ba50_data { /* Ensure timestamp is naturally aligned */ struct { s16 chans[3]; - s64 timetamp __aligned(8); + aligned_s64 timetamp; } scan; }; diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 6c4e74420fd25b9c9624b4a393bd436444d335d5..849c90203071a77ec7d94cec06d4378ece44440b 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -226,12 +226,14 @@ config AD7606_IFACE_PARALLEL tristate "Analog Devices AD7606 ADC driver with parallel interface support" depends on HAS_IOPORT select AD7606 + select IIO_BACKEND help Say yes here to build parallel interface support for Analog Devices: ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). + It also support iio_backended devices for AD7606B. To compile this driver as a module, choose M here: the - module will be called ad7606_parallel. + module will be called ad7606_par. config AD7606_IFACE_SPI tristate "Analog Devices AD7606 ADC driver with spi interface support" @@ -244,6 +246,22 @@ config AD7606_IFACE_SPI To compile this driver as a module, choose M here: the module will be called ad7606_spi. +config AD7625 + tristate "Analog Devices AD7625/AD7626 High Speed ADC driver" + depends on PWM + select IIO_BACKEND + help + Say yes here to build support for Analog Devices: + * AD7625 16-Bit, 6 MSPS PulSAR Analog-to-Digital Converter + * AD7626 16-Bit, 10 MSPS PulSAR Analog-to-Digital Converter + * AD7960 18-Bit, 5 MSPS PulSAR Analog-to-Digital Converter + * AD7961 16-Bit, 5 MSPS PulSAR Analog-to-Digital Converter + + The driver requires the assistance of the AXI ADC IP core to operate. + + To compile this driver as a module, choose M here: the module will be + called ad7625. + config AD7766 tristate "Analog Devices AD7766/AD7767 ADC driver" depends on SPI_MASTER @@ -269,6 +287,18 @@ config AD7768_1 To compile this driver as a module, choose M here: the module will be called ad7768-1. +config AD7779 + tristate "Analog Devices AD7779 ADC driver" + depends on SPI + select CRC8 + select IIO_BUFFER + help + Say yes here to build support for Analog Devices AD777X family + (AD7770, AD7771, AD7779) analog to digital converter (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad7779. + config AD7780 tristate "Analog Devices AD7780 and similar ADCs driver" depends on SPI @@ -575,6 +605,16 @@ config FSL_MX25_ADC Generic Conversion Queue driver used for general purpose ADC in the MX25. This driver supports single measurements using the MX25 ADC. +config GEHC_PMC_ADC + tristate "GE HealthCare PMC ADC driver" + depends on I2C + help + Say yes here to build support for the GE HealthCare PMC 16-bit + 16-Channel ADC. + + To compile this driver as a module, choose M here: the module will be + called gehc-pmc-adc. + config HI8435 tristate "Holt Integrated Circuits HI-8435 threshold detector" select IIO_TRIGGERED_EVENT @@ -1580,7 +1620,6 @@ config TWL4030_MADC config TWL6030_GPADC tristate "TWL6030 GPADC (General Purpose A/D Converter) Support" depends on TWL4030_CORE - default n help Say yes here if you want support for the TWL6030/TWL6032 General Purpose A/D Converter. This will add support for battery type diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 7b91cd98c0e0bda1b9a89ef369756dea51706227..ee19afba62b7fe0a68309c16f3581d98c5b8f653 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -25,8 +25,10 @@ obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o obj-$(CONFIG_AD7606) += ad7606.o +obj-$(CONFIG_AD7625) += ad7625.o obj-$(CONFIG_AD7766) += ad7766.o obj-$(CONFIG_AD7768_1) += ad7768-1.o +obj-$(CONFIG_AD7779) += ad7779.o obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7793) += ad7793.o @@ -52,6 +54,7 @@ obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o obj-$(CONFIG_EP93XX_ADC) += ep93xx_adc.o obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o +obj-$(CONFIG_GEHC_PMC_ADC) += gehc-pmc-adc.o obj-$(CONFIG_HI8435) += hi8435.o obj-$(CONFIG_HX711) += hx711.o obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o diff --git a/drivers/iio/adc/ab8500-gpadc.c b/drivers/iio/adc/ab8500-gpadc.c index 59f66e9cb0e8676872543b950350d448fde1a31d..f3b057f9231004e99b5b5844fc72e16f485a75ed 100644 --- a/drivers/iio/adc/ab8500-gpadc.c +++ b/drivers/iio/adc/ab8500-gpadc.c @@ -1194,7 +1194,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(ab8500_gpadc_pm_ops, static struct platform_driver ab8500_gpadc_driver = { .probe = ab8500_gpadc_probe, - .remove_new = ab8500_gpadc_remove, + .remove = ab8500_gpadc_remove, .driver = { .name = "ab8500-gpadc", .pm = pm_ptr(&ab8500_gpadc_pm_ops), diff --git a/drivers/iio/adc/ad4000.c b/drivers/iio/adc/ad4000.c index 6ea49124508499b37c3536cbf6ae3e200a1f4138..b3b82535f5c14dfe4a5db1c8aa69fd13d1283de7 100644 --- a/drivers/iio/adc/ad4000.c +++ b/drivers/iio/adc/ad4000.c @@ -344,6 +344,8 @@ static int ad4000_single_conversion(struct iio_dev *indio_dev, if (chan->scan_type.sign == 's') *val = sign_extend32(sample, chan->scan_type.realbits - 1); + else + *val = sample; return IIO_VAL_INT; } @@ -637,7 +639,9 @@ static int ad4000_probe(struct spi_device *spi) indio_dev->name = chip->dev_name; indio_dev->num_channels = 1; - devm_mutex_init(dev, &st->lock); + ret = devm_mutex_init(dev, &st->lock); + if (ret) + return ret; st->gain_milli = 1000; if (chip->has_hardware_gain) { diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c index d6876259ad14499df0983b4744834d66aa789f27..606486c4dfe85845b8ad9e18cf4d8725f255ceb2 100644 --- a/drivers/iio/adc/ad7091r-base.c +++ b/drivers/iio/adc/ad7091r-base.c @@ -35,7 +35,7 @@ const struct iio_event_spec ad7091r_events[] = { .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS), }, }; -EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R); +EXPORT_SYMBOL_NS_GPL(ad7091r_events, "IIO_AD7091R"); static int ad7091r_set_channel(struct ad7091r_state *st, unsigned int channel) { @@ -150,7 +150,8 @@ static int ad7091r_read_event_config(struct iio_dev *indio_dev, static int ad7091r_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, + bool state) { struct ad7091r_state *st = iio_priv(indio_dev); @@ -369,7 +370,7 @@ int ad7091r_probe(struct device *dev, const struct ad7091r_init_info *init_info, return devm_iio_device_register(dev, iio_dev); } -EXPORT_SYMBOL_NS_GPL(ad7091r_probe, IIO_AD7091R); +EXPORT_SYMBOL_NS_GPL(ad7091r_probe, "IIO_AD7091R"); bool ad7091r_writeable_reg(struct device *dev, unsigned int reg) { @@ -381,7 +382,7 @@ bool ad7091r_writeable_reg(struct device *dev, unsigned int reg) return true; } } -EXPORT_SYMBOL_NS_GPL(ad7091r_writeable_reg, IIO_AD7091R); +EXPORT_SYMBOL_NS_GPL(ad7091r_writeable_reg, "IIO_AD7091R"); bool ad7091r_volatile_reg(struct device *dev, unsigned int reg) { @@ -393,7 +394,7 @@ bool ad7091r_volatile_reg(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(ad7091r_volatile_reg, IIO_AD7091R); +EXPORT_SYMBOL_NS_GPL(ad7091r_volatile_reg, "IIO_AD7091R"); MODULE_AUTHOR("Beniamin Bia "); MODULE_DESCRIPTION("Analog Devices AD7091Rx multi-channel converters"); diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h index 696bf7a897bb51de16477b5b802919d1ae21124c..092ddea0f395c08d4fb24b6d68a6a4a031531475 100644 --- a/drivers/iio/adc/ad7091r-base.h +++ b/drivers/iio/adc/ad7091r-base.h @@ -65,7 +65,7 @@ struct ad7091r_state { struct regulator *vref; const struct ad7091r_chip_info *chip_info; enum ad7091r_mode mode; - struct mutex lock; /*lock to prevent concurent reads */ + struct mutex lock; /*lock to prevent concurrent reads */ __be16 tx_buf __aligned(IIO_DMA_MINALIGN); __be16 rx_buf; }; diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c index 1b59708abf30769c30ed48229fc9dae4b0316e75..b472b9498fd1307e493579e257769ace233eb073 100644 --- a/drivers/iio/adc/ad7091r5.c +++ b/drivers/iio/adc/ad7091r5.c @@ -135,4 +135,4 @@ module_i2c_driver(ad7091r5_driver); MODULE_AUTHOR("Beniamin Bia "); MODULE_DESCRIPTION("Analog Devices AD7091R5 multi-channel ADC driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD7091R); +MODULE_IMPORT_NS("IIO_AD7091R"); diff --git a/drivers/iio/adc/ad7091r8.c b/drivers/iio/adc/ad7091r8.c index c9e014d6a77cae2844e20cfee53bef25075d91c0..cebade4c2d49ede2bd256ccfa9a064f56437fe4f 100644 --- a/drivers/iio/adc/ad7091r8.c +++ b/drivers/iio/adc/ad7091r8.c @@ -269,4 +269,4 @@ module_spi_driver(ad7091r8_driver); MODULE_AUTHOR("Marcelo Schmitt "); MODULE_DESCRIPTION("Analog Devices AD7091R8 ADC driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_AD7091R); +MODULE_IMPORT_NS("IIO_AD7091R"); diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index b79c48d46cccf88c63d9866999263a65ff545d4a..7314fb32bdecb407f234d6553c54117133c981f7 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -1036,4 +1036,4 @@ module_spi_driver(ad71124_driver); MODULE_AUTHOR("Stefan Popa "); MODULE_DESCRIPTION("Analog Devices AD7124 SPI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); +MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA"); diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index 0702ec71aa29332036b30e5afd1996fc914baf92..8a0c931ca83a83ad6302d7e90e834e09837c2f52 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -3,7 +3,7 @@ * AD717x and AD411x family SPI ADC driver * * Supported devices: - * AD4111/AD4112/AD4114/AD4115/AD4116 + * AD4111/AD4112/AD4113/AD4114/AD4115/AD4116 * AD7172-2/AD7172-4/AD7173-8/AD7175-2 * AD7175-8/AD7176-2/AD7177-2 * @@ -76,14 +76,15 @@ (x) == AD7173_AIN_REF_NEG) #define AD7172_2_ID 0x00d0 -#define AD7175_ID 0x0cd0 #define AD7176_ID 0x0c90 +#define AD7175_ID 0x0cd0 #define AD7175_2_ID 0x0cd0 #define AD7172_4_ID 0x2050 #define AD7173_ID 0x30d0 #define AD4111_ID AD7173_ID #define AD4112_ID AD7173_ID #define AD4114_ID AD7173_ID +#define AD4113_ID 0x31d0 #define AD4116_ID 0x34d0 #define AD4115_ID 0x38d0 #define AD7175_8_ID 0x3cd0 @@ -170,6 +171,7 @@ struct ad7173_device_info { bool has_temp; /* ((AVDD1 − AVSS)/5) */ bool has_pow_supply_monitoring; + bool data_reg_only_16bit; bool has_input_buf; bool has_int_ref; bool has_ref2; @@ -294,6 +296,24 @@ static const struct ad7173_device_info ad4112_device_info = { .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), }; +static const struct ad7173_device_info ad4113_device_info = { + .name = "ad4113", + .id = AD4113_ID, + .num_voltage_in_div = 8, + .num_channels = 16, + .num_configs = 8, + .num_voltage_in = 8, + .num_gpios = 2, + .data_reg_only_16bit = true, + .higher_gpio_bits = true, + .has_vincom_input = true, + .has_input_buf = true, + .has_int_ref = true, + .clock = 2 * HZ_PER_MHZ, + .sinc5_data_rates = ad7173_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), +}; + static const struct ad7173_device_info ad4114_device_info = { .name = "ad4114", .id = AD4114_ID, @@ -985,6 +1005,13 @@ static const struct iio_info ad7173_info = { .update_scan_mode = ad7173_update_scan_mode, }; +static const struct iio_scan_type ad4113_scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_BE, +}; + static const struct iio_chan_spec ad7173_channel_template = { .type = IIO_VOLTAGE, .indexed = 1, @@ -1226,6 +1253,8 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) chan_st_priv->cfg.input_buf = st->info->has_input_buf; chan_st_priv->cfg.ref_sel = AD7173_SETUP_REF_SEL_INT_REF; st->adc_mode |= AD7173_ADC_MODE_REF_EN; + if (st->info->data_reg_only_16bit) + chan_arr[chan_index].scan_type = ad4113_scan_type; chan_index++; } @@ -1306,6 +1335,9 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) chan_st_priv->ain = AD7173_CH_ADDRESS(ain[0], ain[1]); } + if (st->info->data_reg_only_16bit) + chan_arr[chan_index].scan_type = ad4113_scan_type; + chan_index++; } return 0; @@ -1434,6 +1466,7 @@ static int ad7173_probe(struct spi_device *spi) static const struct of_device_id ad7173_of_match[] = { { .compatible = "adi,ad4111", .data = &ad4111_device_info }, { .compatible = "adi,ad4112", .data = &ad4112_device_info }, + { .compatible = "adi,ad4113", .data = &ad4113_device_info }, { .compatible = "adi,ad4114", .data = &ad4114_device_info }, { .compatible = "adi,ad4115", .data = &ad4115_device_info }, { .compatible = "adi,ad4116", .data = &ad4116_device_info }, @@ -1451,6 +1484,7 @@ MODULE_DEVICE_TABLE(of, ad7173_of_match); static const struct spi_device_id ad7173_id_table[] = { { "ad4111", (kernel_ulong_t)&ad4111_device_info }, { "ad4112", (kernel_ulong_t)&ad4112_device_info }, + { "ad4113", (kernel_ulong_t)&ad4113_device_info }, { "ad4114", (kernel_ulong_t)&ad4114_device_info }, { "ad4115", (kernel_ulong_t)&ad4115_device_info }, { "ad4116", (kernel_ulong_t)&ad4116_device_info }, @@ -1475,7 +1509,7 @@ static struct spi_driver ad7173_driver = { }; module_spi_driver(ad7173_driver); -MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); +MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA"); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_AUTHOR("Dumitru Ceclan "); MODULE_DESCRIPTION("Analog Devices AD7173 and similar ADC driver"); diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c index 7042ddfdfc03ee5ea58ca07fb1943feb6538175b..1c87db0e04605042e9a824a3d9d88c3291974691 100644 --- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -1394,6 +1394,9 @@ static int ad7192_probe(struct spi_device *spi) st->int_vref_mv = ret == -ENODEV ? avdd_mv : ret / MILLI; st->chip_info = spi_get_device_match_data(spi); + if (!st->chip_info) + return -ENODEV; + indio_dev->name = st->chip_info->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = st->chip_info->info; @@ -1458,4 +1461,4 @@ module_spi_driver(ad7192_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD7192 and similar ADC"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); +MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA"); diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index 7949b076fb87eac6f69d65a725fbc498407f1812..858c8be2ff1a09e99e8d1fb2f0325bd58e454eda 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -383,7 +383,7 @@ static const char * const ad7266_gpio_labels[] = { static int ad7266_probe(struct spi_device *spi) { - struct ad7266_platform_data *pdata = spi->dev.platform_data; + const struct ad7266_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad7266_state *st; unsigned int i; diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c index 35aa39fe4bde62290996abd3076ac350eedf1052..f9f32737db8079a5b96847442a64fea811438363 100644 --- a/drivers/iio/adc/ad7280a.c +++ b/drivers/iio/adc/ad7280a.c @@ -822,17 +822,15 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) if (FIELD_GET(AD7280A_TRANS_READ_CONV_CHANADDR_MSK, channels[i]) <= AD7280A_CELL_VOLTAGE_6_REG) { if (val >= st->cell_threshhigh) { - u64 tmp = IIO_EVENT_CODE(IIO_VOLTAGE, 1, 0, - IIO_EV_DIR_RISING, - IIO_EV_TYPE_THRESH, - 0, 0, 0); + u64 tmp = IIO_DIFF_EVENT_CODE(IIO_VOLTAGE, 0, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING); iio_push_event(indio_dev, tmp, iio_get_time_ns(indio_dev)); } else if (val <= st->cell_threshlow) { - u64 tmp = IIO_EVENT_CODE(IIO_VOLTAGE, 1, 0, - IIO_EV_DIR_FALLING, - IIO_EV_TYPE_THRESH, - 0, 0, 0); + u64 tmp = IIO_DIFF_EVENT_CODE(IIO_VOLTAGE, 0, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING); iio_push_event(indio_dev, tmp, iio_get_time_ns(indio_dev)); } diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index 4c7f887adbbf2f2c857288b19ce8058ee5ebdffb..60e12faa32070183c64a2037c968177cb903cc11 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -269,7 +269,7 @@ static int ad7291_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { int ret = 0; struct ad7291_chip_info *chip = iio_priv(indio_dev); diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index fb728570debe6432d5f991595cb35e9e7af8b740..4f32cb22f140442b831dc9a4f275e88e4ab2388e 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -13,6 +13,8 @@ * ad7381-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/ad7381-4.pdf * ad7383/4-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/ad7383-4-ad7384-4.pdf * ad7386/7/8-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/ad7386-4-7387-4-7388-4.pdf + * adaq4370-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4370-4.pdf + * adaq4380-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4380-4.pdf */ #include @@ -22,11 +24,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -36,6 +41,8 @@ #define MAX_NUM_CHANNELS 8 /* 2.5V internal reference voltage */ #define AD7380_INTERNAL_REF_MV 2500 +/* 3.3V internal reference voltage for ADAQ */ +#define ADAQ4380_INTERNAL_REF_MV 3300 /* reading and writing registers is more reliable at lower than max speed */ #define AD7380_REG_WR_SPEED_HZ 10000000 @@ -77,6 +84,13 @@ #define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */ #define T_POWERUP_US 5000 /* Power up */ +/* + * AD738x support several SDO lines to increase throughput, but driver currently + * supports only 1 SDO line (standard SPI transaction) + */ +#define AD7380_NUM_SDO_LINES 1 +#define AD7380_DEFAULT_GAIN_MILLI 1000 + struct ad7380_timing_specs { const unsigned int t_csh_ns; /* CS minimum high time */ }; @@ -86,10 +100,12 @@ struct ad7380_chip_info { const struct iio_chan_spec *channels; unsigned int num_channels; unsigned int num_simult_channels; + bool has_hardware_gain; bool has_mux; const char * const *supplies; unsigned int num_supplies; bool external_ref_only; + bool adaq_internal_ref_only; const char * const *vcm_supplies; unsigned int num_vcm_supplies; const unsigned long *available_scan_masks; @@ -181,11 +197,12 @@ static const struct iio_scan_type ad7380_scan_type_16_u[] = { }, }; -#define AD7380_CHANNEL(index, bits, diff, sign) { \ +#define _AD7380_CHANNEL(index, bits, diff, sign, gain) { \ .type = IIO_VOLTAGE, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + ((gain) ? BIT(IIO_CHAN_INFO_SCALE) : 0) | \ ((diff) ? 0 : BIT(IIO_CHAN_INFO_OFFSET)), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + .info_mask_shared_by_type = ((gain) ? 0 : BIT(IIO_CHAN_INFO_SCALE)) | \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .info_mask_shared_by_type_available = \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ @@ -199,6 +216,12 @@ static const struct iio_scan_type ad7380_scan_type_16_u[] = { .num_ext_scan_type = ARRAY_SIZE(ad7380_scan_type_##bits##_##sign), \ } +#define AD7380_CHANNEL(index, bits, diff, sign) \ + _AD7380_CHANNEL(index, bits, diff, sign, false) + +#define ADAQ4380_CHANNEL(index, bits, diff, sign) \ + _AD7380_CHANNEL(index, bits, diff, sign, true) + #define DEFINE_AD7380_2_CHANNEL(name, bits, diff, sign) \ static const struct iio_chan_spec name[] = { \ AD7380_CHANNEL(0, bits, diff, sign), \ @@ -215,6 +238,15 @@ static const struct iio_chan_spec name[] = { \ IIO_CHAN_SOFT_TIMESTAMP(4), \ } +#define DEFINE_ADAQ4380_4_CHANNEL(name, bits, diff, sign) \ +static const struct iio_chan_spec name[] = { \ + ADAQ4380_CHANNEL(0, bits, diff, sign), \ + ADAQ4380_CHANNEL(1, bits, diff, sign), \ + ADAQ4380_CHANNEL(2, bits, diff, sign), \ + ADAQ4380_CHANNEL(3, bits, diff, sign), \ + IIO_CHAN_SOFT_TIMESTAMP(4), \ +} + #define DEFINE_AD7380_8_CHANNEL(name, bits, diff, sign) \ static const struct iio_chan_spec name[] = { \ AD7380_CHANNEL(0, bits, diff, sign), \ @@ -233,6 +265,7 @@ DEFINE_AD7380_2_CHANNEL(ad7380_channels, 16, 1, s); DEFINE_AD7380_2_CHANNEL(ad7381_channels, 14, 1, s); DEFINE_AD7380_4_CHANNEL(ad7380_4_channels, 16, 1, s); DEFINE_AD7380_4_CHANNEL(ad7381_4_channels, 14, 1, s); +DEFINE_ADAQ4380_4_CHANNEL(adaq4380_4_channels, 16, 1, s); /* pseudo differential */ DEFINE_AD7380_2_CHANNEL(ad7383_channels, 16, 0, s); DEFINE_AD7380_2_CHANNEL(ad7384_channels, 14, 0, s); @@ -251,6 +284,10 @@ static const char * const ad7380_supplies[] = { "vcc", "vlogic", }; +static const char * const adaq4380_supplies[] = { + "ldo", "vcc", "vlogic", "vs-p", "vs-n", "refin", +}; + static const char * const ad7380_2_channel_vcm_supplies[] = { "aina", "ainb", }; @@ -341,6 +378,11 @@ static const int ad7380_oversampling_ratios[] = { 1, 2, 4, 8, 16, 32, }; +/* Gains stored as fractions of 1000 so they can be expressed by integers. */ +static const int ad7380_gains[] = { + 300, 600, 1000, 1600, +}; + static const struct ad7380_chip_info ad7380_chip_info = { .name = "ad7380", .channels = ad7380_channels, @@ -510,6 +552,32 @@ static const struct ad7380_chip_info ad7388_4_chip_info = { .timing_specs = &ad7380_4_timing, }; +static const struct ad7380_chip_info adaq4370_4_chip_info = { + .name = "adaq4370-4", + .channels = adaq4380_4_channels, + .num_channels = ARRAY_SIZE(adaq4380_4_channels), + .num_simult_channels = 4, + .supplies = adaq4380_supplies, + .num_supplies = ARRAY_SIZE(adaq4380_supplies), + .adaq_internal_ref_only = true, + .has_hardware_gain = true, + .available_scan_masks = ad7380_4_channel_scan_masks, + .timing_specs = &ad7380_4_timing, +}; + +static const struct ad7380_chip_info adaq4380_4_chip_info = { + .name = "adaq4380-4", + .channels = adaq4380_4_channels, + .num_channels = ARRAY_SIZE(adaq4380_4_channels), + .num_simult_channels = 4, + .supplies = adaq4380_supplies, + .num_supplies = ARRAY_SIZE(adaq4380_supplies), + .adaq_internal_ref_only = true, + .has_hardware_gain = true, + .available_scan_masks = ad7380_4_channel_scan_masks, + .timing_specs = &ad7380_4_timing, +}; + struct ad7380_state { const struct ad7380_chip_info *chip_info; struct spi_device *spi; @@ -520,6 +588,7 @@ struct ad7380_state { bool seq; unsigned int vref_mv; unsigned int vcm_mv[MAX_NUM_CHANNELS]; + unsigned int gain_milli[MAX_NUM_CHANNELS]; /* xfers, message an buffer for reading sample data */ struct spi_transfer normal_xfer[2]; struct spi_message normal_msg; @@ -649,7 +718,8 @@ static int ad7380_set_ch(struct ad7380_state *st, unsigned int ch) if (st->oversampling_ratio > 1) xfer.delay.value = T_CONVERT_0_NS + - T_CONVERT_X_NS * (st->oversampling_ratio - 1); + T_CONVERT_X_NS * (st->oversampling_ratio - 1) * + st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES; return spi_sync_transfer(st->spi, &xfer, 1); } @@ -672,7 +742,8 @@ static void ad7380_update_xfers(struct ad7380_state *st, */ if (st->oversampling_ratio > 1) t_convert = T_CONVERT_0_NS + T_CONVERT_X_NS * - (st->oversampling_ratio - 1); + (st->oversampling_ratio - 1) * + st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES; if (st->seq) { xfer[0].delay.value = xfer[1].delay.value = t_convert; @@ -868,8 +939,15 @@ static int ad7380_read_raw(struct iio_dev *indio_dev, * * (2 × VREF) / 2^N, for differential chips * * VREF / 2^N, for pseudo-differential chips * where N is the ADC resolution (i.e realbits) + * + * The gain is stored as a fraction of 1000 and, as we need to + * divide vref_mv by the gain, we invert the gain/1000 fraction. */ - *val = st->vref_mv; + if (st->chip_info->has_hardware_gain) + *val = mult_frac(st->vref_mv, MILLI, + st->gain_milli[chan->scan_index]); + else + *val = st->vref_mv; *val2 = scan_type->realbits - chan->differential; return IIO_VAL_FRACTIONAL_LOG2; @@ -1021,17 +1099,19 @@ static int ad7380_init(struct ad7380_state *st, bool external_ref_en) /* SPI 1-wire mode */ return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, AD7380_CONFIG2_SDO, - FIELD_PREP(AD7380_CONFIG2_SDO, 1)); + FIELD_PREP(AD7380_CONFIG2_SDO, + AD7380_NUM_SDO_LINES)); } static int ad7380_probe(struct spi_device *spi) { + struct device *dev = &spi->dev; struct iio_dev *indio_dev; struct ad7380_state *st; bool external_ref_en; int ret, i; - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; @@ -1039,21 +1119,32 @@ static int ad7380_probe(struct spi_device *spi) st->spi = spi; st->chip_info = spi_get_device_match_data(spi); if (!st->chip_info) - return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); + return dev_err_probe(dev, -EINVAL, "missing match data\n"); - ret = devm_regulator_bulk_get_enable(&spi->dev, st->chip_info->num_supplies, + ret = devm_regulator_bulk_get_enable(dev, st->chip_info->num_supplies, st->chip_info->supplies); if (ret) - return dev_err_probe(&spi->dev, ret, + return dev_err_probe(dev, ret, "Failed to enable power supplies\n"); fsleep(T_POWERUP_US); - if (st->chip_info->external_ref_only) { - ret = devm_regulator_get_enable_read_voltage(&spi->dev, - "refin"); + if (st->chip_info->adaq_internal_ref_only) { + /* + * ADAQ chips use fixed internal reference but still + * require a specific reference supply to power it. + * "refin" is already enabled with other power supplies + * in bulk_get_enable(). + */ + + st->vref_mv = ADAQ4380_INTERNAL_REF_MV; + + /* these chips don't have a register bit for this */ + external_ref_en = false; + } else if (st->chip_info->external_ref_only) { + ret = devm_regulator_get_enable_read_voltage(dev, "refin"); if (ret < 0) - return dev_err_probe(&spi->dev, ret, + return dev_err_probe(dev, ret, "Failed to get refin regulator\n"); st->vref_mv = ret / 1000; @@ -1065,10 +1156,9 @@ static int ad7380_probe(struct spi_device *spi) * If there is no REFIO supply, then it means that we are using * the internal reference, otherwise REFIO is reference voltage. */ - ret = devm_regulator_get_enable_read_voltage(&spi->dev, - "refio"); + ret = devm_regulator_get_enable_read_voltage(dev, "refio"); if (ret < 0 && ret != -ENODEV) - return dev_err_probe(&spi->dev, ret, + return dev_err_probe(dev, ret, "Failed to get refio regulator\n"); external_ref_en = ret != -ENODEV; @@ -1076,7 +1166,7 @@ static int ad7380_probe(struct spi_device *spi) } if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv)) - return dev_err_probe(&spi->dev, -EINVAL, + return dev_err_probe(dev, -EINVAL, "invalid number of VCM supplies\n"); /* @@ -1086,18 +1176,54 @@ static int ad7380_probe(struct spi_device *spi) for (i = 0; i < st->chip_info->num_vcm_supplies; i++) { const char *vcm = st->chip_info->vcm_supplies[i]; - ret = devm_regulator_get_enable_read_voltage(&spi->dev, vcm); + ret = devm_regulator_get_enable_read_voltage(dev, vcm); if (ret < 0) - return dev_err_probe(&spi->dev, ret, + return dev_err_probe(dev, ret, "Failed to get %s regulator\n", vcm); st->vcm_mv[i] = ret / 1000; } - st->regmap = devm_regmap_init(&spi->dev, NULL, st, &ad7380_regmap_config); + for (i = 0; i < MAX_NUM_CHANNELS; i++) + st->gain_milli[i] = AD7380_DEFAULT_GAIN_MILLI; + + if (st->chip_info->has_hardware_gain) { + device_for_each_child_node_scoped(dev, node) { + unsigned int channel, gain; + int gain_idx; + + ret = fwnode_property_read_u32(node, "reg", &channel); + if (ret) + return dev_err_probe(dev, ret, + "Failed to read reg property\n"); + + if (channel >= st->chip_info->num_channels - 1) + return dev_err_probe(dev, -EINVAL, + "Invalid channel number %i\n", + channel); + + ret = fwnode_property_read_u32(node, "adi,gain-milli", + &gain); + if (ret && ret != -EINVAL) + return dev_err_probe(dev, ret, + "Failed to read gain for channel %i\n", + channel); + if (ret != -EINVAL) { + /* + * Match gain value from dt to one of supported + * gains + */ + gain_idx = find_closest(gain, ad7380_gains, + ARRAY_SIZE(ad7380_gains)); + st->gain_milli[channel] = ad7380_gains[gain_idx]; + } + } + } + + st->regmap = devm_regmap_init(dev, NULL, st, &ad7380_regmap_config); if (IS_ERR(st->regmap)) - return dev_err_probe(&spi->dev, PTR_ERR(st->regmap), + return dev_err_probe(dev, PTR_ERR(st->regmap), "failed to allocate register map\n"); /* @@ -1148,7 +1274,7 @@ static int ad7380_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->available_scan_masks = st->chip_info->available_scan_masks; - ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, iio_pollfunc_store_time, ad7380_trigger_handler, &ad7380_buffer_setup_ops); @@ -1159,7 +1285,7 @@ static int ad7380_probe(struct spi_device *spi) if (ret) return ret; - return devm_iio_device_register(&spi->dev, indio_dev); + return devm_iio_device_register(dev, indio_dev); } static const struct of_device_id ad7380_of_match_table[] = { @@ -1177,6 +1303,8 @@ static const struct of_device_id ad7380_of_match_table[] = { { .compatible = "adi,ad7386-4", .data = &ad7386_4_chip_info }, { .compatible = "adi,ad7387-4", .data = &ad7387_4_chip_info }, { .compatible = "adi,ad7388-4", .data = &ad7388_4_chip_info }, + { .compatible = "adi,adaq4370-4", .data = &adaq4370_4_chip_info }, + { .compatible = "adi,adaq4380-4", .data = &adaq4380_4_chip_info }, { } }; @@ -1195,6 +1323,8 @@ static const struct spi_device_id ad7380_id_table[] = { { "ad7386-4", (kernel_ulong_t)&ad7386_4_chip_info }, { "ad7387-4", (kernel_ulong_t)&ad7387_4_chip_info }, { "ad7388-4", (kernel_ulong_t)&ad7388_4_chip_info }, + { "adaq4370-4", (kernel_ulong_t)&adaq4370_4_chip_info }, + { "adaq4380-4", (kernel_ulong_t)&adaq4380_4_chip_info }, { } }; MODULE_DEVICE_TABLE(spi, ad7380_id_table); diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 9b457472d49c176f75fa211577c3b59e66dac77e..e35d55d03d86ad152fd51e41ad970e78f33b4788 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -13,14 +13,17 @@ #include #include #include +#include #include #include #include #include +#include #include -#include +#include #include +#include #include #include #include @@ -30,15 +33,52 @@ /* * Scales are computed as 5000/32768 and 10000/32768 respectively, - * so that when applied to the raw values they provide mV values + * so that when applied to the raw values they provide mV values. + * The scale arrays are kept as IIO_VAL_INT_PLUS_MICRO, so index + * X is the integer part and X + 1 is the fractional part. */ -static const unsigned int ad7606_scale_avail[2] = { - 152588, 305176 +static const unsigned int ad7606_16bit_hw_scale_avail[2][2] = { + { 0, 152588 }, { 0, 305176 } +}; + +static const unsigned int ad7606_18bit_hw_scale_avail[2][2] = { + { 0, 38147 }, { 0, 76294 } +}; + +static const unsigned int ad7606c_16bit_single_ended_unipolar_scale_avail[3][2] = { + { 0, 76294 }, { 0, 152588 }, { 0, 190735 } +}; + +static const unsigned int ad7606c_16bit_single_ended_bipolar_scale_avail[5][2] = { + { 0, 76294 }, { 0, 152588 }, { 0, 190735 }, { 0, 305176 }, { 0, 381470 } +}; + +static const unsigned int ad7606c_16bit_differential_bipolar_scale_avail[4][2] = { + { 0, 152588 }, { 0, 305176 }, { 0, 381470 }, { 0, 610352 } +}; + +static const unsigned int ad7606c_18bit_single_ended_unipolar_scale_avail[3][2] = { + { 0, 19073 }, { 0, 38147 }, { 0, 47684 } +}; + +static const unsigned int ad7606c_18bit_single_ended_bipolar_scale_avail[5][2] = { + { 0, 19073 }, { 0, 38147 }, { 0, 47684 }, { 0, 76294 }, { 0, 95367 } }; +static const unsigned int ad7606c_18bit_differential_bipolar_scale_avail[4][2] = { + { 0, 38147 }, { 0, 76294 }, { 0, 95367 }, { 0, 152588 } +}; + +static const unsigned int ad7606_16bit_sw_scale_avail[3][2] = { + { 0, 76293 }, { 0, 152588 }, { 0, 305176 } +}; -static const unsigned int ad7616_sw_scale_avail[3] = { - 76293, 152588, 305176 +static const unsigned int ad7607_hw_scale_avail[2][2] = { + { 0, 610352 }, { 1, 220703 } +}; + +static const unsigned int ad7609_hw_scale_avail[2][2] = { + { 0, 152588 }, { 0, 305176 } }; static const unsigned int ad7606_oversampling_avail[7] = { @@ -49,6 +89,227 @@ static const unsigned int ad7616_oversampling_avail[8] = { 1, 2, 4, 8, 16, 32, 64, 128, }; +static const struct iio_chan_spec ad7605_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(4), + AD7605_CHANNEL(0), + AD7605_CHANNEL(1), + AD7605_CHANNEL(2), + AD7605_CHANNEL(3), +}; + +static const struct iio_chan_spec ad7606_channels_16bit[] = { + IIO_CHAN_SOFT_TIMESTAMP(8), + AD7606_CHANNEL(0, 16), + AD7606_CHANNEL(1, 16), + AD7606_CHANNEL(2, 16), + AD7606_CHANNEL(3, 16), + AD7606_CHANNEL(4, 16), + AD7606_CHANNEL(5, 16), + AD7606_CHANNEL(6, 16), + AD7606_CHANNEL(7, 16), +}; + +static const struct iio_chan_spec ad7606_channels_18bit[] = { + IIO_CHAN_SOFT_TIMESTAMP(8), + AD7606_CHANNEL(0, 18), + AD7606_CHANNEL(1, 18), + AD7606_CHANNEL(2, 18), + AD7606_CHANNEL(3, 18), + AD7606_CHANNEL(4, 18), + AD7606_CHANNEL(5, 18), + AD7606_CHANNEL(6, 18), + AD7606_CHANNEL(7, 18), +}; + +static const struct iio_chan_spec ad7607_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(8), + AD7606_CHANNEL(0, 14), + AD7606_CHANNEL(1, 14), + AD7606_CHANNEL(2, 14), + AD7606_CHANNEL(3, 14), + AD7606_CHANNEL(4, 14), + AD7606_CHANNEL(5, 14), + AD7606_CHANNEL(6, 14), + AD7606_CHANNEL(7, 14), +}; + +static const struct iio_chan_spec ad7608_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(8), + AD7606_CHANNEL(0, 18), + AD7606_CHANNEL(1, 18), + AD7606_CHANNEL(2, 18), + AD7606_CHANNEL(3, 18), + AD7606_CHANNEL(4, 18), + AD7606_CHANNEL(5, 18), + AD7606_CHANNEL(6, 18), + AD7606_CHANNEL(7, 18), +}; + +/* + * The current assumption that this driver makes for AD7616, is that it's + * working in Hardware Mode with Serial, Burst and Sequencer modes activated. + * To activate them, following pins must be pulled high: + * -SER/PAR + * -SEQEN + * And following pins must be pulled low: + * -WR/BURST + * -DB4/SER1W + */ +static const struct iio_chan_spec ad7616_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(16), + AD7606_CHANNEL(0, 16), + AD7606_CHANNEL(1, 16), + AD7606_CHANNEL(2, 16), + AD7606_CHANNEL(3, 16), + AD7606_CHANNEL(4, 16), + AD7606_CHANNEL(5, 16), + AD7606_CHANNEL(6, 16), + AD7606_CHANNEL(7, 16), + AD7606_CHANNEL(8, 16), + AD7606_CHANNEL(9, 16), + AD7606_CHANNEL(10, 16), + AD7606_CHANNEL(11, 16), + AD7606_CHANNEL(12, 16), + AD7606_CHANNEL(13, 16), + AD7606_CHANNEL(14, 16), + AD7606_CHANNEL(15, 16), +}; + +static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch); +static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch); +static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch); +static int ad7607_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch); +static int ad7608_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch); +static int ad7609_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch); + +const struct ad7606_chip_info ad7605_4_info = { + .channels = ad7605_channels, + .name = "ad7605-4", + .num_adc_channels = 4, + .num_channels = 5, + .scale_setup_cb = ad7606_16bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7605_4_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7606_8_info = { + .channels = ad7606_channels_16bit, + .name = "ad7606-8", + .num_adc_channels = 8, + .num_channels = 9, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7606_16bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7606_8_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7606_6_info = { + .channels = ad7606_channels_16bit, + .name = "ad7606-6", + .num_adc_channels = 6, + .num_channels = 7, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7606_16bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7606_6_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7606_4_info = { + .channels = ad7606_channels_16bit, + .name = "ad7606-4", + .num_adc_channels = 4, + .num_channels = 5, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7606_16bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7606_4_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7606b_info = { + .channels = ad7606_channels_16bit, + .max_samplerate = 800 * KILO, + .name = "ad7606b", + .num_adc_channels = 8, + .num_channels = 9, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7606_16bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7606b_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7606c_16_info = { + .channels = ad7606_channels_16bit, + .name = "ad7606c16", + .num_adc_channels = 8, + .num_channels = 9, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7606c_16bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7606c_16_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7607_info = { + .channels = ad7607_channels, + .name = "ad7607", + .num_adc_channels = 8, + .num_channels = 9, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7607_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7607_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7608_info = { + .channels = ad7608_channels, + .name = "ad7608", + .num_adc_channels = 8, + .num_channels = 9, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7608_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7608_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7609_info = { + .channels = ad7608_channels, + .name = "ad7609", + .num_adc_channels = 8, + .num_channels = 9, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7609_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7609_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7606c_18_info = { + .channels = ad7606_channels_18bit, + .name = "ad7606c18", + .num_adc_channels = 8, + .num_channels = 9, + .oversampling_avail = ad7606_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), + .scale_setup_cb = ad7606c_18bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7606c_18_info, "IIO_AD7606"); + +const struct ad7606_chip_info ad7616_info = { + .channels = ad7616_channels, + .init_delay_ms = 15, + .name = "ad7616", + .num_adc_channels = 16, + .num_channels = 17, + .oversampling_avail = ad7616_oversampling_avail, + .oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail), + .os_req_reset = true, + .scale_setup_cb = ad7606_16bit_chan_scale_setup, +}; +EXPORT_SYMBOL_NS_GPL(ad7616_info, "IIO_AD7606"); + int ad7606_reset(struct ad7606_state *st) { if (st->gpio_reset) { @@ -60,7 +321,229 @@ int ad7606_reset(struct ad7606_state *st) return -ENODEV; } -EXPORT_SYMBOL_NS_GPL(ad7606_reset, IIO_AD7606); +EXPORT_SYMBOL_NS_GPL(ad7606_reset, "IIO_AD7606"); + +static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch) +{ + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; + + if (!st->sw_mode_en) { + /* tied to logic low, analog input range is +/- 5V */ + cs->range = 0; + cs->scale_avail = ad7606_16bit_hw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7606_16bit_hw_scale_avail); + return 0; + } + + /* Scale of 0.076293 is only available in sw mode */ + /* After reset, in software mode, ±10 V is set by default */ + cs->range = 2; + cs->scale_avail = ad7606_16bit_sw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7606_16bit_sw_scale_avail); + + return 0; +} + +static int ad7606_get_chan_config(struct ad7606_state *st, int ch, + bool *bipolar, bool *differential) +{ + unsigned int num_channels = st->chip_info->num_channels - 1; + struct device *dev = st->dev; + int ret; + + *bipolar = false; + *differential = false; + + device_for_each_child_node_scoped(dev, child) { + u32 pins[2]; + int reg; + + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret) + continue; + + /* channel number (here) is from 1 to num_channels */ + if (reg == 0 || reg > num_channels) { + dev_warn(dev, + "Invalid channel number (ignoring): %d\n", reg); + continue; + } + + if (reg != (ch + 1)) + continue; + + *bipolar = fwnode_property_read_bool(child, "bipolar"); + + ret = fwnode_property_read_u32_array(child, "diff-channels", + pins, ARRAY_SIZE(pins)); + /* Channel is differential, if pins are the same as 'reg' */ + if (ret == 0 && (pins[0] != reg || pins[1] != reg)) { + dev_err(dev, + "Differential pins must be the same as 'reg'"); + return -EINVAL; + } + + *differential = (ret == 0); + + if (*differential && !*bipolar) { + dev_err(dev, + "'bipolar' must be added for diff channel %d\n", + reg); + return -EINVAL; + } + + return 0; + } + + return 0; +} + +static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch) +{ + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; + bool bipolar, differential; + int ret; + + if (!st->sw_mode_en) { + cs->range = 0; + cs->scale_avail = ad7606_18bit_hw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7606_18bit_hw_scale_avail); + return 0; + } + + ret = ad7606_get_chan_config(st, ch, &bipolar, &differential); + if (ret) + return ret; + + if (differential) { + cs->scale_avail = ad7606c_18bit_differential_bipolar_scale_avail; + cs->num_scales = + ARRAY_SIZE(ad7606c_18bit_differential_bipolar_scale_avail); + /* Bipolar differential ranges start at 8 (b1000) */ + cs->reg_offset = 8; + cs->range = 1; + chan->differential = 1; + chan->channel2 = chan->channel; + + return 0; + } + + chan->differential = 0; + + if (bipolar) { + cs->scale_avail = ad7606c_18bit_single_ended_bipolar_scale_avail; + cs->num_scales = + ARRAY_SIZE(ad7606c_18bit_single_ended_bipolar_scale_avail); + /* Bipolar single-ended ranges start at 0 (b0000) */ + cs->reg_offset = 0; + cs->range = 3; + chan->scan_type.sign = 's'; + + return 0; + } + + cs->scale_avail = ad7606c_18bit_single_ended_unipolar_scale_avail; + cs->num_scales = + ARRAY_SIZE(ad7606c_18bit_single_ended_unipolar_scale_avail); + /* Unipolar single-ended ranges start at 5 (b0101) */ + cs->reg_offset = 5; + cs->range = 1; + chan->scan_type.sign = 'u'; + + return 0; +} + +static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch) +{ + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; + bool bipolar, differential; + int ret; + + if (!st->sw_mode_en) { + cs->range = 0; + cs->scale_avail = ad7606_16bit_hw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7606_16bit_hw_scale_avail); + return 0; + } + + ret = ad7606_get_chan_config(st, ch, &bipolar, &differential); + if (ret) + return ret; + + if (differential) { + cs->scale_avail = ad7606c_16bit_differential_bipolar_scale_avail; + cs->num_scales = + ARRAY_SIZE(ad7606c_16bit_differential_bipolar_scale_avail); + /* Bipolar differential ranges start at 8 (b1000) */ + cs->reg_offset = 8; + cs->range = 1; + chan->differential = 1; + chan->channel2 = chan->channel; + chan->scan_type.sign = 's'; + + return 0; + } + + chan->differential = 0; + + if (bipolar) { + cs->scale_avail = ad7606c_16bit_single_ended_bipolar_scale_avail; + cs->num_scales = + ARRAY_SIZE(ad7606c_16bit_single_ended_bipolar_scale_avail); + /* Bipolar single-ended ranges start at 0 (b0000) */ + cs->reg_offset = 0; + cs->range = 3; + chan->scan_type.sign = 's'; + + return 0; + } + + cs->scale_avail = ad7606c_16bit_single_ended_unipolar_scale_avail; + cs->num_scales = + ARRAY_SIZE(ad7606c_16bit_single_ended_unipolar_scale_avail); + /* Unipolar single-ended ranges start at 5 (b0101) */ + cs->reg_offset = 5; + cs->range = 1; + chan->scan_type.sign = 'u'; + + return 0; +} + +static int ad7607_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch) +{ + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; + + cs->range = 0; + cs->scale_avail = ad7607_hw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7607_hw_scale_avail); + return 0; +} + +static int ad7608_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch) +{ + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; + + cs->range = 0; + cs->scale_avail = ad7606_18bit_hw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7606_18bit_hw_scale_avail); + return 0; +} + +static int ad7609_chan_scale_setup(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch) +{ + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; + + cs->range = 0; + cs->scale_avail = ad7609_hw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7609_hw_scale_avail); + return 0; +} static int ad7606_reg_access(struct iio_dev *indio_dev, unsigned int reg, @@ -83,12 +566,85 @@ static int ad7606_reg_access(struct iio_dev *indio_dev, } } +static int ad7606_pwm_set_high(struct ad7606_state *st) +{ + struct pwm_state cnvst_pwm_state; + int ret; + + pwm_get_state(st->cnvst_pwm, &cnvst_pwm_state); + cnvst_pwm_state.enabled = true; + cnvst_pwm_state.duty_cycle = cnvst_pwm_state.period; + + ret = pwm_apply_might_sleep(st->cnvst_pwm, &cnvst_pwm_state); + + return ret; +} + +static int ad7606_pwm_set_low(struct ad7606_state *st) +{ + struct pwm_state cnvst_pwm_state; + int ret; + + pwm_get_state(st->cnvst_pwm, &cnvst_pwm_state); + cnvst_pwm_state.enabled = true; + cnvst_pwm_state.duty_cycle = 0; + + ret = pwm_apply_might_sleep(st->cnvst_pwm, &cnvst_pwm_state); + + return ret; +} + +static int ad7606_pwm_set_swing(struct ad7606_state *st) +{ + struct pwm_state cnvst_pwm_state; + + pwm_get_state(st->cnvst_pwm, &cnvst_pwm_state); + cnvst_pwm_state.enabled = true; + cnvst_pwm_state.duty_cycle = cnvst_pwm_state.period / 2; + + return pwm_apply_might_sleep(st->cnvst_pwm, &cnvst_pwm_state); +} + +static bool ad7606_pwm_is_swinging(struct ad7606_state *st) +{ + struct pwm_state cnvst_pwm_state; + + pwm_get_state(st->cnvst_pwm, &cnvst_pwm_state); + + return cnvst_pwm_state.duty_cycle != cnvst_pwm_state.period && + cnvst_pwm_state.duty_cycle != 0; +} + +static int ad7606_set_sampling_freq(struct ad7606_state *st, unsigned long freq) +{ + struct pwm_state cnvst_pwm_state; + bool is_swinging = ad7606_pwm_is_swinging(st); + bool is_high; + + if (freq == 0) + return -EINVAL; + + /* Retrieve the previous state. */ + pwm_get_state(st->cnvst_pwm, &cnvst_pwm_state); + is_high = cnvst_pwm_state.duty_cycle == cnvst_pwm_state.period; + + cnvst_pwm_state.period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, freq); + cnvst_pwm_state.polarity = PWM_POLARITY_NORMAL; + if (is_high) + cnvst_pwm_state.duty_cycle = cnvst_pwm_state.period; + else if (is_swinging) + cnvst_pwm_state.duty_cycle = cnvst_pwm_state.period / 2; + else + cnvst_pwm_state.duty_cycle = 0; + + return pwm_apply_might_sleep(st->cnvst_pwm, &cnvst_pwm_state); +} + static int ad7606_read_samples(struct ad7606_state *st) { - unsigned int num = st->chip_info->num_channels - 1; - u16 *data = st->data; + unsigned int num = st->chip_info->num_adc_channels; - return st->bops->read_block(st->dev, num, data); + return st->bops->read_block(st->dev, num, &st->data); } static irqreturn_t ad7606_trigger_handler(int irq, void *p) @@ -104,7 +660,7 @@ static irqreturn_t ad7606_trigger_handler(int irq, void *p) if (ret) goto error_ret; - iio_push_to_buffers_with_timestamp(indio_dev, st->data, + iio_push_to_buffers_with_timestamp(indio_dev, &st->data, iio_get_time_ns(indio_dev)); error_ret: iio_trigger_notify_done(indio_dev->trig); @@ -114,24 +670,62 @@ error_ret: return IRQ_HANDLED; } -static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch) +static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch, + int *val) { struct ad7606_state *st = iio_priv(indio_dev); + unsigned int realbits = st->chip_info->channels[1].scan_type.realbits; + const struct iio_chan_spec *chan; int ret; - gpiod_set_value(st->gpio_convst, 1); - ret = wait_for_completion_timeout(&st->completion, - msecs_to_jiffies(1000)); - if (!ret) { - ret = -ETIMEDOUT; - goto error_ret; + if (st->gpio_convst) { + gpiod_set_value(st->gpio_convst, 1); + } else { + ret = ad7606_pwm_set_high(st); + if (ret < 0) + return ret; + } + + /* + * If no backend, wait for the interruption on busy pin, otherwise just add + * a delay to leave time for the data to be available. For now, the latter + * will not happen because IIO_CHAN_INFO_RAW is not supported for the backend. + * TODO: Add support for reading a single value when the backend is used. + */ + if (!st->back) { + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) { + ret = -ETIMEDOUT; + goto error_ret; + } + } else { + fsleep(1); } ret = ad7606_read_samples(st); - if (ret == 0) - ret = st->data[ch]; + if (ret) + goto error_ret; + + chan = &indio_dev->channels[ch + 1]; + if (chan->scan_type.sign == 'u') { + if (realbits > 16) + *val = st->data.buf32[ch]; + else + *val = st->data.buf16[ch]; + } else { + if (realbits > 16) + *val = sign_extend32(st->data.buf32[ch], realbits - 1); + else + *val = sign_extend32(st->data.buf16[ch], realbits - 1); + } error_ret: + if (!st->gpio_convst) { + ret = ad7606_pwm_set_low(st); + if (ret < 0) + return ret; + } gpiod_set_value(st->gpio_convst, 0); return ret; @@ -145,53 +739,57 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, { int ret, ch = 0; struct ad7606_state *st = iio_priv(indio_dev); + struct ad7606_chan_scale *cs; + struct pwm_state cnvst_pwm_state; switch (m) { case IIO_CHAN_INFO_RAW: iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { - ret = ad7606_scan_direct(indio_dev, chan->address); + ret = ad7606_scan_direct(indio_dev, chan->address, val); 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; - *val = 0; - *val2 = st->scale_avail[st->range[ch]]; + cs = &st->chan_scales[ch]; + *val = cs->scale_avail[cs->range][0]; + *val2 = cs->scale_avail[cs->range][1]; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: *val = st->oversampling; return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + /* + * TODO: return the real frequency intead of the requested one once + * pwm_get_state_hw comes upstream. + */ + pwm_get_state(st->cnvst_pwm, &cnvst_pwm_state); + *val = DIV_ROUND_CLOSEST_ULL(NSEC_PER_SEC, cnvst_pwm_state.period); + return IIO_VAL_INT; } return -EINVAL; } -static ssize_t ad7606_show_avail(char *buf, const unsigned int *vals, - unsigned int n, bool micros) -{ - size_t len = 0; - int i; - - for (i = 0; i < n; i++) { - len += scnprintf(buf + len, PAGE_SIZE - len, - micros ? "0.%06u " : "%u ", vals[i]); - } - buf[len - 1] = '\n'; - - return len; -} - static ssize_t in_voltage_scale_available_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7606_state *st = iio_priv(indio_dev); + struct ad7606_chan_scale *cs = &st->chan_scales[0]; + const unsigned int (*vals)[2] = cs->scale_avail; + unsigned int i; + size_t len = 0; + + for (i = 0; i < cs->num_scales; i++) + len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", + vals[i][0], vals[i][1]); + buf[len - 1] = '\n'; - return ad7606_show_avail(buf, st->scale_avail, st->num_scales, true); + return len; } static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); @@ -229,19 +827,27 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, long mask) { struct ad7606_state *st = iio_priv(indio_dev); + unsigned int scale_avail_uv[AD760X_MAX_SCALES]; + struct ad7606_chan_scale *cs; int i, ret, ch = 0; guard(mutex)(&st->lock); switch (mask) { case IIO_CHAN_INFO_SCALE: - i = find_closest(val2, st->scale_avail, st->num_scales); if (st->sw_mode_en) ch = chan->address; - ret = st->write_scale(indio_dev, ch, i); + cs = &st->chan_scales[ch]; + for (i = 0; i < cs->num_scales; i++) { + scale_avail_uv[i] = cs->scale_avail[i][0] * MICRO + + cs->scale_avail[i][1]; + } + val = (val * MICRO) + val2; + i = find_closest(val, scale_avail_uv, cs->num_scales); + ret = st->write_scale(indio_dev, ch, i + cs->reg_offset); if (ret < 0) return ret; - st->range[ch] = i; + cs->range = i; return 0; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: @@ -252,8 +858,13 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, ret = st->write_os(indio_dev, i); if (ret < 0) return ret; + st->oversampling = st->oversampling_avail[i]; return 0; + case IIO_CHAN_INFO_SAMP_FREQ: + if (val < 0 && val2 != 0) + return -EINVAL; + return ad7606_set_sampling_freq(st, val); default: return -EINVAL; } @@ -265,9 +876,15 @@ static ssize_t ad7606_oversampling_ratio_avail(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7606_state *st = iio_priv(indio_dev); + const unsigned int *vals = st->oversampling_avail; + unsigned int i; + size_t len = 0; - return ad7606_show_avail(buf, st->oversampling_avail, - st->num_os_ratios, false); + for (i = 0; i < st->num_os_ratios; i++) + len += scnprintf(buf + len, PAGE_SIZE - len, "%u ", vals[i]); + buf[len - 1] = '\n'; + + return len; } static IIO_DEVICE_ATTR(oversampling_ratio_available, 0444, @@ -301,102 +918,13 @@ static const struct attribute_group ad7606_attribute_group_range = { .attrs = ad7606_attributes_range, }; -static const struct iio_chan_spec ad7605_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(4), - AD7605_CHANNEL(0), - AD7605_CHANNEL(1), - AD7605_CHANNEL(2), - AD7605_CHANNEL(3), -}; - -static const struct iio_chan_spec ad7606_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_CHANNEL(0), - AD7606_CHANNEL(1), - AD7606_CHANNEL(2), - AD7606_CHANNEL(3), - AD7606_CHANNEL(4), - AD7606_CHANNEL(5), - AD7606_CHANNEL(6), - AD7606_CHANNEL(7), -}; - -/* - * The current assumption that this driver makes for AD7616, is that it's - * working in Hardware Mode with Serial, Burst and Sequencer modes activated. - * To activate them, following pins must be pulled high: - * -SER/PAR - * -SEQEN - * And following pins must be pulled low: - * -WR/BURST - * -DB4/SER1W - */ -static const struct iio_chan_spec ad7616_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(16), - AD7606_CHANNEL(0), - AD7606_CHANNEL(1), - AD7606_CHANNEL(2), - AD7606_CHANNEL(3), - AD7606_CHANNEL(4), - AD7606_CHANNEL(5), - AD7606_CHANNEL(6), - AD7606_CHANNEL(7), - AD7606_CHANNEL(8), - AD7606_CHANNEL(9), - AD7606_CHANNEL(10), - AD7606_CHANNEL(11), - AD7606_CHANNEL(12), - AD7606_CHANNEL(13), - AD7606_CHANNEL(14), - AD7606_CHANNEL(15), -}; - -static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { - /* More devices added in future */ - [ID_AD7605_4] = { - .channels = ad7605_channels, - .num_channels = 5, - }, - [ID_AD7606_8] = { - .channels = ad7606_channels, - .num_channels = 9, - .oversampling_avail = ad7606_oversampling_avail, - .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), - }, - [ID_AD7606_6] = { - .channels = ad7606_channels, - .num_channels = 7, - .oversampling_avail = ad7606_oversampling_avail, - .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), - }, - [ID_AD7606_4] = { - .channels = ad7606_channels, - .num_channels = 5, - .oversampling_avail = ad7606_oversampling_avail, - .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), - }, - [ID_AD7606B] = { - .channels = ad7606_channels, - .num_channels = 9, - .oversampling_avail = ad7606_oversampling_avail, - .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), - }, - [ID_AD7616] = { - .channels = ad7616_channels, - .num_channels = 17, - .oversampling_avail = ad7616_oversampling_avail, - .oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail), - .os_req_reset = true, - .init_delay_ms = 15, - }, -}; - static int ad7606_request_gpios(struct ad7606_state *st) { struct device *dev = st->dev; - st->gpio_convst = devm_gpiod_get(dev, "adi,conversion-start", - GPIOD_OUT_LOW); + st->gpio_convst = devm_gpiod_get_optional(dev, "adi,conversion-start", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_convst)) return PTR_ERR(st->gpio_convst); @@ -438,14 +966,24 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id) { struct iio_dev *indio_dev = dev_id; struct ad7606_state *st = iio_priv(indio_dev); + int ret; if (iio_buffer_enabled(indio_dev)) { - gpiod_set_value(st->gpio_convst, 0); + if (st->gpio_convst) { + gpiod_set_value(st->gpio_convst, 0); + } else { + ret = ad7606_pwm_set_low(st); + if (ret < 0) { + dev_err(st->dev, "PWM set low failed"); + goto done; + } + } iio_trigger_poll_nested(st->trig); } else { complete(&st->completion); } +done: return IRQ_HANDLED; }; @@ -478,14 +1016,81 @@ static int ad7606_buffer_predisable(struct iio_dev *indio_dev) return 0; } +static int ad7606_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long info) +{ + struct ad7606_state *st = iio_priv(indio_dev); + struct ad7606_chan_scale *cs; + unsigned int ch = 0; + + switch (info) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + *vals = st->oversampling_avail; + *length = st->num_os_ratios; + *type = IIO_VAL_INT; + + return IIO_AVAIL_LIST; + + case IIO_CHAN_INFO_SCALE: + if (st->sw_mode_en) + ch = chan->address; + + cs = &st->chan_scales[ch]; + *vals = (int *)cs->scale_avail; + *length = cs->num_scales; + *type = IIO_VAL_INT_PLUS_MICRO; + + return IIO_AVAIL_LIST; + } + return -EINVAL; +} + +static int ad7606_backend_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad7606_state *st = iio_priv(indio_dev); + + return ad7606_pwm_set_swing(st); +} + +static int ad7606_backend_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad7606_state *st = iio_priv(indio_dev); + + return ad7606_pwm_set_low(st); +} + +static int ad7606_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct ad7606_state *st = iio_priv(indio_dev); + + /* + * The update scan mode is only for iio backend compatible drivers. + * If the specific update_scan_mode is not defined in the bus ops, + * just do nothing and return 0. + */ + if (!st->bops->update_scan_mode) + return 0; + + return st->bops->update_scan_mode(indio_dev, scan_mask); +} + static const struct iio_buffer_setup_ops ad7606_buffer_ops = { .postenable = &ad7606_buffer_postenable, .predisable = &ad7606_buffer_predisable, }; +static const struct iio_buffer_setup_ops ad7606_backend_buffer_ops = { + .postenable = &ad7606_backend_buffer_postenable, + .predisable = &ad7606_backend_buffer_predisable, +}; + static const struct iio_info ad7606_info_no_os_or_range = { .read_raw = &ad7606_read_raw, .validate_trigger = &ad7606_validate_trigger, + .update_scan_mode = &ad7606_update_scan_mode, }; static const struct iio_info ad7606_info_os_and_range = { @@ -493,14 +1098,16 @@ static const struct iio_info ad7606_info_os_and_range = { .write_raw = &ad7606_write_raw, .attrs = &ad7606_attribute_group_os_and_range, .validate_trigger = &ad7606_validate_trigger, + .update_scan_mode = &ad7606_update_scan_mode, }; -static const struct iio_info ad7606_info_os_range_and_debug = { +static const struct iio_info ad7606_info_sw_mode = { .read_raw = &ad7606_read_raw, .write_raw = &ad7606_write_raw, + .read_avail = &ad7606_read_avail, .debugfs_reg_access = &ad7606_reg_access, - .attrs = &ad7606_attribute_group_os_and_range, .validate_trigger = &ad7606_validate_trigger, + .update_scan_mode = &ad7606_update_scan_mode, }; static const struct iio_info ad7606_info_os = { @@ -508,6 +1115,7 @@ static const struct iio_info ad7606_info_os = { .write_raw = &ad7606_write_raw, .attrs = &ad7606_attribute_group_os, .validate_trigger = &ad7606_validate_trigger, + .update_scan_mode = &ad7606_update_scan_mode, }; static const struct iio_info ad7606_info_range = { @@ -515,14 +1123,60 @@ static const struct iio_info ad7606_info_range = { .write_raw = &ad7606_write_raw, .attrs = &ad7606_attribute_group_range, .validate_trigger = &ad7606_validate_trigger, + .update_scan_mode = &ad7606_update_scan_mode, }; static const struct iio_trigger_ops ad7606_trigger_ops = { .validate_device = iio_trigger_validate_own_device, }; +static int ad7606_sw_mode_setup(struct iio_dev *indio_dev) +{ + struct ad7606_state *st = iio_priv(indio_dev); + + st->sw_mode_en = st->bops->sw_mode_config && + device_property_present(st->dev, "adi,sw-mode"); + if (!st->sw_mode_en) + return 0; + + indio_dev->info = &ad7606_info_sw_mode; + + return st->bops->sw_mode_config(indio_dev); +} + +static int ad7606_chan_scales_setup(struct iio_dev *indio_dev) +{ + unsigned int num_channels = indio_dev->num_channels - 1; + struct ad7606_state *st = iio_priv(indio_dev); + struct iio_chan_spec *chans; + size_t size; + int ch, ret; + + /* Clone IIO channels, since some may be differential */ + size = indio_dev->num_channels * sizeof(*indio_dev->channels); + chans = devm_kzalloc(st->dev, size, GFP_KERNEL); + if (!chans) + return -ENOMEM; + + memcpy(chans, indio_dev->channels, size); + indio_dev->channels = chans; + + for (ch = 0; ch < num_channels; ch++) { + ret = st->chip_info->scale_setup_cb(st, &chans[ch + 1], ch); + if (ret) + return ret; + } + + return 0; +} + +static void ad7606_pwm_disable(void *data) +{ + pwm_disable(data); +} + int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, - const char *name, unsigned int id, + const struct ad7606_chip_info *chip_info, const struct ad7606_bus_ops *bops) { struct ad7606_state *st; @@ -540,18 +1194,14 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, mutex_init(&st->lock); st->bops = bops; st->base_address = base_address; - /* tied to logic low, analog input range is +/- 5V */ - st->range[0] = 0; st->oversampling = 1; - st->scale_avail = ad7606_scale_avail; - st->num_scales = ARRAY_SIZE(ad7606_scale_avail); ret = devm_regulator_get_enable(dev, "avcc"); if (ret) return dev_err_probe(dev, ret, "Failed to enable specified AVcc supply\n"); - st->chip_info = &ad7606_chip_info_tbl[id]; + st->chip_info = chip_info; if (st->chip_info->oversampling_num) { st->oversampling_avail = st->chip_info->oversampling_avail; @@ -574,12 +1224,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, indio_dev->info = &ad7606_info_no_os_or_range; } indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->name = name; + indio_dev->name = chip_info->name; indio_dev->channels = st->chip_info->channels; indio_dev->num_channels = st->chip_info->num_channels; - init_completion(&st->completion); - ret = ad7606_reset(st); if (ret) dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); @@ -593,56 +1241,94 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, st->write_scale = ad7606_write_scale_hw; st->write_os = ad7606_write_os_hw; - if (st->bops->sw_mode_config) - st->sw_mode_en = device_property_present(st->dev, - "adi,sw-mode"); + ret = ad7606_sw_mode_setup(indio_dev); + if (ret) + return ret; + + ret = ad7606_chan_scales_setup(indio_dev); + if (ret) + return ret; + + /* If convst pin is not defined, setup PWM. */ + if (!st->gpio_convst) { + st->cnvst_pwm = devm_pwm_get(dev, NULL); + if (IS_ERR(st->cnvst_pwm)) + return PTR_ERR(st->cnvst_pwm); - if (st->sw_mode_en) { - /* Scale of 0.076293 is only available in sw mode */ - st->scale_avail = ad7616_sw_scale_avail; - st->num_scales = ARRAY_SIZE(ad7616_sw_scale_avail); + /* The PWM is initialized at 1MHz to have a fast enough GPIO emulation. */ + ret = ad7606_set_sampling_freq(st, 1 * MEGA); + if (ret) + return ret; - /* After reset, in software mode, ±10 V is set by default */ - memset32(st->range, 2, ARRAY_SIZE(st->range)); - indio_dev->info = &ad7606_info_os_range_and_debug; + ret = ad7606_pwm_set_low(st); + if (ret) + return ret; - ret = st->bops->sw_mode_config(indio_dev); - if (ret < 0) + /* + * PWM is not disabled when sampling stops, but instead its duty cycle is set + * to 0% to be sure we have a "low" state. After we unload the driver, let's + * disable the PWM. + */ + ret = devm_add_action_or_reset(dev, ad7606_pwm_disable, + st->cnvst_pwm); + if (ret) return ret; } - st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", - indio_dev->name, - iio_device_id(indio_dev)); - if (!st->trig) - return -ENOMEM; + if (st->bops->iio_backend_config) { + /* + * If there is a backend, the PWM should not overpass the maximum sampling + * frequency the chip supports. + */ + ret = ad7606_set_sampling_freq(st, + chip_info->max_samplerate ? : 2 * KILO); + if (ret) + return ret; - st->trig->ops = &ad7606_trigger_ops; - iio_trigger_set_drvdata(st->trig, indio_dev); - ret = devm_iio_trigger_register(dev, st->trig); - if (ret) - return ret; + ret = st->bops->iio_backend_config(dev, indio_dev); + if (ret) + return ret; - indio_dev->trig = iio_trigger_get(st->trig); + indio_dev->setup_ops = &ad7606_backend_buffer_ops; + } else { - ret = devm_request_threaded_irq(dev, irq, - NULL, - &ad7606_interrupt, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - name, indio_dev); - if (ret) - return ret; + /* Reserve the PWM use only for backend (force gpio_convst definition) */ + if (!st->gpio_convst) + return dev_err_probe(dev, -EINVAL, + "No backend, connect convst to a GPIO"); + + init_completion(&st->completion); + st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!st->trig) + return -ENOMEM; + + st->trig->ops = &ad7606_trigger_ops; + iio_trigger_set_drvdata(st->trig, indio_dev); + ret = devm_iio_trigger_register(dev, st->trig); + if (ret) + return ret; - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, - &iio_pollfunc_store_time, - &ad7606_trigger_handler, - &ad7606_buffer_ops); - if (ret) - return ret; + indio_dev->trig = iio_trigger_get(st->trig); + + ret = devm_request_threaded_irq(dev, irq, NULL, &ad7606_interrupt, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + chip_info->name, indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + &iio_pollfunc_store_time, + &ad7606_trigger_handler, + &ad7606_buffer_ops); + if (ret) + return ret; + } return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(ad7606_probe, IIO_AD7606); +EXPORT_SYMBOL_NS_GPL(ad7606_probe, "IIO_AD7606"); #ifdef CONFIG_PM_SLEEP @@ -665,7 +1351,7 @@ static int ad7606_resume(struct device *dev) struct ad7606_state *st = iio_priv(indio_dev); if (st->gpio_standby) { - gpiod_set_value(st->gpio_range, st->range[0]); + gpiod_set_value(st->gpio_range, st->chan_scales[0].range); gpiod_set_value(st->gpio_standby, 1); ad7606_reset(st); } @@ -674,7 +1360,7 @@ static int ad7606_resume(struct device *dev) } SIMPLE_DEV_PM_OPS(ad7606_pm_ops, ad7606_suspend, ad7606_resume); -EXPORT_SYMBOL_NS_GPL(ad7606_pm_ops, IIO_AD7606); +EXPORT_SYMBOL_NS_GPL(ad7606_pm_ops, "IIO_AD7606"); #endif diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index 6649e84d25de6428bc2cecaea9cc10f7add49781..998814a92b8258296777c19df82f35903e7b3deb 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -8,7 +8,9 @@ #ifndef IIO_ADC_AD7606_H_ #define IIO_ADC_AD7606_H_ -#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all) { \ +#define AD760X_MAX_CHANNELS 16 + +#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = num, \ @@ -19,56 +21,111 @@ .scan_index = num, \ .scan_type = { \ .sign = 's', \ - .realbits = 16, \ - .storagebits = 16, \ + .realbits = (bits), \ + .storagebits = (bits) > 16 ? 32 : 16, \ + .endianness = IIO_CPU, \ + }, \ +} + +#define AD7606_SW_CHANNEL(num, bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = num, \ + .address = num, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_separate_available = \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_all_available = \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .scan_index = num, \ + .scan_type = { \ + .sign = 's', \ + .realbits = (bits), \ + .storagebits = (bits) > 16 ? 32 : 16, \ .endianness = IIO_CPU, \ }, \ } #define AD7605_CHANNEL(num) \ AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \ - BIT(IIO_CHAN_INFO_SCALE), 0) + BIT(IIO_CHAN_INFO_SCALE), 0, 16) -#define AD7606_CHANNEL(num) \ +#define AD7606_CHANNEL(num, bits) \ AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \ BIT(IIO_CHAN_INFO_SCALE), \ - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)) + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), bits) + +#define AD7616_CHANNEL(num) AD7606_SW_CHANNEL(num, 16) + +#define AD7606_BI_CHANNEL(num) \ + AD760X_CHANNEL(num, 0, \ + BIT(IIO_CHAN_INFO_SCALE), \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 16) -#define AD7616_CHANNEL(num) \ - AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),\ - 0, BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)) +struct ad7606_state; + +typedef int (*ad7606_scale_setup_cb_t)(struct ad7606_state *st, + struct iio_chan_spec *chan, int ch); /** * struct ad7606_chip_info - chip specific information * @channels: channel specification + * @max_samplerate: maximum supported samplerate + * @name device name * @num_channels: number of channels + * @num_adc_channels the number of channels the ADC actually inputs. + * @scale_setup_cb: callback to setup the scales for each channel * @oversampling_avail pointer to the array which stores the available * oversampling ratios. * @oversampling_num number of elements stored in oversampling_avail array * @os_req_reset some devices require a reset to update oversampling - * @init_delay_ms required delay in miliseconds for initialization + * @init_delay_ms required delay in milliseconds for initialization * after a restart */ struct ad7606_chip_info { const struct iio_chan_spec *channels; + unsigned int max_samplerate; + const char *name; + unsigned int num_adc_channels; unsigned int num_channels; + ad7606_scale_setup_cb_t scale_setup_cb; const unsigned int *oversampling_avail; unsigned int oversampling_num; bool os_req_reset; unsigned long init_delay_ms; }; +/** + * struct ad7606_chan_scale - channel scale configuration + * @scale_avail pointer to the array which stores the available scales + * @num_scales number of elements stored in the scale_avail array + * @range voltage range selection, selects which scale to apply + * @reg_offset offset for the register value, to be applied when + * writing the value of 'range' to the register value + */ +struct ad7606_chan_scale { +#define AD760X_MAX_SCALES 16 + const unsigned int (*scale_avail)[2]; + unsigned int num_scales; + unsigned int range; + unsigned int reg_offset; +}; + /** * struct ad7606_state - driver instance specific data * @dev pointer to kernel device * @chip_info entry in the table of chips that describes this device * @bops bus operations (SPI or parallel) - * @range voltage range selection, selects which scale to apply + * @chan_scales scale configuration for channels * @oversampling oversampling selection + * @cnvst_pwm pointer to the PWM device connected to the cnvst pin * @base_address address from where to read data in parallel operation * @sw_mode_en software mode enabled - * @scale_avail pointer to the array which stores the available scales - * @num_scales number of elements stored in the scale_avail array * @oversampling_avail pointer to the array which stores the available * oversampling ratios. * @num_os_ratios number of elements stored in oversampling_avail array @@ -92,14 +149,14 @@ struct ad7606_state { struct device *dev; const struct ad7606_chip_info *chip_info; const struct ad7606_bus_ops *bops; - unsigned int range[16]; + struct ad7606_chan_scale chan_scales[AD760X_MAX_CHANNELS]; unsigned int oversampling; + struct pwm_device *cnvst_pwm; void __iomem *base_address; bool sw_mode_en; - const unsigned int *scale_avail; - unsigned int num_scales; const unsigned int *oversampling_avail; unsigned int num_os_ratios; + struct iio_backend *back; int (*write_scale)(struct iio_dev *indio_dev, int ch, int val); int (*write_os)(struct iio_dev *indio_dev, int val); @@ -116,24 +173,33 @@ struct ad7606_state { /* * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. - * 16 * 16-bit samples + 64-bit timestamp + * 16 * 16-bit samples + 64-bit timestamp - for AD7616 + * 8 * 32-bit samples + 64-bit timestamp - for AD7616C-18 (and similar) */ - unsigned short data[20] __aligned(IIO_DMA_MINALIGN); + union { + u16 buf16[20]; + u32 buf32[10]; + } data __aligned(IIO_DMA_MINALIGN); __be16 d16[2]; }; /** * struct ad7606_bus_ops - driver bus operations + * @iio_backend_config function pointer for configuring the iio_backend for + * the compatibles that use it * @read_block function pointer for reading blocks of data * @sw_mode_config: pointer to a function which configured the device * for software mode * @reg_read function pointer for reading spi register * @reg_write function pointer for writing spi register * @write_mask function pointer for write spi register with mask + * @update_scan_mode function pointer for handling the calls to iio_info's update_scan + * mode when enabling/disabling channels. * @rd_wr_cmd pointer to the function which calculates the spi address */ struct ad7606_bus_ops { /* more methods added in future? */ + int (*iio_backend_config)(struct device *dev, struct iio_dev *indio_dev); int (*read_block)(struct device *dev, int num, void *data); int (*sw_mode_config)(struct iio_dev *indio_dev); int (*reg_read)(struct ad7606_state *st, unsigned int addr); @@ -144,23 +210,37 @@ struct ad7606_bus_ops { unsigned int addr, unsigned long mask, unsigned int val); + int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask); u16 (*rd_wr_cmd)(int addr, char isWriteOp); }; +/** + * struct ad7606_bus_info - agregate ad7606_chip_info and ad7606_bus_ops + * @chip_info entry in the table of chips that describes this device + * @bops bus operations (SPI or parallel) + */ +struct ad7606_bus_info { + const struct ad7606_chip_info *chip_info; + const struct ad7606_bus_ops *bops; +}; + int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, - const char *name, unsigned int id, + const struct ad7606_chip_info *info, const struct ad7606_bus_ops *bops); int ad7606_reset(struct ad7606_state *st); -enum ad7606_supported_device_ids { - ID_AD7605_4, - ID_AD7606_8, - ID_AD7606_6, - ID_AD7606_4, - ID_AD7606B, - ID_AD7616, -}; +extern const struct ad7606_chip_info ad7605_4_info; +extern const struct ad7606_chip_info ad7606_8_info; +extern const struct ad7606_chip_info ad7606_6_info; +extern const struct ad7606_chip_info ad7606_4_info; +extern const struct ad7606_chip_info ad7606b_info; +extern const struct ad7606_chip_info ad7606c_16_info; +extern const struct ad7606_chip_info ad7606c_18_info; +extern const struct ad7606_chip_info ad7607_info; +extern const struct ad7606_chip_info ad7608_info; +extern const struct ad7606_chip_info ad7609_info; +extern const struct ad7606_chip_info ad7616_info; #ifdef CONFIG_PM_SLEEP extern const struct dev_pm_ops ad7606_pm_ops; diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c index 02d8c309304e24fd097f764d9b674433a6560124..64733b607aa87a3ff101d317c48fbd41b47f279e 100644 --- a/drivers/iio/adc/ad7606_par.c +++ b/drivers/iio/adc/ad7606_par.c @@ -2,20 +2,95 @@ /* * AD7606 Parallel Interface ADC driver * - * Copyright 2011 Analog Devices Inc. + * Copyright 2011 - 2024 Analog Devices Inc. + * Copyright 2024 BayLibre SAS. */ +#include +#include +#include #include #include -#include #include +#include #include -#include -#include +#include #include + #include "ad7606.h" +static const struct iio_chan_spec ad7606b_bi_channels[] = { + AD7606_BI_CHANNEL(0), + AD7606_BI_CHANNEL(1), + AD7606_BI_CHANNEL(2), + AD7606_BI_CHANNEL(3), + AD7606_BI_CHANNEL(4), + AD7606_BI_CHANNEL(5), + AD7606_BI_CHANNEL(6), + AD7606_BI_CHANNEL(7), +}; + +static int ad7606_bi_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) +{ + struct ad7606_state *st = iio_priv(indio_dev); + unsigned int c, ret; + + for (c = 0; c < indio_dev->num_channels; c++) { + if (test_bit(c, scan_mask)) + ret = iio_backend_chan_enable(st->back, c); + else + ret = iio_backend_chan_disable(st->back, c); + if (ret) + return ret; + } + + return 0; +} + +static int ad7606_bi_setup_iio_backend(struct device *dev, struct iio_dev *indio_dev) +{ + struct ad7606_state *st = iio_priv(indio_dev); + unsigned int ret, c; + struct iio_backend_data_fmt data = { + .sign_extend = true, + .enable = true, + }; + + st->back = devm_iio_backend_get(dev, NULL); + if (IS_ERR(st->back)) + return PTR_ERR(st->back); + + /* If the device is iio_backend powered the PWM is mandatory */ + if (!st->cnvst_pwm) + return dev_err_probe(st->dev, -EINVAL, + "A PWM is mandatory when using backend.\n"); + + ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev); + if (ret) + return ret; + + ret = devm_iio_backend_enable(dev, st->back); + if (ret) + return ret; + + for (c = 0; c < indio_dev->num_channels; c++) { + ret = iio_backend_data_format_set(st->back, c, &data); + if (ret) + return ret; + } + + indio_dev->channels = ad7606b_bi_channels; + indio_dev->num_channels = 8; + + return 0; +} + +static const struct ad7606_bus_ops ad7606_bi_bops = { + .iio_backend_config = ad7606_bi_setup_iio_backend, + .update_scan_mode = ad7606_bi_update_scan_mode, +}; + static int ad7606_par16_read_block(struct device *dev, int count, void *buf) { @@ -89,12 +164,32 @@ static const struct ad7606_bus_ops ad7606_par8_bops = { static int ad7606_par_probe(struct platform_device *pdev) { - const struct platform_device_id *id = platform_get_device_id(pdev); + const struct ad7606_chip_info *chip_info; + const struct platform_device_id *id; struct resource *res; void __iomem *addr; resource_size_t remap_size; int irq; + /* + * If a firmware node is available (ACPI or DT), platform_device_id is null + * and we must use get_match_data. + */ + if (dev_fwnode(&pdev->dev)) { + chip_info = device_get_match_data(&pdev->dev); + if (device_property_present(&pdev->dev, "io-backends")) + /* + * If a backend is available ,call the core probe with backend + * bops, otherwise use the former bops. + */ + return ad7606_probe(&pdev->dev, 0, NULL, + chip_info, + &ad7606_bi_bops); + } else { + id = platform_get_device_id(pdev); + chip_info = (const struct ad7606_chip_info *)id->driver_data; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -105,26 +200,33 @@ static int ad7606_par_probe(struct platform_device *pdev) remap_size = resource_size(res); - return ad7606_probe(&pdev->dev, irq, addr, - id->name, id->driver_data, + return ad7606_probe(&pdev->dev, irq, addr, chip_info, remap_size > 1 ? &ad7606_par16_bops : &ad7606_par8_bops); } static const struct platform_device_id ad7606_driver_ids[] = { - { .name = "ad7605-4", .driver_data = ID_AD7605_4, }, - { .name = "ad7606-4", .driver_data = ID_AD7606_4, }, - { .name = "ad7606-6", .driver_data = ID_AD7606_6, }, - { .name = "ad7606-8", .driver_data = ID_AD7606_8, }, + { .name = "ad7605-4", .driver_data = (kernel_ulong_t)&ad7605_4_info, }, + { .name = "ad7606-4", .driver_data = (kernel_ulong_t)&ad7606_4_info, }, + { .name = "ad7606-6", .driver_data = (kernel_ulong_t)&ad7606_6_info, }, + { .name = "ad7606-8", .driver_data = (kernel_ulong_t)&ad7606_8_info, }, + { .name = "ad7606b", .driver_data = (kernel_ulong_t)&ad7606b_info, }, + { .name = "ad7607", .driver_data = (kernel_ulong_t)&ad7607_info, }, + { .name = "ad7608", .driver_data = (kernel_ulong_t)&ad7608_info, }, + { .name = "ad7609", .driver_data = (kernel_ulong_t)&ad7609_info, }, { } }; MODULE_DEVICE_TABLE(platform, ad7606_driver_ids); static const struct of_device_id ad7606_of_match[] = { - { .compatible = "adi,ad7605-4" }, - { .compatible = "adi,ad7606-4" }, - { .compatible = "adi,ad7606-6" }, - { .compatible = "adi,ad7606-8" }, + { .compatible = "adi,ad7605-4", .data = &ad7605_4_info }, + { .compatible = "adi,ad7606-4", .data = &ad7606_4_info }, + { .compatible = "adi,ad7606-6", .data = &ad7606_6_info }, + { .compatible = "adi,ad7606-8", .data = &ad7606_8_info }, + { .compatible = "adi,ad7606b", .data = &ad7606b_info }, + { .compatible = "adi,ad7607", .data = &ad7607_info }, + { .compatible = "adi,ad7608", .data = &ad7608_info }, + { .compatible = "adi,ad7609", .data = &ad7609_info }, { } }; MODULE_DEVICE_TABLE(of, ad7606_of_match); @@ -143,4 +245,5 @@ module_platform_driver(ad7606_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD7606); +MODULE_IMPORT_NS("IIO_AD7606"); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index 62ec121953079944210563c2e8e618615148bf17..e2c1475257065c98bf8e2512bda921d6d88a3002 100644 --- a/drivers/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c @@ -5,10 +5,10 @@ * Copyright 2011 Analog Devices Inc. */ +#include #include #include #include -#include #include #include "ad7606.h" @@ -67,14 +67,26 @@ static const struct iio_chan_spec ad7616_sw_channels[] = { static const struct iio_chan_spec ad7606b_sw_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(8), - AD7616_CHANNEL(0), - AD7616_CHANNEL(1), - AD7616_CHANNEL(2), - AD7616_CHANNEL(3), - AD7616_CHANNEL(4), - AD7616_CHANNEL(5), - AD7616_CHANNEL(6), - AD7616_CHANNEL(7), + AD7606_SW_CHANNEL(0, 16), + AD7606_SW_CHANNEL(1, 16), + AD7606_SW_CHANNEL(2, 16), + AD7606_SW_CHANNEL(3, 16), + AD7606_SW_CHANNEL(4, 16), + AD7606_SW_CHANNEL(5, 16), + AD7606_SW_CHANNEL(6, 16), + AD7606_SW_CHANNEL(7, 16), +}; + +static const struct iio_chan_spec ad7606c_18_sw_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(8), + AD7606_SW_CHANNEL(0, 18), + AD7606_SW_CHANNEL(1, 18), + AD7606_SW_CHANNEL(2, 18), + AD7606_SW_CHANNEL(3, 18), + AD7606_SW_CHANNEL(4, 18), + AD7606_SW_CHANNEL(5, 18), + AD7606_SW_CHANNEL(6, 18), + AD7606_SW_CHANNEL(7, 18), }; static const unsigned int ad7606B_oversampling_avail[9] = { @@ -120,6 +132,32 @@ static int ad7606_spi_read_block(struct device *dev, return 0; } +static int ad7606_spi_read_block14to16(struct device *dev, + int count, void *buf) +{ + struct spi_device *spi = to_spi_device(dev); + struct spi_transfer xfer = { + .bits_per_word = 14, + .len = count * sizeof(u16), + .rx_buf = buf, + }; + + return spi_sync_transfer(spi, &xfer, 1); +} + +static int ad7606_spi_read_block18to32(struct device *dev, + int count, void *buf) +{ + struct spi_device *spi = to_spi_device(dev); + struct spi_transfer xfer = { + .bits_per_word = 18, + .len = count * sizeof(u32), + .rx_buf = buf, + }; + + return spi_sync_transfer(spi, &xfer, 1); +} + static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr) { struct spi_device *spi = to_spi_device(st->dev); @@ -283,10 +321,31 @@ static int ad7606B_sw_mode_config(struct iio_dev *indio_dev) return 0; } +static int ad7606c_18_sw_mode_config(struct iio_dev *indio_dev) +{ + int ret; + + ret = ad7606B_sw_mode_config(indio_dev); + if (ret) + return ret; + + indio_dev->channels = ad7606c_18_sw_channels; + + return 0; +} + static const struct ad7606_bus_ops ad7606_spi_bops = { .read_block = ad7606_spi_read_block, }; +static const struct ad7606_bus_ops ad7607_spi_bops = { + .read_block = ad7606_spi_read_block14to16, +}; + +static const struct ad7606_bus_ops ad7608_spi_bops = { + .read_block = ad7606_spi_read_block18to32, +}; + static const struct ad7606_bus_ops ad7616_spi_bops = { .read_block = ad7606_spi_read_block, .reg_read = ad7606_spi_reg_read, @@ -296,7 +355,7 @@ static const struct ad7606_bus_ops ad7616_spi_bops = { .sw_mode_config = ad7616_sw_mode_config, }; -static const struct ad7606_bus_ops ad7606B_spi_bops = { +static const struct ad7606_bus_ops ad7606b_spi_bops = { .read_block = ad7606_spi_read_block, .reg_read = ad7606_spi_reg_read, .reg_write = ad7606_spi_reg_write, @@ -305,46 +364,106 @@ static const struct ad7606_bus_ops ad7606B_spi_bops = { .sw_mode_config = ad7606B_sw_mode_config, }; +static const struct ad7606_bus_ops ad7606c_18_spi_bops = { + .read_block = ad7606_spi_read_block18to32, + .reg_read = ad7606_spi_reg_read, + .reg_write = ad7606_spi_reg_write, + .write_mask = ad7606_spi_write_mask, + .rd_wr_cmd = ad7606B_spi_rd_wr_cmd, + .sw_mode_config = ad7606c_18_sw_mode_config, +}; + +static const struct ad7606_bus_info ad7605_4_bus_info = { + .chip_info = &ad7605_4_info, + .bops = &ad7606_spi_bops, +}; + +static const struct ad7606_bus_info ad7606_8_bus_info = { + .chip_info = &ad7606_8_info, + .bops = &ad7606_spi_bops, +}; + +static const struct ad7606_bus_info ad7606_6_bus_info = { + .chip_info = &ad7606_6_info, + .bops = &ad7606_spi_bops, +}; + +static const struct ad7606_bus_info ad7606_4_bus_info = { + .chip_info = &ad7606_4_info, + .bops = &ad7606_spi_bops, +}; + +static const struct ad7606_bus_info ad7606b_bus_info = { + .chip_info = &ad7606b_info, + .bops = &ad7606b_spi_bops, +}; + +static const struct ad7606_bus_info ad7606c_16_bus_info = { + .chip_info = &ad7606c_16_info, + .bops = &ad7606b_spi_bops, +}; + +static const struct ad7606_bus_info ad7606c_18_bus_info = { + .chip_info = &ad7606c_18_info, + .bops = &ad7606c_18_spi_bops, +}; + +static const struct ad7606_bus_info ad7607_bus_info = { + .chip_info = &ad7607_info, + .bops = &ad7607_spi_bops, +}; + +static const struct ad7606_bus_info ad7608_bus_info = { + .chip_info = &ad7608_info, + .bops = &ad7608_spi_bops, +}; + +static const struct ad7606_bus_info ad7609_bus_info = { + .chip_info = &ad7609_info, + .bops = &ad7608_spi_bops, +}; + +static const struct ad7606_bus_info ad7616_bus_info = { + .chip_info = &ad7616_info, + .bops = &ad7616_spi_bops, +}; + static int ad7606_spi_probe(struct spi_device *spi) { - const struct spi_device_id *id = spi_get_device_id(spi); - const struct ad7606_bus_ops *bops; - - switch (id->driver_data) { - case ID_AD7616: - bops = &ad7616_spi_bops; - break; - case ID_AD7606B: - bops = &ad7606B_spi_bops; - break; - default: - bops = &ad7606_spi_bops; - break; - } + const struct ad7606_bus_info *bus_info = spi_get_device_match_data(spi); return ad7606_probe(&spi->dev, spi->irq, NULL, - id->name, id->driver_data, - bops); + bus_info->chip_info, bus_info->bops); } static const struct spi_device_id ad7606_id_table[] = { - { "ad7605-4", ID_AD7605_4 }, - { "ad7606-4", ID_AD7606_4 }, - { "ad7606-6", ID_AD7606_6 }, - { "ad7606-8", ID_AD7606_8 }, - { "ad7606b", ID_AD7606B }, - { "ad7616", ID_AD7616 }, + { "ad7605-4", (kernel_ulong_t)&ad7605_4_bus_info }, + { "ad7606-4", (kernel_ulong_t)&ad7606_4_bus_info }, + { "ad7606-6", (kernel_ulong_t)&ad7606_6_bus_info }, + { "ad7606-8", (kernel_ulong_t)&ad7606_8_bus_info }, + { "ad7606b", (kernel_ulong_t)&ad7606b_bus_info }, + { "ad7606c-16", (kernel_ulong_t)&ad7606c_16_bus_info }, + { "ad7606c-18", (kernel_ulong_t)&ad7606c_18_bus_info }, + { "ad7607", (kernel_ulong_t)&ad7607_bus_info }, + { "ad7608", (kernel_ulong_t)&ad7608_bus_info }, + { "ad7609", (kernel_ulong_t)&ad7609_bus_info }, + { "ad7616", (kernel_ulong_t)&ad7616_bus_info }, { } }; MODULE_DEVICE_TABLE(spi, ad7606_id_table); static const struct of_device_id ad7606_of_match[] = { - { .compatible = "adi,ad7605-4" }, - { .compatible = "adi,ad7606-4" }, - { .compatible = "adi,ad7606-6" }, - { .compatible = "adi,ad7606-8" }, - { .compatible = "adi,ad7606b" }, - { .compatible = "adi,ad7616" }, + { .compatible = "adi,ad7605-4", .data = &ad7605_4_bus_info }, + { .compatible = "adi,ad7606-4", .data = &ad7606_4_bus_info }, + { .compatible = "adi,ad7606-6", .data = &ad7606_6_bus_info }, + { .compatible = "adi,ad7606-8", .data = &ad7606_8_bus_info }, + { .compatible = "adi,ad7606b", .data = &ad7606b_bus_info }, + { .compatible = "adi,ad7606c-16", .data = &ad7606c_16_bus_info }, + { .compatible = "adi,ad7606c-18", .data = &ad7606c_18_bus_info }, + { .compatible = "adi,ad7607", .data = &ad7607_bus_info }, + { .compatible = "adi,ad7608", .data = &ad7608_bus_info }, + { .compatible = "adi,ad7609", .data = &ad7609_bus_info }, + { .compatible = "adi,ad7616", .data = &ad7616_bus_info }, { } }; MODULE_DEVICE_TABLE(of, ad7606_of_match); @@ -363,4 +482,4 @@ module_spi_driver(ad7606_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD7606); +MODULE_IMPORT_NS("IIO_AD7606"); diff --git a/drivers/iio/adc/ad7625.c b/drivers/iio/adc/ad7625.c new file mode 100644 index 0000000000000000000000000000000000000000..aefe3bf75c914783441b1f3e3c824bda0533b2fb --- /dev/null +++ b/drivers/iio/adc/ad7625.c @@ -0,0 +1,684 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Analog Devices Inc. AD7625 ADC driver + * + * Copyright 2024 Analog Devices Inc. + * Copyright 2024 BayLibre, SAS + * + * Note that this driver requires the AXI ADC IP block configured for + * LVDS to function. See Documentation/iio/ad7625.rst for more + * information. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AD7625_INTERNAL_REF_MV 4096 +#define AD7960_MAX_NBW_FREQ (2 * MEGA) + +struct ad7625_timing_spec { + /* Max conversion high time (t_{CNVH}). */ + unsigned int conv_high_ns; + /* Max conversion to MSB delay (t_{MSB}). */ + unsigned int conv_msb_ns; +}; + +struct ad7625_chip_info { + const char *name; + const unsigned int max_sample_freq_hz; + const struct ad7625_timing_spec *timing_spec; + const struct iio_chan_spec chan_spec; + const bool has_power_down_state; + const bool has_bandwidth_control; + const bool has_internal_vref; +}; + +/* AD7625_CHAN_SPEC - Define a chan spec structure for a specific chip */ +#define AD7625_CHAN_SPEC(_bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .differential = 1, \ + .channel = 0, \ + .channel2 = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = 0, \ + .scan_type.sign = 's', \ + .scan_type.storagebits = (_bits) > 16 ? 32 : 16, \ + .scan_type.realbits = (_bits), \ +} + +struct ad7625_state { + const struct ad7625_chip_info *info; + struct iio_backend *back; + /* rate of the clock gated by the "clk_gate" PWM */ + u32 ref_clk_rate_hz; + /* PWM burst signal for transferring acquired data to the host */ + struct pwm_device *clk_gate_pwm; + /* + * PWM control signal for initiating data conversion. Analog + * inputs are sampled beginning on this signal's rising edge. + */ + struct pwm_device *cnv_pwm; + /* + * Waveforms containing the last-requested and rounded + * properties for the clk_gate and cnv PWMs + */ + struct pwm_waveform clk_gate_wf; + struct pwm_waveform cnv_wf; + unsigned int vref_mv; + u32 sampling_freq_hz; + /* + * Optional GPIOs for controlling device state. EN0 and EN1 + * determine voltage reference configuration and on/off state. + * EN2 controls the device -3dB bandwidth (and by extension, max + * sample rate). EN3 controls the VCM reference output. EN2 and + * EN3 are only present for the AD796x devices. + */ + struct gpio_desc *en_gpios[4]; + bool can_power_down; + bool can_refin; + bool can_ref_4v096; + /* + * Indicate whether the bandwidth can be narrow (9MHz). + * When true, device sample rate must also be < 2MSPS. + */ + bool can_narrow_bandwidth; + /* Indicate whether the bandwidth can be wide (28MHz). */ + bool can_wide_bandwidth; + bool can_ref_5v; + bool can_snooze; + bool can_test_pattern; + /* Indicate whether there is a REFIN supply connected */ + bool have_refin; +}; + +static const struct ad7625_timing_spec ad7625_timing_spec = { + .conv_high_ns = 40, + .conv_msb_ns = 145, +}; + +static const struct ad7625_timing_spec ad7626_timing_spec = { + .conv_high_ns = 40, + .conv_msb_ns = 80, +}; + +/* + * conv_msb_ns is set to 0 instead of the datasheet maximum of 200ns to + * avoid exceeding the minimum conversion time, i.e. it is effectively + * modulo 200 and offset by a full period. Values greater than or equal + * to the period would be rejected by the PWM API. + */ +static const struct ad7625_timing_spec ad7960_timing_spec = { + .conv_high_ns = 80, + .conv_msb_ns = 0, +}; + +static const struct ad7625_chip_info ad7625_chip_info = { + .name = "ad7625", + .max_sample_freq_hz = 6 * MEGA, + .timing_spec = &ad7625_timing_spec, + .chan_spec = AD7625_CHAN_SPEC(16), + .has_power_down_state = false, + .has_bandwidth_control = false, + .has_internal_vref = true, +}; + +static const struct ad7625_chip_info ad7626_chip_info = { + .name = "ad7626", + .max_sample_freq_hz = 10 * MEGA, + .timing_spec = &ad7626_timing_spec, + .chan_spec = AD7625_CHAN_SPEC(16), + .has_power_down_state = true, + .has_bandwidth_control = false, + .has_internal_vref = true, +}; + +static const struct ad7625_chip_info ad7960_chip_info = { + .name = "ad7960", + .max_sample_freq_hz = 5 * MEGA, + .timing_spec = &ad7960_timing_spec, + .chan_spec = AD7625_CHAN_SPEC(18), + .has_power_down_state = true, + .has_bandwidth_control = true, + .has_internal_vref = false, +}; + +static const struct ad7625_chip_info ad7961_chip_info = { + .name = "ad7961", + .max_sample_freq_hz = 5 * MEGA, + .timing_spec = &ad7960_timing_spec, + .chan_spec = AD7625_CHAN_SPEC(16), + .has_power_down_state = true, + .has_bandwidth_control = true, + .has_internal_vref = false, +}; + +enum ad7960_mode { + AD7960_MODE_POWER_DOWN, + AD7960_MODE_SNOOZE, + AD7960_MODE_NARROW_BANDWIDTH, + AD7960_MODE_WIDE_BANDWIDTH, + AD7960_MODE_TEST_PATTERN, +}; + +static int ad7625_set_sampling_freq(struct ad7625_state *st, u32 freq) +{ + u32 target; + struct pwm_waveform clk_gate_wf = { }, cnv_wf = { }; + int ret; + + target = DIV_ROUND_UP(NSEC_PER_SEC, freq); + cnv_wf.period_length_ns = clamp(target, 100, 10 * KILO); + + /* + * Use the maximum conversion time t_CNVH from the datasheet as + * the duty_cycle for ref_clk, cnv, and clk_gate + */ + cnv_wf.duty_length_ns = st->info->timing_spec->conv_high_ns; + + ret = pwm_round_waveform_might_sleep(st->cnv_pwm, &cnv_wf); + if (ret) + return ret; + + /* + * Set up the burst signal for transferring data. period and + * offset should mirror the CNV signal + */ + clk_gate_wf.period_length_ns = cnv_wf.period_length_ns; + + clk_gate_wf.duty_length_ns = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * + st->info->chan_spec.scan_type.realbits, + st->ref_clk_rate_hz); + + /* max t_MSB from datasheet */ + clk_gate_wf.duty_offset_ns = st->info->timing_spec->conv_msb_ns; + + ret = pwm_round_waveform_might_sleep(st->clk_gate_pwm, &clk_gate_wf); + if (ret) + return ret; + + st->cnv_wf = cnv_wf; + st->clk_gate_wf = clk_gate_wf; + + /* TODO: Add a rounding API for PWMs that can simplify this */ + target = DIV_ROUND_CLOSEST(st->ref_clk_rate_hz, freq); + st->sampling_freq_hz = DIV_ROUND_CLOSEST(st->ref_clk_rate_hz, + target); + + return 0; +} + +static int ad7625_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long info) +{ + struct ad7625_state *st = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + *val = st->sampling_freq_hz; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = st->vref_mv; + *val2 = chan->scan_type.realbits - 1; + + return IIO_VAL_FRACTIONAL_LOG2; + + default: + return -EINVAL; + } +} + +static int ad7625_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long info) +{ + struct ad7625_state *st = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) + return ad7625_set_sampling_freq(st, val); + unreachable(); + default: + return -EINVAL; + } +} + +static int ad7625_parse_mode(struct device *dev, struct ad7625_state *st, + int num_gpios) +{ + bool en_always_on[4], en_always_off[4]; + bool en_may_be_on[4], en_may_be_off[4]; + char en_gpio_buf[4]; + char always_on_buf[18]; + int i; + + for (i = 0; i < num_gpios; i++) { + snprintf(en_gpio_buf, sizeof(en_gpio_buf), "en%d", i); + snprintf(always_on_buf, sizeof(always_on_buf), + "adi,en%d-always-on", i); + /* Set the device to 0b0000 (power-down mode) by default */ + st->en_gpios[i] = devm_gpiod_get_optional(dev, en_gpio_buf, + GPIOD_OUT_LOW); + if (IS_ERR(st->en_gpios[i])) + return dev_err_probe(dev, PTR_ERR(st->en_gpios[i]), + "failed to get EN%d GPIO\n", i); + + en_always_on[i] = device_property_read_bool(dev, always_on_buf); + if (st->en_gpios[i] && en_always_on[i]) + return dev_err_probe(dev, -EINVAL, + "cannot have adi,en%d-always-on and en%d-gpios\n", i, i); + + en_may_be_off[i] = !en_always_on[i]; + en_may_be_on[i] = en_always_on[i] || st->en_gpios[i]; + en_always_off[i] = !en_always_on[i] && !st->en_gpios[i]; + } + + /* + * Power down is mode 0bXX00, but not all devices have a valid + * power down state. + */ + st->can_power_down = en_may_be_off[1] && en_may_be_off[0] && + st->info->has_power_down_state; + /* + * The REFIN pin can take a 1.2V (AD762x) or 2.048V (AD796x) + * external reference when the mode is 0bXX01. + */ + st->can_refin = en_may_be_off[1] && en_may_be_on[0]; + /* 4.096V can be applied to REF when the EN mode is 0bXX10. */ + st->can_ref_4v096 = en_may_be_on[1] && en_may_be_off[0]; + + /* Avoid AD796x-specific setup if the part is an AD762x */ + if (num_gpios == 2) + return 0; + + /* mode 0b1100 (AD796x) is invalid */ + if (en_always_on[3] && en_always_on[2] && + en_always_off[1] && en_always_off[0]) + return dev_err_probe(dev, -EINVAL, + "EN GPIOs set to invalid mode 0b1100\n"); + /* + * 5V can be applied to the AD796x REF pin when the EN mode is + * the same (0bX001 or 0bX101) as for can_refin, and REFIN is + * 0V. + */ + st->can_ref_5v = st->can_refin; + /* + * Bandwidth (AD796x) is controlled solely by EN2. If it's + * specified and not hard-wired, then we can configure it to + * change the bandwidth between 28MHz and 9MHz. + */ + st->can_narrow_bandwidth = en_may_be_on[2]; + /* Wide bandwidth mode is possible if EN2 can be 0. */ + st->can_wide_bandwidth = en_may_be_off[2]; + /* Snooze mode (AD796x) is 0bXX11 when REFIN = 0V. */ + st->can_snooze = en_may_be_on[1] && en_may_be_on[0]; + /* Test pattern mode (AD796x) is 0b0100. */ + st->can_test_pattern = en_may_be_off[3] && en_may_be_on[2] && + en_may_be_off[1] && en_may_be_off[0]; + + return 0; +} + +/* Set EN1 and EN0 based on reference voltage source */ +static void ad7625_set_en_gpios_for_vref(struct ad7625_state *st, + bool have_refin, int ref_mv) +{ + if (have_refin || ref_mv == 5000) { + gpiod_set_value_cansleep(st->en_gpios[1], 0); + gpiod_set_value_cansleep(st->en_gpios[0], 1); + } else if (ref_mv == 4096) { + gpiod_set_value_cansleep(st->en_gpios[1], 1); + gpiod_set_value_cansleep(st->en_gpios[0], 0); + } else { + /* + * Unreachable by AD796x, since the driver will error if + * neither REF nor REFIN is provided + */ + gpiod_set_value_cansleep(st->en_gpios[1], 1); + gpiod_set_value_cansleep(st->en_gpios[0], 1); + } +} + +static int ad7960_set_mode(struct ad7625_state *st, enum ad7960_mode mode, + bool have_refin, int ref_mv) +{ + switch (mode) { + case AD7960_MODE_POWER_DOWN: + if (!st->can_power_down) + return -EINVAL; + + gpiod_set_value_cansleep(st->en_gpios[2], 0); + gpiod_set_value_cansleep(st->en_gpios[1], 0); + gpiod_set_value_cansleep(st->en_gpios[0], 0); + + return 0; + + case AD7960_MODE_SNOOZE: + if (!st->can_snooze) + return -EINVAL; + + gpiod_set_value_cansleep(st->en_gpios[1], 1); + gpiod_set_value_cansleep(st->en_gpios[0], 1); + + return 0; + + case AD7960_MODE_NARROW_BANDWIDTH: + if (!st->can_narrow_bandwidth) + return -EINVAL; + + gpiod_set_value_cansleep(st->en_gpios[2], 1); + ad7625_set_en_gpios_for_vref(st, have_refin, ref_mv); + + return 0; + + case AD7960_MODE_WIDE_BANDWIDTH: + if (!st->can_wide_bandwidth) + return -EINVAL; + + gpiod_set_value_cansleep(st->en_gpios[2], 0); + ad7625_set_en_gpios_for_vref(st, have_refin, ref_mv); + + return 0; + + case AD7960_MODE_TEST_PATTERN: + if (!st->can_test_pattern) + return -EINVAL; + + gpiod_set_value_cansleep(st->en_gpios[3], 0); + gpiod_set_value_cansleep(st->en_gpios[2], 1); + gpiod_set_value_cansleep(st->en_gpios[1], 0); + gpiod_set_value_cansleep(st->en_gpios[0], 0); + + return 0; + + default: + return -EINVAL; + } +} + +static int ad7625_buffer_preenable(struct iio_dev *indio_dev) +{ + struct ad7625_state *st = iio_priv(indio_dev); + int ret; + + ret = pwm_set_waveform_might_sleep(st->cnv_pwm, &st->cnv_wf, false); + if (ret) + return ret; + + ret = pwm_set_waveform_might_sleep(st->clk_gate_pwm, + &st->clk_gate_wf, false); + if (ret) { + /* Disable cnv PWM if clk_gate setup failed */ + pwm_disable(st->cnv_pwm); + return ret; + } + + return 0; +} + +static int ad7625_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad7625_state *st = iio_priv(indio_dev); + + pwm_disable(st->clk_gate_pwm); + pwm_disable(st->cnv_pwm); + + return 0; +} + +static const struct iio_info ad7625_info = { + .read_raw = ad7625_read_raw, + .write_raw = ad7625_write_raw, +}; + +static const struct iio_buffer_setup_ops ad7625_buffer_setup_ops = { + .preenable = &ad7625_buffer_preenable, + .postdisable = &ad7625_buffer_postdisable, +}; + +static int devm_ad7625_pwm_get(struct device *dev, + struct ad7625_state *st) +{ + struct clk *ref_clk; + u32 ref_clk_rate_hz; + + st->cnv_pwm = devm_pwm_get(dev, "cnv"); + if (IS_ERR(st->cnv_pwm)) + return dev_err_probe(dev, PTR_ERR(st->cnv_pwm), + "failed to get cnv pwm\n"); + + /* Preemptively disable the PWM in case it was enabled at boot */ + pwm_disable(st->cnv_pwm); + + st->clk_gate_pwm = devm_pwm_get(dev, "clk_gate"); + if (IS_ERR(st->clk_gate_pwm)) + return dev_err_probe(dev, PTR_ERR(st->clk_gate_pwm), + "failed to get clk_gate pwm\n"); + + /* Preemptively disable the PWM in case it was enabled at boot */ + pwm_disable(st->clk_gate_pwm); + + ref_clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(ref_clk)) + return dev_err_probe(dev, PTR_ERR(ref_clk), + "failed to get ref_clk"); + + ref_clk_rate_hz = clk_get_rate(ref_clk); + if (!ref_clk_rate_hz) + return dev_err_probe(dev, -EINVAL, + "failed to get ref_clk rate"); + + st->ref_clk_rate_hz = ref_clk_rate_hz; + + return 0; +} + +/* + * There are three required input voltages for each device, plus two + * conditionally-optional (depending on part) REF and REFIN voltages + * where their validity depends upon the EN pin configuration. + * + * Power-up info for the device says to bring up vio, then vdd2, then + * vdd1, so list them in that order in the regulator_names array. + * + * The reference voltage source is determined like so: + * - internal reference: neither REF or REFIN is connected (invalid for + * AD796x) + * - internal buffer, external reference: REF not connected, REFIN + * connected + * - external reference: REF connected, REFIN not connected + */ +static int devm_ad7625_regulator_setup(struct device *dev, + struct ad7625_state *st) +{ + static const char * const regulator_names[] = { "vio", "vdd2", "vdd1" }; + int ret, ref_mv; + + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), + regulator_names); + if (ret) + return ret; + + ret = devm_regulator_get_enable_read_voltage(dev, "ref"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to get REF voltage\n"); + + ref_mv = ret == -ENODEV ? 0 : ret / 1000; + + ret = devm_regulator_get_enable_optional(dev, "refin"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to get REFIN voltage\n"); + + st->have_refin = ret != -ENODEV; + + if (st->have_refin && !st->can_refin) + return dev_err_probe(dev, -EINVAL, + "REFIN provided in unsupported mode\n"); + + if (!st->info->has_internal_vref && !st->have_refin && !ref_mv) + return dev_err_probe(dev, -EINVAL, + "Need either REFIN or REF"); + + if (st->have_refin && ref_mv) + return dev_err_probe(dev, -EINVAL, + "cannot have both REFIN and REF supplies\n"); + + if (ref_mv == 4096 && !st->can_ref_4v096) + return dev_err_probe(dev, -EINVAL, + "REF is 4.096V in unsupported mode\n"); + + if (ref_mv == 5000 && !st->can_ref_5v) + return dev_err_probe(dev, -EINVAL, + "REF is 5V in unsupported mode\n"); + + st->vref_mv = ref_mv ?: AD7625_INTERNAL_REF_MV; + + return 0; +} + +static int ad7625_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct iio_dev *indio_dev; + struct ad7625_state *st; + int ret; + u32 default_sample_freq; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->info = device_get_match_data(dev); + if (!st->info) + return dev_err_probe(dev, -EINVAL, "no chip info\n"); + + if (device_property_read_bool(dev, "adi,no-dco")) + return dev_err_probe(dev, -EINVAL, + "self-clocked mode not supported\n"); + + if (st->info->has_bandwidth_control) + ret = ad7625_parse_mode(dev, st, 4); + else + ret = ad7625_parse_mode(dev, st, 2); + + if (ret) + return ret; + + ret = devm_ad7625_regulator_setup(dev, st); + if (ret) + return ret; + + /* Set the device mode based on detected EN configuration. */ + if (!st->info->has_bandwidth_control) { + ad7625_set_en_gpios_for_vref(st, st->have_refin, st->vref_mv); + } else { + /* + * If neither sampling mode is available, then report an error, + * since the other modes are not useful defaults. + */ + if (st->can_wide_bandwidth) { + ret = ad7960_set_mode(st, AD7960_MODE_WIDE_BANDWIDTH, + st->have_refin, st->vref_mv); + } else if (st->can_narrow_bandwidth) { + ret = ad7960_set_mode(st, AD7960_MODE_NARROW_BANDWIDTH, + st->have_refin, st->vref_mv); + } else { + return dev_err_probe(dev, -EINVAL, + "couldn't set device to wide or narrow bandwidth modes\n"); + } + + if (ret) + return dev_err_probe(dev, -EINVAL, + "failed to set EN pins\n"); + } + + ret = devm_ad7625_pwm_get(dev, st); + if (ret) + return ret; + + indio_dev->channels = &st->info->chan_spec; + indio_dev->num_channels = 1; + indio_dev->name = st->info->name; + indio_dev->info = &ad7625_info; + indio_dev->setup_ops = &ad7625_buffer_setup_ops; + + st->back = devm_iio_backend_get(dev, NULL); + if (IS_ERR(st->back)) + return dev_err_probe(dev, PTR_ERR(st->back), + "failed to get IIO backend"); + + ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev); + if (ret) + return ret; + + ret = devm_iio_backend_enable(dev, st->back); + if (ret) + return ret; + + /* + * Set the initial sampling frequency to the maximum, unless the + * AD796x device is limited to narrow bandwidth by EN2 == 1, in + * which case the sampling frequency should be limited to 2MSPS + */ + default_sample_freq = st->info->max_sample_freq_hz; + if (st->info->has_bandwidth_control && !st->can_wide_bandwidth) + default_sample_freq = AD7960_MAX_NBW_FREQ; + + ret = ad7625_set_sampling_freq(st, default_sample_freq); + if (ret) + dev_err_probe(dev, ret, + "failed to set valid sampling frequency\n"); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id ad7625_of_match[] = { + { .compatible = "adi,ad7625", .data = &ad7625_chip_info }, + { .compatible = "adi,ad7626", .data = &ad7626_chip_info }, + { .compatible = "adi,ad7960", .data = &ad7960_chip_info }, + { .compatible = "adi,ad7961", .data = &ad7961_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(of, ad7625_of_match); + +static const struct platform_device_id ad7625_device_ids[] = { + { .name = "ad7625", .driver_data = (kernel_ulong_t)&ad7625_chip_info }, + { .name = "ad7626", .driver_data = (kernel_ulong_t)&ad7626_chip_info }, + { .name = "ad7960", .driver_data = (kernel_ulong_t)&ad7960_chip_info }, + { .name = "ad7961", .driver_data = (kernel_ulong_t)&ad7961_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(platform, ad7625_device_ids); + +static struct platform_driver ad7625_driver = { + .probe = ad7625_probe, + .driver = { + .name = "ad7625", + .of_match_table = ad7625_of_match, + }, + .id_table = ad7625_device_ids, +}; +module_platform_driver(ad7625_driver); + +MODULE_AUTHOR("Trevor Gamblin "); +MODULE_DESCRIPTION("Analog Devices AD7625 ADC"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/adc/ad7779.c b/drivers/iio/adc/ad7779.c new file mode 100644 index 0000000000000000000000000000000000000000..2537dab69a35c9420ec22f22166df93f03630cc6 --- /dev/null +++ b/drivers/iio/adc/ad7779.c @@ -0,0 +1,914 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * AD7770, AD7771, AD7779 ADC + * + * Copyright 2023-2024 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define AD7779_SPI_READ_CMD BIT(7) + +#define AD7779_DISABLE_SD BIT(7) + +#define AD7779_REG_CH_DISABLE 0x08 +#define AD7779_REG_CH_SYNC_OFFSET(ch) (0x09 + (ch)) +#define AD7779_REG_CH_CONFIG(ch) (0x00 + (ch)) +#define AD7779_REG_GENERAL_USER_CONFIG_1 0x11 +#define AD7779_REG_GENERAL_USER_CONFIG_2 0x12 +#define AD7779_REG_GENERAL_USER_CONFIG_3 0x13 +#define AD7779_REG_DOUT_FORMAT 0x14 +#define AD7779_REG_ADC_MUX_CONFIG 0x15 +#define AD7779_REG_GPIO_CONFIG 0x17 +#define AD7779_REG_BUFFER_CONFIG_1 0x19 +#define AD7779_REG_GLOBAL_MUX_CONFIG 0x16 +#define AD7779_REG_BUFFER_CONFIG_2 0x1A +#define AD7779_REG_GPIO_DATA 0x18 +#define AD7779_REG_CH_OFFSET_UPPER_BYTE(ch) (0x1C + (ch) * 6) +#define AD7779_REG_CH_OFFSET_LOWER_BYTE(ch) (0x1E + (ch) * 6) +#define AD7779_REG_CH_GAIN_UPPER_BYTE(ch) (0x1F + (ch) * 6) +#define AD7779_REG_CH_OFFSET_MID_BYTE(ch) (0x1D + (ch) * 6) +#define AD7779_REG_CH_GAIN_MID_BYTE(ch) (0x20 + (ch) * 6) +#define AD7779_REG_CH_ERR_REG(ch) (0x4C + (ch)) +#define AD7779_REG_CH0_1_SAT_ERR 0x54 +#define AD7779_REG_CH_GAIN_LOWER_BYTE(ch) (0x21 + (ch) * 6) +#define AD7779_REG_CH2_3_SAT_ERR 0x55 +#define AD7779_REG_CH4_5_SAT_ERR 0x56 +#define AD7779_REG_CH6_7_SAT_ERR 0x57 +#define AD7779_REG_CHX_ERR_REG_EN 0x58 +#define AD7779_REG_GEN_ERR_REG_1 0x59 +#define AD7779_REG_GEN_ERR_REG_1_EN 0x5A +#define AD7779_REG_GEN_ERR_REG_2 0x5B +#define AD7779_REG_GEN_ERR_REG_2_EN 0x5C +#define AD7779_REG_STATUS_REG_1 0x5D +#define AD7779_REG_STATUS_REG_2 0x5E +#define AD7779_REG_STATUS_REG_3 0x5F +#define AD7779_REG_SRC_N_MSB 0x60 +#define AD7779_REG_SRC_N_LSB 0x61 +#define AD7779_REG_SRC_IF_MSB 0x62 +#define AD7779_REG_SRC_IF_LSB 0x63 +#define AD7779_REG_SRC_UPDATE 0x64 + +#define AD7779_FILTER_MSK BIT(6) +#define AD7779_MOD_POWERMODE_MSK BIT(6) +#define AD7779_MOD_PDB_REFOUT_MSK BIT(4) +#define AD7779_MOD_SPI_EN_MSK BIT(4) +#define AD7779_USRMOD_INIT_MSK GENMASK(6, 4) + +/* AD7779_REG_DOUT_FORMAT */ +#define AD7779_DOUT_FORMAT_MSK GENMASK(7, 6) +#define AD7779_DOUT_HEADER_FORMAT BIT(5) +#define AD7779_DCLK_CLK_DIV_MSK GENMASK(3, 1) + +#define AD7779_REFMUX_CTRL_MSK GENMASK(7, 6) +#define AD7779_SPI_CRC_EN_MSK BIT(0) + +#define AD7779_MAXCLK_LOWPOWER (4096 * HZ_PER_KHZ) +#define AD7779_NUM_CHANNELS 8 +#define AD7779_RESET_BUF_SIZE 8 +#define AD7779_CHAN_DATA_SIZE 4 + +#define AD7779_LOWPOWER_DIV 512 +#define AD7779_HIGHPOWER_DIV 2048 + +#define AD7779_SINC3_MAXFREQ (16 * HZ_PER_KHZ) +#define AD7779_SINC5_MAXFREQ (128 * HZ_PER_KHZ) + +#define AD7779_DEFAULT_SAMPLING_FREQ (8 * HZ_PER_KHZ) +#define AD7779_DEFAULT_SAMPLING_2LINE (4 * HZ_PER_KHZ) +#define AD7779_DEFAULT_SAMPLING_1LINE (2 * HZ_PER_KHZ) + +#define AD7779_SPIMODE_MAX_SAMP_FREQ (16 * HZ_PER_KHZ) + +#define GAIN_REL 0x555555 +#define AD7779_FREQ_MSB_MSK GENMASK(15, 8) +#define AD7779_FREQ_LSB_MSK GENMASK(7, 0) +#define AD7779_UPPER GENMASK(23, 16) +#define AD7779_MID GENMASK(15, 8) +#define AD7779_LOWER GENMASK(7, 0) + +#define AD7779_REG_MSK GENMASK(6, 0) + +#define AD7779_CRC8_POLY 0x07 +DECLARE_CRC8_TABLE(ad7779_crc8_table); + +enum ad7779_filter { + AD7779_SINC3, + AD7779_SINC5, +}; + +enum ad7779_variant { + ad7770, + ad7771, + ad7779, +}; + +enum ad7779_power_mode { + AD7779_LOW_POWER, + AD7779_HIGH_POWER, +}; + +struct ad7779_chip_info { + const char *name; + struct iio_chan_spec const *channels; +}; + +struct ad7779_state { + struct spi_device *spi; + const struct ad7779_chip_info *chip_info; + struct clk *mclk; + struct iio_trigger *trig; + struct completion completion; + unsigned int sampling_freq; + enum ad7779_filter filter_enabled; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + struct { + u32 chans[8]; + aligned_s64 timestamp; + } data __aligned(IIO_DMA_MINALIGN); + u32 spidata_tx[8]; + u8 reg_rx_buf[3]; + u8 reg_tx_buf[3]; + u8 reset_buf[8]; +}; + +static const char * const ad7779_filter_type[] = { + [AD7779_SINC3] = "sinc3", + [AD7779_SINC5] = "sinc5", +}; + +static const char * const ad7779_power_supplies[] = { + "avdd1", "avdd2", "avdd4", +}; + +static int ad7779_spi_read(struct ad7779_state *st, u8 reg, u8 *rbuf) +{ + int ret; + u8 crc_buf[2]; + u8 exp_crc; + struct spi_transfer t = { + .tx_buf = st->reg_tx_buf, + .rx_buf = st->reg_rx_buf, + }; + + st->reg_tx_buf[0] = AD7779_SPI_READ_CMD | FIELD_GET(AD7779_REG_MSK, reg); + st->reg_tx_buf[1] = 0; + + if (reg == AD7779_REG_GEN_ERR_REG_1_EN) { + t.len = 2; + } else { + t.len = 3; + st->reg_tx_buf[2] = crc8(ad7779_crc8_table, st->reg_tx_buf, + t.len - 1, 0); + } + + ret = spi_sync_transfer(st->spi, &t, 1); + if (ret) + return ret; + + crc_buf[0] = AD7779_SPI_READ_CMD | FIELD_GET(AD7779_REG_MSK, reg); + crc_buf[1] = st->reg_rx_buf[1]; + exp_crc = crc8(ad7779_crc8_table, crc_buf, ARRAY_SIZE(crc_buf), 0); + if (reg != AD7779_REG_GEN_ERR_REG_1_EN && exp_crc != st->reg_rx_buf[2]) { + dev_err(&st->spi->dev, "Bad CRC %x, expected %x", + st->reg_rx_buf[2], exp_crc); + return -EINVAL; + } + *rbuf = st->reg_rx_buf[1]; + + return 0; +} + +static int ad7779_spi_write(struct ad7779_state *st, u8 reg, u8 val) +{ + u8 length = 3; + + st->reg_tx_buf[0] = FIELD_GET(AD7779_REG_MSK, reg); + st->reg_tx_buf[1] = val; + if (reg == AD7779_REG_GEN_ERR_REG_1_EN) + length = 2; + else + st->reg_tx_buf[2] = crc8(ad7779_crc8_table, st->reg_tx_buf, + length - 1, 0); + + return spi_write(st->spi, st->reg_tx_buf, length); +} + +static int ad7779_spi_write_mask(struct ad7779_state *st, u8 reg, u8 mask, + u8 val) +{ + int ret; + u8 regval, data; + + ret = ad7779_spi_read(st, reg, &data); + if (ret) + return ret; + + regval = (data & ~mask) | (val & mask); + + if (regval == data) + return 0; + + return ad7779_spi_write(st, reg, regval); +} + +static int ad7779_reg_access(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int writeval, + unsigned int *readval) +{ + struct ad7779_state *st = iio_priv(indio_dev); + u8 rval; + int ret; + + if (readval) { + ret = ad7779_spi_read(st, reg, &rval); + *readval = rval; + return ret; + } + + return ad7779_spi_write(st, reg, writeval); +} + +static int ad7779_set_sampling_frequency(struct ad7779_state *st, + unsigned int sampling_freq) +{ + int ret; + unsigned int dec; + unsigned int frac; + unsigned int div; + unsigned int decimal; + unsigned int freq_khz; + + if (st->filter_enabled == AD7779_SINC3 && + sampling_freq > AD7779_SINC3_MAXFREQ) + return -EINVAL; + + if (st->filter_enabled == AD7779_SINC5 && + sampling_freq > AD7779_SINC5_MAXFREQ) + return -EINVAL; + + if (sampling_freq > AD7779_SPIMODE_MAX_SAMP_FREQ) + return -EINVAL; + + div = AD7779_HIGHPOWER_DIV; + + freq_khz = sampling_freq / HZ_PER_KHZ; + dec = div / freq_khz; + frac = div % freq_khz; + + ret = ad7779_spi_write(st, AD7779_REG_SRC_N_MSB, + FIELD_GET(AD7779_FREQ_MSB_MSK, dec)); + if (ret) + return ret; + ret = ad7779_spi_write(st, AD7779_REG_SRC_N_LSB, + FIELD_GET(AD7779_FREQ_LSB_MSK, dec)); + if (ret) + return ret; + + if (frac) { + /* + * In order to obtain the first three decimals of the decimation + * the initial number is multiplied with 10^3 prior to the + * division, then the original division result is subtracted and + * the number is divided by 10^3. + */ + decimal = ((mult_frac(div, KILO, freq_khz) - dec * KILO) << 16) + / KILO; + ret = ad7779_spi_write(st, AD7779_REG_SRC_N_MSB, + FIELD_GET(AD7779_FREQ_MSB_MSK, decimal)); + if (ret) + return ret; + ret = ad7779_spi_write(st, AD7779_REG_SRC_N_LSB, + FIELD_GET(AD7779_FREQ_LSB_MSK, decimal)); + if (ret) + return ret; + } else { + ret = ad7779_spi_write(st, AD7779_REG_SRC_N_MSB, + FIELD_GET(AD7779_FREQ_MSB_MSK, 0x0)); + if (ret) + return ret; + ret = ad7779_spi_write(st, AD7779_REG_SRC_N_LSB, + FIELD_GET(AD7779_FREQ_LSB_MSK, 0x0)); + if (ret) + return ret; + } + ret = ad7779_spi_write(st, AD7779_REG_SRC_UPDATE, BIT(0)); + if (ret) + return ret; + + /* SRC update settling time */ + fsleep(15); + + ret = ad7779_spi_write(st, AD7779_REG_SRC_UPDATE, 0x0); + if (ret) + return ret; + + /* SRC update settling time */ + fsleep(15); + + st->sampling_freq = sampling_freq; + + return 0; +} + +static int ad7779_get_filter(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + struct ad7779_state *st = iio_priv(indio_dev); + u8 temp; + int ret; + + ret = ad7779_spi_read(st, AD7779_REG_GENERAL_USER_CONFIG_2, &temp); + if (ret) + return ret; + + return FIELD_GET(AD7779_FILTER_MSK, temp); +} + +static int ad7779_set_filter(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + unsigned int mode) +{ + struct ad7779_state *st = iio_priv(indio_dev); + int ret; + + ret = ad7779_spi_write_mask(st, + AD7779_REG_GENERAL_USER_CONFIG_2, + AD7779_FILTER_MSK, + FIELD_PREP(AD7779_FILTER_MSK, mode)); + if (ret) + return ret; + + ret = ad7779_set_sampling_frequency(st, st->sampling_freq); + if (ret) + return ret; + + st->filter_enabled = mode; + + return 0; +} + +static int ad7779_get_calibscale(struct ad7779_state *st, int channel) +{ + int ret; + u8 calibscale[3]; + + ret = ad7779_spi_read(st, AD7779_REG_CH_GAIN_LOWER_BYTE(channel), + &calibscale[0]); + if (ret) + return ret; + + ret = ad7779_spi_read(st, AD7779_REG_CH_GAIN_MID_BYTE(channel), + &calibscale[1]); + if (ret) + return ret; + + ret = ad7779_spi_read(st, AD7779_REG_CH_GAIN_UPPER_BYTE(channel), + &calibscale[2]); + if (ret) + return ret; + + return get_unaligned_be24(calibscale); +} + +static int ad7779_set_calibscale(struct ad7779_state *st, int channel, int val) +{ + int ret; + unsigned int gain; + u8 gain_bytes[3]; + + /* + * The gain value is relative to 0x555555, which represents a gain of 1 + */ + gain = DIV_ROUND_CLOSEST_ULL((u64)val * 5592405LL, MEGA); + put_unaligned_be24(gain, gain_bytes); + ret = ad7779_spi_write(st, AD7779_REG_CH_GAIN_UPPER_BYTE(channel), + gain_bytes[0]); + if (ret) + return ret; + + ret = ad7779_spi_write(st, AD7779_REG_CH_GAIN_MID_BYTE(channel), + gain_bytes[1]); + if (ret) + return ret; + + return ad7779_spi_write(st, AD7779_REG_CH_GAIN_LOWER_BYTE(channel), + gain_bytes[2]); +} + +static int ad7779_get_calibbias(struct ad7779_state *st, int channel) +{ + int ret; + u8 calibbias[3]; + + ret = ad7779_spi_read(st, AD7779_REG_CH_OFFSET_LOWER_BYTE(channel), + &calibbias[0]); + if (ret) + return ret; + + ret = ad7779_spi_read(st, AD7779_REG_CH_OFFSET_MID_BYTE(channel), + &calibbias[1]); + if (ret) + return ret; + + ret = ad7779_spi_read(st, AD7779_REG_CH_OFFSET_UPPER_BYTE(channel), + &calibbias[2]); + if (ret) + return ret; + + return get_unaligned_be24(calibbias); +} + +static int ad7779_set_calibbias(struct ad7779_state *st, int channel, int val) +{ + int ret; + u8 calibbias[3]; + + put_unaligned_be24(val, calibbias); + ret = ad7779_spi_write(st, AD7779_REG_CH_OFFSET_UPPER_BYTE(channel), + calibbias[0]); + if (ret) + return ret; + + ret = ad7779_spi_write(st, AD7779_REG_CH_OFFSET_MID_BYTE(channel), + calibbias[1]); + if (ret) + return ret; + + return ad7779_spi_write(st, AD7779_REG_CH_OFFSET_LOWER_BYTE(channel), + calibbias[2]); +} + +static int ad7779_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct ad7779_state *st = iio_priv(indio_dev); + int ret; + + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + ret = ad7779_get_calibscale(st, chan->channel); + if (ret < 0) + return ret; + *val = ret; + *val2 = GAIN_REL; + return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_CALIBBIAS: + ret = ad7779_get_calibbias(st, chan->channel); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + *val = st->sampling_freq; + if (*val < 0) + return -EINVAL; + return IIO_VAL_INT; + default: + return -EINVAL; + } + } + unreachable(); +} + +static int ad7779_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long mask) +{ + struct ad7779_state *st = iio_priv(indio_dev); + + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + return ad7779_set_calibscale(st, chan->channel, val2); + case IIO_CHAN_INFO_CALIBBIAS: + return ad7779_set_calibbias(st, chan->channel, val); + case IIO_CHAN_INFO_SAMP_FREQ: + return ad7779_set_sampling_frequency(st, val); + default: + return -EINVAL; + } + } + unreachable(); +} + +static int ad7779_buffer_preenable(struct iio_dev *indio_dev) +{ + int ret; + struct ad7779_state *st = iio_priv(indio_dev); + + ret = ad7779_spi_write_mask(st, + AD7779_REG_GENERAL_USER_CONFIG_3, + AD7779_MOD_SPI_EN_MSK, + FIELD_PREP(AD7779_MOD_SPI_EN_MSK, 1)); + if (ret) + return ret; + + /* + * DRDY output cannot be disabled at device level therefore we mask + * the irq at host end. + */ + enable_irq(st->spi->irq); + + return 0; +} + +static int ad7779_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad7779_state *st = iio_priv(indio_dev); + + disable_irq(st->spi->irq); + + return ad7779_spi_write(st, AD7779_REG_GENERAL_USER_CONFIG_3, + AD7779_DISABLE_SD); +} + +static irqreturn_t ad7779_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7779_state *st = iio_priv(indio_dev); + int ret; + struct spi_transfer t = { + .rx_buf = st->data.chans, + .tx_buf = st->spidata_tx, + .len = AD7779_NUM_CHANNELS * AD7779_CHAN_DATA_SIZE, + }; + + st->spidata_tx[0] = AD7779_SPI_READ_CMD; + ret = spi_sync_transfer(st->spi, &t, 1); + if (ret) { + dev_err(&st->spi->dev, "SPI transfer error in IRQ handler"); + goto exit_handler; + } + + iio_push_to_buffers_with_timestamp(indio_dev, &st->data, pf->timestamp); + +exit_handler: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static int ad7779_reset(struct iio_dev *indio_dev, struct gpio_desc *reset_gpio) +{ + struct ad7779_state *st = iio_priv(indio_dev); + int ret; + struct spi_transfer t = { + .tx_buf = st->reset_buf, + .len = 8, + }; + + if (reset_gpio) { + gpiod_set_value(reset_gpio, 1); + /* Delay for reset to occur is 225 microseconds */ + fsleep(230); + ret = 0; + } else { + memset(st->reset_buf, 0xff, sizeof(st->reset_buf)); + ret = spi_sync_transfer(st->spi, &t, 1); + if (ret) + return ret; + } + + /* Delay for reset to occur is 225 microseconds */ + fsleep(230); + + return ret; +} + +static const struct iio_info ad7779_info = { + .read_raw = ad7779_read_raw, + .write_raw = ad7779_write_raw, + .debugfs_reg_access = &ad7779_reg_access, +}; + +static const struct iio_enum ad7779_filter_enum = { + .items = ad7779_filter_type, + .num_items = ARRAY_SIZE(ad7779_filter_type), + .get = ad7779_get_filter, + .set = ad7779_set_filter, +}; + +static const struct iio_chan_spec_ext_info ad7779_ext_filter[] = { + IIO_ENUM("filter_type", IIO_SHARED_BY_ALL, &ad7779_filter_enum), + IIO_ENUM_AVAILABLE("filter_type", IIO_SHARED_BY_ALL, + &ad7779_filter_enum), + { } +}; + +#define AD777x_CHAN_S(index, _ext_info) \ + { \ + .type = IIO_VOLTAGE, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ + .address = (index), \ + .indexed = 1, \ + .channel = (index), \ + .scan_index = (index), \ + .ext_info = (_ext_info), \ + .scan_type = { \ + .sign = 's', \ + .realbits = 24, \ + .storagebits = 32, \ + .endianness = IIO_BE, \ + }, \ + } + +#define AD777x_CHAN_NO_FILTER_S(index) \ + AD777x_CHAN_S(index, NULL) + +#define AD777x_CHAN_FILTER_S(index) \ + AD777x_CHAN_S(index, ad7779_ext_filter) +static const struct iio_chan_spec ad7779_channels[] = { + AD777x_CHAN_NO_FILTER_S(0), + AD777x_CHAN_NO_FILTER_S(1), + AD777x_CHAN_NO_FILTER_S(2), + AD777x_CHAN_NO_FILTER_S(3), + AD777x_CHAN_NO_FILTER_S(4), + AD777x_CHAN_NO_FILTER_S(5), + AD777x_CHAN_NO_FILTER_S(6), + AD777x_CHAN_NO_FILTER_S(7), + IIO_CHAN_SOFT_TIMESTAMP(8), +}; + +static const struct iio_chan_spec ad7779_channels_filter[] = { + AD777x_CHAN_FILTER_S(0), + AD777x_CHAN_FILTER_S(1), + AD777x_CHAN_FILTER_S(2), + AD777x_CHAN_FILTER_S(3), + AD777x_CHAN_FILTER_S(4), + AD777x_CHAN_FILTER_S(5), + AD777x_CHAN_FILTER_S(6), + AD777x_CHAN_FILTER_S(7), + IIO_CHAN_SOFT_TIMESTAMP(8), +}; + +static const struct iio_buffer_setup_ops ad7779_buffer_setup_ops = { + .preenable = ad7779_buffer_preenable, + .postdisable = ad7779_buffer_postdisable, +}; + +static const struct iio_trigger_ops ad7779_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, +}; + +static int ad7779_conf(struct ad7779_state *st, struct gpio_desc *start_gpio) +{ + int ret; + + ret = ad7779_spi_write_mask(st, AD7779_REG_GEN_ERR_REG_1_EN, + AD7779_SPI_CRC_EN_MSK, + FIELD_PREP(AD7779_SPI_CRC_EN_MSK, 1)); + if (ret) + return ret; + + ret = ad7779_spi_write_mask(st, AD7779_REG_GENERAL_USER_CONFIG_1, + AD7779_USRMOD_INIT_MSK, + FIELD_PREP(AD7779_USRMOD_INIT_MSK, 5)); + if (ret) + return ret; + + ret = ad7779_spi_write_mask(st, AD7779_REG_DOUT_FORMAT, + AD7779_DCLK_CLK_DIV_MSK, + FIELD_PREP(AD7779_DCLK_CLK_DIV_MSK, 1)); + if (ret) + return ret; + + ret = ad7779_spi_write_mask(st, AD7779_REG_ADC_MUX_CONFIG, + AD7779_REFMUX_CTRL_MSK, + FIELD_PREP(AD7779_REFMUX_CTRL_MSK, 1)); + if (ret) + return ret; + + ret = ad7779_set_sampling_frequency(st, AD7779_DEFAULT_SAMPLING_FREQ); + if (ret) + return ret; + + gpiod_set_value(start_gpio, 0); + /* Start setup time */ + fsleep(15); + gpiod_set_value(start_gpio, 1); + /* Start setup time */ + fsleep(15); + gpiod_set_value(start_gpio, 0); + /* Start setup time */ + fsleep(15); + + return 0; +} + +static int ad7779_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct ad7779_state *st; + struct gpio_desc *reset_gpio, *start_gpio; + struct device *dev = &spi->dev; + int ret = -EINVAL; + + if (!spi->irq) + return dev_err_probe(dev, ret, "DRDY irq not present\n"); + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + ret = devm_regulator_bulk_get_enable(dev, + ARRAY_SIZE(ad7779_power_supplies), + ad7779_power_supplies); + if (ret) + return dev_err_probe(dev, ret, + "failed to get and enable supplies\n"); + + st->mclk = devm_clk_get_enabled(dev, "mclk"); + if (IS_ERR(st->mclk)) + return PTR_ERR(st->mclk); + + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) + return PTR_ERR(reset_gpio); + + start_gpio = devm_gpiod_get(dev, "start", GPIOD_OUT_HIGH); + if (IS_ERR(start_gpio)) + return PTR_ERR(start_gpio); + + crc8_populate_msb(ad7779_crc8_table, AD7779_CRC8_POLY); + st->spi = spi; + + st->chip_info = spi_get_device_match_data(spi); + if (!st->chip_info) + return -ENODEV; + + ret = ad7779_reset(indio_dev, reset_gpio); + if (ret) + return ret; + + ret = ad7779_conf(st, start_gpio); + if (ret) + return ret; + + indio_dev->name = st->chip_info->name; + indio_dev->info = &ad7779_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = ARRAY_SIZE(ad7779_channels); + + st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, + iio_device_id(indio_dev)); + if (!st->trig) + return -ENOMEM; + + st->trig->ops = &ad7779_trigger_ops; + + iio_trigger_set_drvdata(st->trig, st); + + ret = devm_request_irq(dev, spi->irq, iio_trigger_generic_data_rdy_poll, + IRQF_ONESHOT | IRQF_NO_AUTOEN, indio_dev->name, + st->trig); + if (ret) + return dev_err_probe(dev, ret, "request IRQ %d failed\n", + st->spi->irq); + + ret = devm_iio_trigger_register(dev, st->trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(st->trig); + + init_completion(&st->completion); + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + &iio_pollfunc_store_time, + &ad7779_trigger_handler, + &ad7779_buffer_setup_ops); + if (ret) + return ret; + + ret = ad7779_spi_write_mask(st, AD7779_REG_DOUT_FORMAT, + AD7779_DCLK_CLK_DIV_MSK, + FIELD_PREP(AD7779_DCLK_CLK_DIV_MSK, 7)); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static int ad7779_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7779_state *st = iio_priv(indio_dev); + + return ad7779_spi_write_mask(st, AD7779_REG_GENERAL_USER_CONFIG_1, + AD7779_MOD_POWERMODE_MSK, + FIELD_PREP(AD7779_MOD_POWERMODE_MSK, + AD7779_LOW_POWER)); +} + +static int ad7779_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7779_state *st = iio_priv(indio_dev); + + return ad7779_spi_write_mask(st, AD7779_REG_GENERAL_USER_CONFIG_1, + AD7779_MOD_POWERMODE_MSK, + FIELD_PREP(AD7779_MOD_POWERMODE_MSK, + AD7779_HIGH_POWER)); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(ad7779_pm_ops, ad7779_suspend, ad7779_resume); + +static const struct ad7779_chip_info ad7770_chip_info = { + .name = "ad7770", + .channels = ad7779_channels, +}; + +static const struct ad7779_chip_info ad7771_chip_info = { + .name = "ad7771", + .channels = ad7779_channels_filter, +}; + +static const struct ad7779_chip_info ad7779_chip_info = { + .name = "ad7779", + .channels = ad7779_channels, +}; + +static const struct spi_device_id ad7779_id[] = { + { + .name = "ad7770", + .driver_data = (kernel_ulong_t)&ad7770_chip_info, + }, + { + .name = "ad7771", + .driver_data = (kernel_ulong_t)&ad7771_chip_info, + }, + { + .name = "ad7779", + .driver_data = (kernel_ulong_t)&ad7779_chip_info, + }, + { } +}; +MODULE_DEVICE_TABLE(spi, ad7779_id); + +static const struct of_device_id ad7779_of_table[] = { + { + .compatible = "adi,ad7770", + .data = &ad7770_chip_info, + }, + { + .compatible = "adi,ad7771", + .data = &ad7771_chip_info, + }, + { + .compatible = "adi,ad7779", + .data = &ad7779_chip_info, + }, + { } +}; +MODULE_DEVICE_TABLE(of, ad7779_of_table); + +static struct spi_driver ad7779_driver = { + .driver = { + .name = "ad7779", + .pm = pm_sleep_ptr(&ad7779_pm_ops), + .of_match_table = ad7779_of_table, + }, + .probe = ad7779_probe, + .id_table = ad7779_id, +}; +module_spi_driver(ad7779_driver); + +MODULE_AUTHOR("Ramona Alexandra Nechita "); +MODULE_DESCRIPTION("Analog Devices AD7779 ADC"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/adc/ad7780.c b/drivers/iio/adc/ad7780.c index e9b0c577c9cca451ad1b104ce97348956ea29898..24d2dcad8f4da309fafea787c2db252981663a45 100644 --- a/drivers/iio/adc/ad7780.c +++ b/drivers/iio/adc/ad7780.c @@ -152,7 +152,7 @@ static int ad7780_write_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_SCALE: - if (val != 0) + if (val != 0 || val2 == 0) return -EINVAL; vref = st->int_vref_mv * 1000000LL; @@ -375,4 +375,4 @@ module_spi_driver(ad7780_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD7780 and similar ADCs"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); +MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA"); diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c index 86effe8501b440fefe53636ab50dfa751200215f..e1bf13fe2cd76d6ce4995c8baf2f0425df02f3e1 100644 --- a/drivers/iio/adc/ad7791.c +++ b/drivers/iio/adc/ad7791.c @@ -371,7 +371,7 @@ static const struct iio_info ad7791_no_filter_info = { }; static int ad7791_setup(struct ad7791_state *st, - struct ad7791_platform_data *pdata) + const struct ad7791_platform_data *pdata) { /* Set to poweron-reset default values */ st->mode = AD7791_MODE_BUFFER; @@ -401,7 +401,7 @@ static void ad7791_reg_disable(void *reg) static int ad7791_probe(struct spi_device *spi) { - struct ad7791_platform_data *pdata = spi->dev.platform_data; + const struct ad7791_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad7791_state *st; int ret; @@ -474,4 +474,4 @@ module_spi_driver(ad7791_driver); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("Analog Devices AD7787/AD7788/AD7789/AD7790/AD7791 ADC driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); +MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA"); diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index abebd519cafa30c8d4a2ef1a9887e430f7c217ca..d55c71566707f327818bb75a812e4d309d683211 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -770,7 +770,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { static int ad7793_probe(struct spi_device *spi) { - const struct ad7793_platform_data *pdata = spi->dev.platform_data; + const struct ad7793_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad7793_state *st; struct iio_dev *indio_dev; int ret, vref_mv = 0; @@ -849,4 +849,4 @@ module_spi_driver(ad7793_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); +MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA"); diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index 6265ce7df703067533a96f704a3ccbd11725e517..69add1dc4b5388ed0a18196f248412725eb324a7 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -41,7 +41,7 @@ enum ad7887_channels { }; /** - * struct ad7887_chip_info - chip specifc information + * struct ad7887_chip_info - chip specific information * @int_vref_mv: the internal reference voltage * @channels: channels specification * @num_channels: number of channels @@ -234,7 +234,7 @@ static void ad7887_reg_disable(void *data) static int ad7887_probe(struct spi_device *spi) { - struct ad7887_platform_data *pdata = spi->dev.platform_data; + const struct ad7887_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad7887_state *st; struct iio_dev *indio_dev; uint8_t mode; diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 09680015a7ab54c5b668c500d1d995c67463e6a2..acc44cb34f8245b9d68359c8addabed623d42393 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -48,7 +48,7 @@ struct ad7923_state { struct spi_device *spi; - struct spi_transfer ring_xfer[5]; + struct spi_transfer ring_xfer[9]; struct spi_transfer scan_single_xfer[2]; struct spi_message ring_msg; struct spi_message scan_single_msg; @@ -64,7 +64,7 @@ struct ad7923_state { * Length = 8 channels + 4 extra for 8 byte timestamp */ __be16 rx_buf[12] __aligned(IIO_DMA_MINALIGN); - __be16 tx_buf[4]; + __be16 tx_buf[8]; }; struct ad7923_chip_info { diff --git a/drivers/iio/adc/ad7944.c b/drivers/iio/adc/ad7944.c index 0f36138a714456043ded05f44420db7277d50205..a5aea4e9f1a7bdd8ca10f9f4580ad3216ddcdfcb 100644 --- a/drivers/iio/adc/ad7944.c +++ b/drivers/iio/adc/ad7944.c @@ -80,7 +80,7 @@ struct ad7944_adc { }; /* quite time before CNV rising edge */ -#define T_QUIET_NS 20 +#define AD7944_T_QUIET_NS 20 static const struct ad7944_timing_spec ad7944_timing_spec = { .conv_ns = 420, @@ -150,7 +150,7 @@ static int ad7944_3wire_cs_mode_init_msg(struct device *dev, struct ad7944_adc * * CS is tied to CNV and we need a low to high transition to start the * conversion, so place CNV low for t_QUIET to prepare for this. */ - xfers[0].delay.value = T_QUIET_NS; + xfers[0].delay.value = AD7944_T_QUIET_NS; xfers[0].delay.unit = SPI_DELAY_UNIT_NSECS; /* diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 0f107e3fc2c85575e6820f995949a5345e9d69d3..aa44b4e2542b2679c6b5fbe7346e3e9dc17721af 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -406,7 +406,7 @@ static int ad799x_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct ad799x_state *st = iio_priv(indio_dev); int ret; diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 05fb7a75531fb7a71e05022044290c2b79252887..d358958ab31084cfcf942a203a59cfa1955e7d7d 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -1280,4 +1280,4 @@ module_spi_driver(ad9467_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD9467 ADC driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_BACKEND); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index ea4aabd3960a086db8562e99a1f9a8e71750e8d2..3fd200b34161c592d9a6cc6410e935cbe2ee7282 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -43,7 +43,7 @@ void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm) * to select the channel */ sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK; } -EXPORT_SYMBOL_NS_GPL(ad_sd_set_comm, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_set_comm, "IIO_AD_SIGMA_DELTA"); /** * ad_sd_write_reg() - Write a register @@ -95,7 +95,7 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, return ret; } -EXPORT_SYMBOL_NS_GPL(ad_sd_write_reg, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_write_reg, "IIO_AD_SIGMA_DELTA"); static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta, unsigned int reg, unsigned int size, uint8_t *val) @@ -172,7 +172,7 @@ int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, out: return ret; } -EXPORT_SYMBOL_NS_GPL(ad_sd_read_reg, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_read_reg, "IIO_AD_SIGMA_DELTA"); /** * ad_sd_reset() - Reset the serial interface @@ -200,7 +200,7 @@ int ad_sd_reset(struct ad_sigma_delta *sigma_delta, return ret; } -EXPORT_SYMBOL_NS_GPL(ad_sd_reset, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_reset, "IIO_AD_SIGMA_DELTA"); int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, unsigned int mode, unsigned int channel) @@ -239,7 +239,7 @@ out: return ret; } -EXPORT_SYMBOL_NS_GPL(ad_sd_calibrate, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_calibrate, "IIO_AD_SIGMA_DELTA"); /** * ad_sd_calibrate_all() - Performs channel calibration @@ -263,7 +263,7 @@ int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, return 0; } -EXPORT_SYMBOL_NS_GPL(ad_sd_calibrate_all, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_calibrate_all, "IIO_AD_SIGMA_DELTA"); /** * ad_sigma_delta_single_conversion() - Performs a single data conversion @@ -339,7 +339,7 @@ out: return IIO_VAL_INT; } -EXPORT_SYMBOL_NS_GPL(ad_sigma_delta_single_conversion, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sigma_delta_single_conversion, "IIO_AD_SIGMA_DELTA"); static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) { @@ -469,7 +469,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) /* * Data array after transfer will look like (if status is appended): * data[] = { [0][sample][sample][sample][status] } - * Keeping the first byte 0 shifts the status postion by 1 byte to the right. + * Keeping the first byte 0 shifts the status position by 1 byte to the right. */ status_pos = reg_size + 1; @@ -564,7 +564,7 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig) return 0; } -EXPORT_SYMBOL_NS_GPL(ad_sd_validate_trigger, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_validate_trigger, "IIO_AD_SIGMA_DELTA"); static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_dev) { @@ -638,7 +638,7 @@ int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indi return devm_ad_sd_probe_trigger(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(devm_ad_sd_setup_buffer_and_trigger, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(devm_ad_sd_setup_buffer_and_trigger, "IIO_AD_SIGMA_DELTA"); /** * ad_sd_init() - Initializes a ad_sigma_delta struct @@ -656,7 +656,7 @@ int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, sigma_delta->spi = spi; sigma_delta->info = info; - /* If the field is unset in ad_sigma_delta_info, asume there can only be 1 slot. */ + /* If the field is unset in ad_sigma_delta_info, assume there can only be 1 slot. */ if (!info->num_slots) sigma_delta->num_slots = 1; else @@ -683,7 +683,7 @@ int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, return 0; } -EXPORT_SYMBOL_NS_GPL(ad_sd_init, IIO_AD_SIGMA_DELTA); +EXPORT_SYMBOL_NS_GPL(ad_sd_init, "IIO_AD_SIGMA_DELTA"); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs"); diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index 5c8c87eb36d19fb57d9d028d200ee43f0c198262..c7357601f0f869e57636f00bb1e26c059c3ab15c 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -437,5 +437,5 @@ module_platform_driver(adi_axi_adc_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices Generic AXI ADC IP core driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_DMAENGINE_BUFFER); -MODULE_IMPORT_NS(IIO_BACKEND); +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER"); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index d7fd21e7c6e2a607916205fa1ed8fe989132455d..8e5aaf15a9215083d90312e037b18c2b09e132e8 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -2625,7 +2625,7 @@ MODULE_DEVICE_TABLE(of, at91_adc_dt_match); static struct platform_driver at91_adc_driver = { .probe = at91_adc_probe, - .remove_new = at91_adc_remove, + .remove = at91_adc_remove, .driver = { .name = "at91-sama5d2_adc", .of_match_table = at91_adc_dt_match, diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 9c39acff17e6585937d10670a72f088620f0b5ac..a3f0a232166613239abd58652339a433698c86f2 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -1341,7 +1341,7 @@ MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); static struct platform_driver at91_adc_driver = { .probe = at91_adc_probe, - .remove_new = at91_adc_remove, + .remove = at91_adc_remove, .driver = { .name = DRIVER_NAME, .of_match_table = at91_adc_dt_ids, diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index 6c1a5d1b0a83d4f52b0387b3f3cd156e92b07b56..9fd7027623d0c2ed49d91b25d1e9cfea59caa929 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -155,52 +155,22 @@ enum axp813_adc_channel_v { AXP813_BATT_V, }; -static struct iio_map axp20x_maps[] = { - { - .consumer_dev_name = "axp20x-usb-power-supply", - .consumer_channel = "vbus_v", - .adc_channel_label = "vbus_v", - }, { - .consumer_dev_name = "axp20x-usb-power-supply", - .consumer_channel = "vbus_i", - .adc_channel_label = "vbus_i", - }, { - .consumer_dev_name = "axp20x-ac-power-supply", - .consumer_channel = "acin_v", - .adc_channel_label = "acin_v", - }, { - .consumer_dev_name = "axp20x-ac-power-supply", - .consumer_channel = "acin_i", - .adc_channel_label = "acin_i", - }, { - .consumer_dev_name = "axp20x-battery-power-supply", - .consumer_channel = "batt_v", - .adc_channel_label = "batt_v", - }, { - .consumer_dev_name = "axp20x-battery-power-supply", - .consumer_channel = "batt_chrg_i", - .adc_channel_label = "batt_chrg_i", - }, { - .consumer_dev_name = "axp20x-battery-power-supply", - .consumer_channel = "batt_dischrg_i", - .adc_channel_label = "batt_dischrg_i", - }, { /* sentinel */ } +static const struct iio_map axp20x_maps[] = { + IIO_MAP("vbus_v", "axp20x-usb-power-supply", "vbus_v"), + IIO_MAP("vbus_i", "axp20x-usb-power-supply", "vbus_i"), + IIO_MAP("acin_v", "axp20x-ac-power-supply", "acin_v"), + IIO_MAP("acin_i", "axp20x-ac-power-supply", "acin_i"), + IIO_MAP("batt_v", "axp20x-battery-power-supply", "batt_v"), + IIO_MAP("batt_chrg_i", "axp20x-battery-power-supply", "batt_chrg_i"), + IIO_MAP("batt_dischrg_i", "axp20x-battery-power-supply", "batt_dischrg_i"), + { /* sentinel */ } }; -static struct iio_map axp22x_maps[] = { - { - .consumer_dev_name = "axp20x-battery-power-supply", - .consumer_channel = "batt_v", - .adc_channel_label = "batt_v", - }, { - .consumer_dev_name = "axp20x-battery-power-supply", - .consumer_channel = "batt_chrg_i", - .adc_channel_label = "batt_chrg_i", - }, { - .consumer_dev_name = "axp20x-battery-power-supply", - .consumer_channel = "batt_dischrg_i", - .adc_channel_label = "batt_dischrg_i", - }, { /* sentinel */ } +static const struct iio_map axp22x_maps[] = { + IIO_MAP("batt_v", "axp20x-battery-power-supply", "batt_v"), + IIO_MAP("batt_chrg_i", "axp20x-battery-power-supply", "batt_chrg_i"), + IIO_MAP("batt_dischrg_i", "axp20x-battery-power-supply", "batt_dischrg_i"), + { /* sentinel */ } }; static struct iio_map axp717_maps[] = { @@ -1044,7 +1014,7 @@ struct axp_data { unsigned long adc_en2_mask; int (*adc_rate)(struct axp20x_adc_iio *info, int rate); - struct iio_map *maps; + const struct iio_map *maps; }; static const struct axp_data axp192_data = { @@ -1212,7 +1182,7 @@ static struct platform_driver axp20x_adc_driver = { }, .id_table = axp20x_adc_id_match, .probe = axp20x_probe, - .remove_new = axp20x_remove, + .remove = axp20x_remove, }; module_platform_driver(axp20x_adc_driver); diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 8c3acc0cd7e99a4f378bc630f4e9eb3671e45348..45542efc3ece0c1ca28becba494b8f9826ee43bd 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -103,7 +103,7 @@ static const struct iio_chan_spec axp288_adc_channels[] = { }; /* for consumer drivers */ -static struct iio_map axp288_adc_default_maps[] = { +static const struct iio_map axp288_adc_default_maps[] = { IIO_MAP("TS_PIN", "axp288-batt", "axp288-batt-temp"), IIO_MAP("PMIC_TEMP", "axp288-pmic", "axp288-pmic-temp"), IIO_MAP("GPADC", "axp288-gpadc", "axp288-system-temp"), diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index cdfe304eaa201112ac0d8d529809e8e26ffafdce..f258668b0dc71ee8f4de4ab01a6819a39250f333 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -611,10 +611,10 @@ static const struct of_device_id iproc_adc_of_match[] = { MODULE_DEVICE_TABLE(of, iproc_adc_of_match); static struct platform_driver iproc_adc_driver = { - .probe = iproc_adc_probe, - .remove_new = iproc_adc_remove, - .driver = { - .name = "iproc-static-adc", + .probe = iproc_adc_probe, + .remove = iproc_adc_remove, + .driver = { + .name = "iproc-static-adc", .of_match_table = iproc_adc_of_match, }, }; diff --git a/drivers/iio/adc/da9150-gpadc.c b/drivers/iio/adc/da9150-gpadc.c index 8f0d3fb63b677c8e4834363762a01cb38ec42743..0290345ade84176addb53eae2c6d8630faa504f1 100644 --- a/drivers/iio/adc/da9150-gpadc.c +++ b/drivers/iio/adc/da9150-gpadc.c @@ -291,27 +291,11 @@ static const struct iio_chan_spec da9150_gpadc_channels[] = { }; /* Default maps used by da9150-charger */ -static struct iio_map da9150_gpadc_default_maps[] = { - { - .consumer_dev_name = "da9150-charger", - .consumer_channel = "CHAN_IBUS", - .adc_channel_label = "IBUS", - }, - { - .consumer_dev_name = "da9150-charger", - .consumer_channel = "CHAN_VBUS", - .adc_channel_label = "VBUS", - }, - { - .consumer_dev_name = "da9150-charger", - .consumer_channel = "CHAN_TJUNC", - .adc_channel_label = "TJUNC_CORE", - }, - { - .consumer_dev_name = "da9150-charger", - .consumer_channel = "CHAN_VBAT", - .adc_channel_label = "VBAT", - }, +static const struct iio_map da9150_gpadc_default_maps[] = { + IIO_MAP("IBUS", "da9150-charger", "CHAN_IBUS"), + IIO_MAP("VBUS", "da9150-charger", "CHAN_VBUS"), + IIO_MAP("TJUNC_CORE", "da9150-charger", "CHAN_TJUNC"), + IIO_MAP("VBAT", "da9150-charger", "CHAN_VBAT"), {}, }; diff --git a/drivers/iio/adc/dln2-adc.c b/drivers/iio/adc/dln2-adc.c index de7252a10047d56d391bbb5e238bf7eb7730c5e5..30328626d9beef28beb077c4de3767886c3b4e96 100644 --- a/drivers/iio/adc/dln2-adc.c +++ b/drivers/iio/adc/dln2-adc.c @@ -700,7 +700,7 @@ static void dln2_adc_remove(struct platform_device *pdev) static struct platform_driver dln2_adc_driver = { .driver.name = DLN2_ADC_MOD_NAME, .probe = dln2_adc_probe, - .remove_new = dln2_adc_remove, + .remove = dln2_adc_remove, }; module_platform_driver(dln2_adc_driver); diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c index cc38d5e0608eed8a4d514c7e94d26adc035ba924..a3e9c697e2cbee73ea09084273ae4b1acb872e2e 100644 --- a/drivers/iio/adc/ep93xx_adc.c +++ b/drivers/iio/adc/ep93xx_adc.c @@ -238,7 +238,7 @@ static struct platform_driver ep93xx_adc_driver = { .of_match_table = ep93xx_adc_of_ids, }, .probe = ep93xx_adc_probe, - .remove_new = ep93xx_adc_remove, + .remove = ep93xx_adc_remove, }; module_platform_driver(ep93xx_adc_driver); diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 4d00ee8dd14d0898a1f28b518f7d12d87bc19046..4614cf848535944a41e0ab19f35c5ca0546000c0 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -1008,7 +1008,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(exynos_adc_pm_ops, exynos_adc_suspend, static struct platform_driver exynos_adc_driver = { .probe = exynos_adc_probe, - .remove_new = exynos_adc_remove, + .remove = exynos_adc_remove, .driver = { .name = "exynos-adc", .of_match_table = exynos_adc_match, diff --git a/drivers/iio/adc/gehc-pmc-adc.c b/drivers/iio/adc/gehc-pmc-adc.c new file mode 100644 index 0000000000000000000000000000000000000000..d1167818b17d65987774cd5545cab6b5492de04e --- /dev/null +++ b/drivers/iio/adc/gehc-pmc-adc.c @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The GE HealthCare PMC ADC is a 16-Channel (Voltage and current), 16-Bit + * ADC with an I2C Interface. + * + * Copyright (C) 2024, GE HealthCare + * + * Authors: + * Herve Codina + */ +#include +#include +#include +#include +#include +#include +#include +#include + +struct pmc_adc { + struct i2c_client *client; +}; + +#define PMC_ADC_CMD_REQUEST_PROTOCOL_VERSION 0x01 +#define PMC_ADC_CMD_READ_VOLTAGE(_ch) (0x10 | (_ch)) +#define PMC_ADC_CMD_READ_CURRENT(_ch) (0x20 | (_ch)) + +#define PMC_ADC_VOLTAGE_CHANNEL(_ch, _ds_name) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_ch), \ + .address = PMC_ADC_CMD_READ_VOLTAGE(_ch), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ + .datasheet_name = (_ds_name), \ +} + +#define PMC_ADC_CURRENT_CHANNEL(_ch, _ds_name) { \ + .type = IIO_CURRENT, \ + .indexed = 1, \ + .channel = (_ch), \ + .address = PMC_ADC_CMD_READ_CURRENT(_ch), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ + .datasheet_name = (_ds_name), \ +} + +static const struct iio_chan_spec pmc_adc_channels[] = { + PMC_ADC_VOLTAGE_CHANNEL(0, "CH0_V"), + PMC_ADC_VOLTAGE_CHANNEL(1, "CH1_V"), + PMC_ADC_VOLTAGE_CHANNEL(2, "CH2_V"), + PMC_ADC_VOLTAGE_CHANNEL(3, "CH3_V"), + PMC_ADC_VOLTAGE_CHANNEL(4, "CH4_V"), + PMC_ADC_VOLTAGE_CHANNEL(5, "CH5_V"), + PMC_ADC_VOLTAGE_CHANNEL(6, "CH6_V"), + PMC_ADC_VOLTAGE_CHANNEL(7, "CH7_V"), + PMC_ADC_VOLTAGE_CHANNEL(8, "CH8_V"), + PMC_ADC_VOLTAGE_CHANNEL(9, "CH9_V"), + PMC_ADC_VOLTAGE_CHANNEL(10, "CH10_V"), + PMC_ADC_VOLTAGE_CHANNEL(11, "CH11_V"), + PMC_ADC_VOLTAGE_CHANNEL(12, "CH12_V"), + PMC_ADC_VOLTAGE_CHANNEL(13, "CH13_V"), + PMC_ADC_VOLTAGE_CHANNEL(14, "CH14_V"), + PMC_ADC_VOLTAGE_CHANNEL(15, "CH15_V"), + + PMC_ADC_CURRENT_CHANNEL(0, "CH0_I"), + PMC_ADC_CURRENT_CHANNEL(1, "CH1_I"), + PMC_ADC_CURRENT_CHANNEL(2, "CH2_I"), + PMC_ADC_CURRENT_CHANNEL(3, "CH3_I"), + PMC_ADC_CURRENT_CHANNEL(4, "CH4_I"), + PMC_ADC_CURRENT_CHANNEL(5, "CH5_I"), + PMC_ADC_CURRENT_CHANNEL(6, "CH6_I"), + PMC_ADC_CURRENT_CHANNEL(7, "CH7_I"), + PMC_ADC_CURRENT_CHANNEL(8, "CH8_I"), + PMC_ADC_CURRENT_CHANNEL(9, "CH9_I"), + PMC_ADC_CURRENT_CHANNEL(10, "CH10_I"), + PMC_ADC_CURRENT_CHANNEL(11, "CH11_I"), + PMC_ADC_CURRENT_CHANNEL(12, "CH12_I"), + PMC_ADC_CURRENT_CHANNEL(13, "CH13_I"), + PMC_ADC_CURRENT_CHANNEL(14, "CH14_I"), + PMC_ADC_CURRENT_CHANNEL(15, "CH15_I"), +}; + +static int pmc_adc_read_raw_ch(struct pmc_adc *pmc_adc, u8 cmd, int *val) +{ + s32 ret; + + ret = i2c_smbus_read_word_swapped(pmc_adc->client, cmd); + if (ret < 0) { + dev_err(&pmc_adc->client->dev, "i2c read word failed (%d)\n", ret); + return ret; + } + + *val = sign_extend32(ret, 15); + return 0; +} + +static int pmc_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct pmc_adc *pmc_adc = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + /* Values are directly read in mV or mA */ + ret = pmc_adc_read_raw_ch(pmc_adc, chan->address, val); + if (ret) + return ret; + return IIO_VAL_INT; + } + + return -EINVAL; +} + +static int pmc_adc_fwnode_xlate(struct iio_dev *indio_dev, + const struct fwnode_reference_args *iiospec) +{ + enum iio_chan_type expected_type; + unsigned int i; + + /* + * args[0]: Acquisition type (i.e. voltage or current) + * args[1]: PMC ADC channel number + */ + if (iiospec->nargs != 2) + return -EINVAL; + + switch (iiospec->args[0]) { + case GEHC_PMC_ADC_VOLTAGE: + expected_type = IIO_VOLTAGE; + break; + case GEHC_PMC_ADC_CURRENT: + expected_type = IIO_CURRENT; + break; + default: + dev_err(&indio_dev->dev, "Invalid channel type %llu\n", + iiospec->args[0]); + return -EINVAL; + } + + for (i = 0; i < indio_dev->num_channels; i++) + if (indio_dev->channels[i].type == expected_type && + indio_dev->channels[i].channel == iiospec->args[1]) + return i; + + dev_err(&indio_dev->dev, "Invalid channel type %llu number %llu\n", + iiospec->args[0], iiospec->args[1]); + return -EINVAL; +} + +static const struct iio_info pmc_adc_info = { + .read_raw = pmc_adc_read_raw, + .fwnode_xlate = pmc_adc_fwnode_xlate, +}; + +static const char *const pmc_adc_regulator_names[] = { + "vdd", + "vdda", + "vddio", + "vref", +}; + +static int pmc_adc_probe(struct i2c_client *client) +{ + struct iio_dev *indio_dev; + struct pmc_adc *pmc_adc; + struct clk *clk; + s32 val; + int ret; + + ret = devm_regulator_bulk_get_enable(&client->dev, ARRAY_SIZE(pmc_adc_regulator_names), + pmc_adc_regulator_names); + if (ret) + return dev_err_probe(&client->dev, ret, "Failed to get regulators\n"); + + clk = devm_clk_get_optional_enabled(&client->dev, "osc"); + if (IS_ERR(clk)) + return dev_err_probe(&client->dev, PTR_ERR(clk), "Failed to get osc clock\n"); + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*pmc_adc)); + if (!indio_dev) + return -ENOMEM; + + pmc_adc = iio_priv(indio_dev); + pmc_adc->client = client; + + val = i2c_smbus_read_byte_data(pmc_adc->client, PMC_ADC_CMD_REQUEST_PROTOCOL_VERSION); + if (val < 0) + return dev_err_probe(&client->dev, val, "Failed to get protocol version\n"); + + if (val != 0x01) + return dev_err_probe(&client->dev, -EINVAL, + "Unsupported protocol version 0x%02x\n", val); + + indio_dev->name = "pmc_adc"; + indio_dev->info = &pmc_adc_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = pmc_adc_channels; + indio_dev->num_channels = ARRAY_SIZE(pmc_adc_channels); + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct of_device_id pmc_adc_of_match[] = { + { .compatible = "gehc,pmc-adc"}, + { } +}; +MODULE_DEVICE_TABLE(of, pmc_adc_of_match); + +static const struct i2c_device_id pmc_adc_id_table[] = { + { "pmc-adc" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pmc_adc_id_table); + +static struct i2c_driver pmc_adc_i2c_driver = { + .driver = { + .name = "pmc-adc", + .of_match_table = pmc_adc_of_match, + }, + .id_table = pmc_adc_id_table, + .probe = pmc_adc_probe, +}; + +module_i2c_driver(pmc_adc_i2c_driver); + +MODULE_AUTHOR("Herve Codina "); +MODULE_DESCRIPTION("GE HealthCare PMC ADC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index fb635a756440300432b0bbcf1fd9ebce2e9ab92d..689e34f069877ec525c5f9ee7258d5140d4bba70 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -132,7 +132,7 @@ static int hi8435_read_event_config(struct iio_dev *idev, static int hi8435_write_event_config(struct iio_dev *idev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct hi8435_priv *priv = iio_priv(idev); int ret; diff --git a/drivers/iio/adc/imx8qxp-adc.c b/drivers/iio/adc/imx8qxp-adc.c index fe82198170d5999b0648d5adbc0f156ca5b2e0e6..3d19d7d744aa46d8bfaeb2c36503297f56ebd36f 100644 --- a/drivers/iio/adc/imx8qxp-adc.c +++ b/drivers/iio/adc/imx8qxp-adc.c @@ -487,7 +487,7 @@ MODULE_DEVICE_TABLE(of, imx8qxp_adc_match); static struct platform_driver imx8qxp_adc_driver = { .probe = imx8qxp_adc_probe, - .remove_new = imx8qxp_adc_remove, + .remove = imx8qxp_adc_remove, .driver = { .name = ADC_DRIVER_NAME, .of_match_table = imx8qxp_adc_match, diff --git a/drivers/iio/adc/imx93_adc.c b/drivers/iio/adc/imx93_adc.c index 4ccf4819f1f131f3283bf804424e842705b9bf53..002eb19587d679789a9affa1f9514a720998c470 100644 --- a/drivers/iio/adc/imx93_adc.c +++ b/drivers/iio/adc/imx93_adc.c @@ -470,7 +470,7 @@ MODULE_DEVICE_TABLE(of, imx93_adc_match); static struct platform_driver imx93_adc_driver = { .probe = imx93_adc_probe, - .remove_new = imx93_adc_remove, + .remove = imx93_adc_remove, .driver = { .name = IMX93_ADC_DRIVER_NAME, .of_match_table = imx93_adc_match, diff --git a/drivers/iio/adc/intel_mrfld_adc.c b/drivers/iio/adc/intel_mrfld_adc.c index 30733252aa56f83a8c4e47459853e81d22270b18..c178850eaaab103bba5729ada102e0e2408bf4de 100644 --- a/drivers/iio/adc/intel_mrfld_adc.c +++ b/drivers/iio/adc/intel_mrfld_adc.c @@ -164,7 +164,7 @@ static const struct iio_chan_spec mrfld_adc_channels[] = { BCOVE_ADC_CHANNEL(IIO_TEMP, 8, "CH8", 0xC6), }; -static struct iio_map iio_maps[] = { +static const struct iio_map iio_maps[] = { IIO_MAP("CH0", "bcove-battery", "VBATRSLT"), IIO_MAP("CH1", "bcove-battery", "BATTID"), IIO_MAP("CH2", "bcove-battery", "IBATRSLT"), diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c index 6d9b354bc705bb712dbed6c1ae588e50c76d522a..33bf8aef79e36212594114625564ded781070be5 100644 --- a/drivers/iio/adc/lp8788_adc.c +++ b/drivers/iio/adc/lp8788_adc.c @@ -26,7 +26,7 @@ struct lp8788_adc { struct lp8788 *lp; - struct iio_map *map; + const struct iio_map *map; struct mutex lock; }; @@ -149,17 +149,9 @@ static const struct iio_chan_spec lp8788_adc_channels[] = { }; /* default maps used by iio consumer (lp8788-charger driver) */ -static struct iio_map lp8788_default_iio_maps[] = { - { - .consumer_dev_name = "lp8788-charger", - .consumer_channel = "lp8788_vbatt_5p0", - .adc_channel_label = "VBATT_5P0", - }, - { - .consumer_dev_name = "lp8788-charger", - .consumer_channel = "lp8788_adc1", - .adc_channel_label = "ADC1", - }, +static const struct iio_map lp8788_default_iio_maps[] = { + IIO_MAP("VBATT_5P0", "lp8788-charger", "lp8788_vbatt_5p0"), + IIO_MAP("ADC1", "lp8788-charger", "lp8788_adc1"), { } }; @@ -168,7 +160,7 @@ static int lp8788_iio_map_register(struct device *dev, struct lp8788_platform_data *pdata, struct lp8788_adc *adc) { - struct iio_map *map; + const struct iio_map *map; int ret; map = (!pdata || !pdata->adc_pdata) ? diff --git a/drivers/iio/adc/ltc2497-core.c b/drivers/iio/adc/ltc2497-core.c index 996f6cbbed3ce161c7ad6acda6289607197caae8..2dc5c704426949a4ec62c42591d6c2c40ffb79cc 100644 --- a/drivers/iio/adc/ltc2497-core.c +++ b/drivers/iio/adc/ltc2497-core.c @@ -168,6 +168,7 @@ static const struct iio_info ltc2497core_info = { int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) { struct ltc2497core_driverdata *ddata = iio_priv(indio_dev); + struct iio_map *plat_data = dev_get_platdata(dev); int ret; /* @@ -200,16 +201,10 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) return ret; } - if (dev->platform_data) { - struct iio_map *plat_data; - - plat_data = (struct iio_map *)dev->platform_data; - - ret = iio_map_array_register(indio_dev, plat_data); - if (ret) { - dev_err(&indio_dev->dev, "iio map err: %d\n", ret); - goto err_regulator_disable; - } + ret = iio_map_array_register(indio_dev, plat_data); + if (ret) { + dev_err(&indio_dev->dev, "iio map err: %d\n", ret); + goto err_regulator_disable; } ddata->addr_prev = LTC2497_CONFIG_DEFAULT; @@ -231,7 +226,7 @@ err_regulator_disable: return ret; } -EXPORT_SYMBOL_NS(ltc2497core_probe, LTC2497); +EXPORT_SYMBOL_NS(ltc2497core_probe, "LTC2497"); void ltc2497core_remove(struct iio_dev *indio_dev) { @@ -243,7 +238,7 @@ void ltc2497core_remove(struct iio_dev *indio_dev) regulator_disable(ddata->ref); } -EXPORT_SYMBOL_NS(ltc2497core_remove, LTC2497); +EXPORT_SYMBOL_NS(ltc2497core_remove, "LTC2497"); MODULE_DESCRIPTION("common code for LTC2496/LTC2497 drivers"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/ltc2497.h b/drivers/iio/adc/ltc2497.h index 781519b52475623fe3bd6f7e1a4e9275d77fb0e0..64e81c95a3dd05911b6717c09ac0560c9f47f304 100644 --- a/drivers/iio/adc/ltc2497.h +++ b/drivers/iio/adc/ltc2497.h @@ -23,4 +23,4 @@ struct ltc2497core_driverdata { int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev); void ltc2497core_remove(struct iio_dev *indio_dev); -MODULE_IMPORT_NS(LTC2497); +MODULE_IMPORT_NS("LTC2497"); diff --git a/drivers/iio/adc/max11205.c b/drivers/iio/adc/max11205.c index 9d8bc0b154dd358ce99f5bc68dc8d3bacfec3d55..6c803df220b6e98b0f8e0d5b527a98d7adf6c517 100644 --- a/drivers/iio/adc/max11205.c +++ b/drivers/iio/adc/max11205.c @@ -177,4 +177,4 @@ module_spi_driver(max11205_spi_driver); MODULE_AUTHOR("Ramona Bolboaca "); MODULE_DESCRIPTION("MAX11205 ADC driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); +MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA"); diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index d0c6e94f7204eed7432d77a0b23de108d2c126f9..9a0baea08ab6162b024932f3f65c8a68d156672d 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -392,7 +393,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev, if (data < 0) return data; - data = (rxbuf[1] | rxbuf[0] << 8) & + data = get_unaligned_be16(rxbuf) & ((1 << st->chip_info->bits) - 1); } else { /* Get reading */ @@ -943,7 +944,7 @@ error_ret: static int max1363_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct max1363_state *st = iio_priv(indio_dev); diff --git a/drivers/iio/adc/max34408.c b/drivers/iio/adc/max34408.c index ffec22be2d593343c8cec1891fa2c6c6b3f18019..971e6e5dee9b1587bb823193d392bbe191bfd939 100644 --- a/drivers/iio/adc/max34408.c +++ b/drivers/iio/adc/max34408.c @@ -161,7 +161,7 @@ static int max34408_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: /* - * calcluate current for 8bit ADC with Rsense + * calculate current for 8bit ADC with Rsense * value. * 10 mV * 1000 / Rsense uOhm = max current * (max current * adc val * 1000) / (2^8 - 1) mA diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c index 198c7e68e0cf271271004997634b923b08f80147..cf8a8c0412ec948a00a0558227a6a2f854315ae2 100644 --- a/drivers/iio/adc/men_z188_adc.c +++ b/drivers/iio/adc/men_z188_adc.c @@ -172,4 +172,4 @@ MODULE_AUTHOR("Johannes Thumshirn "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("IIO ADC driver for MEN 16z188 ADC Core"); MODULE_ALIAS("mcb:16z188"); -MODULE_IMPORT_NS(MCB); +MODULE_IMPORT_NS("MCB"); diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index e16b0e28974e8ffc0e2ab5a56c7f8b7e8e8fa87b..2d475b43e717ff08a2e5e20504dc657ebbb921a5 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -1483,7 +1483,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops, static struct platform_driver meson_sar_adc_driver = { .probe = meson_sar_adc_probe, - .remove_new = meson_sar_adc_remove, + .remove = meson_sar_adc_remove, .driver = { .name = "meson-saradc", .of_match_table = meson_sar_adc_of_match, diff --git a/drivers/iio/adc/mp2629_adc.c b/drivers/iio/adc/mp2629_adc.c index 5fbf9b6abd9c7c05322a305f7b315c75f6d179a5..1cb043b17437780970ce355f9d93fd36cbd26826 100644 --- a/drivers/iio/adc/mp2629_adc.c +++ b/drivers/iio/adc/mp2629_adc.c @@ -52,7 +52,7 @@ static struct iio_chan_spec mp2629_channels[] = { MP2629_ADC_CHAN(INPUT_CURRENT, IIO_CURRENT) }; -static struct iio_map mp2629_adc_maps[] = { +static const struct iio_map mp2629_adc_maps[] = { MP2629_MAP(BATT_VOLT, "batt-volt"), MP2629_MAP(SYSTEM_VOLT, "system-volt"), MP2629_MAP(INPUT_VOLT, "input-volt"), @@ -195,7 +195,7 @@ static struct platform_driver mp2629_adc_driver = { .of_match_table = mp2629_adc_of_match, }, .probe = mp2629_adc_probe, - .remove_new = mp2629_adc_remove, + .remove = mp2629_adc_remove, }; module_platform_driver(mp2629_adc_driver); diff --git a/drivers/iio/adc/mt6360-adc.c b/drivers/iio/adc/mt6360-adc.c index 83161e6d29b901eda4cfc21dfd3d10ec21b1d2ce..4eb2455d6ffacb8f09a404df4490b5a11e49660d 100644 --- a/drivers/iio/adc/mt6360-adc.c +++ b/drivers/iio/adc/mt6360-adc.c @@ -124,7 +124,7 @@ static int mt6360_adc_read_channel(struct mt6360_adc_data *mad, int channel, int usleep_range(ADC_LOOP_TIME_US / 2, ADC_LOOP_TIME_US); } - *val = rpt[1] << 8 | rpt[2]; + *val = get_unaligned_be16(&rpt[1]); ret = IIO_VAL_INT; out_adc_conv: diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c index 8c7b64e78dbbc8a8e0483195d91a3c7185bd0a7e..152cbe265e1a2ea9acf934f3a9ccef2da2628c40 100644 --- a/drivers/iio/adc/mxs-lradc-adc.c +++ b/drivers/iio/adc/mxs-lradc-adc.c @@ -819,10 +819,10 @@ static void mxs_lradc_adc_remove(struct platform_device *pdev) static struct platform_driver mxs_lradc_adc_driver = { .driver = { - .name = "mxs-lradc-adc", + .name = "mxs-lradc-adc", }, - .probe = mxs_lradc_adc_probe, - .remove_new = mxs_lradc_adc_remove, + .probe = mxs_lradc_adc_probe, + .remove = mxs_lradc_adc_remove, }; module_platform_driver(mxs_lradc_adc_driver); diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c index 3a55465951e7938311e5f1c4e668f7c8770b82a6..7c1511ee3a4b4a3278e0390f59809ccd9ef9722f 100644 --- a/drivers/iio/adc/npcm_adc.c +++ b/drivers/iio/adc/npcm_adc.c @@ -337,7 +337,7 @@ static void npcm_adc_remove(struct platform_device *pdev) static struct platform_driver npcm_adc_driver = { .probe = npcm_adc_probe, - .remove_new = npcm_adc_remove, + .remove = npcm_adc_remove, .driver = { .name = "npcm_adc", .of_match_table = npcm_adc_match, diff --git a/drivers/iio/adc/pac1921.c b/drivers/iio/adc/pac1921.c index 36e813d9c73f1c25afe114466ec716a440cf7069..b0f6727cfe3835de5ac962e6221f39fe1d3acfb8 100644 --- a/drivers/iio/adc/pac1921.c +++ b/drivers/iio/adc/pac1921.c @@ -241,7 +241,7 @@ static inline void pac1921_calc_scale(int dividend, int divisor, int *val, s64 tmp; tmp = div_s64(dividend * (s64)NANO, divisor); - *val = (int)div_s64_rem(tmp, NANO, val2); + *val = div_s64_rem(tmp, NANO, val2); } /* @@ -260,7 +260,7 @@ static void pac1921_calc_current_scales(struct pac1921_priv *priv) int max = (PAC1921_MAX_VSENSE_MV * MICRO) >> i; int vsense_lsb = DIV_ROUND_CLOSEST(max, PAC1921_RES_RESOLUTION); - pac1921_calc_scale(vsense_lsb, (int)priv->rshunt_uohm, + pac1921_calc_scale(vsense_lsb, priv->rshunt_uohm, &priv->current_scales[i][0], &priv->current_scales[i][1]); } @@ -314,7 +314,7 @@ static int pac1921_check_push_overflow(struct iio_dev *indio_dev, s64 timestamp) timestamp); } - priv->prev_ovf_flags = (u8)flags; + priv->prev_ovf_flags = flags; return 0; } @@ -329,8 +329,7 @@ static int pac1921_check_push_overflow(struct iio_dev *indio_dev, s64 timestamp) static int pac1921_read_res(struct pac1921_priv *priv, unsigned long reg, u16 *val) { - int ret = regmap_bulk_read(priv->regmap, (unsigned int)reg, val, - sizeof(*val)); + int ret = regmap_bulk_read(priv->regmap, reg, val, sizeof(*val)); if (ret) return ret; @@ -366,7 +365,7 @@ static int pac1921_read_raw(struct iio_dev *indio_dev, if (ret) return ret; - *val = (int)res_val; + *val = res_val; return IIO_VAL_INT; } @@ -400,10 +399,10 @@ static int pac1921_read_raw(struct iio_dev *indio_dev, s64 tmp = curr_scale[0] * (s64)NANO + curr_scale[1]; /* Multiply by max_vbus (V) / dv_gain */ - tmp *= PAC1921_MAX_VBUS_V >> (int)priv->dv_gain; + tmp *= PAC1921_MAX_VBUS_V >> priv->dv_gain; /* Convert back to INT_PLUS_NANO */ - *val = (int)div_s64_rem(tmp, NANO, val2); + *val = div_s64_rem(tmp, NANO, val2); return IIO_VAL_INT_PLUS_NANO; } @@ -426,7 +425,7 @@ static int pac1921_read_raw(struct iio_dev *indio_dev, * 1/(integr_period_usecs/MICRO) = MICRO/integr_period_usecs */ *val = MICRO; - *val2 = (int)priv->integr_period_usecs; + *val2 = priv->integr_period_usecs; return IIO_VAL_FRACTIONAL; default: @@ -503,7 +502,7 @@ static int pac1921_lookup_scale(const int (*const scales_tbl)[2], size_t size, for (unsigned int i = 0; i < size; i++) if (scales_tbl[i][0] == scale_val && scales_tbl[i][1] == scale_val2) - return (int)i; + return i; return -EINVAL; } @@ -553,7 +552,7 @@ static int pac1921_update_gain_from_scale(struct pac1921_priv *priv, if (ret < 0) return ret; - return pac1921_update_gain(priv, &priv->dv_gain, (u8)ret, + return pac1921_update_gain(priv, &priv->dv_gain, ret, PAC1921_GAIN_DV_GAIN_MASK); case PAC1921_CHAN_VSENSE: ret = pac1921_lookup_scale(pac1921_vsense_scales, @@ -562,7 +561,7 @@ static int pac1921_update_gain_from_scale(struct pac1921_priv *priv, if (ret < 0) return ret; - return pac1921_update_gain(priv, &priv->di_gain, (u8)ret, + return pac1921_update_gain(priv, &priv->di_gain, ret, PAC1921_GAIN_DI_GAIN_MASK); case PAC1921_CHAN_CURRENT: ret = pac1921_lookup_scale(priv->current_scales, @@ -571,7 +570,7 @@ static int pac1921_update_gain_from_scale(struct pac1921_priv *priv, if (ret < 0) return ret; - return pac1921_update_gain(priv, &priv->di_gain, (u8)ret, + return pac1921_update_gain(priv, &priv->di_gain, ret, PAC1921_GAIN_DI_GAIN_MASK); default: return -EINVAL; @@ -586,7 +585,7 @@ static int pac1921_lookup_int_num_samples(int num_samples) { for (unsigned int i = 0; i < ARRAY_SIZE(pac1921_int_num_samples); i++) if (pac1921_int_num_samples[i] == num_samples) - return (int)i; + return i; return -EINVAL; } @@ -607,7 +606,7 @@ static int pac1921_update_int_num_samples(struct pac1921_priv *priv, if (ret < 0) return ret; - n_samples = (u8)ret; + n_samples = ret; if (priv->n_samples == n_samples) return 0; @@ -700,7 +699,8 @@ static int pac1921_read_event_config(struct iio_dev *indio_dev, static int pac1921_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, + bool state) { struct pac1921_priv *priv = iio_priv(indio_dev); u8 ovf_bit; @@ -770,7 +770,7 @@ static ssize_t pac1921_read_shunt_resistor(struct iio_dev *indio_dev, guard(mutex)(&priv->lock); - vals[0] = (int)priv->rshunt_uohm; + vals[0] = priv->rshunt_uohm; vals[1] = MICRO; return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals); @@ -793,13 +793,13 @@ static ssize_t pac1921_write_shunt_resistor(struct iio_dev *indio_dev, if (ret) return ret; - rshunt_uohm = (u32)val * MICRO + (u32)val_fract; + rshunt_uohm = val * MICRO + val_fract; if (rshunt_uohm == 0 || rshunt_uohm > INT_MAX) return -EINVAL; guard(mutex)(&priv->lock); - priv->rshunt_uohm = (u32)rshunt_uohm; + priv->rshunt_uohm = rshunt_uohm; pac1921_calc_current_scales(priv); @@ -1077,7 +1077,7 @@ static int pac1921_init(struct pac1921_priv *priv) /* * Init control register: * - VPower free run integration mode - * - OUT pin full scale range: 3V (HW detault) + * - OUT pin full scale range: 3V (HW default) * - no timeout, no sleep, no sleep override, no recalc (HW defaults) */ val = FIELD_PREP(PAC1921_CONTROL_MXSL_MASK, @@ -1168,10 +1168,12 @@ static int pac1921_probe(struct i2c_client *client) priv->regmap = devm_regmap_init_i2c(client, &pac1921_regmap_config); if (IS_ERR(priv->regmap)) - return dev_err_probe(dev, (int)PTR_ERR(priv->regmap), + return dev_err_probe(dev, PTR_ERR(priv->regmap), "Cannot initialize register map\n"); - devm_mutex_init(dev, &priv->lock); + ret = devm_mutex_init(dev, &priv->lock); + if (ret) + return ret; priv->dv_gain = PAC1921_DEFAULT_DV_GAIN; priv->di_gain = PAC1921_DEFAULT_DI_GAIN; @@ -1191,7 +1193,7 @@ static int pac1921_probe(struct i2c_client *client) priv->vdd = devm_regulator_get(dev, "vdd"); if (IS_ERR(priv->vdd)) - return dev_err_probe(dev, (int)PTR_ERR(priv->vdd), + return dev_err_probe(dev, PTR_ERR(priv->vdd), "Cannot get vdd regulator\n"); ret = regulator_enable(priv->vdd); diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c index 7ef249d8328661072c17542a5c7142d96c0d2834..20802b7f49ea84c00dd6e8c717d956cb20448f4a 100644 --- a/drivers/iio/adc/pac1934.c +++ b/drivers/iio/adc/pac1934.c @@ -1507,7 +1507,7 @@ static int pac1934_probe(struct i2c_client *client) indio_dev->name = pac1934_chip_config[ret].name; } - if (acpi_match_device(dev->driver->acpi_match_table, dev)) + if (is_acpi_device_node(dev_fwnode(dev))) ret = pac1934_acpi_parse_channel_config(client, info); else /* diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 203cbbc707198e4f254244f2bd1d79f8f99f9a0b..d283ee8fb1d2f219674ece7faa5492503671ac94 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -456,7 +456,7 @@ static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc, * raw high threshold = (ideal threshold + INL) * gain error + offset error * * The gain error include both gain error, as specified in the datasheet, and - * the gain error drift. These paramenters vary depending on device and whether + * the gain error drift. These parameters vary depending on device and whether * the channel is calibrated (trimmed) or not. */ static int palmas_gpadc_threshold_with_tolerance(int val, const int INL, @@ -676,7 +676,7 @@ static int palmas_gpadc_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct palmas_gpadc *adc = iio_priv(indio_dev); int adc_chan = chan->channel; diff --git a/drivers/iio/adc/qcom-pm8xxx-xoadc.c b/drivers/iio/adc/qcom-pm8xxx-xoadc.c index 9e1112f5acc6a46b02491f89e76d8168f3a9dbc7..31f88cf7f7f18297132d152648b312c0fb60608e 100644 --- a/drivers/iio/adc/qcom-pm8xxx-xoadc.c +++ b/drivers/iio/adc/qcom-pm8xxx-xoadc.c @@ -821,7 +821,6 @@ static int pm8xxx_xoadc_parse_channel(struct device *dev, static int pm8xxx_xoadc_parse_channels(struct pm8xxx_xoadc *adc) { - struct fwnode_handle *child; struct pm8xxx_chan_info *ch; int ret; int i; @@ -844,16 +843,15 @@ static int pm8xxx_xoadc_parse_channels(struct pm8xxx_xoadc *adc) return -ENOMEM; i = 0; - device_for_each_child_node(adc->dev, child) { + device_for_each_child_node_scoped(adc->dev, child) { ch = &adc->chans[i]; ret = pm8xxx_xoadc_parse_channel(adc->dev, child, adc->variant->channels, &adc->iio_chans[i], ch); - if (ret) { - fwnode_handle_put(child); + if (ret) return ret; - } + i++; } @@ -1016,7 +1014,7 @@ static struct platform_driver pm8xxx_xoadc_driver = { .of_match_table = pm8xxx_xoadc_id_table, }, .probe = pm8xxx_xoadc_probe, - .remove_new = pm8xxx_xoadc_remove, + .remove = pm8xxx_xoadc_remove, }; module_platform_driver(pm8xxx_xoadc_driver); diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c index 9b69f40beed8eacf3e8e7b4c1cac4c0c5a57164f..af3c2f659f5e90e330fc272aa6741472fc488d57 100644 --- a/drivers/iio/adc/qcom-spmi-adc5.c +++ b/drivers/iio/adc/qcom-spmi-adc5.c @@ -830,7 +830,7 @@ static int adc5_get_fw_data(struct adc5_chip *adc) adc->nchannels = device_get_child_node_count(adc->dev); if (!adc->nchannels) - return -EINVAL; + return dev_err_probe(adc->dev, -EINVAL, "no channels defined\n"); adc->iio_chans = devm_kcalloc(adc->dev, adc->nchannels, sizeof(*adc->iio_chans), GFP_KERNEL); @@ -903,7 +903,7 @@ static int adc5_probe(struct platform_device *pdev) ret = adc5_get_fw_data(adc); if (ret) - return dev_err_probe(dev, ret, "adc get dt data failed\n"); + return ret; irq_eoc = platform_get_irq(pdev, 0); if (irq_eoc < 0) { diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index f5c6f1f27b2c7de16326c0465f6c3c7899abb746..00a7f098202543891d7ae6c0ab2904b78b96b8fb 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -754,7 +754,6 @@ static int vadc_get_fw_data(struct vadc_priv *vadc) const struct vadc_channels *vadc_chan; struct iio_chan_spec *iio_chan; struct vadc_channel_prop prop; - struct fwnode_handle *child; unsigned int index = 0; int ret; @@ -774,12 +773,10 @@ static int vadc_get_fw_data(struct vadc_priv *vadc) iio_chan = vadc->iio_chans; - device_for_each_child_node(vadc->dev, child) { + device_for_each_child_node_scoped(vadc->dev, child) { ret = vadc_get_fw_channel_data(vadc->dev, &prop, child); - if (ret) { - fwnode_handle_put(child); + if (ret) return ret; - } prop.scale_fn_type = vadc_chans[prop.channel].scale_fn_type; vadc->chan_props[index] = prop; diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c index 15a21d2860e758f3dec44403e79a4d2271199496..11170b5852d17f52e5a088de47605d5c83ddca74 100644 --- a/drivers/iio/adc/rcar-gyroadc.c +++ b/drivers/iio/adc/rcar-gyroadc.c @@ -592,7 +592,7 @@ static const struct dev_pm_ops rcar_gyroadc_pm_ops = { static struct platform_driver rcar_gyroadc_driver = { .probe = rcar_gyroadc_probe, - .remove_new = rcar_gyroadc_remove, + .remove = rcar_gyroadc_remove, .driver = { .name = DRIVER_NAME, .of_match_table = rcar_gyroadc_match, diff --git a/drivers/iio/adc/rn5t618-adc.c b/drivers/iio/adc/rn5t618-adc.c index ce5f3011fe00c45f56a109821526d2dc4171508d..b33536157adc998668d4d0c6d6a3e806d28381a1 100644 --- a/drivers/iio/adc/rn5t618-adc.c +++ b/drivers/iio/adc/rn5t618-adc.c @@ -185,7 +185,7 @@ static const struct iio_chan_spec rn5t618_adc_iio_channels[] = { RN5T618_ADC_CHANNEL(AIN0, IIO_VOLTAGE, "AIN0") }; -static struct iio_map rn5t618_maps[] = { +static const struct iio_map rn5t618_maps[] = { IIO_MAP("VADP", "rn5t618-power", "vadp"), IIO_MAP("VUSB", "rn5t618-power", "vusb"), { /* sentinel */ } diff --git a/drivers/iio/adc/sd_adc_modulator.c b/drivers/iio/adc/sd_adc_modulator.c index 654b6a38b650a197c28bf1341c4ca6a7ea0cc82b..9f7a75168aac31ef49982905a810c4519ad545e6 100644 --- a/drivers/iio/adc/sd_adc_modulator.c +++ b/drivers/iio/adc/sd_adc_modulator.c @@ -159,4 +159,4 @@ module_platform_driver(iio_sd_mod_adc); MODULE_DESCRIPTION("Basic sigma delta modulator"); MODULE_AUTHOR("Arnaud Pouliquen "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_BACKEND); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 616dd729666aa1129c465e040ab701956d91d4ec..2201ee9987ae426a2497a2725a85ec877d52fea0 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -906,7 +906,7 @@ MODULE_DEVICE_TABLE(of, stm32_adc_of_match); static struct platform_driver stm32_adc_driver = { .probe = stm32_adc_probe, - .remove_new = stm32_adc_remove, + .remove = stm32_adc_remove, .driver = { .name = "stm32-adc-core", .of_match_table = stm32_adc_of_match, diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 32ca26ed59f7af111d4da0caa73cafa98fd472c4..9d3b23efcc068a794636a069e89005001508c91a 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -2644,7 +2644,7 @@ MODULE_DEVICE_TABLE(of, stm32_adc_of_match); static struct platform_driver stm32_adc_driver = { .probe = stm32_adc_probe, - .remove_new = stm32_adc_remove, + .remove = stm32_adc_remove, .driver = { .name = "stm32-adc", .of_match_table = stm32_adc_of_match, diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 2037f73426d4b3420072ad578548a4eb20611204..1f9eca2fb2bf8ca0d681b452cb7e2054f07b33c2 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -1890,11 +1890,11 @@ static struct platform_driver stm32_dfsdm_adc_driver = { .pm = pm_sleep_ptr(&stm32_dfsdm_adc_pm_ops), }, .probe = stm32_dfsdm_adc_probe, - .remove_new = stm32_dfsdm_adc_remove, + .remove = stm32_dfsdm_adc_remove, }; module_platform_driver(stm32_dfsdm_adc_driver); MODULE_DESCRIPTION("STM32 sigma delta ADC"); MODULE_AUTHOR("Arnaud Pouliquen "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_BACKEND); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index bef59fcc0d807c9626ef530bf8da536cc1a0fafd..041dc9ebc048237ee699f6ee51e2f152342f26b5 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -506,7 +506,7 @@ static const struct dev_pm_ops stm32_dfsdm_core_pm_ops = { static struct platform_driver stm32_dfsdm_driver = { .probe = stm32_dfsdm_probe, - .remove_new = stm32_dfsdm_core_remove, + .remove = stm32_dfsdm_core_remove, .driver = { .name = "stm32-dfsdm", .of_match_table = stm32_dfsdm_of_match, diff --git a/drivers/iio/adc/sun20i-gpadc-iio.c b/drivers/iio/adc/sun20i-gpadc-iio.c index 6a893d484cf7038f306eca6851beff4c84740864..136b8d9c294f4679adf813316eae19c2926a2742 100644 --- a/drivers/iio/adc/sun20i-gpadc-iio.c +++ b/drivers/iio/adc/sun20i-gpadc-iio.c @@ -155,7 +155,6 @@ static int sun20i_gpadc_alloc_channels(struct iio_dev *indio_dev, unsigned int channel; int num_channels, i, ret; struct iio_chan_spec *channels; - struct fwnode_handle *node; num_channels = device_get_child_node_count(dev); if (num_channels == 0) @@ -167,12 +166,10 @@ static int sun20i_gpadc_alloc_channels(struct iio_dev *indio_dev, return -ENOMEM; i = 0; - device_for_each_child_node(dev, node) { + device_for_each_child_node_scoped(dev, node) { ret = fwnode_property_read_u32(node, "reg", &channel); - if (ret) { - fwnode_handle_put(node); + if (ret) return dev_err_probe(dev, ret, "invalid channel number\n"); - } channels[i].type = IIO_VOLTAGE; channels[i].indexed = 1; diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index 100ecced5fc11aa1882bff154b2756e30f01d9c9..8b27458dcd661bb6cd9958d2ea0c5746ee68f35c 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -114,11 +114,8 @@ struct sun4i_gpadc_iio { .datasheet_name = _name, \ } -static struct iio_map sun4i_gpadc_hwmon_maps[] = { - { - .adc_channel_label = "temp_adc", - .consumer_dev_name = "iio_hwmon.0", - }, +static const struct iio_map sun4i_gpadc_hwmon_maps[] = { + IIO_MAP("temp_adc", "iio_hwmon.0", NULL), { /* sentinel */ }, }; @@ -700,7 +697,7 @@ static struct platform_driver sun4i_gpadc_driver = { }, .id_table = sun4i_gpadc_id, .probe = sun4i_gpadc_probe, - .remove_new = sun4i_gpadc_remove, + .remove = sun4i_gpadc_remove, }; MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_id); diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 6d1bc9659946df0be15ebc550c84e966a90c9fce..47fe8e16aee42d375a74f9e97d4220542b04566d 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -806,7 +806,7 @@ static int ads1015_disable_event_config(struct ads1015_data *data, static int ads1015_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct ads1015_data *data = iio_priv(indio_dev); int ret; @@ -1032,8 +1032,7 @@ static int ads1015_probe(struct i2c_client *client) } if (client->irq && chip->has_comparator) { - unsigned long irq_trig = - irqd_get_trigger_type(irq_get_irq_data(client->irq)); + unsigned long irq_trig = irq_get_trigger_type(client->irq); unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK | ADS1015_CFG_COMP_LAT_MASK | ADS1015_CFG_COMP_POL_MASK; unsigned int cfg_comp = diff --git a/drivers/iio/adc/ti-ads1119.c b/drivers/iio/adc/ti-ads1119.c index 1c760637514928ba35c3cfdf9be4d49d431aac38..e9d9d4d46d3809c02bd9cf2e6874b16919d55d6e 100644 --- a/drivers/iio/adc/ti-ads1119.c +++ b/drivers/iio/adc/ti-ads1119.c @@ -804,7 +804,7 @@ static const struct of_device_id __maybe_unused ads1119_of_match[] = { MODULE_DEVICE_TABLE(of, ads1119_of_match); static const struct i2c_device_id ads1119_id[] = { - { "ads1119", 0 }, + { "ads1119" }, { } }; MODULE_DEVICE_TABLE(i2c, ads1119_id); diff --git a/drivers/iio/adc/ti-ads1298.c b/drivers/iio/adc/ti-ads1298.c index 0f9f75baaebbf7b6bb099a5c08496bddc06a01bc..36d43495f603a717ae5b0c38f3ecd7cdaacf3230 100644 --- a/drivers/iio/adc/ti-ads1298.c +++ b/drivers/iio/adc/ti-ads1298.c @@ -294,7 +294,7 @@ static int ads1298_get_scale(struct ads1298_private *priv, if (ret) return ret; - /* Refererence in millivolts */ + /* Reference in millivolts */ *val = regval & ADS1298_MASK_CONFIG3_VREF_4V ? 4000 : 2400; } diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 426e3c9f88a16ee6c60f85fef6ef6a95a9ee97e1..fe1509d3b1e766cf13ea77b1d6b0781f54515dba 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -494,7 +494,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, /* * We check the complete FIFO. We programmed just one entry but in case * something went wrong we left empty handed (-EAGAIN previously) and - * then the value apeared somehow in the FIFO we would have two entries. + * then the value appeared somehow in the FIFO we would have two entries. * Therefore we read every item and keep only the latest version of the * requested channel. */ @@ -740,12 +740,12 @@ MODULE_DEVICE_TABLE(of, ti_adc_dt_ids); static struct platform_driver tiadc_driver = { .driver = { - .name = "TI-am335x-adc", - .pm = pm_sleep_ptr(&tiadc_pm_ops), + .name = "TI-am335x-adc", + .pm = pm_sleep_ptr(&tiadc_pm_ops), .of_match_table = ti_adc_dt_ids, }, - .probe = tiadc_probe, - .remove_new = tiadc_remove, + .probe = tiadc_probe, + .remove = tiadc_remove, }; module_platform_driver(tiadc_driver); diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c index 0253064fadec844bf59af43189313fb5e7e5eb3a..0ea51ddeaa0a0a9bc22caa75b5001584993bfc73 100644 --- a/drivers/iio/adc/twl4030-madc.c +++ b/drivers/iio/adc/twl4030-madc.c @@ -248,7 +248,7 @@ static const struct s16_fract twl4030_divider_ratios[16] = { {15, 100}, /* CHANNEL 11 */ {1, 4}, /* CHANNEL 12 */ {1, 1}, /* CHANNEL 13 Reserved channels */ - {1, 1}, /* CHANNEL 14 Reseved channels */ + {1, 1}, /* CHANNEL 14 Reserved channels */ {5, 11}, /* CHANNEL 15 */ }; @@ -914,7 +914,7 @@ MODULE_DEVICE_TABLE(of, twl_madc_of_match); static struct platform_driver twl4030_madc_driver = { .probe = twl4030_madc_probe, - .remove_new = twl4030_madc_remove, + .remove = twl4030_madc_remove, .driver = { .name = "twl4030_madc", .of_match_table = twl_madc_of_match, diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c index 6a3db2bce460903dd6f242820055022b090fa1f6..ef7430e6877dcd160a644a4a72bd1e79fdb42be0 100644 --- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -1003,7 +1003,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(twl6030_gpadc_pm_ops, twl6030_gpadc_suspend, static struct platform_driver twl6030_gpadc_driver = { .probe = twl6030_gpadc_probe, - .remove_new = twl6030_gpadc_remove, + .remove = twl6030_gpadc_remove, .driver = { .name = DRIVER_NAME, .pm = pm_sleep_ptr(&twl6030_gpadc_pm_ops), diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 5afd2feb8c3ddcea1b66ef02acbc967338d94508..4d83c12975c53a82b5f47fb62b2c377aed0beebb 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -972,7 +972,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(vf610_adc_pm_ops, vf610_adc_suspend, static struct platform_driver vf610_adc_driver = { .probe = vf610_adc_probe, - .remove_new = vf610_adc_remove, + .remove = vf610_adc_remove, .driver = { .name = DRIVER_NAME, .of_match_table = vf610_adc_match, diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c index ebc583b07e0c00bd08c3219f595edd8df26a8378..76dd0343f5f76a6b1a8882e41d6a7f333c3a36e4 100644 --- a/drivers/iio/adc/xilinx-ams.c +++ b/drivers/iio/adc/xilinx-ams.c @@ -905,7 +905,7 @@ static int ams_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct ams *ams = iio_priv(indio_dev); unsigned int alarm; diff --git a/drivers/iio/adc/xilinx-xadc-events.c b/drivers/iio/adc/xilinx-xadc-events.c index 1bd375fb10e085276edb95ae5ce6d6a987821460..c188d3dcab48fea007ac065397bb17f952ca09db 100644 --- a/drivers/iio/adc/xilinx-xadc-events.c +++ b/drivers/iio/adc/xilinx-xadc-events.c @@ -121,7 +121,7 @@ int xadc_read_event_config(struct iio_dev *indio_dev, int xadc_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { unsigned int alarm = xadc_get_alarm_mask(chan); struct xadc *xadc = iio_priv(indio_dev); @@ -220,7 +220,7 @@ int xadc_write_event_value(struct iio_dev *indio_dev, /* * Since we store the hysteresis as relative (to the threshold) * value, but the hardware expects an absolute value we need to - * recalcualte this value whenever the hysteresis or the + * recalculate this value whenever the hysteresis or the * threshold changes. */ if (xadc->threshold[offset] < xadc->temp_hysteresis) diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h index 3036f4d613ff5d44018c098781576d3f71fd5b49..b4d9d468311723fa79cfd7f10781f788dbf9c9db 100644 --- a/drivers/iio/adc/xilinx-xadc.h +++ b/drivers/iio/adc/xilinx-xadc.h @@ -25,7 +25,7 @@ int xadc_read_event_config(struct iio_dev *indio_dev, enum iio_event_direction dir); int xadc_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state); + enum iio_event_direction dir, bool state); int xadc_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, enum iio_event_info info, diff --git a/drivers/iio/addac/ad74115.c b/drivers/iio/addac/ad74115.c index 3ee0dd5537c168724d6fc143411abacc8d830f16..a7e480f2472db972536de3d77d4aabefb8353027 100644 --- a/drivers/iio/addac/ad74115.c +++ b/drivers/iio/addac/ad74115.c @@ -191,7 +191,7 @@ enum ad74115_gpio_mode { }; struct ad74115_channels { - struct iio_chan_spec *channels; + const struct iio_chan_spec *channels; unsigned int num_channels; }; @@ -1295,46 +1295,46 @@ static const struct iio_info ad74115_info = { _AD74115_ADC_CHANNEL(_type, index, BIT(IIO_CHAN_INFO_SCALE) \ | BIT(IIO_CHAN_INFO_OFFSET)) -static struct iio_chan_spec ad74115_voltage_input_channels[] = { +static const struct iio_chan_spec ad74115_voltage_input_channels[] = { AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), }; -static struct iio_chan_spec ad74115_voltage_output_channels[] = { +static const struct iio_chan_spec ad74115_voltage_output_channels[] = { AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_MAIN), AD74115_ADC_CHANNEL(IIO_CURRENT, AD74115_ADC_CH_CONV1), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), }; -static struct iio_chan_spec ad74115_current_input_channels[] = { +static const struct iio_chan_spec ad74115_current_input_channels[] = { AD74115_ADC_CHANNEL(IIO_CURRENT, AD74115_ADC_CH_CONV1), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), }; -static struct iio_chan_spec ad74115_current_output_channels[] = { +static const struct iio_chan_spec ad74115_current_output_channels[] = { AD74115_DAC_CHANNEL(IIO_CURRENT, AD74115_DAC_CH_MAIN), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), }; -static struct iio_chan_spec ad74115_2_wire_resistance_input_channels[] = { +static const struct iio_chan_spec ad74115_2_wire_resistance_input_channels[] = { _AD74115_ADC_CHANNEL(IIO_RESISTANCE, AD74115_ADC_CH_CONV1, BIT(IIO_CHAN_INFO_PROCESSED)), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), }; -static struct iio_chan_spec ad74115_3_4_wire_resistance_input_channels[] = { +static const struct iio_chan_spec ad74115_3_4_wire_resistance_input_channels[] = { AD74115_ADC_CHANNEL(IIO_RESISTANCE, AD74115_ADC_CH_CONV1), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), }; -static struct iio_chan_spec ad74115_digital_input_logic_channels[] = { +static const struct iio_chan_spec ad74115_digital_input_logic_channels[] = { AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_COMPARATOR), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV2), }; -static struct iio_chan_spec ad74115_digital_input_loop_channels[] = { +static const struct iio_chan_spec ad74115_digital_input_loop_channels[] = { AD74115_DAC_CHANNEL(IIO_CURRENT, AD74115_DAC_CH_MAIN), AD74115_DAC_CHANNEL(IIO_VOLTAGE, AD74115_DAC_CH_COMPARATOR), AD74115_ADC_CHANNEL(IIO_VOLTAGE, AD74115_ADC_CH_CONV1), diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 69c586525d2158e918d2feb6308eabd57c6bf689..daea2bde7acf95211d705bfc6a86f754c82642e0 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -6,9 +6,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -45,8 +47,8 @@ struct ad74413r_channel_config { }; struct ad74413r_channels { - struct iio_chan_spec *channels; - unsigned int num_channels; + const struct iio_chan_spec *channels; + unsigned int num_channels; }; struct ad74413r_state { @@ -59,7 +61,7 @@ struct ad74413r_state { unsigned int num_gpo_gpios; unsigned int num_comparator_gpios; u32 sense_resistor_ohms; - + int refin_reg_uv; /* * Synchronize consecutive operations when doing a one-shot * conversion and when updating the ADC samples SPI message. @@ -68,11 +70,9 @@ struct ad74413r_state { const struct ad74413r_chip_info *chip_info; struct spi_device *spi; - struct regulator *refin_reg; struct regmap *regmap; struct device *dev; struct iio_trigger *trig; - struct gpio_desc *reset_gpio; size_t adc_active_channels; struct spi_message adc_samples_msg; @@ -407,12 +407,16 @@ static int ad74413r_gpio_set_comp_config(struct gpio_chip *chip, static int ad74413r_reset(struct ad74413r_state *st) { + struct gpio_desc *reset_gpio; int ret; - if (st->reset_gpio) { - gpiod_set_value_cansleep(st->reset_gpio, 1); + reset_gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(reset_gpio)) + return PTR_ERR(reset_gpio); + + if (reset_gpio) { fsleep(50); - gpiod_set_value_cansleep(st->reset_gpio, 0); + gpiod_set_value_cansleep(reset_gpio, 0); return 0; } @@ -660,7 +664,7 @@ static int ad74413r_get_output_voltage_scale(struct ad74413r_state *st, static int ad74413r_get_output_current_scale(struct ad74413r_state *st, int *val, int *val2) { - *val = regulator_get_voltage(st->refin_reg); + *val = st->refin_reg_uv; *val2 = st->sense_resistor_ohms * AD74413R_DAC_CODE_MAX * 1000; return IIO_VAL_FRACTIONAL; @@ -861,19 +865,12 @@ static int ad74413r_get_single_adc_result(struct iio_dev *indio_dev, unsigned int channel, int *val) { struct ad74413r_state *st = iio_priv(indio_dev); - int ret; - - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; - - mutex_lock(&st->lock); - ret = _ad74413r_get_single_adc_result(st, channel, val); - mutex_unlock(&st->lock); - - iio_device_release_direct_mode(indio_dev); - return ret; + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + guard(mutex)(&st->lock); + return _ad74413r_get_single_adc_result(st, channel, val); + } + unreachable(); } static void ad74413r_adc_to_resistance_result(int adc_result, int *val) @@ -895,7 +892,7 @@ static int ad74413r_update_scan_mode(struct iio_dev *indio_dev, unsigned int channel; int ret = -EINVAL; - mutex_lock(&st->lock); + guard(mutex)(&st->lock); spi_message_init(&st->adc_samples_msg); st->adc_active_channels = 0; @@ -903,11 +900,11 @@ static int ad74413r_update_scan_mode(struct iio_dev *indio_dev, for_each_clear_bit(channel, active_scan_mask, AD74413R_CHANNEL_MAX) { ret = ad74413r_set_adc_channel_enable(st, channel, false); if (ret) - goto out; + return ret; } if (*active_scan_mask == 0) - goto out; + return ret; /* * The read select register is used to select which register's value @@ -925,7 +922,7 @@ static int ad74413r_update_scan_mode(struct iio_dev *indio_dev, for_each_set_bit(channel, active_scan_mask, AD74413R_CHANNEL_MAX) { ret = ad74413r_set_adc_channel_enable(st, channel, true); if (ret) - goto out; + return ret; st->adc_active_channels++; @@ -956,11 +953,7 @@ static int ad74413r_update_scan_mode(struct iio_dev *indio_dev, xfer->cs_change = 0; spi_message_add_tail(xfer, &st->adc_samples_msg); - -out: - mutex_unlock(&st->lock); - - return ret; + return 0; } static int ad74413r_buffer_postenable(struct iio_dev *indio_dev) @@ -1138,34 +1131,34 @@ static const struct iio_info ad74413r_info = { AD74413R_ADC_CHANNEL(IIO_CURRENT, BIT(IIO_CHAN_INFO_SCALE) \ | BIT(IIO_CHAN_INFO_OFFSET)) -static struct iio_chan_spec ad74413r_voltage_output_channels[] = { +static const struct iio_chan_spec ad74413r_voltage_output_channels[] = { AD74413R_DAC_CHANNEL(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_SCALE)), AD74413R_ADC_CURRENT_CHANNEL, }; -static struct iio_chan_spec ad74413r_current_output_channels[] = { +static const struct iio_chan_spec ad74413r_current_output_channels[] = { AD74413R_DAC_CHANNEL(IIO_CURRENT, BIT(IIO_CHAN_INFO_SCALE)), AD74413R_ADC_VOLTAGE_CHANNEL, }; -static struct iio_chan_spec ad74413r_voltage_input_channels[] = { +static const struct iio_chan_spec ad74413r_voltage_input_channels[] = { AD74413R_ADC_VOLTAGE_CHANNEL, }; -static struct iio_chan_spec ad74413r_current_input_channels[] = { +static const struct iio_chan_spec ad74413r_current_input_channels[] = { AD74413R_ADC_CURRENT_CHANNEL, }; -static struct iio_chan_spec ad74413r_current_input_loop_channels[] = { +static const struct iio_chan_spec ad74413r_current_input_loop_channels[] = { AD74413R_DAC_CHANNEL(IIO_CURRENT, BIT(IIO_CHAN_INFO_SCALE)), AD74413R_ADC_CURRENT_CHANNEL, }; -static struct iio_chan_spec ad74413r_resistance_input_channels[] = { +static const struct iio_chan_spec ad74413r_resistance_input_channels[] = { AD74413R_ADC_CHANNEL(IIO_RESISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)), }; -static struct iio_chan_spec ad74413r_digital_input_channels[] = { +static const struct iio_chan_spec ad74413r_digital_input_channels[] = { AD74413R_ADC_VOLTAGE_CHANNEL, }; @@ -1270,7 +1263,8 @@ static int ad74413r_setup_channels(struct iio_dev *indio_dev) { struct ad74413r_state *st = iio_priv(indio_dev); struct ad74413r_channel_config *config; - struct iio_chan_spec *channels, *chans; + const struct iio_chan_spec *chans; + struct iio_chan_spec *channels; unsigned int i, num_chans, chan_i; int ret; @@ -1346,11 +1340,6 @@ static int ad74413r_setup_gpios(struct ad74413r_state *st) return 0; } -static void ad74413r_regulator_disable(void *regulator) -{ - regulator_disable(regulator); -} - static int ad74413r_probe(struct spi_device *spi) { struct ad74413r_state *st; @@ -1369,7 +1358,10 @@ static int ad74413r_probe(struct spi_device *spi) if (!st->chip_info) return -EINVAL; - mutex_init(&st->lock); + ret = devm_mutex_init(st->dev, &st->lock); + if (ret) + return ret; + init_completion(&st->adc_data_completion); st->regmap = devm_regmap_init(st->dev, NULL, st, @@ -1377,23 +1369,11 @@ static int ad74413r_probe(struct spi_device *spi) if (IS_ERR(st->regmap)) return PTR_ERR(st->regmap); - st->reset_gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(st->reset_gpio)) - return PTR_ERR(st->reset_gpio); - - st->refin_reg = devm_regulator_get(st->dev, "refin"); - if (IS_ERR(st->refin_reg)) - return dev_err_probe(st->dev, PTR_ERR(st->refin_reg), - "Failed to get refin regulator\n"); - - ret = regulator_enable(st->refin_reg); - if (ret) - return ret; - - ret = devm_add_action_or_reset(st->dev, ad74413r_regulator_disable, - st->refin_reg); - if (ret) - return ret; + ret = devm_regulator_get_enable_read_voltage(st->dev, "refin"); + if (ret < 0) + return dev_err_probe(st->dev, ret, + "Failed to get refin regulator voltage\n"); + st->refin_reg_uv = ret; st->sense_resistor_ohms = 100000000; device_property_read_u32(st->dev, "shunt-resistor-micro-ohms", diff --git a/drivers/iio/addac/stx104.c b/drivers/iio/addac/stx104.c index 6946a65512ca29ca0f89ef499873c6a50ee82202..7bdf2cb9417657331e47a1dfb610ebbb28b6f0c1 100644 --- a/drivers/iio/addac/stx104.c +++ b/drivers/iio/addac/stx104.c @@ -520,4 +520,4 @@ module_isa_driver(stx104_driver, num_stx104); MODULE_AUTHOR("William Breathitt Gray "); MODULE_DESCRIPTION("Apex Embedded Systems STX104 IIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(I8254); +MODULE_IMPORT_NS("I8254"); diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c index 56e5913ab82d1c045c9ca27012008a4495502cbf..b6a46036d5eadfcb9487d2eaaab1eb68d820096a 100644 --- a/drivers/iio/afe/iio-rescale.c +++ b/drivers/iio/afe/iio-rescale.c @@ -107,7 +107,7 @@ int rescale_process_scale(struct rescale *rescale, int scale_type, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_NS_GPL(rescale_process_scale, IIO_RESCALE); +EXPORT_SYMBOL_NS_GPL(rescale_process_scale, "IIO_RESCALE"); int rescale_process_offset(struct rescale *rescale, int scale_type, int scale, int scale2, int schan_off, @@ -141,7 +141,7 @@ int rescale_process_offset(struct rescale *rescale, int scale_type, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_NS_GPL(rescale_process_offset, IIO_RESCALE); +EXPORT_SYMBOL_NS_GPL(rescale_process_offset, "IIO_RESCALE"); static int rescale_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c index dbde1443d6ede552fdf1fe0915686735c971f898..7ea784304ffb8d3a743b1f1058f6665abe855904 100644 --- a/drivers/iio/buffer/industrialio-buffer-dma.c +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -248,7 +248,7 @@ void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) iio_dma_buffer_queue_wake(queue); dma_fence_end_signalling(cookie); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_block_done, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_block_done, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_block_list_abort() - Indicate that a list block has been @@ -287,7 +287,7 @@ void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, iio_dma_buffer_queue_wake(queue); dma_fence_end_signalling(cookie); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_block_list_abort, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_block_list_abort, "IIO_DMA_BUFFER"); static bool iio_dma_block_reusable(struct iio_dma_buffer_block *block) { @@ -420,7 +420,7 @@ out_unlock: return ret; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_request_update, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_request_update, "IIO_DMA_BUFFER"); static void iio_dma_buffer_fileio_free(struct iio_dma_buffer_queue *queue) { @@ -506,7 +506,7 @@ int iio_dma_buffer_enable(struct iio_buffer *buffer, return 0; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_enable, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_enable, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_disable() - Disable DMA buffer @@ -530,7 +530,7 @@ int iio_dma_buffer_disable(struct iio_buffer *buffer, return 0; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_disable, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_disable, "IIO_DMA_BUFFER"); static void iio_dma_buffer_enqueue(struct iio_dma_buffer_queue *queue, struct iio_dma_buffer_block *block) @@ -636,7 +636,7 @@ int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, { return iio_dma_buffer_io(buffer, n, user_buffer, false); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_read, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_read, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_write() - DMA buffer write callback @@ -653,7 +653,7 @@ int iio_dma_buffer_write(struct iio_buffer *buffer, size_t n, return iio_dma_buffer_io(buffer, n, (__force __user char *)user_buffer, true); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_write, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_write, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_usage() - DMA buffer data_available and @@ -696,7 +696,7 @@ size_t iio_dma_buffer_usage(struct iio_buffer *buf) return data_available; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_usage, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_usage, "IIO_DMA_BUFFER"); struct iio_dma_buffer_block * iio_dma_buffer_attach_dmabuf(struct iio_buffer *buffer, @@ -723,7 +723,7 @@ iio_dma_buffer_attach_dmabuf(struct iio_buffer *buffer, return block; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_attach_dmabuf, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_attach_dmabuf, "IIO_DMA_BUFFER"); void iio_dma_buffer_detach_dmabuf(struct iio_buffer *buffer, struct iio_dma_buffer_block *block) @@ -731,7 +731,7 @@ void iio_dma_buffer_detach_dmabuf(struct iio_buffer *buffer, block->state = IIO_BLOCK_STATE_DEAD; iio_buffer_block_put_atomic(block); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_detach_dmabuf, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_detach_dmabuf, "IIO_DMA_BUFFER"); static int iio_dma_can_enqueue_block(struct iio_dma_buffer_block *block) { @@ -784,7 +784,7 @@ out_end_signalling: return ret; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_enqueue_dmabuf, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_enqueue_dmabuf, "IIO_DMA_BUFFER"); void iio_dma_buffer_lock_queue(struct iio_buffer *buffer) { @@ -792,7 +792,7 @@ void iio_dma_buffer_lock_queue(struct iio_buffer *buffer) mutex_lock(&queue->lock); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_lock_queue, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_lock_queue, "IIO_DMA_BUFFER"); void iio_dma_buffer_unlock_queue(struct iio_buffer *buffer) { @@ -800,7 +800,7 @@ void iio_dma_buffer_unlock_queue(struct iio_buffer *buffer) mutex_unlock(&queue->lock); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_unlock_queue, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_unlock_queue, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_set_bytes_per_datum() - DMA buffer set_bytes_per_datum callback @@ -816,7 +816,7 @@ int iio_dma_buffer_set_bytes_per_datum(struct iio_buffer *buffer, size_t bpd) return 0; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_set_bytes_per_datum, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_set_bytes_per_datum, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_set_length - DMA buffer set_length callback @@ -836,7 +836,7 @@ int iio_dma_buffer_set_length(struct iio_buffer *buffer, unsigned int length) return 0; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_set_length, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_set_length, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_init() - Initialize DMA buffer queue @@ -864,7 +864,7 @@ int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, return 0; } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_init, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_init, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_exit() - Cleanup DMA buffer queue @@ -882,7 +882,7 @@ void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue) mutex_unlock(&queue->lock); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_exit, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_exit, "IIO_DMA_BUFFER"); /** * iio_dma_buffer_release() - Release final buffer resources @@ -896,7 +896,7 @@ void iio_dma_buffer_release(struct iio_dma_buffer_queue *queue) { mutex_destroy(&queue->lock); } -EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_release, IIO_DMA_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_release, "IIO_DMA_BUFFER"); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("DMA buffer for the IIO framework"); diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 19af1caf14cd34e04f8cd851abe9a6fcc1aabfa0..d2e1529ad8fd5e651a8c954466cbf105d08e8100 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -286,7 +286,7 @@ void iio_dmaengine_buffer_free(struct iio_buffer *buffer) iio_buffer_put(buffer); } -EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_free, IIO_DMAENGINE_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_free, "IIO_DMAENGINE_BUFFER"); struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, @@ -312,7 +312,7 @@ struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev, return buffer; } -EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_setup_ext, IIO_DMAENGINE_BUFFER); +EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_setup_ext, "IIO_DMAENGINE_BUFFER"); static void __devm_iio_dmaengine_buffer_free(void *buffer) { @@ -345,9 +345,9 @@ int devm_iio_dmaengine_buffer_setup_ext(struct device *dev, return devm_add_action_or_reset(dev, __devm_iio_dmaengine_buffer_free, buffer); } -EXPORT_SYMBOL_NS_GPL(devm_iio_dmaengine_buffer_setup_ext, IIO_DMAENGINE_BUFFER); +EXPORT_SYMBOL_NS_GPL(devm_iio_dmaengine_buffer_setup_ext, "IIO_DMAENGINE_BUFFER"); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("DMA buffer for the IIO framework"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_DMA_BUFFER); +MODULE_IMPORT_NS("IIO_DMA_BUFFER"); diff --git a/drivers/iio/cdc/ad7150.c b/drivers/iio/cdc/ad7150.c index 4c03b9e834b88d6eafabb63999a1ed2c1720118f..e64a41bae32c67e43fc9021c186170c4bacb2ae3 100644 --- a/drivers/iio/cdc/ad7150.c +++ b/drivers/iio/cdc/ad7150.c @@ -232,7 +232,7 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, static int ad7150_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct ad7150_chip_info *chip = iio_priv(indio_dev); int ret = 0; diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig index 6c87223f58d9031c8c6f660d6f6a72c93534b4b5..330fe0af946f753a45ef02a79355645119bd1e8a 100644 --- a/drivers/iio/chemical/Kconfig +++ b/drivers/iio/chemical/Kconfig @@ -50,6 +50,8 @@ config BME680 select REGMAP select BME680_I2C if I2C select BME680_SPI if SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Bosch Sensortec BME680 sensor with temperature, pressure, humidity and gas sensing capability. diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h index b2c547ac8d34995266621487914f2cb41b25e6d5..00ab89b3138b4fe072e829d652abffebaa06b741 100644 --- a/drivers/iio/chemical/bme680.h +++ b/drivers/iio/chemical/bme680.h @@ -2,6 +2,8 @@ #ifndef BME680_H_ #define BME680_H_ +#include + #define BME680_REG_CHIP_ID 0xD0 #define BME680_CHIP_ID_VAL 0x61 #define BME680_REG_SOFT_RESET 0xE0 @@ -25,8 +27,6 @@ #define BME680_OSRS_TEMP_MASK GENMASK(7, 5) #define BME680_OSRS_PRESS_MASK GENMASK(4, 2) #define BME680_MODE_MASK GENMASK(1, 0) -#define BME680_MODE_FORCED 1 -#define BME680_MODE_SLEEP 0 #define BME680_REG_CONFIG 0x75 #define BME680_FILTER_MASK GENMASK(4, 2) @@ -42,6 +42,7 @@ #define BME680_RHRANGE_MASK GENMASK(5, 4) #define BME680_REG_RES_HEAT_VAL 0x00 #define BME680_RSERROR_MASK GENMASK(7, 4) +#define BME680_REG_IDAC_HEAT_0 0x50 #define BME680_REG_RES_HEAT_0 0x5A #define BME680_REG_GAS_WAIT_0 0x64 #define BME680_ADC_GAS_RES GENMASK(15, 6) @@ -63,7 +64,11 @@ #define BME680_MEAS_TRIM_MASK GENMASK(24, 4) -#define BME680_STARTUP_TIME_US 5000 +/* Datasheet Section 1.1, Table 1 */ +#define BME680_STARTUP_TIME_US 2000 + +#define BME680_NUM_CHANNELS 4 +#define BME680_NUM_BULK_READ_REGS 15 /* Calibration Parameters */ #define BME680_T2_LSB_REG 0x8A diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c index 0b96534c6867a67096329e63ea13a6822646aaf0..d12270409c8ad2ed6d88475b8d3af7722b33c754 100644 --- a/drivers/iio/chemical/bme680_core.c +++ b/drivers/iio/chemical/bme680_core.c @@ -16,8 +16,11 @@ #include #include +#include #include #include +#include +#include #include @@ -95,6 +98,19 @@ struct bme680_calib { s8 range_sw_err; }; +/* values of CTRL_MEAS register */ +enum bme680_op_mode { + BME680_MODE_SLEEP = 0, + BME680_MODE_FORCED = 1, +}; + +enum bme680_scan { + BME680_TEMP, + BME680_PRESS, + BME680_HUMID, + BME680_GAS, +}; + struct bme680_data { struct regmap *regmap; struct bme680_calib bme680; @@ -102,11 +118,17 @@ struct bme680_data { u8 oversampling_temp; u8 oversampling_press; u8 oversampling_humid; + u8 preheat_curr_mA; u16 heater_dur; u16 heater_temp; + struct { + s32 chan[4]; + aligned_s64 ts; + } scan; + union { - u8 buf[3]; + u8 buf[BME680_NUM_BULK_READ_REGS]; unsigned int check; __be16 be16; u8 bme680_cal_buf_1[BME680_CALIB_RANGE_1_LEN]; @@ -133,27 +155,71 @@ const struct regmap_config bme680_regmap_config = { .volatile_table = &bme680_volatile_table, .cache_type = REGCACHE_RBTREE, }; -EXPORT_SYMBOL_NS(bme680_regmap_config, IIO_BME680); +EXPORT_SYMBOL_NS(bme680_regmap_config, "IIO_BME680"); static const struct iio_chan_spec bme680_channels[] = { { .type = IIO_TEMP, + /* PROCESSED maintained for ABI backwards compatibility */ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_CPU, + }, }, { .type = IIO_PRESSURE, + /* PROCESSED maintained for ABI backwards compatibility */ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .scan_index = 1, + .scan_type = { + .sign = 'u', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_CPU, + }, }, { .type = IIO_HUMIDITYRELATIVE, + /* PROCESSED maintained for ABI backwards compatibility */ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .scan_index = 2, + .scan_type = { + .sign = 'u', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_CPU, + }, }, { .type = IIO_RESISTANCE, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .scan_index = 3, + .scan_type = { + .sign = 'u', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_CPU, + }, + }, + IIO_CHAN_SOFT_TIMESTAMP(4), + { + .type = IIO_CURRENT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .output = 1, + .scan_index = -1, }, }; @@ -224,7 +290,7 @@ static int bme680_read_calib(struct bme680_data *data, calib->res_heat_val = data->bme680_cal_buf_3[RES_HEAT_VAL]; calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK, - data->bme680_cal_buf_3[RES_HEAT_RANGE]); + data->bme680_cal_buf_3[RES_HEAT_RANGE]); calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK, data->bme680_cal_buf_3[RANGE_SW_ERR]); @@ -438,19 +504,19 @@ static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc, u32 calc_gas_res; /* Look up table for the possible gas range values */ - static const u32 lookupTable[16] = {2147483647u, 2147483647u, - 2147483647u, 2147483647u, 2147483647u, - 2126008810u, 2147483647u, 2130303777u, - 2147483647u, 2147483647u, 2143188679u, - 2136746228u, 2147483647u, 2126008810u, - 2147483647u, 2147483647u}; - - var1 = ((1340 + (5 * (s64) calib->range_sw_err)) * - ((s64) lookupTable[gas_range])) >> 16; + static const u32 lookup_table[16] = { + 2147483647u, 2147483647u, 2147483647u, 2147483647u, + 2147483647u, 2126008810u, 2147483647u, 2130303777u, + 2147483647u, 2147483647u, 2143188679u, 2136746228u, + 2147483647u, 2126008810u, 2147483647u, 2147483647u + }; + + var1 = ((1340LL + (5 * calib->range_sw_err)) * + (lookup_table[gas_range])) >> 16; var2 = ((gas_res_adc << 15) - 16777216) + var1; var3 = ((125000 << (15 - gas_range)) * var1) >> 9; var3 += (var2 >> 1); - calc_gas_res = div64_s64(var3, (s64) var2); + calc_gas_res = div64_s64(var3, (s64)var2); return calc_gas_res; } @@ -468,7 +534,7 @@ static u8 bme680_calc_heater_res(struct bme680_data *data, u16 temp) if (temp > 400) /* Cap temperature */ temp = 400; - var1 = (((s32) BME680_AMB_TEMP * calib->par_gh3) / 1000) * 256; + var1 = (((s32)BME680_AMB_TEMP * calib->par_gh3) / 1000) * 256; var2 = (calib->par_gh1 + 784) * (((((calib->par_gh2 + 154009) * temp * 5) / 100) + 3276800) / 10); @@ -502,23 +568,22 @@ static u8 bme680_calc_heater_dur(u16 dur) return durval; } -static int bme680_set_mode(struct bme680_data *data, bool mode) +/* Taken from datasheet, section 5.3.3 */ +static u8 bme680_calc_heater_preheat_current(u8 curr) +{ + return 8 * curr - 1; +} + +static int bme680_set_mode(struct bme680_data *data, enum bme680_op_mode mode) { struct device *dev = regmap_get_device(data->regmap); int ret; - if (mode) { - ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS, - BME680_MODE_MASK, BME680_MODE_FORCED); - if (ret < 0) - dev_err(dev, "failed to set forced mode\n"); - - } else { - ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS, - BME680_MODE_MASK, BME680_MODE_SLEEP); - if (ret < 0) - dev_err(dev, "failed to set sleep mode\n"); - + ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS, + BME680_MODE_MASK, mode); + if (ret < 0) { + dev_err(dev, "failed to set ctrl_meas register\n"); + return ret; } return ret; @@ -546,7 +611,7 @@ static int bme680_wait_for_eoc(struct bme680_data *data) data->oversampling_humid) * 1936) + (477 * 4) + (477 * 5) + 1000 + (data->heater_dur * 1000); - usleep_range(wait_eoc_us, wait_eoc_us + 100); + fsleep(wait_eoc_us); ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &data->check); if (ret) { @@ -571,9 +636,8 @@ static int bme680_chip_config(struct bme680_data *data) int ret; u8 osrs; - osrs = FIELD_PREP( - BME680_OSRS_HUMIDITY_MASK, - bme680_oversampling_to_reg(data->oversampling_humid)); + osrs = FIELD_PREP(BME680_OSRS_HUMIDITY_MASK, + bme680_oversampling_to_reg(data->oversampling_humid)); /* * Highly recommended to set oversampling of humidity before * temperature/pressure oversampling. @@ -587,8 +651,7 @@ static int bme680_chip_config(struct bme680_data *data) /* IIR filter settings */ ret = regmap_update_bits(data->regmap, BME680_REG_CONFIG, - BME680_FILTER_MASK, - BME680_FILTER_COEFF_VAL); + BME680_FILTER_MASK, BME680_FILTER_COEFF_VAL); if (ret < 0) { dev_err(dev, "failed to write config register\n"); return ret; @@ -609,14 +672,27 @@ static int bme680_chip_config(struct bme680_data *data) return 0; } +static int bme680_preheat_curr_config(struct bme680_data *data, u8 val) +{ + struct device *dev = regmap_get_device(data->regmap); + u8 heatr_curr; + int ret; + + heatr_curr = bme680_calc_heater_preheat_current(val); + ret = regmap_write(data->regmap, BME680_REG_IDAC_HEAT_0, heatr_curr); + if (ret < 0) + dev_err(dev, "failed to write idac_heat_0 register\n"); + + return ret; +} + static int bme680_gas_config(struct bme680_data *data) { struct device *dev = regmap_get_device(data->regmap); int ret; u8 heatr_res, heatr_dur; - /* Go to sleep */ - ret = bme680_set_mode(data, false); + ret = bme680_set_mode(data, BME680_MODE_SLEEP); if (ret < 0) return ret; @@ -638,6 +714,10 @@ static int bme680_gas_config(struct bme680_data *data) return ret; } + ret = bme680_preheat_curr_config(data, data->preheat_curr_mA); + if (ret) + return ret; + /* Enable the gas sensor and select heater profile set-point 0 */ ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_GAS_1, BME680_RUN_GAS_MASK | BME680_NB_CONV_MASK, @@ -649,23 +729,20 @@ static int bme680_gas_config(struct bme680_data *data) return ret; } -static int bme680_read_temp(struct bme680_data *data, int *val) +static int bme680_read_temp(struct bme680_data *data, s16 *comp_temp) { int ret; u32 adc_temp; - s16 comp_temp; ret = bme680_read_temp_adc(data, &adc_temp); if (ret) return ret; - comp_temp = bme680_compensate_temp(data, adc_temp); - *val = comp_temp * 10; /* Centidegrees to millidegrees */ - return IIO_VAL_INT; + *comp_temp = bme680_compensate_temp(data, adc_temp); + return 0; } -static int bme680_read_press(struct bme680_data *data, - int *val, int *val2) +static int bme680_read_press(struct bme680_data *data, u32 *comp_press) { int ret; u32 adc_press; @@ -679,16 +756,14 @@ static int bme680_read_press(struct bme680_data *data, if (ret) return ret; - *val = bme680_compensate_press(data, adc_press, t_fine); - *val2 = 1000; - return IIO_VAL_FRACTIONAL; + *comp_press = bme680_compensate_press(data, adc_press, t_fine); + return 0; } -static int bme680_read_humid(struct bme680_data *data, - int *val, int *val2) +static int bme680_read_humid(struct bme680_data *data, u32 *comp_humidity) { int ret; - u32 adc_humidity, comp_humidity; + u32 adc_humidity; s32 t_fine; ret = bme680_get_t_fine(data, &t_fine); @@ -699,15 +774,11 @@ static int bme680_read_humid(struct bme680_data *data, if (ret) return ret; - comp_humidity = bme680_compensate_humid(data, adc_humidity, t_fine); - - *val = comp_humidity; - *val2 = 1000; - return IIO_VAL_FRACTIONAL; + *comp_humidity = bme680_compensate_humid(data, adc_humidity, t_fine); + return 0; } -static int bme680_read_gas(struct bme680_data *data, - int *val) +static int bme680_read_gas(struct bme680_data *data, int *comp_gas_res) { struct device *dev = regmap_get_device(data->regmap); int ret; @@ -742,9 +813,8 @@ static int bme680_read_gas(struct bme680_data *data, } gas_range = FIELD_GET(BME680_GAS_RANGE_MASK, gas_regs_val); - - *val = bme680_compensate_gas(data, adc_gas_res, gas_range); - return IIO_VAL_INT; + *comp_gas_res = bme680_compensate_gas(data, adc_gas_res, gas_range); + return 0; } static int bme680_read_raw(struct iio_dev *indio_dev, @@ -752,12 +822,12 @@ static int bme680_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct bme680_data *data = iio_priv(indio_dev); - int ret; + int chan_val, ret; + s16 temp_chan_val; guard(mutex)(&data->lock); - /* set forced mode to trigger measurement */ - ret = bme680_set_mode(data, true); + ret = bme680_set_mode(data, BME680_MODE_FORCED); if (ret < 0) return ret; @@ -769,13 +839,77 @@ static int bme680_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_TEMP: - return bme680_read_temp(data, val); + ret = bme680_read_temp(data, &temp_chan_val); + if (ret) + return ret; + + *val = temp_chan_val * 10; + return IIO_VAL_INT; case IIO_PRESSURE: - return bme680_read_press(data, val, val2); + ret = bme680_read_press(data, &chan_val); + if (ret) + return ret; + + *val = chan_val; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; case IIO_HUMIDITYRELATIVE: - return bme680_read_humid(data, val, val2); + ret = bme680_read_humid(data, &chan_val); + if (ret) + return ret; + + *val = chan_val; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; case IIO_RESISTANCE: - return bme680_read_gas(data, val); + ret = bme680_read_gas(data, &chan_val); + if (ret) + return ret; + + *val = chan_val; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_TEMP: + ret = bme680_read_temp(data, (s16 *)&chan_val); + if (ret) + return ret; + + *val = chan_val; + return IIO_VAL_INT; + case IIO_PRESSURE: + ret = bme680_read_press(data, &chan_val); + if (ret) + return ret; + + *val = chan_val; + return IIO_VAL_INT; + case IIO_HUMIDITYRELATIVE: + ret = bme680_read_humid(data, &chan_val); + if (ret) + return ret; + + *val = chan_val; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_TEMP: + *val = 10; + return IIO_VAL_INT; + case IIO_PRESSURE: + *val = 1; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + case IIO_HUMIDITYRELATIVE: + *val = 1; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; default: return -EINVAL; } @@ -836,6 +970,15 @@ static int bme680_write_raw(struct iio_dev *indio_dev, return bme680_chip_config(data); } + case IIO_CHAN_INFO_PROCESSED: + { + switch (chan->type) { + case IIO_CURRENT: + return bme680_preheat_curr_config(data, (u8)val); + default: + return -EINVAL; + } + } default: return -EINVAL; } @@ -861,6 +1004,86 @@ static const struct iio_info bme680_info = { .attrs = &bme680_attribute_group, }; +static const unsigned long bme680_avail_scan_masks[] = { + BIT(BME680_GAS) | BIT(BME680_HUMID) | BIT(BME680_PRESS) | BIT(BME680_TEMP), + 0 +}; + +static irqreturn_t bme680_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct bme680_data *data = iio_priv(indio_dev); + struct device *dev = regmap_get_device(data->regmap); + u32 adc_temp, adc_press, adc_humid; + u16 adc_gas_res, gas_regs_val; + u8 gas_range; + s32 t_fine; + int ret; + + guard(mutex)(&data->lock); + + ret = bme680_set_mode(data, BME680_MODE_FORCED); + if (ret < 0) + goto out; + + ret = bme680_wait_for_eoc(data); + if (ret) + goto out; + + ret = regmap_bulk_read(data->regmap, BME680_REG_MEAS_STAT_0, + data->buf, sizeof(data->buf)); + if (ret) { + dev_err(dev, "failed to burst read sensor data\n"); + goto out; + } + if (data->buf[0] & BME680_GAS_MEAS_BIT) { + dev_err(dev, "gas measurement incomplete\n"); + goto out; + } + + /* Temperature calculations */ + adc_temp = FIELD_GET(BME680_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[5])); + if (adc_temp == BME680_MEAS_SKIPPED) { + dev_err(dev, "reading temperature skipped\n"); + goto out; + } + data->scan.chan[0] = bme680_compensate_temp(data, adc_temp); + t_fine = bme680_calc_t_fine(data, adc_temp); + + /* Pressure calculations */ + adc_press = FIELD_GET(BME680_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[2])); + if (adc_press == BME680_MEAS_SKIPPED) { + dev_err(dev, "reading pressure skipped\n"); + goto out; + } + data->scan.chan[1] = bme680_compensate_press(data, adc_press, t_fine); + + /* Humidity calculations */ + adc_humid = get_unaligned_be16(&data->buf[8]); + if (adc_humid == BME680_MEAS_SKIPPED) { + dev_err(dev, "reading humidity skipped\n"); + goto out; + } + data->scan.chan[2] = bme680_compensate_humid(data, adc_humid, t_fine); + + /* Gas calculations */ + gas_regs_val = get_unaligned_be16(&data->buf[13]); + adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val); + if ((gas_regs_val & BME680_GAS_STAB_BIT) == 0) { + dev_err(dev, "heater failed to reach the target temperature\n"); + goto out; + } + gas_range = FIELD_GET(BME680_GAS_RANGE_MASK, gas_regs_val); + data->scan.chan[3] = bme680_compensate_gas(data, adc_gas_res, gas_range); + + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + iio_get_time_ns(indio_dev)); +out: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + int bme680_core_probe(struct device *dev, struct regmap *regmap, const char *name) { @@ -879,6 +1102,7 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap, indio_dev->name = name; indio_dev->channels = bme680_channels; indio_dev->num_channels = ARRAY_SIZE(bme680_channels); + indio_dev->available_scan_masks = bme680_avail_scan_masks; indio_dev->info = &bme680_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -888,13 +1112,13 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap, data->oversampling_temp = 8; /* 8X oversampling rate */ data->heater_temp = 320; /* degree Celsius */ data->heater_dur = 150; /* milliseconds */ + data->preheat_curr_mA = 0; - ret = regmap_write(regmap, BME680_REG_SOFT_RESET, - BME680_CMD_SOFTRESET); + ret = regmap_write(regmap, BME680_REG_SOFT_RESET, BME680_CMD_SOFTRESET); if (ret < 0) return dev_err_probe(dev, ret, "Failed to reset chip\n"); - usleep_range(BME680_STARTUP_TIME_US, BME680_STARTUP_TIME_US + 1000); + fsleep(BME680_STARTUP_TIME_US); ret = regmap_read(regmap, BME680_REG_CHIP_ID, &data->check); if (ret < 0) @@ -922,9 +1146,17 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap, return dev_err_probe(dev, ret, "failed to set gas config data\n"); + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + bme680_trigger_handler, + NULL); + if (ret) + return dev_err_probe(dev, ret, + "iio triggered buffer setup failed\n"); + return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(bme680_core_probe, IIO_BME680); +EXPORT_SYMBOL_NS_GPL(bme680_core_probe, "IIO_BME680"); MODULE_AUTHOR("Himanshu Jha "); MODULE_DESCRIPTION("Bosch BME680 Driver"); diff --git a/drivers/iio/chemical/bme680_i2c.c b/drivers/iio/chemical/bme680_i2c.c index 7c4224d75955f74354e549c99e60e5048086ee12..7a949228b4a614a4e4c09553a4e640784cff0e2a 100644 --- a/drivers/iio/chemical/bme680_i2c.c +++ b/drivers/iio/chemical/bme680_i2c.c @@ -60,4 +60,4 @@ module_i2c_driver(bme680_i2c_driver); MODULE_AUTHOR("Himanshu Jha "); MODULE_DESCRIPTION("BME680 I2C driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_BME680); +MODULE_IMPORT_NS("IIO_BME680"); diff --git a/drivers/iio/chemical/bme680_spi.c b/drivers/iio/chemical/bme680_spi.c index 7c54bd17d4b06dd352083a481d6c0f5eb8f606ad..3916a51ba68e1712d79ed245432b8b40c80e0a00 100644 --- a/drivers/iio/chemical/bme680_spi.c +++ b/drivers/iio/chemical/bme680_spi.c @@ -163,4 +163,4 @@ module_spi_driver(bme680_spi_driver); MODULE_AUTHOR("Himanshu Jha "); MODULE_DESCRIPTION("Bosch BME680 SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_BME680); +MODULE_IMPORT_NS("IIO_BME680"); diff --git a/drivers/iio/chemical/ens160_core.c b/drivers/iio/chemical/ens160_core.c index c1aa3b498d3b88ed5e8c82076670fd2d2c2bda0b..4a89cd5894d9f14c7a6d093ac13e12bc434440fa 100644 --- a/drivers/iio/chemical/ens160_core.c +++ b/drivers/iio/chemical/ens160_core.c @@ -360,7 +360,7 @@ int devm_ens160_core_probe(struct device *dev, struct regmap *regmap, int irq, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS(devm_ens160_core_probe, IIO_ENS160); +EXPORT_SYMBOL_NS(devm_ens160_core_probe, "IIO_ENS160"); MODULE_AUTHOR("Gustavo Silva "); MODULE_DESCRIPTION("ScioSense ENS160 driver"); diff --git a/drivers/iio/chemical/ens160_i2c.c b/drivers/iio/chemical/ens160_i2c.c index 57a189a4c257c4cd57b9f3356ae71dc0e976bcf0..aa0dfe639245011867f37f5c369d7c49805f9914 100644 --- a/drivers/iio/chemical/ens160_i2c.c +++ b/drivers/iio/chemical/ens160_i2c.c @@ -59,4 +59,4 @@ module_i2c_driver(ens160_i2c_driver); MODULE_AUTHOR("Gustavo Silva "); MODULE_DESCRIPTION("ScioSense ENS160 I2C driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ENS160); +MODULE_IMPORT_NS("IIO_ENS160"); diff --git a/drivers/iio/chemical/ens160_spi.c b/drivers/iio/chemical/ens160_spi.c index 10e4f5fd0f45cb2c86fddba8fc05424678bca001..a674c0e1bf4b493c7ce11cd355f074a9464d1ed2 100644 --- a/drivers/iio/chemical/ens160_spi.c +++ b/drivers/iio/chemical/ens160_spi.c @@ -58,4 +58,4 @@ module_spi_driver(ens160_spi_driver); MODULE_AUTHOR("Gustavo Silva "); MODULE_DESCRIPTION("ScioSense ENS160 SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ENS160); +MODULE_IMPORT_NS("IIO_ENS160"); diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c index 7be5a45cf71ae8ac71b8cb10b4e1e912b00040e8..ac3080929f0b1c472c0339b151f9d866df13753a 100644 --- a/drivers/iio/chemical/scd30_core.c +++ b/drivers/iio/chemical/scd30_core.c @@ -747,7 +747,7 @@ int scd30_probe(struct device *dev, int irq, const char *name, void *priv, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS(scd30_probe, IIO_SCD30); +EXPORT_SYMBOL_NS(scd30_probe, "IIO_SCD30"); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor core driver"); diff --git a/drivers/iio/chemical/scd30_i2c.c b/drivers/iio/chemical/scd30_i2c.c index b31dfaf52df9c5cb5476efd19c0563d9daa39422..436df9c61a719f600bfc4a57856c3b668d82f477 100644 --- a/drivers/iio/chemical/scd30_i2c.c +++ b/drivers/iio/chemical/scd30_i2c.c @@ -137,4 +137,4 @@ module_i2c_driver(scd30_i2c_driver); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_SCD30); +MODULE_IMPORT_NS("IIO_SCD30"); diff --git a/drivers/iio/chemical/scd30_serial.c b/drivers/iio/chemical/scd30_serial.c index 55044f07d5a37137cbe4c011bcebc1d35e4428bf..e8b453aae859eef015ab56ae009451da024b4e62 100644 --- a/drivers/iio/chemical/scd30_serial.c +++ b/drivers/iio/chemical/scd30_serial.c @@ -261,4 +261,4 @@ module_serdev_device_driver(scd30_serdev_driver); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor serial driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_SCD30); +MODULE_IMPORT_NS("IIO_SCD30"); diff --git a/drivers/iio/chemical/sps30.c b/drivers/iio/chemical/sps30.c index 814ce0aad1cccd6e06d1993c2779e803ec90090b..6f4f2ba2c09d5e691df13bc11ca9e3a910d98dc8 100644 --- a/drivers/iio/chemical/sps30.c +++ b/drivers/iio/chemical/sps30.c @@ -372,7 +372,7 @@ int sps30_probe(struct device *dev, const char *name, void *priv, const struct s return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(sps30_probe, IIO_SPS30); +EXPORT_SYMBOL_NS_GPL(sps30_probe, "IIO_SPS30"); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor driver"); diff --git a/drivers/iio/chemical/sps30_i2c.c b/drivers/iio/chemical/sps30_i2c.c index 1b21b6bcd0e7a4e3c8741a3e9d7f93073274a66c..f692c089d17b40f77f29729248eb20a3666ff170 100644 --- a/drivers/iio/chemical/sps30_i2c.c +++ b/drivers/iio/chemical/sps30_i2c.c @@ -256,4 +256,4 @@ module_i2c_driver(sps30_i2c_driver); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_SPS30); +MODULE_IMPORT_NS("IIO_SPS30"); diff --git a/drivers/iio/chemical/sps30_serial.c b/drivers/iio/chemical/sps30_serial.c index a6dfbe28c914c7f6e8a3adacf14019447272e21e..008bc88590f37017a0da53a34c14bbc8ec78383c 100644 --- a/drivers/iio/chemical/sps30_serial.c +++ b/drivers/iio/chemical/sps30_serial.c @@ -429,4 +429,4 @@ module_serdev_device_driver(sps30_serial_driver); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor serial driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_SPS30); +MODULE_IMPORT_NS("IIO_SPS30"); diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c index 9b279937a24e0d5a3ace1c042b63e0669e301ecc..ad1882f608c0a28a828fb65ffcabba9628fa2f63 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c @@ -169,7 +169,7 @@ s32 hid_sensor_read_poll_value(struct hid_sensor_common *st) return value; } -EXPORT_SYMBOL_NS(hid_sensor_read_poll_value, IIO_HID_ATTRIBUTES); +EXPORT_SYMBOL_NS(hid_sensor_read_poll_value, "IIO_HID_ATTRIBUTES"); int hid_sensor_read_samp_freq_value(struct hid_sensor_common *st, int *val1, int *val2) @@ -196,7 +196,7 @@ int hid_sensor_read_samp_freq_value(struct hid_sensor_common *st, return IIO_VAL_INT_PLUS_MICRO; } -EXPORT_SYMBOL_NS(hid_sensor_read_samp_freq_value, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_read_samp_freq_value, "IIO_HID"); int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st, int val1, int val2) @@ -231,7 +231,7 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st, return 0; } -EXPORT_SYMBOL_NS(hid_sensor_write_samp_freq_value, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_write_samp_freq_value, "IIO_HID"); int hid_sensor_read_raw_hyst_value(struct hid_sensor_common *st, int *val1, int *val2) @@ -254,7 +254,7 @@ int hid_sensor_read_raw_hyst_value(struct hid_sensor_common *st, return IIO_VAL_INT_PLUS_MICRO; } -EXPORT_SYMBOL_NS(hid_sensor_read_raw_hyst_value, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_read_raw_hyst_value, "IIO_HID"); int hid_sensor_read_raw_hyst_rel_value(struct hid_sensor_common *st, int *val1, int *val2) @@ -276,7 +276,7 @@ int hid_sensor_read_raw_hyst_rel_value(struct hid_sensor_common *st, int *val1, return IIO_VAL_INT_PLUS_MICRO; } -EXPORT_SYMBOL_NS(hid_sensor_read_raw_hyst_rel_value, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_read_raw_hyst_rel_value, "IIO_HID"); int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st, @@ -308,7 +308,7 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st, return 0; } -EXPORT_SYMBOL_NS(hid_sensor_write_raw_hyst_value, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_write_raw_hyst_value, "IIO_HID"); int hid_sensor_write_raw_hyst_rel_value(struct hid_sensor_common *st, int val1, int val2) @@ -339,7 +339,7 @@ int hid_sensor_write_raw_hyst_rel_value(struct hid_sensor_common *st, return 0; } -EXPORT_SYMBOL_NS(hid_sensor_write_raw_hyst_rel_value, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_write_raw_hyst_rel_value, "IIO_HID"); /* * This fuction applies the unit exponent to the scale. @@ -423,14 +423,14 @@ int hid_sensor_format_scale(u32 usage_id, return IIO_VAL_INT_PLUS_NANO; } -EXPORT_SYMBOL_NS(hid_sensor_format_scale, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_format_scale, "IIO_HID"); int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st, int64_t raw_value) { return st->timestamp_ns_scale * raw_value; } -EXPORT_SYMBOL_NS(hid_sensor_convert_timestamp, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_convert_timestamp, "IIO_HID"); static int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev, @@ -477,7 +477,7 @@ int hid_sensor_get_report_latency(struct hid_sensor_common *st) return value; } -EXPORT_SYMBOL_NS(hid_sensor_get_report_latency, IIO_HID_ATTRIBUTES); +EXPORT_SYMBOL_NS(hid_sensor_get_report_latency, "IIO_HID_ATTRIBUTES"); int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency_ms) { @@ -485,13 +485,13 @@ int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency_ms) st->report_latency.index, sizeof(latency_ms), &latency_ms); } -EXPORT_SYMBOL_NS(hid_sensor_set_report_latency, IIO_HID_ATTRIBUTES); +EXPORT_SYMBOL_NS(hid_sensor_set_report_latency, "IIO_HID_ATTRIBUTES"); bool hid_sensor_batch_mode_supported(struct hid_sensor_common *st) { return st->report_latency.index > 0 && st->report_latency.report_id > 0; } -EXPORT_SYMBOL_NS(hid_sensor_batch_mode_supported, IIO_HID_ATTRIBUTES); +EXPORT_SYMBOL_NS(hid_sensor_batch_mode_supported, "IIO_HID_ATTRIBUTES"); int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, u32 usage_id, @@ -583,7 +583,7 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, return 0; } -EXPORT_SYMBOL_NS(hid_sensor_parse_common_attributes, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_parse_common_attributes, "IIO_HID"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_DESCRIPTION("HID Sensor common attribute processing"); diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index abb09fefc792c54e8e0cd53ab34c05aaf253bbd8..48193937275b30cc7ca80188736afb14592c3040 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -147,7 +147,7 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) return 0; } -EXPORT_SYMBOL_NS(hid_sensor_power_state, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_power_state, "IIO_HID"); int hid_sensor_power_state(struct hid_sensor_common *st, bool state) { @@ -222,7 +222,7 @@ void hid_sensor_remove_trigger(struct iio_dev *indio_dev, iio_trigger_free(attrb->trigger); iio_triggered_buffer_cleanup(indio_dev); } -EXPORT_SYMBOL_NS(hid_sensor_remove_trigger, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_remove_trigger, "IIO_HID"); static const struct iio_trigger_ops hid_sensor_trigger_ops = { .set_trigger_state = &hid_sensor_data_rdy_trigger_set_state, @@ -289,7 +289,7 @@ error_triggered_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); return ret; } -EXPORT_SYMBOL_NS(hid_sensor_setup_trigger, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_setup_trigger, "IIO_HID"); static int __maybe_unused hid_sensor_suspend(struct device *dev) { @@ -319,9 +319,9 @@ const struct dev_pm_ops hid_sensor_pm_ops = { SET_RUNTIME_PM_OPS(hid_sensor_suspend, hid_sensor_runtime_resume, NULL) }; -EXPORT_SYMBOL_NS(hid_sensor_pm_ops, IIO_HID); +EXPORT_SYMBOL_NS(hid_sensor_pm_ops, "IIO_HID"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_DESCRIPTION("HID Sensor trigger processing"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID_ATTRIBUTES); +MODULE_IMPORT_NS("IIO_HID_ATTRIBUTES"); diff --git a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c index f44458c380d92823ce2e7e5f78ca877ea4c06118..c081b5caa475f38228b6cec4f759275bd77ca736 100644 --- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c +++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c @@ -55,7 +55,7 @@ void inv_sensors_timestamp_init(struct inv_sensors_timestamp *ts, /* use theoretical value for chip period */ inv_update_acc(&ts->chip_period, chip->clock_period); } -EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_init, IIO_INV_SENSORS_TIMESTAMP); +EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_init, "IIO_INV_SENSORS_TIMESTAMP"); int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts, uint32_t period, bool fifo) @@ -70,9 +70,13 @@ int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts, if (mult != ts->mult) ts->new_mult = mult; + /* When FIFO is off, directly apply the new ODR */ + if (!fifo) + inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); + return 0; } -EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP); +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) { @@ -162,7 +166,7 @@ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts, if (valid) inv_align_timestamp_it(ts); } -EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_interrupt, IIO_INV_SENSORS_TIMESTAMP); +EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_interrupt, "IIO_INV_SENSORS_TIMESTAMP"); void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts, uint32_t fifo_period, size_t fifo_nb, @@ -194,7 +198,7 @@ void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts, ts->timestamp = ts->it.up - interval; } } -EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_apply_odr, IIO_INV_SENSORS_TIMESTAMP); +EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_apply_odr, "IIO_INV_SENSORS_TIMESTAMP"); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense sensors timestamp module"); diff --git a/drivers/iio/common/ms_sensors/ms_sensors_i2c.c b/drivers/iio/common/ms_sensors/ms_sensors_i2c.c index 9c9bc77003c7ff33c66a2f080f9b940a6921d025..588470863681830a2a210a6c491b8a2a844d4460 100644 --- a/drivers/iio/common/ms_sensors/ms_sensors_i2c.c +++ b/drivers/iio/common/ms_sensors/ms_sensors_i2c.c @@ -58,7 +58,7 @@ int ms_sensors_reset(void *cli, u8 cmd, unsigned int delay) return 0; } -EXPORT_SYMBOL_NS(ms_sensors_reset, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_reset, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_read_prom_word() - PROM word read function @@ -84,7 +84,7 @@ int ms_sensors_read_prom_word(void *cli, int cmd, u16 *word) return 0; } -EXPORT_SYMBOL_NS(ms_sensors_read_prom_word, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_read_prom_word, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_convert_and_read() - ADC conversion & read function @@ -130,7 +130,7 @@ err: dev_err(&client->dev, "Unable to make sensor adc conversion\n"); return ret; } -EXPORT_SYMBOL_NS(ms_sensors_convert_and_read, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_convert_and_read, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_crc_valid() - CRC check function @@ -248,7 +248,7 @@ int ms_sensors_read_serial(struct i2c_client *client, u64 *sn) return 0; } -EXPORT_SYMBOL_NS(ms_sensors_read_serial, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_read_serial, "IIO_MEAS_SPEC_SENSORS"); static int ms_sensors_read_config_reg(struct i2c_client *client, u8 *config_reg) @@ -299,7 +299,7 @@ ssize_t ms_sensors_write_resolution(struct ms_ht_dev *dev_data, MS_SENSORS_CONFIG_REG_WRITE, config_reg); } -EXPORT_SYMBOL_NS(ms_sensors_write_resolution, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_write_resolution, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_show_battery_low() - Show device battery low indicator @@ -326,7 +326,7 @@ ssize_t ms_sensors_show_battery_low(struct ms_ht_dev *dev_data, return sysfs_emit(buf, "%d\n", (config_reg & 0x40) >> 6); } -EXPORT_SYMBOL_NS(ms_sensors_show_battery_low, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_show_battery_low, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_show_heater() - Show device heater @@ -353,7 +353,7 @@ ssize_t ms_sensors_show_heater(struct ms_ht_dev *dev_data, return sysfs_emit(buf, "%d\n", (config_reg & 0x4) >> 2); } -EXPORT_SYMBOL_NS(ms_sensors_show_heater, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_show_heater, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_write_heater() - Write device heater @@ -401,7 +401,7 @@ ssize_t ms_sensors_write_heater(struct ms_ht_dev *dev_data, return len; } -EXPORT_SYMBOL_NS(ms_sensors_write_heater, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_write_heater, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_ht_read_temperature() - Read temperature @@ -442,7 +442,7 @@ int ms_sensors_ht_read_temperature(struct ms_ht_dev *dev_data, return 0; } -EXPORT_SYMBOL_NS(ms_sensors_ht_read_temperature, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_ht_read_temperature, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_ht_read_humidity() - Read humidity @@ -485,7 +485,7 @@ int ms_sensors_ht_read_humidity(struct ms_ht_dev *dev_data, return 0; } -EXPORT_SYMBOL_NS(ms_sensors_ht_read_humidity, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_ht_read_humidity, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_tp_crc4() - Calculate PROM CRC for @@ -602,7 +602,7 @@ int ms_sensors_tp_read_prom(struct ms_tp_dev *dev_data) return 0; } -EXPORT_SYMBOL_NS(ms_sensors_tp_read_prom, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_tp_read_prom, "IIO_MEAS_SPEC_SENSORS"); /** * ms_sensors_read_temp_and_pressure() - read temp and pressure @@ -688,7 +688,7 @@ int ms_sensors_read_temp_and_pressure(struct ms_tp_dev *dev_data, return 0; } -EXPORT_SYMBOL_NS(ms_sensors_read_temp_and_pressure, IIO_MEAS_SPEC_SENSORS); +EXPORT_SYMBOL_NS(ms_sensors_read_temp_and_pressure, "IIO_MEAS_SPEC_SENSORS"); MODULE_DESCRIPTION("Measurement-Specialties common i2c driver"); MODULE_AUTHOR("William Markezana "); diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c index e64d242145e04c7918c1d4f9d7f55ec376af2188..65f8a2b13cfd2a2d65bfae83ebf2135222800f76 100644 --- a/drivers/iio/common/ssp_sensors/ssp_dev.c +++ b/drivers/iio/common/ssp_sensors/ssp_dev.c @@ -205,7 +205,7 @@ u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type type) { return data->delay_buf[type]; } -EXPORT_SYMBOL_NS(ssp_get_sensor_delay, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_get_sensor_delay, "IIO_SSP_SENSORS"); /** * ssp_enable_sensor() - enables data acquisition for sensor @@ -267,7 +267,7 @@ int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type, derror: return ret; } -EXPORT_SYMBOL_NS(ssp_enable_sensor, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_enable_sensor, "IIO_SSP_SENSORS"); /** * ssp_change_delay() - changes data acquisition for sensor @@ -298,7 +298,7 @@ int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type, return 0; } -EXPORT_SYMBOL_NS(ssp_change_delay, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_change_delay, "IIO_SSP_SENSORS"); /** * ssp_disable_sensor() - disables sensor @@ -335,7 +335,7 @@ int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type) return 0; } -EXPORT_SYMBOL_NS(ssp_disable_sensor, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_disable_sensor, "IIO_SSP_SENSORS"); static irqreturn_t ssp_irq_thread_fn(int irq, void *dev_id) { @@ -478,7 +478,7 @@ void ssp_register_consumer(struct iio_dev *indio_dev, enum ssp_sensor_type type) data->sensor_devs[type] = indio_dev; } -EXPORT_SYMBOL_NS(ssp_register_consumer, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_register_consumer, "IIO_SSP_SENSORS"); static int ssp_probe(struct spi_device *spi) { diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c index 88b8b56bfa51b654a5036b6a251d3963f75871c0..caa404edd9d045859a4f39bed5b8d70715770430 100644 --- a/drivers/iio/common/ssp_sensors/ssp_iio.c +++ b/drivers/iio/common/ssp_sensors/ssp_iio.c @@ -32,7 +32,7 @@ int ssp_common_buffer_postenable(struct iio_dev *indio_dev) return ssp_enable_sensor(data, spd->type, ssp_get_sensor_delay(data, spd->type)); } -EXPORT_SYMBOL_NS(ssp_common_buffer_postenable, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_common_buffer_postenable, "IIO_SSP_SENSORS"); /** * ssp_common_buffer_postdisable() - generic postdisable callback for ssp buffer @@ -55,7 +55,7 @@ int ssp_common_buffer_postdisable(struct iio_dev *indio_dev) return ret; } -EXPORT_SYMBOL_NS(ssp_common_buffer_postdisable, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_common_buffer_postdisable, "IIO_SSP_SENSORS"); /** * ssp_common_process_data() - Common process data callback for ssp sensors @@ -91,9 +91,9 @@ int ssp_common_process_data(struct iio_dev *indio_dev, void *buf, return iio_push_to_buffers_with_timestamp(indio_dev, spd->buffer, calculated_time); } -EXPORT_SYMBOL_NS(ssp_common_process_data, IIO_SSP_SENSORS); +EXPORT_SYMBOL_NS(ssp_common_process_data, "IIO_SSP_SENSORS"); MODULE_AUTHOR("Karol Wrona "); MODULE_DESCRIPTION("Samsung sensorhub commons"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_SSP_SENSORS); +MODULE_IMPORT_NS("IIO_SSP_SENSORS"); diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index e2f108ca949ccd8d1474c4155f31dcd2077f97a9..57f087c2216f928c0d85cd6c90a22fd93a75c671 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c @@ -76,4 +76,4 @@ st_sensors_get_buffer_element_error: return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(st_sensors_trigger_handler, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_trigger_handler, "IIO_ST_SENSORS"); diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 1b4287991d00ae71785b472936af1d574f343242..e4f5a7ff7e74c95882e772fed510538be76fa462 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -46,7 +46,7 @@ int st_sensors_debugfs_reg_access(struct iio_dev *indio_dev, return 0; } -EXPORT_SYMBOL_NS(st_sensors_debugfs_reg_access, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_debugfs_reg_access, "IIO_ST_SENSORS"); static int st_sensors_match_odr(struct st_sensor_settings *sensor_settings, unsigned int odr, struct st_sensor_odr_avl *odr_out) @@ -110,7 +110,7 @@ unlock_mutex: return err; } -EXPORT_SYMBOL_NS(st_sensors_set_odr, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_set_odr, "IIO_ST_SENSORS"); static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings, unsigned int fs, int *index_fs_avl) @@ -203,7 +203,7 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) set_enable_error: return err; } -EXPORT_SYMBOL_NS(st_sensors_set_enable, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_set_enable, "IIO_ST_SENSORS"); int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable) { @@ -217,7 +217,7 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable) axis_enable); return err; } -EXPORT_SYMBOL_NS(st_sensors_set_axis_enable, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_set_axis_enable, "IIO_ST_SENSORS"); int st_sensors_power_enable(struct iio_dev *indio_dev) @@ -236,7 +236,7 @@ int st_sensors_power_enable(struct iio_dev *indio_dev) return 0; } -EXPORT_SYMBOL_NS(st_sensors_power_enable, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_power_enable, "IIO_ST_SENSORS"); static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, struct st_sensors_platform_data *pdata) @@ -331,7 +331,7 @@ void st_sensors_dev_name_probe(struct device *dev, char *name, int len) /* The name from the match takes precedence if present */ strscpy(name, match, len); } -EXPORT_SYMBOL_NS(st_sensors_dev_name_probe, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_dev_name_probe, "IIO_ST_SENSORS"); int st_sensors_init_sensor(struct iio_dev *indio_dev, struct st_sensors_platform_data *pdata) @@ -418,7 +418,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, return err; } -EXPORT_SYMBOL_NS(st_sensors_init_sensor, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_init_sensor, "IIO_ST_SENSORS"); int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) { @@ -467,7 +467,7 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) st_accel_set_dataready_irq_error: return err; } -EXPORT_SYMBOL_NS(st_sensors_set_dataready_irq, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_set_dataready_irq, "IIO_ST_SENSORS"); int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale) { @@ -490,7 +490,7 @@ int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale) st_sensors_match_scale_error: return err; } -EXPORT_SYMBOL_NS(st_sensors_set_fullscale_by_gain, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_set_fullscale_by_gain, "IIO_ST_SENSORS"); static int st_sensors_read_axis_data(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, int *data) @@ -555,7 +555,7 @@ out: return err; } -EXPORT_SYMBOL_NS(st_sensors_read_info_raw, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_read_info_raw, "IIO_ST_SENSORS"); /* * st_sensors_get_settings_index() - get index of the sensor settings for a @@ -582,7 +582,7 @@ int st_sensors_get_settings_index(const char *name, return -ENODEV; } -EXPORT_SYMBOL_NS(st_sensors_get_settings_index, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_get_settings_index, "IIO_ST_SENSORS"); /* * st_sensors_verify_id() - verify sensor ID (WhoAmI) is matching with the @@ -614,7 +614,7 @@ int st_sensors_verify_id(struct iio_dev *indio_dev) return 0; } -EXPORT_SYMBOL_NS(st_sensors_verify_id, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_verify_id, "IIO_ST_SENSORS"); ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, struct device_attribute *attr, char *buf) @@ -634,7 +634,7 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, return len; } -EXPORT_SYMBOL_NS(st_sensors_sysfs_sampling_frequency_avail, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_sysfs_sampling_frequency_avail, "IIO_ST_SENSORS"); ssize_t st_sensors_sysfs_scale_avail(struct device *dev, struct device_attribute *attr, char *buf) @@ -656,7 +656,7 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev, return len; } -EXPORT_SYMBOL_NS(st_sensors_sysfs_scale_avail, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_sysfs_scale_avail, "IIO_ST_SENSORS"); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics ST-sensors core"); diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c index ee95082c741062d6d7dfe9071ddab3e96d0b0fd5..7156302fe99772e98992fdb8023d77a3b460bcaa 100644 --- a/drivers/iio/common/st_sensors/st_sensors_i2c.c +++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c @@ -61,7 +61,7 @@ int st_sensors_i2c_configure(struct iio_dev *indio_dev, return 0; } -EXPORT_SYMBOL_NS(st_sensors_i2c_configure, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_i2c_configure, "IIO_ST_SENSORS"); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics ST-sensors i2c driver"); diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c index 63e302c3fbaa1bc229c3bbfa4c65411a087f71b0..0da27013943d9fc3b326b7274104a454719358c6 100644 --- a/drivers/iio/common/st_sensors/st_sensors_spi.c +++ b/drivers/iio/common/st_sensors/st_sensors_spi.c @@ -113,7 +113,7 @@ int st_sensors_spi_configure(struct iio_dev *indio_dev, return 0; } -EXPORT_SYMBOL_NS(st_sensors_spi_configure, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_spi_configure, "IIO_ST_SENSORS"); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics ST-sensors spi driver"); diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c index a0df9250a69ff6a18461ffee4dcbbb3d2f3d35c3..9d4bf822a15dfcdd6c2835f6b9d7698cd3cb0b08 100644 --- a/drivers/iio/common/st_sensors/st_sensors_trigger.c +++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c @@ -134,11 +134,11 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev, iio_trigger_set_drvdata(sdata->trig, indio_dev); sdata->trig->ops = trigger_ops; - irq_trig = irqd_get_trigger_type(irq_get_irq_data(sdata->irq)); /* * If the IRQ is triggered on falling edge, we need to mark the * interrupt as active low, if the hardware supports this. */ + irq_trig = irq_get_trigger_type(sdata->irq); switch(irq_trig) { case IRQF_TRIGGER_FALLING: case IRQF_TRIGGER_LOW: @@ -227,7 +227,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev, return 0; } -EXPORT_SYMBOL_NS(st_sensors_allocate_trigger, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_allocate_trigger, "IIO_ST_SENSORS"); int st_sensors_validate_device(struct iio_trigger *trig, struct iio_dev *indio_dev) @@ -239,4 +239,4 @@ int st_sensors_validate_device(struct iio_trigger *trig, return 0; } -EXPORT_SYMBOL_NS(st_sensors_validate_device, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_sensors_validate_device, "IIO_ST_SENSORS"); diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 9f5d5ebb8653743292632a449064f884df80f5e3..5d01ba4edbf30c929f49466e4993224a7d00a5f0 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -6,9 +6,28 @@ menu "Digital to analog converters" +config AD3552R_HS + tristate "Analog Devices AD3552R DAC High Speed driver" + select AD3552R_LIB + select IIO_BACKEND + help + Say yes here to build support for Analog Devices AD3552R + Digital to Analog Converter High Speed driver. + + The driver requires the assistance of an IP core to operate, + since data is streamed into target device via DMA, sent over a + QSPI + DDR (Double Data Rate) bus. + + To compile this driver as a module, choose M here: the + module will be called ad3552r-hs. + +config AD3552R_LIB + tristate + config AD3552R tristate "Analog Devices AD3552R DAC driver" depends on SPI_MASTER + select AD3552R_LIB select IIO_BUFFER select IIO_TRIGGERED_BUFFER help @@ -306,6 +325,19 @@ config AD7303 To compile this driver as module choose M here: the module will be called ad7303. +config AD8460 + tristate "Analog Devices AD8460 DAC driver" + depends on SPI + select REGMAP_SPI + select IIO_BUFFER + select IIO_BUFFER_DMAENGINE + help + Say yes here to build support for Analog Devices AD8460 Digital to + Analog Converters (DAC). + + To compile this driver as a module choose M here: the module will be called + ad8460. + config AD8801 tristate "Analog Devices AD8801/AD8803 DAC driver" depends on SPI_MASTER diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 2cf148f16306db9e6e436575e1bca9b33eeba614..414c152be779d8935a677a38cfe5a04e5dba5af6 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -4,6 +4,8 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_AD3552R_HS) += ad3552r-hs.o +obj-$(CONFIG_AD3552R_LIB) += ad3552r-common.o obj-$(CONFIG_AD3552R) += ad3552r.o obj-$(CONFIG_AD5360) += ad5360.o obj-$(CONFIG_AD5380) += ad5380.o @@ -28,6 +30,7 @@ obj-$(CONFIG_AD5686_SPI) += ad5686-spi.o obj-$(CONFIG_AD5696_I2C) += ad5696-i2c.o obj-$(CONFIG_AD7293) += ad7293.o obj-$(CONFIG_AD7303) += ad7303.o +obj-$(CONFIG_AD8460) += ad8460.o obj-$(CONFIG_AD8801) += ad8801.o obj-$(CONFIG_AD9739A) += ad9739a.o obj-$(CONFIG_ADI_AXI_DAC) += adi-axi-dac.o diff --git a/drivers/iio/dac/ad3552r-common.c b/drivers/iio/dac/ad3552r-common.c new file mode 100644 index 0000000000000000000000000000000000000000..0f495df2e5ce77adfe04a05cebb22232674ed6cf --- /dev/null +++ b/drivers/iio/dac/ad3552r-common.c @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (c) 2010-2024 Analog Devices Inc. +// Copyright (c) 2024 Baylibre, SAS + +#include +#include +#include +#include +#include + +#include "ad3552r.h" + +const s32 ad3552r_ch_ranges[AD3552R_MAX_RANGES][2] = { + [AD3552R_CH_OUTPUT_RANGE_0__2P5V] = { 0, 2500 }, + [AD3552R_CH_OUTPUT_RANGE_0__5V] = { 0, 5000 }, + [AD3552R_CH_OUTPUT_RANGE_0__10V] = { 0, 10000 }, + [AD3552R_CH_OUTPUT_RANGE_NEG_5__5V] = { -5000, 5000 }, + [AD3552R_CH_OUTPUT_RANGE_NEG_10__10V] = { -10000, 10000 } +}; +EXPORT_SYMBOL_NS_GPL(ad3552r_ch_ranges, "IIO_AD3552R"); + +const s32 ad3542r_ch_ranges[AD3542R_MAX_RANGES][2] = { + [AD3542R_CH_OUTPUT_RANGE_0__2P5V] = { 0, 2500 }, + [AD3542R_CH_OUTPUT_RANGE_0__3V] = { 0, 3000 }, + [AD3542R_CH_OUTPUT_RANGE_0__5V] = { 0, 5000 }, + [AD3542R_CH_OUTPUT_RANGE_0__10V] = { 0, 10000 }, + [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = { -2500, 7500 }, + [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = { -5000, 5000 } +}; +EXPORT_SYMBOL_NS_GPL(ad3542r_ch_ranges, "IIO_AD3552R"); + +/* Gain * AD3552R_GAIN_SCALE */ +static const s32 gains_scaling_table[] = { + [AD3552R_CH_GAIN_SCALING_1] = 1000, + [AD3552R_CH_GAIN_SCALING_0_5] = 500, + [AD3552R_CH_GAIN_SCALING_0_25] = 250, + [AD3552R_CH_GAIN_SCALING_0_125] = 125 +}; + +u16 ad3552r_calc_custom_gain(u8 p, u8 n, s16 goffs) +{ + return FIELD_PREP(AD3552R_MASK_CH_RANGE_OVERRIDE, 1) | + FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_P, p) | + FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_N, n) | + FIELD_PREP(AD3552R_MASK_CH_OFFSET_BIT_8, abs(goffs)) | + FIELD_PREP(AD3552R_MASK_CH_OFFSET_POLARITY, goffs < 0); +} +EXPORT_SYMBOL_NS_GPL(ad3552r_calc_custom_gain, "IIO_AD3552R"); + +static void ad3552r_get_custom_range(struct ad3552r_ch_data *ch_data, + s32 *v_min, s32 *v_max) +{ + s64 vref, tmp, common, offset, gn, gp; + /* + * From datasheet formula (In Volts): + * Vmin = 2.5 + [(GainN + Offset / 1024) * 2.5 * Rfb * 1.03] + * Vmax = 2.5 - [(GainP + Offset / 1024) * 2.5 * Rfb * 1.03] + * Calculus are converted to milivolts + */ + vref = 2500; + /* 2.5 * 1.03 * 1000 (To mV) */ + common = 2575 * ch_data->rfb; + offset = ch_data->gain_offset; + + gn = gains_scaling_table[ch_data->n]; + tmp = (1024 * gn + AD3552R_GAIN_SCALE * offset) * common; + tmp = div_s64(tmp, 1024 * AD3552R_GAIN_SCALE); + *v_max = vref + tmp; + + gp = gains_scaling_table[ch_data->p]; + tmp = (1024 * gp - AD3552R_GAIN_SCALE * offset) * common; + tmp = div_s64(tmp, 1024 * AD3552R_GAIN_SCALE); + *v_min = vref - tmp; +} + +void ad3552r_calc_gain_and_offset(struct ad3552r_ch_data *ch_data, + const struct ad3552r_model_data *model_data) +{ + s32 idx, v_max, v_min, span, rem; + s64 tmp; + + if (ch_data->range_override) { + ad3552r_get_custom_range(ch_data, &v_min, &v_max); + } else { + /* Normal range */ + idx = ch_data->range; + v_min = model_data->ranges_table[idx][0]; + v_max = model_data->ranges_table[idx][1]; + } + + /* + * From datasheet formula: + * Vout = Span * (D / 65536) + Vmin + * Converted to scale and offset: + * Scale = Span / 65536 + * Offset = 65536 * Vmin / Span + * + * Reminders are in micros in order to be printed as + * IIO_VAL_INT_PLUS_MICRO + */ + span = v_max - v_min; + ch_data->scale_int = div_s64_rem(span, 65536, &rem); + /* Do operations in microvolts */ + ch_data->scale_dec = DIV_ROUND_CLOSEST((s64)rem * 1000000, 65536); + + ch_data->offset_int = div_s64_rem(v_min * 65536, span, &rem); + tmp = (s64)rem * 1000000; + ch_data->offset_dec = div_s64(tmp, span); +} +EXPORT_SYMBOL_NS_GPL(ad3552r_calc_gain_and_offset, "IIO_AD3552R"); + +int ad3552r_get_ref_voltage(struct device *dev, u32 *val) +{ + int voltage; + int delta = 100000; + + voltage = devm_regulator_get_enable_read_voltage(dev, "vref"); + if (voltage < 0 && voltage != -ENODEV) + return dev_err_probe(dev, voltage, + "Error getting vref voltage\n"); + + if (voltage == -ENODEV) { + if (device_property_read_bool(dev, "adi,vref-out-en")) + *val = AD3552R_INTERNAL_VREF_PIN_2P5V; + else + *val = AD3552R_INTERNAL_VREF_PIN_FLOATING; + + return 0; + } + + if (voltage > 2500000 + delta || voltage < 2500000 - delta) { + dev_warn(dev, "vref-supply must be 2.5V"); + return -EINVAL; + } + + *val = AD3552R_EXTERNAL_VREF_PIN_INPUT; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ad3552r_get_ref_voltage, "IIO_AD3552R"); + +int ad3552r_get_drive_strength(struct device *dev, u32 *val) +{ + int err; + u32 drive_strength; + + err = device_property_read_u32(dev, "adi,sdo-drive-strength", + &drive_strength); + if (err) + return err; + + if (drive_strength > 3) { + dev_err_probe(dev, -EINVAL, + "adi,sdo-drive-strength must be less than 4\n"); + return -EINVAL; + } + + *val = drive_strength; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ad3552r_get_drive_strength, "IIO_AD3552R"); + +int ad3552r_get_custom_gain(struct device *dev, struct fwnode_handle *child, + u8 *gs_p, u8 *gs_n, u16 *rfb, s16 *goffs) +{ + int err; + u32 val; + struct fwnode_handle *gain_child __free(fwnode_handle) = + fwnode_get_named_child_node(child, + "custom-output-range-config"); + + if (!gain_child) + return dev_err_probe(dev, -EINVAL, + "custom-output-range-config mandatory\n"); + + err = fwnode_property_read_u32(gain_child, "adi,gain-scaling-p", &val); + if (err) + return dev_err_probe(dev, err, + "adi,gain-scaling-p mandatory\n"); + *gs_p = val; + + err = fwnode_property_read_u32(gain_child, "adi,gain-scaling-n", &val); + if (err) + return dev_err_probe(dev, err, + "adi,gain-scaling-n property mandatory\n"); + *gs_n = val; + + err = fwnode_property_read_u32(gain_child, "adi,rfb-ohms", &val); + if (err) + return dev_err_probe(dev, err, + "adi,rfb-ohms mandatory\n"); + *rfb = val; + + err = fwnode_property_read_u32(gain_child, "adi,gain-offset", &val); + if (err) + return dev_err_probe(dev, err, + "adi,gain-offset mandatory\n"); + *goffs = val; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ad3552r_get_custom_gain, "IIO_AD3552R"); + +static int ad3552r_find_range(const struct ad3552r_model_data *model_info, + s32 *vals) +{ + int i; + + for (i = 0; i < model_info->num_ranges; i++) + if (vals[0] == model_info->ranges_table[i][0] * 1000 && + vals[1] == model_info->ranges_table[i][1] * 1000) + return i; + + return -EINVAL; +} + +int ad3552r_get_output_range(struct device *dev, + const struct ad3552r_model_data *model_info, + struct fwnode_handle *child, u32 *val) +{ + int ret; + s32 vals[2]; + + /* This property is optional, so returning -ENOENT if missing */ + if (!fwnode_property_present(child, "adi,output-range-microvolt")) + return -ENOENT; + + ret = fwnode_property_read_u32_array(child, + "adi,output-range-microvolt", + vals, 2); + if (ret) + return dev_err_probe(dev, ret, + "invalid adi,output-range-microvolt\n"); + + ret = ad3552r_find_range(model_info, vals); + if (ret < 0) + return dev_err_probe(dev, ret, + "invalid adi,output-range-microvolt value\n"); + + *val = ret; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ad3552r_get_output_range, "IIO_AD3552R"); + +MODULE_DESCRIPTION("ad3552r common functions"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/dac/ad3552r-hs.c b/drivers/iio/dac/ad3552r-hs.c new file mode 100644 index 0000000000000000000000000000000000000000..216c634f3eaf727fe07e123f9a237b2ab59fb324 --- /dev/null +++ b/drivers/iio/dac/ad3552r-hs.c @@ -0,0 +1,529 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Analog Devices AD3552R + * Digital to Analog converter driver, High Speed version + * + * Copyright 2024 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ad3552r.h" +#include "ad3552r-hs.h" + +struct ad3552r_hs_state { + const struct ad3552r_model_data *model_data; + struct gpio_desc *reset_gpio; + struct device *dev; + struct iio_backend *back; + bool single_channel; + struct ad3552r_ch_data ch_data[AD3552R_MAX_CH]; + struct ad3552r_hs_platform_data *data; +}; + +static int ad3552r_qspi_update_reg_bits(struct ad3552r_hs_state *st, + u32 reg, u32 mask, u32 val, + size_t xfer_size) +{ + u32 rval; + int ret; + + ret = st->data->bus_reg_read(st->back, reg, &rval, xfer_size); + if (ret) + return ret; + + rval = (rval & ~mask) | val; + + return st->data->bus_reg_write(st->back, reg, rval, xfer_size); +} + +static int ad3552r_hs_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct ad3552r_hs_state *st = iio_priv(indio_dev); + int ret; + int ch = chan->channel; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + /* + * Using 4 lanes (QSPI), then using 2 as DDR mode is + * considered always on (considering buffering mode always). + */ + *val = DIV_ROUND_CLOSEST(st->data->bus_sample_data_clock_hz * + 4 * 2, chan->scan_type.realbits); + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_RAW: + ret = st->data->bus_reg_read(st->back, + AD3552R_REG_ADDR_CH_DAC_16B(chan->channel), + val, 2); + if (ret) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = st->ch_data[ch].scale_int; + *val2 = st->ch_data[ch].scale_dec; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_OFFSET: + *val = st->ch_data[ch].offset_int; + *val2 = st->ch_data[ch].offset_dec; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int ad3552r_hs_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct ad3552r_hs_state *st = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + return st->data->bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_DAC_16B(chan->channel), + val, 2); + } + unreachable(); + default: + return -EINVAL; + } +} + +static int ad3552r_hs_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad3552r_hs_state *st = iio_priv(indio_dev); + struct iio_backend_data_fmt fmt = { + .type = IIO_BACKEND_DATA_UNSIGNED + }; + int loop_len, val, ret; + + switch (*indio_dev->active_scan_mask) { + case AD3552R_CH0_ACTIVE: + st->single_channel = true; + loop_len = 2; + val = AD3552R_REG_ADDR_CH_DAC_16B(0); + break; + case AD3552R_CH1_ACTIVE: + st->single_channel = true; + loop_len = 2; + val = AD3552R_REG_ADDR_CH_DAC_16B(1); + break; + case AD3552R_CH0_ACTIVE | AD3552R_CH1_ACTIVE: + st->single_channel = false; + loop_len = 4; + val = AD3552R_REG_ADDR_CH_DAC_16B(1); + break; + default: + return -EINVAL; + } + + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_STREAM_MODE, + loop_len, 1); + if (ret) + return ret; + + /* Inform DAC chip to switch into DDR mode */ + ret = ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + AD3552R_MASK_SPI_CONFIG_DDR, 1); + if (ret) + return ret; + + /* Inform DAC IP to go for DDR mode from now on */ + ret = iio_backend_ddr_enable(st->back); + if (ret) { + dev_err(st->dev, "could not set DDR mode, not streaming"); + goto exit_err; + } + + ret = iio_backend_data_transfer_addr(st->back, val); + if (ret) + goto exit_err; + + ret = iio_backend_data_format_set(st->back, 0, &fmt); + if (ret) + goto exit_err; + + ret = iio_backend_data_stream_enable(st->back); + if (ret) + goto exit_err; + + return 0; + +exit_err: + ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + 0, 1); + + iio_backend_ddr_disable(st->back); + + return ret; +} + +static int ad3552r_hs_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad3552r_hs_state *st = iio_priv(indio_dev); + int ret; + + ret = iio_backend_data_stream_disable(st->back); + if (ret) + return ret; + + /* Inform DAC to set in SDR mode */ + ret = ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + 0, 1); + if (ret) + return ret; + + ret = iio_backend_ddr_disable(st->back); + if (ret) + return ret; + + return 0; +} + +static inline int ad3552r_hs_set_output_range(struct ad3552r_hs_state *st, + int ch, unsigned int mode) +{ + int val; + + if (ch == 0) + val = FIELD_PREP(AD3552R_MASK_CH0_RANGE, mode); + else + val = FIELD_PREP(AD3552R_MASK_CH1_RANGE, mode); + + return ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch), + val, 1); +} + +static int ad3552r_hs_reset(struct ad3552r_hs_state *st) +{ + int ret; + + st->reset_gpio = devm_gpiod_get_optional(st->dev, + "reset", GPIOD_OUT_HIGH); + if (IS_ERR(st->reset_gpio)) + return PTR_ERR(st->reset_gpio); + + if (st->reset_gpio) { + fsleep(10); + gpiod_set_value_cansleep(st->reset_gpio, 0); + } else { + ret = ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_A, + AD3552R_MASK_SOFTWARE_RESET, + AD3552R_MASK_SOFTWARE_RESET, 1); + if (ret) + return ret; + } + msleep(100); + + return 0; +} + +static int ad3552r_hs_scratch_pad_test(struct ad3552r_hs_state *st) +{ + int ret, val; + + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + AD3552R_SCRATCH_PAD_TEST_VAL1, 1); + if (ret) + return ret; + + ret = st->data->bus_reg_read(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (ret) + return ret; + + if (val != AD3552R_SCRATCH_PAD_TEST_VAL1) + return dev_err_probe(st->dev, -EIO, + "SCRATCH_PAD_TEST mismatch. Expected 0x%x, Read 0x%x\n", + AD3552R_SCRATCH_PAD_TEST_VAL1, val); + + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + AD3552R_SCRATCH_PAD_TEST_VAL2, 1); + if (ret) + return ret; + + ret = st->data->bus_reg_read(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (ret) + return ret; + + if (val != AD3552R_SCRATCH_PAD_TEST_VAL2) + return dev_err_probe(st->dev, -EIO, + "SCRATCH_PAD_TEST mismatch. Expected 0x%x, Read 0x%x\n", + AD3552R_SCRATCH_PAD_TEST_VAL2, val); + + return 0; +} + +static int ad3552r_hs_setup_custom_gain(struct ad3552r_hs_state *st, + int ch, u16 gain, u16 offset) +{ + int ret; + + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_CH_OFFSET(ch), + offset, 1); + if (ret) + return ret; + + return st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_CH_GAIN(ch), + gain, 1); +} + +static int ad3552r_hs_setup(struct ad3552r_hs_state *st) +{ + u16 id; + u16 gain = 0, offset = 0; + u32 ch, val, range; + int ret; + + ret = ad3552r_hs_reset(st); + if (ret) + return ret; + + ret = iio_backend_ddr_disable(st->back); + if (ret) + return ret; + + ret = ad3552r_hs_scratch_pad_test(st); + if (ret) + return ret; + + ret = st->data->bus_reg_read(st->back, AD3552R_REG_ADDR_PRODUCT_ID_L, + &val, 1); + if (ret) + return ret; + + id = val; + + ret = st->data->bus_reg_read(st->back, AD3552R_REG_ADDR_PRODUCT_ID_H, + &val, 1); + if (ret) + return ret; + + id |= val << 8; + if (id != st->model_data->chip_id) + dev_info(st->dev, "Chip ID error. Expected 0x%x, Read 0x%x\n", + AD3552R_ID, id); + + ret = st->data->bus_reg_write(st->back, + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + 0, 1); + if (ret) + return ret; + + ret = st->data->bus_reg_write(st->back, + AD3552R_REG_ADDR_TRANSFER_REGISTER, + FIELD_PREP(AD3552R_MASK_MULTI_IO_MODE, + AD3552R_QUAD_SPI) | + AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE, 1); + if (ret) + return ret; + + ret = iio_backend_data_source_set(st->back, 0, IIO_BACKEND_EXTERNAL); + if (ret) + return ret; + + ret = iio_backend_data_source_set(st->back, 1, IIO_BACKEND_EXTERNAL); + if (ret) + return ret; + + ret = ad3552r_get_ref_voltage(st->dev, &val); + if (ret < 0) + return ret; + + val = ret; + + ret = ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + AD3552R_MASK_REFERENCE_VOLTAGE_SEL, + val, 1); + if (ret) + return ret; + + ret = ad3552r_get_drive_strength(st->dev, &val); + if (!ret) { + ret = ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SDO_DRIVE_STRENGTH, + val, 1); + if (ret) + return ret; + } + + device_for_each_child_node_scoped(st->dev, child) { + ret = fwnode_property_read_u32(child, "reg", &ch); + if (ret) + return dev_err_probe(st->dev, ret, + "reg property missing\n"); + + ret = ad3552r_get_output_range(st->dev, st->model_data, child, + &range); + if (ret && ret != -ENOENT) + return ret; + if (ret == -ENOENT) { + ret = ad3552r_get_custom_gain(st->dev, child, + &st->ch_data[ch].p, + &st->ch_data[ch].n, + &st->ch_data[ch].rfb, + &st->ch_data[ch].gain_offset); + if (ret) + return ret; + + gain = ad3552r_calc_custom_gain(st->ch_data[ch].p, + st->ch_data[ch].n, + st->ch_data[ch].gain_offset); + offset = abs(st->ch_data[ch].gain_offset); + + st->ch_data[ch].range_override = 1; + + ret = ad3552r_hs_setup_custom_gain(st, ch, gain, + offset); + if (ret) + return ret; + } else { + st->ch_data[ch].range = range; + + ret = ad3552r_hs_set_output_range(st, ch, range); + if (ret) + return ret; + } + + ad3552r_calc_gain_and_offset(&st->ch_data[ch], st->model_data); + } + + return 0; +} + +static const struct iio_buffer_setup_ops ad3552r_hs_buffer_setup_ops = { + .postenable = ad3552r_hs_buffer_postenable, + .predisable = ad3552r_hs_buffer_predisable, +}; + +#define AD3552R_CHANNEL(ch) { \ + .type = IIO_VOLTAGE, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .output = 1, \ + .indexed = 1, \ + .channel = (ch), \ + .scan_index = (ch), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + } \ +} + +static const struct iio_chan_spec ad3552r_hs_channels[] = { + AD3552R_CHANNEL(0), + AD3552R_CHANNEL(1), +}; + +static const struct iio_info ad3552r_hs_info = { + .read_raw = &ad3552r_hs_read_raw, + .write_raw = &ad3552r_hs_write_raw, +}; + +static int ad3552r_hs_probe(struct platform_device *pdev) +{ + struct ad3552r_hs_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->dev = &pdev->dev; + + st->data = dev_get_platdata(st->dev); + if (!st->data) + return dev_err_probe(st->dev, -ENODEV, "No platform data !"); + + st->back = devm_iio_backend_get(&pdev->dev, NULL); + if (IS_ERR(st->back)) + return PTR_ERR(st->back); + + ret = devm_iio_backend_enable(&pdev->dev, st->back); + if (ret) + return ret; + + st->model_data = device_get_match_data(&pdev->dev); + if (!st->model_data) + return -ENODEV; + + indio_dev->name = "ad3552r"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->setup_ops = &ad3552r_hs_buffer_setup_ops; + indio_dev->channels = ad3552r_hs_channels; + indio_dev->num_channels = ARRAY_SIZE(ad3552r_hs_channels); + indio_dev->info = &ad3552r_hs_info; + + ret = devm_iio_backend_request_buffer(&pdev->dev, st->back, indio_dev); + if (ret) + return ret; + + ret = ad3552r_hs_setup(st); + if (ret) + return ret; + + return devm_iio_device_register(&pdev->dev, indio_dev); +} + +static const struct ad3552r_model_data ad3552r_model_data = { + .model_name = "ad3552r", + .chip_id = AD3552R_ID, + .num_hw_channels = 2, + .ranges_table = ad3552r_ch_ranges, + .num_ranges = ARRAY_SIZE(ad3552r_ch_ranges), +}; + +static const struct of_device_id ad3552r_hs_of_id[] = { + { .compatible = "adi,ad3552r", .data = &ad3552r_model_data }, + { } +}; +MODULE_DEVICE_TABLE(of, ad3552r_hs_of_id); + +static struct platform_driver ad3552r_hs_driver = { + .driver = { + .name = "ad3552r-hs", + .of_match_table = ad3552r_hs_of_id, + }, + .probe = ad3552r_hs_probe, +}; +module_platform_driver(ad3552r_hs_driver); + +MODULE_AUTHOR("Dragos Bogdan "); +MODULE_AUTHOR("Angelo Dureghello "); +MODULE_DESCRIPTION("AD3552R Driver - High Speed version"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_BACKEND"); +MODULE_IMPORT_NS("IIO_AD3552R"); diff --git a/drivers/iio/dac/ad3552r-hs.h b/drivers/iio/dac/ad3552r-hs.h new file mode 100644 index 0000000000000000000000000000000000000000..724261d38dea3f5550de40f7e343385d00f46499 --- /dev/null +++ b/drivers/iio/dac/ad3552r-hs.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre, SAS + */ +#ifndef __LINUX_PLATFORM_DATA_AD3552R_HS_H__ +#define __LINUX_PLATFORM_DATA_AD3552R_HS_H__ + +struct iio_backend; + +struct ad3552r_hs_platform_data { + int (*bus_reg_read)(struct iio_backend *back, u32 reg, u32 *val, + size_t data_size); + int (*bus_reg_write)(struct iio_backend *back, u32 reg, u32 val, + size_t data_size); + u32 bus_sample_data_clock_hz; +}; + +#endif /* __LINUX_PLATFORM_DATA_AD3552R_HS_H__ */ diff --git a/drivers/iio/dac/ad3552r.c b/drivers/iio/dac/ad3552r.c index 7d61b2fe66243641119fb43e1b89f5e635dc7c0e..e7206af53af619eaaf5daca81e66ed1782ef82a2 100644 --- a/drivers/iio/dac/ad3552r.c +++ b/drivers/iio/dac/ad3552r.c @@ -6,271 +6,15 @@ * Copyright 2021 Analog Devices Inc. */ #include +#include #include #include #include #include #include -#include #include -/* Register addresses */ -/* Primary address space */ -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_A 0x00 -#define AD3552R_MASK_SOFTWARE_RESET (BIT(7) | BIT(0)) -#define AD3552R_MASK_ADDR_ASCENSION BIT(5) -#define AD3552R_MASK_SDO_ACTIVE BIT(4) -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_B 0x01 -#define AD3552R_MASK_SINGLE_INST BIT(7) -#define AD3552R_MASK_SHORT_INSTRUCTION BIT(3) -#define AD3552R_REG_ADDR_DEVICE_CONFIG 0x02 -#define AD3552R_MASK_DEVICE_STATUS(n) BIT(4 + (n)) -#define AD3552R_MASK_CUSTOM_MODES GENMASK(3, 2) -#define AD3552R_MASK_OPERATING_MODES GENMASK(1, 0) -#define AD3552R_REG_ADDR_CHIP_TYPE 0x03 -#define AD3552R_MASK_CLASS GENMASK(7, 0) -#define AD3552R_REG_ADDR_PRODUCT_ID_L 0x04 -#define AD3552R_REG_ADDR_PRODUCT_ID_H 0x05 -#define AD3552R_REG_ADDR_CHIP_GRADE 0x06 -#define AD3552R_MASK_GRADE GENMASK(7, 4) -#define AD3552R_MASK_DEVICE_REVISION GENMASK(3, 0) -#define AD3552R_REG_ADDR_SCRATCH_PAD 0x0A -#define AD3552R_REG_ADDR_SPI_REVISION 0x0B -#define AD3552R_REG_ADDR_VENDOR_L 0x0C -#define AD3552R_REG_ADDR_VENDOR_H 0x0D -#define AD3552R_REG_ADDR_STREAM_MODE 0x0E -#define AD3552R_MASK_LENGTH GENMASK(7, 0) -#define AD3552R_REG_ADDR_TRANSFER_REGISTER 0x0F -#define AD3552R_MASK_MULTI_IO_MODE GENMASK(7, 6) -#define AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE BIT(2) -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_C 0x10 -#define AD3552R_MASK_CRC_ENABLE (GENMASK(7, 6) |\ - GENMASK(1, 0)) -#define AD3552R_MASK_STRICT_REGISTER_ACCESS BIT(5) -#define AD3552R_REG_ADDR_INTERFACE_STATUS_A 0x11 -#define AD3552R_MASK_INTERFACE_NOT_READY BIT(7) -#define AD3552R_MASK_CLOCK_COUNTING_ERROR BIT(5) -#define AD3552R_MASK_INVALID_OR_NO_CRC BIT(3) -#define AD3552R_MASK_WRITE_TO_READ_ONLY_REGISTER BIT(2) -#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS BIT(1) -#define AD3552R_MASK_REGISTER_ADDRESS_INVALID BIT(0) -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_D 0x14 -#define AD3552R_MASK_ALERT_ENABLE_PULLUP BIT(6) -#define AD3552R_MASK_MEM_CRC_EN BIT(4) -#define AD3552R_MASK_SDO_DRIVE_STRENGTH GENMASK(3, 2) -#define AD3552R_MASK_DUAL_SPI_SYNCHROUNOUS_EN BIT(1) -#define AD3552R_MASK_SPI_CONFIG_DDR BIT(0) -#define AD3552R_REG_ADDR_SH_REFERENCE_CONFIG 0x15 -#define AD3552R_MASK_IDUMP_FAST_MODE BIT(6) -#define AD3552R_MASK_SAMPLE_HOLD_DIFFERENTIAL_USER_EN BIT(5) -#define AD3552R_MASK_SAMPLE_HOLD_USER_TRIM GENMASK(4, 3) -#define AD3552R_MASK_SAMPLE_HOLD_USER_ENABLE BIT(2) -#define AD3552R_MASK_REFERENCE_VOLTAGE_SEL GENMASK(1, 0) -#define AD3552R_REG_ADDR_ERR_ALARM_MASK 0x16 -#define AD3552R_MASK_REF_RANGE_ALARM BIT(6) -#define AD3552R_MASK_CLOCK_COUNT_ERR_ALARM BIT(5) -#define AD3552R_MASK_MEM_CRC_ERR_ALARM BIT(4) -#define AD3552R_MASK_SPI_CRC_ERR_ALARM BIT(3) -#define AD3552R_MASK_WRITE_TO_READ_ONLY_ALARM BIT(2) -#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS_ALARM BIT(1) -#define AD3552R_MASK_REGISTER_ADDRESS_INVALID_ALARM BIT(0) -#define AD3552R_REG_ADDR_ERR_STATUS 0x17 -#define AD3552R_MASK_REF_RANGE_ERR_STATUS BIT(6) -#define AD3552R_MASK_DUAL_SPI_STREAM_EXCEEDS_DAC_ERR_STATUS BIT(5) -#define AD3552R_MASK_MEM_CRC_ERR_STATUS BIT(4) -#define AD3552R_MASK_RESET_STATUS BIT(0) -#define AD3552R_REG_ADDR_POWERDOWN_CONFIG 0x18 -#define AD3552R_MASK_CH_DAC_POWERDOWN(ch) BIT(4 + (ch)) -#define AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(ch) BIT(ch) -#define AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE 0x19 -#define AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch) ((ch) ? GENMASK(7, 4) :\ - GENMASK(3, 0)) -#define AD3552R_REG_ADDR_CH_OFFSET(ch) (0x1B + (ch) * 2) -#define AD3552R_MASK_CH_OFFSET_BITS_0_7 GENMASK(7, 0) -#define AD3552R_REG_ADDR_CH_GAIN(ch) (0x1C + (ch) * 2) -#define AD3552R_MASK_CH_RANGE_OVERRIDE BIT(7) -#define AD3552R_MASK_CH_GAIN_SCALING_N GENMASK(6, 5) -#define AD3552R_MASK_CH_GAIN_SCALING_P GENMASK(4, 3) -#define AD3552R_MASK_CH_OFFSET_POLARITY BIT(2) -#define AD3552R_MASK_CH_OFFSET_BIT_8 BIT(0) -/* - * Secondary region - * For multibyte registers specify the highest address because the access is - * done in descending order - */ -#define AD3552R_SECONDARY_REGION_START 0x28 -#define AD3552R_REG_ADDR_HW_LDAC_16B 0x28 -#define AD3552R_REG_ADDR_CH_DAC_16B(ch) (0x2C - (1 - ch) * 2) -#define AD3552R_REG_ADDR_DAC_PAGE_MASK_16B 0x2E -#define AD3552R_REG_ADDR_CH_SELECT_16B 0x2F -#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_16B 0x31 -#define AD3552R_REG_ADDR_SW_LDAC_16B 0x32 -#define AD3552R_REG_ADDR_CH_INPUT_16B(ch) (0x36 - (1 - ch) * 2) -/* 3 bytes registers */ -#define AD3552R_REG_START_24B 0x37 -#define AD3552R_REG_ADDR_HW_LDAC_24B 0x37 -#define AD3552R_REG_ADDR_CH_DAC_24B(ch) (0x3D - (1 - ch) * 3) -#define AD3552R_REG_ADDR_DAC_PAGE_MASK_24B 0x40 -#define AD3552R_REG_ADDR_CH_SELECT_24B 0x41 -#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_24B 0x44 -#define AD3552R_REG_ADDR_SW_LDAC_24B 0x45 -#define AD3552R_REG_ADDR_CH_INPUT_24B(ch) (0x4B - (1 - ch) * 3) - -/* Useful defines */ -#define AD3552R_MAX_CH 2 -#define AD3552R_MASK_CH(ch) BIT(ch) -#define AD3552R_MASK_ALL_CH GENMASK(1, 0) -#define AD3552R_MAX_REG_SIZE 3 -#define AD3552R_READ_BIT BIT(7) -#define AD3552R_ADDR_MASK GENMASK(6, 0) -#define AD3552R_MASK_DAC_12B 0xFFF0 -#define AD3552R_DEFAULT_CONFIG_B_VALUE 0x8 -#define AD3552R_SCRATCH_PAD_TEST_VAL1 0x34 -#define AD3552R_SCRATCH_PAD_TEST_VAL2 0xB2 -#define AD3552R_GAIN_SCALE 1000 -#define AD3552R_LDAC_PULSE_US 100 - -enum ad3552r_ch_vref_select { - /* Internal source with Vref I/O floating */ - AD3552R_INTERNAL_VREF_PIN_FLOATING, - /* Internal source with Vref I/O at 2.5V */ - AD3552R_INTERNAL_VREF_PIN_2P5V, - /* External source with Vref I/O as input */ - AD3552R_EXTERNAL_VREF_PIN_INPUT -}; - -enum ad3552r_id { - AD3541R_ID = 0x400b, - AD3542R_ID = 0x4009, - AD3551R_ID = 0x400a, - AD3552R_ID = 0x4008, -}; - -enum ad3552r_ch_output_range { - /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ - AD3552R_CH_OUTPUT_RANGE_0__2P5V, - /* Range from 0 V to 5 V. Requires Rfb1x connection */ - AD3552R_CH_OUTPUT_RANGE_0__5V, - /* Range from 0 V to 10 V. Requires Rfb2x connection */ - AD3552R_CH_OUTPUT_RANGE_0__10V, - /* Range from -5 V to 5 V. Requires Rfb2x connection */ - AD3552R_CH_OUTPUT_RANGE_NEG_5__5V, - /* Range from -10 V to 10 V. Requires Rfb4x connection */ - AD3552R_CH_OUTPUT_RANGE_NEG_10__10V, -}; - -static const s32 ad3552r_ch_ranges[][2] = { - [AD3552R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, - [AD3552R_CH_OUTPUT_RANGE_0__5V] = {0, 5000}, - [AD3552R_CH_OUTPUT_RANGE_0__10V] = {0, 10000}, - [AD3552R_CH_OUTPUT_RANGE_NEG_5__5V] = {-5000, 5000}, - [AD3552R_CH_OUTPUT_RANGE_NEG_10__10V] = {-10000, 10000} -}; - -enum ad3542r_ch_output_range { - /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__2P5V, - /* Range from 0 V to 3 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__3V, - /* Range from 0 V to 5 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__5V, - /* Range from 0 V to 10 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_0__10V, - /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, - /* Range from -5 V to 5 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_NEG_5__5V, -}; - -static const s32 ad3542r_ch_ranges[][2] = { - [AD3542R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, - [AD3542R_CH_OUTPUT_RANGE_0__3V] = {0, 3000}, - [AD3542R_CH_OUTPUT_RANGE_0__5V] = {0, 5000}, - [AD3542R_CH_OUTPUT_RANGE_0__10V] = {0, 10000}, - [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = {-2500, 7500}, - [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = {-5000, 5000} -}; - -enum ad3552r_ch_gain_scaling { - /* Gain scaling of 1 */ - AD3552R_CH_GAIN_SCALING_1, - /* Gain scaling of 0.5 */ - AD3552R_CH_GAIN_SCALING_0_5, - /* Gain scaling of 0.25 */ - AD3552R_CH_GAIN_SCALING_0_25, - /* Gain scaling of 0.125 */ - AD3552R_CH_GAIN_SCALING_0_125, -}; - -/* Gain * AD3552R_GAIN_SCALE */ -static const s32 gains_scaling_table[] = { - [AD3552R_CH_GAIN_SCALING_1] = 1000, - [AD3552R_CH_GAIN_SCALING_0_5] = 500, - [AD3552R_CH_GAIN_SCALING_0_25] = 250, - [AD3552R_CH_GAIN_SCALING_0_125] = 125 -}; - -enum ad3552r_dev_attributes { - /* - Direct register values */ - /* From 0-3 */ - AD3552R_SDO_DRIVE_STRENGTH, - /* - * 0 -> Internal Vref, vref_io pin floating (default) - * 1 -> Internal Vref, vref_io driven by internal vref - * 2 or 3 -> External Vref - */ - AD3552R_VREF_SELECT, - /* Read registers in ascending order if set. Else descending */ - AD3552R_ADDR_ASCENSION, -}; - -enum ad3552r_ch_attributes { - /* DAC powerdown */ - AD3552R_CH_DAC_POWERDOWN, - /* DAC amplifier powerdown */ - AD3552R_CH_AMPLIFIER_POWERDOWN, - /* Select the output range. Select from enum ad3552r_ch_output_range */ - AD3552R_CH_OUTPUT_RANGE_SEL, - /* - * Over-rider the range selector in order to manually set the output - * voltage range - */ - AD3552R_CH_RANGE_OVERRIDE, - /* Manually set the offset voltage */ - AD3552R_CH_GAIN_OFFSET, - /* Sets the polarity of the offset. */ - AD3552R_CH_GAIN_OFFSET_POLARITY, - /* PDAC gain scaling */ - AD3552R_CH_GAIN_SCALING_P, - /* NDAC gain scaling */ - AD3552R_CH_GAIN_SCALING_N, - /* Rfb value */ - AD3552R_CH_RFB, - /* Channel select. When set allow Input -> DAC and Mask -> DAC */ - AD3552R_CH_SELECT, -}; - -struct ad3552r_ch_data { - s32 scale_int; - s32 scale_dec; - s32 offset_int; - s32 offset_dec; - s16 gain_offset; - u16 rfb; - u8 n; - u8 p; - u8 range; - bool range_override; -}; - -struct ad3552r_model_data { - const char *model_name; - enum ad3552r_id chip_id; - unsigned int num_hw_channels; - const s32 (*ranges_table)[2]; - int num_ranges; - bool requires_output_range; -}; +#include "ad3552r.h" struct ad3552r_desc { const struct ad3552r_model_data *model_data; @@ -285,45 +29,6 @@ struct ad3552r_desc { unsigned int num_ch; }; -static const u16 addr_mask_map[][2] = { - [AD3552R_ADDR_ASCENSION] = { - AD3552R_REG_ADDR_INTERFACE_CONFIG_A, - AD3552R_MASK_ADDR_ASCENSION - }, - [AD3552R_SDO_DRIVE_STRENGTH] = { - AD3552R_REG_ADDR_INTERFACE_CONFIG_D, - AD3552R_MASK_SDO_DRIVE_STRENGTH - }, - [AD3552R_VREF_SELECT] = { - AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, - AD3552R_MASK_REFERENCE_VOLTAGE_SEL - }, -}; - -/* 0 -> reg addr, 1->ch0 mask, 2->ch1 mask */ -static const u16 addr_mask_map_ch[][3] = { - [AD3552R_CH_DAC_POWERDOWN] = { - AD3552R_REG_ADDR_POWERDOWN_CONFIG, - AD3552R_MASK_CH_DAC_POWERDOWN(0), - AD3552R_MASK_CH_DAC_POWERDOWN(1) - }, - [AD3552R_CH_AMPLIFIER_POWERDOWN] = { - AD3552R_REG_ADDR_POWERDOWN_CONFIG, - AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(0), - AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(1) - }, - [AD3552R_CH_OUTPUT_RANGE_SEL] = { - AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, - AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), - AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1) - }, - [AD3552R_CH_SELECT] = { - AD3552R_REG_ADDR_CH_SELECT_16B, - AD3552R_MASK_CH(0), - AD3552R_MASK_CH(1) - } -}; - static u8 _ad3552r_reg_len(u8 addr) { switch (addr) { @@ -399,11 +104,6 @@ static int ad3552r_read_reg(struct ad3552r_desc *dac, u8 addr, u16 *val) return 0; } -static u16 ad3552r_field_prep(u16 val, u16 mask) -{ - return (val << __ffs(mask)) & mask; -} - /* Update field of a register, shift val if needed */ static int ad3552r_update_reg_field(struct ad3552r_desc *dac, u8 addr, u16 mask, u16 val) @@ -416,21 +116,11 @@ static int ad3552r_update_reg_field(struct ad3552r_desc *dac, u8 addr, u16 mask, return ret; reg &= ~mask; - reg |= ad3552r_field_prep(val, mask); + reg |= val; return ad3552r_write_reg(dac, addr, reg); } -static int ad3552r_set_ch_value(struct ad3552r_desc *dac, - enum ad3552r_ch_attributes attr, - u8 ch, - u16 val) -{ - /* Update register related to attributes in chip */ - return ad3552r_update_reg_field(dac, addr_mask_map_ch[attr][0], - addr_mask_map_ch[attr][ch + 1], val); -} - #define AD3552R_CH_DAC(_idx) ((struct iio_chan_spec) { \ .type = IIO_VOLTAGE, \ .output = true, \ @@ -510,8 +200,14 @@ static int ad3552r_write_raw(struct iio_dev *indio_dev, val); break; case IIO_CHAN_INFO_ENABLE: - err = ad3552r_set_ch_value(dac, AD3552R_CH_DAC_POWERDOWN, - chan->channel, !val); + if (chan->channel == 0) + val = FIELD_PREP(AD3552R_MASK_CH_DAC_POWERDOWN(0), !val); + else + val = FIELD_PREP(AD3552R_MASK_CH_DAC_POWERDOWN(1), !val); + + err = ad3552r_update_reg_field(dac, AD3552R_REG_ADDR_POWERDOWN_CONFIG, + AD3552R_MASK_CH_DAC_POWERDOWN(chan->channel), + val); break; default: err = -EINVAL; @@ -715,83 +411,9 @@ static int ad3552r_reset(struct ad3552r_desc *dac) } return ad3552r_update_reg_field(dac, - addr_mask_map[AD3552R_ADDR_ASCENSION][0], - addr_mask_map[AD3552R_ADDR_ASCENSION][1], - val); -} - -static void ad3552r_get_custom_range(struct ad3552r_desc *dac, s32 i, s32 *v_min, - s32 *v_max) -{ - s64 vref, tmp, common, offset, gn, gp; - /* - * From datasheet formula (In Volts): - * Vmin = 2.5 + [(GainN + Offset / 1024) * 2.5 * Rfb * 1.03] - * Vmax = 2.5 - [(GainP + Offset / 1024) * 2.5 * Rfb * 1.03] - * Calculus are converted to milivolts - */ - vref = 2500; - /* 2.5 * 1.03 * 1000 (To mV) */ - common = 2575 * dac->ch_data[i].rfb; - offset = dac->ch_data[i].gain_offset; - - gn = gains_scaling_table[dac->ch_data[i].n]; - tmp = (1024 * gn + AD3552R_GAIN_SCALE * offset) * common; - tmp = div_s64(tmp, 1024 * AD3552R_GAIN_SCALE); - *v_max = vref + tmp; - - gp = gains_scaling_table[dac->ch_data[i].p]; - tmp = (1024 * gp - AD3552R_GAIN_SCALE * offset) * common; - tmp = div_s64(tmp, 1024 * AD3552R_GAIN_SCALE); - *v_min = vref - tmp; -} - -static void ad3552r_calc_gain_and_offset(struct ad3552r_desc *dac, s32 ch) -{ - s32 idx, v_max, v_min, span, rem; - s64 tmp; - - if (dac->ch_data[ch].range_override) { - ad3552r_get_custom_range(dac, ch, &v_min, &v_max); - } else { - /* Normal range */ - idx = dac->ch_data[ch].range; - v_min = dac->model_data->ranges_table[idx][0]; - v_max = dac->model_data->ranges_table[idx][1]; - } - - /* - * From datasheet formula: - * Vout = Span * (D / 65536) + Vmin - * Converted to scale and offset: - * Scale = Span / 65536 - * Offset = 65536 * Vmin / Span - * - * Reminders are in micros in order to be printed as - * IIO_VAL_INT_PLUS_MICRO - */ - span = v_max - v_min; - dac->ch_data[ch].scale_int = div_s64_rem(span, 65536, &rem); - /* Do operations in microvolts */ - dac->ch_data[ch].scale_dec = DIV_ROUND_CLOSEST((s64)rem * 1000000, - 65536); - - dac->ch_data[ch].offset_int = div_s64_rem(v_min * 65536, span, &rem); - tmp = (s64)rem * 1000000; - dac->ch_data[ch].offset_dec = div_s64(tmp, span); -} - -static int ad3552r_find_range(const struct ad3552r_model_data *model_data, - s32 *vals) -{ - int i; - - for (i = 0; i < model_data->num_ranges; i++) - if (vals[0] == model_data->ranges_table[i][0] * 1000 && - vals[1] == model_data->ranges_table[i][1] * 1000) - return i; - - return -EINVAL; + AD3552R_REG_ADDR_INTERFACE_CONFIG_A, + AD3552R_MASK_ADDR_ASCENSION, + FIELD_PREP(AD3552R_MASK_ADDR_ASCENSION, val)); } static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac, @@ -799,57 +421,30 @@ static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac, u32 ch) { struct device *dev = &dac->spi->dev; - u32 val; int err; u8 addr; - u16 reg = 0, offset; - - struct fwnode_handle *gain_child __free(fwnode_handle) - = fwnode_get_named_child_node(child, - "custom-output-range-config"); - if (!gain_child) - return dev_err_probe(dev, -EINVAL, - "mandatory custom-output-range-config property missing\n"); - - dac->ch_data[ch].range_override = 1; - reg |= ad3552r_field_prep(1, AD3552R_MASK_CH_RANGE_OVERRIDE); - - err = fwnode_property_read_u32(gain_child, "adi,gain-scaling-p", &val); - if (err) - return dev_err_probe(dev, err, - "mandatory adi,gain-scaling-p property missing\n"); - reg |= ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_P); - dac->ch_data[ch].p = val; - - err = fwnode_property_read_u32(gain_child, "adi,gain-scaling-n", &val); - if (err) - return dev_err_probe(dev, err, - "mandatory adi,gain-scaling-n property missing\n"); - reg |= ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_N); - dac->ch_data[ch].n = val; - - err = fwnode_property_read_u32(gain_child, "adi,rfb-ohms", &val); - if (err) - return dev_err_probe(dev, err, - "mandatory adi,rfb-ohms property missing\n"); - dac->ch_data[ch].rfb = val; + u16 reg; - err = fwnode_property_read_u32(gain_child, "adi,gain-offset", &val); + err = ad3552r_get_custom_gain(dev, child, + &dac->ch_data[ch].p, + &dac->ch_data[ch].n, + &dac->ch_data[ch].rfb, + &dac->ch_data[ch].gain_offset); if (err) - return dev_err_probe(dev, err, - "mandatory adi,gain-offset property missing\n"); - dac->ch_data[ch].gain_offset = val; + return err; - offset = abs((s32)val); - reg |= ad3552r_field_prep((offset >> 8), AD3552R_MASK_CH_OFFSET_BIT_8); + dac->ch_data[ch].range_override = 1; - reg |= ad3552r_field_prep((s32)val < 0, AD3552R_MASK_CH_OFFSET_POLARITY); addr = AD3552R_REG_ADDR_CH_GAIN(ch); err = ad3552r_write_reg(dac, addr, - offset & AD3552R_MASK_CH_OFFSET_BITS_0_7); + abs((s32)dac->ch_data[ch].gain_offset) & + AD3552R_MASK_CH_OFFSET_BITS_0_7); if (err) return dev_err_probe(dev, err, "Error writing register\n"); + reg = ad3552r_calc_custom_gain(dac->ch_data[ch].p, dac->ch_data[ch].n, + dac->ch_data[ch].gain_offset); + err = ad3552r_write_reg(dac, addr, reg); if (err) return dev_err_probe(dev, err, "Error writing register\n"); @@ -860,49 +455,31 @@ static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac, static int ad3552r_configure_device(struct ad3552r_desc *dac) { struct device *dev = &dac->spi->dev; - int err, cnt = 0, voltage, delta = 100000; - u32 vals[2], val, ch; + int err, cnt = 0; + u32 val, ch; dac->gpio_ldac = devm_gpiod_get_optional(dev, "ldac", GPIOD_OUT_HIGH); if (IS_ERR(dac->gpio_ldac)) return dev_err_probe(dev, PTR_ERR(dac->gpio_ldac), "Error getting gpio ldac"); - voltage = devm_regulator_get_enable_read_voltage(dev, "vref"); - if (voltage < 0 && voltage != -ENODEV) - return dev_err_probe(dev, voltage, "Error getting vref voltage\n"); - - if (voltage == -ENODEV) { - if (device_property_read_bool(dev, "adi,vref-out-en")) - val = AD3552R_INTERNAL_VREF_PIN_2P5V; - else - val = AD3552R_INTERNAL_VREF_PIN_FLOATING; - } else { - if (voltage > 2500000 + delta || voltage < 2500000 - delta) { - dev_warn(dev, "vref-supply must be 2.5V"); - return -EINVAL; - } - val = AD3552R_EXTERNAL_VREF_PIN_INPUT; - } + err = ad3552r_get_ref_voltage(dev, &val); + if (err < 0) + return err; err = ad3552r_update_reg_field(dac, - addr_mask_map[AD3552R_VREF_SELECT][0], - addr_mask_map[AD3552R_VREF_SELECT][1], - val); + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + AD3552R_MASK_REFERENCE_VOLTAGE_SEL, + FIELD_PREP(AD3552R_MASK_REFERENCE_VOLTAGE_SEL, val)); if (err) return err; - err = device_property_read_u32(dev, "adi,sdo-drive-strength", &val); + err = ad3552r_get_drive_strength(dev, &val); if (!err) { - if (val > 3) { - dev_err(dev, "adi,sdo-drive-strength must be less than 4\n"); - return -EINVAL; - } - err = ad3552r_update_reg_field(dac, - addr_mask_map[AD3552R_SDO_DRIVE_STRENGTH][0], - addr_mask_map[AD3552R_SDO_DRIVE_STRENGTH][1], - val); + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SDO_DRIVE_STRENGTH, + FIELD_PREP(AD3552R_MASK_SDO_DRIVE_STRENGTH, val)); if (err) return err; } @@ -923,24 +500,21 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac) "reg must be less than %d\n", dac->model_data->num_hw_channels); - if (fwnode_property_present(child, "adi,output-range-microvolt")) { - err = fwnode_property_read_u32_array(child, - "adi,output-range-microvolt", - vals, - 2); - if (err) - return dev_err_probe(dev, err, - "adi,output-range-microvolt property could not be parsed\n"); - - err = ad3552r_find_range(dac->model_data, vals); - if (err < 0) - return dev_err_probe(dev, err, - "Invalid adi,output-range-microvolt value\n"); - - val = err; - err = ad3552r_set_ch_value(dac, - AD3552R_CH_OUTPUT_RANGE_SEL, - ch, val); + err = ad3552r_get_output_range(dev, dac->model_data, + child, &val); + if (err && err != -ENOENT) + return err; + + if (!err) { + if (ch == 0) + val = FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), val); + else + val = FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1), val); + + err = ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch), + val); if (err) return err; @@ -955,10 +529,17 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac) return err; } - ad3552r_calc_gain_and_offset(dac, ch); + ad3552r_calc_gain_and_offset(&dac->ch_data[ch], dac->model_data); dac->enabled_ch |= BIT(ch); - err = ad3552r_set_ch_value(dac, AD3552R_CH_SELECT, ch, 1); + if (ch == 0) + val = FIELD_PREP(AD3552R_MASK_CH(0), 1); + else + val = FIELD_PREP(AD3552R_MASK_CH(1), 1); + + err = ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_CH_SELECT_16B, + AD3552R_MASK_CH(ch), val); if (err < 0) return err; @@ -970,8 +551,15 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac) /* Disable unused channels */ for_each_clear_bit(ch, &dac->enabled_ch, dac->model_data->num_hw_channels) { - err = ad3552r_set_ch_value(dac, AD3552R_CH_AMPLIFIER_POWERDOWN, - ch, 1); + if (ch == 0) + val = FIELD_PREP(AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(0), 1); + else + val = FIELD_PREP(AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(1), 1); + + err = ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_POWERDOWN_CONFIG, + AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(ch), + val); if (err) return err; } @@ -1140,3 +728,4 @@ module_spi_driver(ad3552r_driver); MODULE_AUTHOR("Mihail Chindris "); MODULE_DESCRIPTION("Analog Device AD3552R DAC"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS("IIO_AD3552R"); diff --git a/drivers/iio/dac/ad3552r.h b/drivers/iio/dac/ad3552r.h new file mode 100644 index 0000000000000000000000000000000000000000..fd5a3dfd1d1cfe102ddccc4db5f5739d885f84b1 --- /dev/null +++ b/drivers/iio/dac/ad3552r.h @@ -0,0 +1,228 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * AD3552R Digital <-> Analog converters common header + * + * Copyright 2021-2024 Analog Devices Inc. + * Author: Angelo Dureghello + */ + +#ifndef __DRIVERS_IIO_DAC_AD3552R_H__ +#define __DRIVERS_IIO_DAC_AD3552R_H__ + +/* Register addresses */ +/* Primary address space */ +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_A 0x00 +#define AD3552R_MASK_SOFTWARE_RESET (BIT(7) | BIT(0)) +#define AD3552R_MASK_ADDR_ASCENSION BIT(5) +#define AD3552R_MASK_SDO_ACTIVE BIT(4) +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_B 0x01 +#define AD3552R_MASK_SINGLE_INST BIT(7) +#define AD3552R_MASK_SHORT_INSTRUCTION BIT(3) +#define AD3552R_REG_ADDR_DEVICE_CONFIG 0x02 +#define AD3552R_MASK_DEVICE_STATUS(n) BIT(4 + (n)) +#define AD3552R_MASK_CUSTOM_MODES GENMASK(3, 2) +#define AD3552R_MASK_OPERATING_MODES GENMASK(1, 0) +#define AD3552R_REG_ADDR_CHIP_TYPE 0x03 +#define AD3552R_MASK_CLASS GENMASK(7, 0) +#define AD3552R_REG_ADDR_PRODUCT_ID_L 0x04 +#define AD3552R_REG_ADDR_PRODUCT_ID_H 0x05 +#define AD3552R_REG_ADDR_CHIP_GRADE 0x06 +#define AD3552R_MASK_GRADE GENMASK(7, 4) +#define AD3552R_MASK_DEVICE_REVISION GENMASK(3, 0) +#define AD3552R_REG_ADDR_SCRATCH_PAD 0x0A +#define AD3552R_REG_ADDR_SPI_REVISION 0x0B +#define AD3552R_REG_ADDR_VENDOR_L 0x0C +#define AD3552R_REG_ADDR_VENDOR_H 0x0D +#define AD3552R_REG_ADDR_STREAM_MODE 0x0E +#define AD3552R_MASK_LENGTH GENMASK(7, 0) +#define AD3552R_REG_ADDR_TRANSFER_REGISTER 0x0F +#define AD3552R_MASK_MULTI_IO_MODE GENMASK(7, 6) +#define AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE BIT(2) +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_C 0x10 +#define AD3552R_MASK_CRC_ENABLE \ + (GENMASK(7, 6) | GENMASK(1, 0)) +#define AD3552R_MASK_STRICT_REGISTER_ACCESS BIT(5) +#define AD3552R_REG_ADDR_INTERFACE_STATUS_A 0x11 +#define AD3552R_MASK_INTERFACE_NOT_READY BIT(7) +#define AD3552R_MASK_CLOCK_COUNTING_ERROR BIT(5) +#define AD3552R_MASK_INVALID_OR_NO_CRC BIT(3) +#define AD3552R_MASK_WRITE_TO_READ_ONLY_REGISTER BIT(2) +#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS BIT(1) +#define AD3552R_MASK_REGISTER_ADDRESS_INVALID BIT(0) +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_D 0x14 +#define AD3552R_MASK_ALERT_ENABLE_PULLUP BIT(6) +#define AD3552R_MASK_MEM_CRC_EN BIT(4) +#define AD3552R_MASK_SDO_DRIVE_STRENGTH GENMASK(3, 2) +#define AD3552R_MASK_DUAL_SPI_SYNCHROUNOUS_EN BIT(1) +#define AD3552R_MASK_SPI_CONFIG_DDR BIT(0) +#define AD3552R_REG_ADDR_SH_REFERENCE_CONFIG 0x15 +#define AD3552R_MASK_IDUMP_FAST_MODE BIT(6) +#define AD3552R_MASK_SAMPLE_HOLD_DIFF_USER_EN BIT(5) +#define AD3552R_MASK_SAMPLE_HOLD_USER_TRIM GENMASK(4, 3) +#define AD3552R_MASK_SAMPLE_HOLD_USER_ENABLE BIT(2) +#define AD3552R_MASK_REFERENCE_VOLTAGE_SEL GENMASK(1, 0) +#define AD3552R_REG_ADDR_ERR_ALARM_MASK 0x16 +#define AD3552R_MASK_REF_RANGE_ALARM BIT(6) +#define AD3552R_MASK_CLOCK_COUNT_ERR_ALARM BIT(5) +#define AD3552R_MASK_MEM_CRC_ERR_ALARM BIT(4) +#define AD3552R_MASK_SPI_CRC_ERR_ALARM BIT(3) +#define AD3552R_MASK_WRITE_TO_READ_ONLY_ALARM BIT(2) +#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS_ALARM BIT(1) +#define AD3552R_MASK_REGISTER_ADDRESS_INVALID_ALARM BIT(0) +#define AD3552R_REG_ADDR_ERR_STATUS 0x17 +#define AD3552R_MASK_REF_RANGE_ERR_STATUS BIT(6) +#define AD3552R_MASK_STREAM_EXCEEDS_DAC_ERR_STATUS BIT(5) +#define AD3552R_MASK_MEM_CRC_ERR_STATUS BIT(4) +#define AD3552R_MASK_RESET_STATUS BIT(0) +#define AD3552R_REG_ADDR_POWERDOWN_CONFIG 0x18 +#define AD3552R_MASK_CH_DAC_POWERDOWN(ch) BIT(4 + (ch)) +#define AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(ch) BIT(ch) +#define AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE 0x19 +#define AD3552R_MASK_CH0_RANGE GENMASK(2, 0) +#define AD3552R_MASK_CH1_RANGE GENMASK(6, 4) +#define AD3552R_MASK_CH_OUTPUT_RANGE GENMASK(7, 0) +#define AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch) \ + ((ch) ? GENMASK(7, 4) : GENMASK(3, 0)) +#define AD3552R_REG_ADDR_CH_OFFSET(ch) (0x1B + (ch) * 2) +#define AD3552R_MASK_CH_OFFSET_BITS_0_7 GENMASK(7, 0) +#define AD3552R_REG_ADDR_CH_GAIN(ch) (0x1C + (ch) * 2) +#define AD3552R_MASK_CH_RANGE_OVERRIDE BIT(7) +#define AD3552R_MASK_CH_GAIN_SCALING_N GENMASK(6, 5) +#define AD3552R_MASK_CH_GAIN_SCALING_P GENMASK(4, 3) +#define AD3552R_MASK_CH_OFFSET_POLARITY BIT(2) +#define AD3552R_MASK_CH_OFFSET_BIT_8 BIT(8) +/* + * Secondary region + * For multibyte registers specify the highest address because the access is + * done in descending order + */ +#define AD3552R_SECONDARY_REGION_START 0x28 +#define AD3552R_REG_ADDR_HW_LDAC_16B 0x28 +#define AD3552R_REG_ADDR_CH_DAC_16B(ch) (0x2C - (1 - (ch)) * 2) +#define AD3552R_REG_ADDR_DAC_PAGE_MASK_16B 0x2E +#define AD3552R_REG_ADDR_CH_SELECT_16B 0x2F +#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_16B 0x31 +#define AD3552R_REG_ADDR_SW_LDAC_16B 0x32 +#define AD3552R_REG_ADDR_CH_INPUT_16B(ch) (0x36 - (1 - (ch)) * 2) +/* 3 bytes registers */ +#define AD3552R_REG_START_24B 0x37 +#define AD3552R_REG_ADDR_HW_LDAC_24B 0x37 +#define AD3552R_REG_ADDR_CH_DAC_24B(ch) (0x3D - (1 - (ch)) * 3) +#define AD3552R_REG_ADDR_DAC_PAGE_MASK_24B 0x40 +#define AD3552R_REG_ADDR_CH_SELECT_24B 0x41 +#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_24B 0x44 +#define AD3552R_REG_ADDR_SW_LDAC_24B 0x45 +#define AD3552R_REG_ADDR_CH_INPUT_24B(ch) (0x4B - (1 - (ch)) * 3) + +#define AD3552R_MAX_CH 2 +#define AD3552R_MASK_CH(ch) BIT(ch) +#define AD3552R_MASK_ALL_CH GENMASK(1, 0) +#define AD3552R_MAX_REG_SIZE 3 +#define AD3552R_READ_BIT BIT(7) +#define AD3552R_ADDR_MASK GENMASK(6, 0) +#define AD3552R_MASK_DAC_12B GENMASK(15, 4) +#define AD3552R_DEFAULT_CONFIG_B_VALUE 0x8 +#define AD3552R_SCRATCH_PAD_TEST_VAL1 0x34 +#define AD3552R_SCRATCH_PAD_TEST_VAL2 0xB2 +#define AD3552R_GAIN_SCALE 1000 +#define AD3552R_LDAC_PULSE_US 100 + +#define AD3552R_CH0_ACTIVE BIT(0) +#define AD3552R_CH1_ACTIVE BIT(1) + +#define AD3552R_MAX_RANGES 5 +#define AD3542R_MAX_RANGES 6 +#define AD3552R_QUAD_SPI 2 + +extern const s32 ad3552r_ch_ranges[AD3552R_MAX_RANGES][2]; +extern const s32 ad3542r_ch_ranges[AD3542R_MAX_RANGES][2]; + +enum ad3552r_id { + AD3541R_ID = 0x400b, + AD3542R_ID = 0x4009, + AD3551R_ID = 0x400a, + AD3552R_ID = 0x4008, +}; + +struct ad3552r_model_data { + const char *model_name; + enum ad3552r_id chip_id; + unsigned int num_hw_channels; + const s32 (*ranges_table)[2]; + int num_ranges; + bool requires_output_range; +}; + +struct ad3552r_ch_data { + s32 scale_int; + s32 scale_dec; + s32 offset_int; + s32 offset_dec; + s16 gain_offset; + u16 rfb; + u8 n; + u8 p; + u8 range; + bool range_override; +}; + +enum ad3552r_ch_gain_scaling { + /* Gain scaling of 1 */ + AD3552R_CH_GAIN_SCALING_1, + /* Gain scaling of 0.5 */ + AD3552R_CH_GAIN_SCALING_0_5, + /* Gain scaling of 0.25 */ + AD3552R_CH_GAIN_SCALING_0_25, + /* Gain scaling of 0.125 */ + AD3552R_CH_GAIN_SCALING_0_125, +}; + +enum ad3552r_ch_vref_select { + /* Internal source with Vref I/O floating */ + AD3552R_INTERNAL_VREF_PIN_FLOATING, + /* Internal source with Vref I/O at 2.5V */ + AD3552R_INTERNAL_VREF_PIN_2P5V, + /* External source with Vref I/O as input */ + AD3552R_EXTERNAL_VREF_PIN_INPUT +}; + +enum ad3542r_ch_output_range { + /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ + AD3542R_CH_OUTPUT_RANGE_0__2P5V, + /* Range from 0 V to 3 V. Requires Rfb1x connection */ + AD3542R_CH_OUTPUT_RANGE_0__3V, + /* Range from 0 V to 5 V. Requires Rfb1x connection */ + AD3542R_CH_OUTPUT_RANGE_0__5V, + /* Range from 0 V to 10 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_0__10V, + /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, + /* Range from -5 V to 5 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_NEG_5__5V, +}; + +enum ad3552r_ch_output_range { + /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ + AD3552R_CH_OUTPUT_RANGE_0__2P5V, + /* Range from 0 V to 5 V. Requires Rfb1x connection */ + AD3552R_CH_OUTPUT_RANGE_0__5V, + /* Range from 0 V to 10 V. Requires Rfb2x connection */ + AD3552R_CH_OUTPUT_RANGE_0__10V, + /* Range from -5 V to 5 V. Requires Rfb2x connection */ + AD3552R_CH_OUTPUT_RANGE_NEG_5__5V, + /* Range from -10 V to 10 V. Requires Rfb4x connection */ + AD3552R_CH_OUTPUT_RANGE_NEG_10__10V, +}; + +int ad3552r_get_output_range(struct device *dev, + const struct ad3552r_model_data *model_info, + struct fwnode_handle *child, u32 *val); +int ad3552r_get_custom_gain(struct device *dev, struct fwnode_handle *child, + u8 *gs_p, u8 *gs_n, u16 *rfb, s16 *goffs); +u16 ad3552r_calc_custom_gain(u8 p, u8 n, s16 goffs); +int ad3552r_get_ref_voltage(struct device *dev, u32 *val); +int ad3552r_get_drive_strength(struct device *dev, u32 *val); +void ad3552r_calc_gain_and_offset(struct ad3552r_ch_data *ch_data, + const struct ad3552r_model_data *model_data); + +#endif /* __DRIVERS_IIO_DAC_AD3552R_H__ */ diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index 2e3e33f92bc0afebe30c5cdbef177648a0bc969c..392a1c7aee03b515e9e068a1fc9bb4e594bef267 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -47,7 +47,6 @@ struct ad5380_chip_info { * struct ad5380_state - driver instance specific data * @regmap: regmap instance used by the device * @chip_info: chip model specific constants, available modes etc - * @vref_reg: vref supply regulator * @vref: actual reference voltage used in uA * @pwr_down: whether the chip is currently in power down mode * @lock: lock to protect the data buffer during regmap ops @@ -55,7 +54,6 @@ struct ad5380_chip_info { struct ad5380_state { struct regmap *regmap; const struct ad5380_chip_info *chip_info; - struct regulator *vref_reg; int vref; bool pwr_down; struct mutex lock; @@ -341,14 +339,14 @@ static const struct ad5380_chip_info ad5380_chip_info_tbl[] = { }, }; -static int ad5380_alloc_channels(struct iio_dev *indio_dev) +static int ad5380_alloc_channels(struct device *dev, struct iio_dev *indio_dev) { struct ad5380_state *st = iio_priv(indio_dev); struct iio_chan_spec *channels; unsigned int i; - channels = kcalloc(st->chip_info->num_channels, - sizeof(struct iio_chan_spec), GFP_KERNEL); + channels = devm_kcalloc(dev, st->chip_info->num_channels, + sizeof(struct iio_chan_spec), GFP_KERNEL); if (!channels) return -ENOMEM; @@ -379,7 +377,6 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap, } st = iio_priv(indio_dev); - dev_set_drvdata(dev, indio_dev); st->chip_info = &ad5380_chip_info_tbl[type]; st->regmap = regmap; @@ -391,68 +388,32 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap, mutex_init(&st->lock); - ret = ad5380_alloc_channels(indio_dev); - if (ret) { - dev_err(dev, "Failed to allocate channel spec: %d\n", ret); - return ret; - } + ret = ad5380_alloc_channels(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to allocate channel spec\n"); if (st->chip_info->int_vref == 2500) ctrl |= AD5380_CTRL_INT_VREF_2V5; - st->vref_reg = devm_regulator_get(dev, "vref"); - if (!IS_ERR(st->vref_reg)) { - ret = regulator_enable(st->vref_reg); - if (ret) { - dev_err(dev, "Failed to enable vref regulators: %d\n", - ret); - goto error_free_reg; - } - - ret = regulator_get_voltage(st->vref_reg); - if (ret < 0) - goto error_disable_reg; - - st->vref = ret / 1000; - } else { + ret = devm_regulator_get_enable_read_voltage(dev, "vref"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(dev, ret, "Failed to get vref voltage\n"); + if (ret == -ENODEV) { st->vref = st->chip_info->int_vref; ctrl |= AD5380_CTRL_INT_VREF_EN; + } else { + st->vref = ret / 1000; } ret = regmap_write(st->regmap, AD5380_REG_SF_CTRL, ctrl); - if (ret) { - dev_err(dev, "Failed to write to device: %d\n", ret); - goto error_disable_reg; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to write to device\n"); - ret = iio_device_register(indio_dev); - if (ret) { - dev_err(dev, "Failed to register iio device: %d\n", ret); - goto error_disable_reg; - } + ret = devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to register iio device\n"); return 0; - -error_disable_reg: - if (!IS_ERR(st->vref_reg)) - regulator_disable(st->vref_reg); -error_free_reg: - kfree(indio_dev->channels); - - return ret; -} - -static void ad5380_remove(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5380_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - kfree(indio_dev->channels); - - if (!IS_ERR(st->vref_reg)) - regulator_disable(st->vref_reg); } static bool ad5380_reg_false(struct device *dev, unsigned int reg) @@ -486,11 +447,6 @@ static int ad5380_spi_probe(struct spi_device *spi) return ad5380_probe(&spi->dev, regmap, id->driver_data, id->name); } -static void ad5380_spi_remove(struct spi_device *spi) -{ - ad5380_remove(&spi->dev); -} - static const struct spi_device_id ad5380_spi_ids[] = { { "ad5380-3", ID_AD5380_3 }, { "ad5380-5", ID_AD5380_5 }, @@ -517,7 +473,6 @@ static struct spi_driver ad5380_spi_driver = { .name = "ad5380", }, .probe = ad5380_spi_probe, - .remove = ad5380_spi_remove, .id_table = ad5380_spi_ids, }; @@ -559,11 +514,6 @@ static int ad5380_i2c_probe(struct i2c_client *i2c) return ad5380_probe(&i2c->dev, regmap, id->driver_data, id->name); } -static void ad5380_i2c_remove(struct i2c_client *i2c) -{ - ad5380_remove(&i2c->dev); -} - static const struct i2c_device_id ad5380_i2c_ids[] = { { "ad5380-3", ID_AD5380_3 }, { "ad5380-5", ID_AD5380_5 }, @@ -590,7 +540,6 @@ static struct i2c_driver ad5380_i2c_driver = { .name = "ad5380", }, .probe = ad5380_i2c_probe, - .remove = ad5380_i2c_remove, .id_table = ad5380_i2c_ids, }; diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 7644acfd879e046ebea39e16a5566f58e9ceefed..1462ee640b16863e779bb550fa64445b5c8bd72c 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -384,7 +384,7 @@ static int ad5421_write_raw(struct iio_dev *indio_dev, static int ad5421_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct ad5421_state *st = iio_priv(indio_dev); unsigned int mask; diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 708629efc15734deb51d9aa330e845b2e0d3bfa4..6ad99f97eed55ff4ff4be22f3d6ef3a858dcf87e 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -32,7 +32,6 @@ * struct ad5446_state - driver instance specific data * @dev: this device * @chip_info: chip model specific constants, available modes etc - * @reg: supply regulator * @vref_mv: actual reference voltage used * @cached_val: store/retrieve values during power down * @pwr_down_mode: power down mode (1k, 100k or tristate) @@ -43,7 +42,6 @@ struct ad5446_state { struct device *dev; const struct ad5446_chip_info *chip_info; - struct regulator *reg; unsigned short vref_mv; unsigned cached_val; unsigned pwr_down_mode; @@ -226,32 +224,15 @@ static int ad5446_probe(struct device *dev, const char *name, { struct ad5446_state *st; struct iio_dev *indio_dev; - struct regulator *reg; - int ret, voltage_uv = 0; - - reg = devm_regulator_get(dev, "vcc"); - if (!IS_ERR(reg)) { - ret = regulator_enable(reg); - if (ret) - return ret; - - ret = regulator_get_voltage(reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; - } + int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } + if (!indio_dev) + return -ENOMEM; + st = iio_priv(indio_dev); st->chip_info = chip_info; - dev_set_drvdata(dev, indio_dev); - st->reg = reg; st->dev = dev; indio_dev->name = name; @@ -264,33 +245,19 @@ static int ad5446_probe(struct device *dev, const char *name, st->pwr_down_mode = MODE_PWRDWN_1k; - if (st->chip_info->int_vref_mv) - st->vref_mv = st->chip_info->int_vref_mv; - else if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - dev_warn(dev, "reference voltage unspecified\n"); - - ret = iio_device_register(indio_dev); - if (ret) - goto error_disable_reg; - - return 0; - -error_disable_reg: - if (!IS_ERR(reg)) - regulator_disable(reg); - return ret; -} - -static void ad5446_remove(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5446_state *st = iio_priv(indio_dev); + ret = devm_regulator_get_enable_read_voltage(dev, "vcc"); + if (ret < 0 && ret != -ENODEV) + return ret; + if (ret == -ENODEV) { + if (chip_info->int_vref_mv) + st->vref_mv = chip_info->int_vref_mv; + else + dev_warn(dev, "reference voltage unspecified\n"); + } else { + st->vref_mv = ret / 1000; + } - iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + return devm_iio_device_register(dev, indio_dev); } #if IS_ENABLED(CONFIG_SPI_MASTER) @@ -491,18 +458,12 @@ static int ad5446_spi_probe(struct spi_device *spi) &ad5446_spi_chip_info[id->driver_data]); } -static void ad5446_spi_remove(struct spi_device *spi) -{ - ad5446_remove(&spi->dev); -} - static struct spi_driver ad5446_spi_driver = { .driver = { .name = "ad5446", .of_match_table = ad5446_of_ids, }, .probe = ad5446_spi_probe, - .remove = ad5446_spi_remove, .id_table = ad5446_spi_ids, }; @@ -575,11 +536,6 @@ static int ad5446_i2c_probe(struct i2c_client *i2c) &ad5446_i2c_chip_info[id->driver_data]); } -static void ad5446_i2c_remove(struct i2c_client *i2c) -{ - ad5446_remove(&i2c->dev); -} - static const struct i2c_device_id ad5446_i2c_ids[] = { {"ad5301", ID_AD5602}, {"ad5311", ID_AD5612}, @@ -596,7 +552,6 @@ static struct i2c_driver ad5446_i2c_driver = { .name = "ad5446", }, .probe = ad5446_i2c_probe, - .remove = ad5446_i2c_remove, .id_table = ad5446_i2c_ids, }; diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index e6c5be728bb211032629ab7f1d8b288b050bb1a2..ff0765c8af47f89659a0cd5756b97f6d6c0462ed 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -270,38 +270,29 @@ static const struct iio_chan_spec ad5504_channels[] = { static int ad5504_probe(struct spi_device *spi) { - struct ad5504_platform_data *pdata = spi->dev.platform_data; + const struct ad5504_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad5504_state *st; - struct regulator *reg; - int ret, voltage_uv = 0; + int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; - reg = devm_regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(reg)) { - ret = regulator_enable(reg); - if (ret) - return ret; - ret = regulator_get_voltage(reg); - if (ret < 0) - goto error_disable_reg; + st = iio_priv(indio_dev); - voltage_uv = ret; + ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vcc"); + if (ret < 0 && ret != -ENODEV) + return ret; + if (ret == -ENODEV) { + if (pdata->vref_mv) + st->vref_mv = pdata->vref_mv; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); + } else { + st->vref_mv = ret / 1000; } - spi_set_drvdata(spi, indio_dev); - st = iio_priv(indio_dev); - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else if (pdata) - st->vref_mv = pdata->vref_mv; - else - dev_warn(&spi->dev, "reference voltage unspecified\n"); - - st->reg = reg; st->spi = spi; indio_dev->name = spi_get_device_id(st->spi)->name; indio_dev->info = &ad5504_info; @@ -320,31 +311,10 @@ static int ad5504_probe(struct spi_device *spi) spi_get_device_id(st->spi)->name, indio_dev); if (ret) - goto error_disable_reg; + return ret; } - ret = iio_device_register(indio_dev); - if (ret) - goto error_disable_reg; - - return 0; - -error_disable_reg: - if (!IS_ERR(reg)) - regulator_disable(reg); - - return ret; -} - -static void ad5504_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad5504_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad5504_id[] = { @@ -359,7 +329,6 @@ static struct spi_driver ad5504_driver = { .name = "ad5504", }, .probe = ad5504_probe, - .remove = ad5504_remove, .id_table = ad5504_id, }; module_spi_driver(ad5504_driver); diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c index 4763402dbcd66d04391111e8c96fc774dd3a16d5..50d19304bacbc6e0b0ced51e0fdf948b603d04e6 100644 --- a/drivers/iio/dac/ad5592r-base.c +++ b/drivers/iio/dac/ad5592r-base.c @@ -665,7 +665,7 @@ error_disable_reg: return ret; } -EXPORT_SYMBOL_NS_GPL(ad5592r_probe, IIO_AD5592R); +EXPORT_SYMBOL_NS_GPL(ad5592r_probe, "IIO_AD5592R"); void ad5592r_remove(struct device *dev) { @@ -679,7 +679,7 @@ void ad5592r_remove(struct device *dev) if (st->reg) regulator_disable(st->reg); } -EXPORT_SYMBOL_NS_GPL(ad5592r_remove, IIO_AD5592R); +EXPORT_SYMBOL_NS_GPL(ad5592r_remove, "IIO_AD5592R"); MODULE_AUTHOR("Paul Cercueil "); MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters"); diff --git a/drivers/iio/dac/ad5592r.c b/drivers/iio/dac/ad5592r.c index 32d950bbb1ca0b89157bbf84a6b256f3b3c76341..fd82d8701322c4ec5b3bcb5d413e369e7c5a26b8 100644 --- a/drivers/iio/dac/ad5592r.c +++ b/drivers/iio/dac/ad5592r.c @@ -168,4 +168,4 @@ module_spi_driver(ad5592r_spi_driver); MODULE_AUTHOR("Paul Cercueil "); MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD5592R); +MODULE_IMPORT_NS("IIO_AD5592R"); diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index 62e1fbb9e9101eaa46fd7a24ae10e6617120fbfe..ddd13ad821a794ad501d101c36c651d82119cabb 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -147,4 +147,4 @@ module_i2c_driver(ad5593r_driver); MODULE_AUTHOR("Paul Cercueil "); MODULE_DESCRIPTION("Analog Devices AD5593R multi-channel converters"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD5592R); +MODULE_IMPORT_NS("IIO_AD5592R"); diff --git a/drivers/iio/dac/ad5624r.h b/drivers/iio/dac/ad5624r.h index 13964f3a22a46a050be4812cd6fdc4d57ca526f6..14a439b06eb6a284b7763e084f133dada7978d08 100644 --- a/drivers/iio/dac/ad5624r.h +++ b/drivers/iio/dac/ad5624r.h @@ -54,7 +54,6 @@ struct ad5624r_chip_info { struct ad5624r_state { struct spi_device *us; const struct ad5624r_chip_info *chip_info; - struct regulator *reg; unsigned short vref_mv; unsigned pwr_down_mask; unsigned pwr_down_mode; diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index 9304d0499bae821e5b123e4663511098a0632af2..2fd38ac8f698856910d186099f8ffa2c34ebe5d1 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -223,50 +223,26 @@ static int ad5624r_probe(struct spi_device *spi) { struct ad5624r_state *st; struct iio_dev *indio_dev; - int ret, voltage_uv = 0; + bool external_vref; + int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); - st->reg = devm_regulator_get_optional(&spi->dev, "vref"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); - if (ret) - return ret; - - ret = regulator_get_voltage(st->reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; - } else { - if (PTR_ERR(st->reg) != -ENODEV) - return PTR_ERR(st->reg); + ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref"); + if (ret == -ENODEV) /* Backwards compatibility. This naming is not correct */ - st->reg = devm_regulator_get_optional(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); - if (ret) - return ret; - - ret = regulator_get_voltage(st->reg); - if (ret < 0) - goto error_disable_reg; - - voltage_uv = ret; - } - } + ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vcc"); + if (ret < 0 && ret != -ENODEV) + return ret; + + external_vref = ret != -ENODEV; + st->vref_mv = external_vref ? ret / 1000 : st->chip_info->int_vref_mv; - spi_set_drvdata(spi, indio_dev); st->chip_info = &ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - st->vref_mv = st->chip_info->int_vref_mv; - st->us = spi; indio_dev->name = spi_get_device_id(spi)->name; @@ -276,31 +252,11 @@ static int ad5624r_probe(struct spi_device *spi) indio_dev->num_channels = AD5624R_DAC_CHANNELS; ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, - !!voltage_uv, 16); - if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); + external_vref, 16); if (ret) - goto error_disable_reg; - - return 0; - -error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); - - return ret; -} - -static void ad5624r_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad5624r_state *st = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad5624r_id[] = { @@ -319,7 +275,6 @@ static struct spi_driver ad5624r_driver = { .name = "ad5624r", }, .probe = ad5624r_probe, - .remove = ad5624r_remove, .id_table = ad5624r_id, }; module_spi_driver(ad5624r_driver); diff --git a/drivers/iio/dac/ad5686-spi.c b/drivers/iio/dac/ad5686-spi.c index 8ba2ea70451a952107b852e5fe9b53faa39c263e..39b5dad0d6a5ee9abae9dcefcd90a2c512192f3a 100644 --- a/drivers/iio/dac/ad5686-spi.c +++ b/drivers/iio/dac/ad5686-spi.c @@ -135,4 +135,4 @@ module_spi_driver(ad5686_spi_driver); MODULE_AUTHOR("Stefan Popa "); MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD5686); +MODULE_IMPORT_NS("IIO_AD5686"); diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 57cc0f0eedc6c6b09a6949bfa2da36a94269eaa7..8dc578b087845a8473cab8bf38ab2349b6590efb 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -543,7 +543,7 @@ error_disable_reg: regulator_disable(st->reg); return ret; } -EXPORT_SYMBOL_NS_GPL(ad5686_probe, IIO_AD5686); +EXPORT_SYMBOL_NS_GPL(ad5686_probe, "IIO_AD5686"); void ad5686_remove(struct device *dev) { @@ -554,7 +554,7 @@ void ad5686_remove(struct device *dev) if (!IS_ERR(st->reg)) regulator_disable(st->reg); } -EXPORT_SYMBOL_NS_GPL(ad5686_remove, IIO_AD5686); +EXPORT_SYMBOL_NS_GPL(ad5686_remove, "IIO_AD5686"); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC"); diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index 81541f755a3e1bb34a5c5621a803e3fb6e3c3a17..bbcda246c54705678b63b3bd8e0a0f5002665293 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -125,4 +125,4 @@ module_i2c_driver(ad5686_i2c_driver); MODULE_AUTHOR("Stefan Popa "); MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_AD5686); +MODULE_IMPORT_NS("IIO_AD5686"); diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 0b24cb19ac9d1c8032e3dd6354f7b86cd47088b1..05e80b6ae2cc3fe2be68e5477e95047889e3ef83 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -699,7 +699,6 @@ static const struct ad5755_platform_data ad5755_default_pdata = { static struct ad5755_platform_data *ad5755_parse_fw(struct device *dev) { - struct fwnode_handle *pp; struct ad5755_platform_data *pdata; unsigned int tmp; unsigned int tmparray[3]; @@ -746,11 +745,12 @@ static struct ad5755_platform_data *ad5755_parse_fw(struct device *dev) } devnr = 0; - device_for_each_child_node(dev, pp) { + device_for_each_child_node_scoped(dev, pp) { if (devnr >= AD5755_NUM_CHANNELS) { dev_err(dev, "There are too many channels defined in DT\n"); - goto error_out; + devm_kfree(dev, pdata); + return NULL; } pdata->dac[devnr].mode = AD5755_MODE_CURRENT_4mA_20mA; @@ -800,11 +800,6 @@ static struct ad5755_platform_data *ad5755_parse_fw(struct device *dev) } return pdata; - - error_out: - fwnode_handle_put(pp); - devm_kfree(dev, pdata); - return NULL; } static int ad5755_probe(struct spi_device *spi) diff --git a/drivers/iio/dac/ad5761.c b/drivers/iio/dac/ad5761.c index 6aa1a068adb06172278d1e8d8a030ab20289461e..0aa5ba7f465482edffdc5b23bbf79fb210075913 100644 --- a/drivers/iio/dac/ad5761.c +++ b/drivers/iio/dac/ad5761.c @@ -53,7 +53,6 @@ enum ad5761_supported_device_ids { /** * struct ad5761_state - driver instance specific data * @spi: spi_device - * @vref_reg: reference voltage regulator * @use_intref: true when the internal voltage reference is used * @vref: actual voltage reference in mVolts * @range: output range mode used @@ -62,7 +61,6 @@ enum ad5761_supported_device_ids { */ struct ad5761_state { struct spi_device *spi; - struct regulator *vref_reg; struct mutex lock; bool use_intref; @@ -287,63 +285,6 @@ static const struct ad5761_chip_info ad5761_chip_infos[] = { }, }; -static int ad5761_get_vref(struct ad5761_state *st, - const struct ad5761_chip_info *chip_info) -{ - int ret; - - st->vref_reg = devm_regulator_get_optional(&st->spi->dev, "vref"); - if (PTR_ERR(st->vref_reg) == -ENODEV) { - /* Use Internal regulator */ - if (!chip_info->int_vref) { - dev_err(&st->spi->dev, - "Voltage reference not found\n"); - return -EIO; - } - - st->use_intref = true; - st->vref = chip_info->int_vref; - return 0; - } - - if (IS_ERR(st->vref_reg)) { - dev_err(&st->spi->dev, - "Error getting voltage reference regulator\n"); - return PTR_ERR(st->vref_reg); - } - - ret = regulator_enable(st->vref_reg); - if (ret) { - dev_err(&st->spi->dev, - "Failed to enable voltage reference\n"); - return ret; - } - - ret = regulator_get_voltage(st->vref_reg); - if (ret < 0) { - dev_err(&st->spi->dev, - "Failed to get voltage reference value\n"); - goto disable_regulator_vref; - } - - if (ret < 2000000 || ret > 3000000) { - dev_warn(&st->spi->dev, - "Invalid external voltage ref. value %d uV\n", ret); - ret = -EIO; - goto disable_regulator_vref; - } - - st->vref = ret / 1000; - st->use_intref = false; - - return 0; - -disable_regulator_vref: - regulator_disable(st->vref_reg); - st->vref_reg = NULL; - return ret; -} - static int ad5761_probe(struct spi_device *spi) { struct iio_dev *iio_dev; @@ -361,11 +302,28 @@ static int ad5761_probe(struct spi_device *spi) st = iio_priv(iio_dev); st->spi = spi; - spi_set_drvdata(spi, iio_dev); - ret = ad5761_get_vref(st, chip_info); - if (ret) - return ret; + ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(&spi->dev, ret, + "Failed to get voltage reference value\n"); + if (ret == -ENODEV) { + /* Use Internal regulator */ + if (!chip_info->int_vref) + return dev_err_probe(&spi->dev, -EIO, + "Voltage reference not found\n"); + + st->use_intref = true; + st->vref = chip_info->int_vref; + } else { + if (ret < 2000000 || ret > 3000000) + return dev_err_probe(&spi->dev, -EIO, + "Invalid external voltage ref. value %d uV\n", + ret); + + st->use_intref = false; + st->vref = ret / 1000; + } if (pdata) voltage_range = pdata->voltage_range; @@ -374,35 +332,15 @@ static int ad5761_probe(struct spi_device *spi) ret = ad5761_spi_set_range(st, voltage_range); if (ret) - goto disable_regulator_err; + return ret; iio_dev->info = &ad5761_info; iio_dev->modes = INDIO_DIRECT_MODE; iio_dev->channels = &chip_info->channel; iio_dev->num_channels = 1; iio_dev->name = spi_get_device_id(st->spi)->name; - ret = iio_device_register(iio_dev); - if (ret) - goto disable_regulator_err; - - return 0; - -disable_regulator_err: - if (!IS_ERR_OR_NULL(st->vref_reg)) - regulator_disable(st->vref_reg); - - return ret; -} - -static void ad5761_remove(struct spi_device *spi) -{ - struct iio_dev *iio_dev = spi_get_drvdata(spi); - struct ad5761_state *st = iio_priv(iio_dev); - - iio_device_unregister(iio_dev); - if (!IS_ERR_OR_NULL(st->vref_reg)) - regulator_disable(st->vref_reg); + return devm_iio_device_register(&spi->dev, iio_dev); } static const struct spi_device_id ad5761_id[] = { @@ -419,7 +357,6 @@ static struct spi_driver ad5761_driver = { .name = "ad5761", }, .probe = ad5761_probe, - .remove = ad5761_remove, .id_table = ad5761_id, }; module_spi_driver(ad5761_driver); diff --git a/drivers/iio/dac/ad5770r.c b/drivers/iio/dac/ad5770r.c index c360ebf5297ab9461e25ae831af2c291346c66aa..25cf11d0471b60071a7912d3886b6d8baac9dc0e 100644 --- a/drivers/iio/dac/ad5770r.c +++ b/drivers/iio/dac/ad5770r.c @@ -17,6 +17,7 @@ #include #include #include +#include #define ADI_SPI_IF_CONFIG_A 0x00 #define ADI_SPI_IF_CONFIG_B 0x01 @@ -121,7 +122,6 @@ struct ad5770r_out_range { * struct ad5770r_state - driver instance specific data * @spi: spi_device * @regmap: regmap - * @vref_reg: fixed regulator for reference configuration * @gpio_reset: gpio descriptor * @output_mode: array contains channels output ranges * @vref: reference value @@ -133,7 +133,6 @@ struct ad5770r_out_range { struct ad5770r_state { struct spi_device *spi; struct regmap *regmap; - struct regulator *vref_reg; struct gpio_desc *gpio_reset; struct ad5770r_out_range output_mode[AD5770R_MAX_CHANNELS]; int vref; @@ -325,7 +324,7 @@ static int ad5770r_read_raw(struct iio_dev *indio_dev, if (ret) return 0; - buf16 = st->transf_buf[0] + (st->transf_buf[1] << 8); + buf16 = get_unaligned_le16(st->transf_buf); *val = buf16 >> 2; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -590,13 +589,6 @@ static int ad5770r_init(struct ad5770r_state *st) return ret; } -static void ad5770r_disable_regulator(void *data) -{ - struct ad5770r_state *st = data; - - regulator_disable(st->vref_reg); -} - static int ad5770r_probe(struct spi_device *spi) { struct ad5770r_state *st; @@ -621,34 +613,12 @@ static int ad5770r_probe(struct spi_device *spi) } st->regmap = regmap; - st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref"); - if (!IS_ERR(st->vref_reg)) { - ret = regulator_enable(st->vref_reg); - if (ret) { - dev_err(&spi->dev, - "Failed to enable vref regulators: %d\n", ret); - return ret; - } + ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(&spi->dev, ret, "Failed to get vref voltage\n"); - ret = devm_add_action_or_reset(&spi->dev, - ad5770r_disable_regulator, - st); - if (ret < 0) - return ret; - - ret = regulator_get_voltage(st->vref_reg); - if (ret < 0) - return ret; - - st->vref = ret / 1000; - } else { - if (PTR_ERR(st->vref_reg) == -ENODEV) { - st->vref = AD5770R_LOW_VREF_mV; - st->internal_ref = true; - } else { - return PTR_ERR(st->vref_reg); - } - } + st->internal_ref = ret == -ENODEV; + st->vref = st->internal_ref ? AD5770R_LOW_VREF_mV : ret / 1000; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->info = &ad5770r_info; diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 75b549827e15a5d9aff5541ee098bdd3920c30b7..57374f78f6b885e1d4f2fb452ac0563b85fc222e 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -61,11 +62,14 @@ /** * struct ad5791_chip_info - chip specific information + * @name: name of the dac chip + * @channel: channel specification * @get_lin_comp: function pointer to the device specific function */ - struct ad5791_chip_info { - int (*get_lin_comp) (unsigned int span); + const char *name; + const struct iio_chan_spec channel; + int (*get_lin_comp)(unsigned int span); }; /** @@ -73,6 +77,9 @@ struct ad5791_chip_info { * @spi: spi_device * @reg_vdd: positive supply regulator * @reg_vss: negative supply regulator + * @gpio_reset: reset gpio + * @gpio_clear: clear gpio + * @gpio_ldac: load dac gpio * @chip_info: chip model specific constants * @vref_mv: actual reference voltage used * @vref_neg_mv: voltage of the negative supply @@ -85,6 +92,9 @@ struct ad5791_state { struct spi_device *spi; struct regulator *reg_vdd; struct regulator *reg_vss; + struct gpio_desc *gpio_reset; + struct gpio_desc *gpio_clear; + struct gpio_desc *gpio_ldac; const struct ad5791_chip_info *chip_info; unsigned short vref_mv; unsigned int vref_neg_mv; @@ -98,13 +108,6 @@ struct ad5791_state { } data[3] __aligned(IIO_DMA_MINALIGN); }; -enum ad5791_supported_device_ids { - ID_AD5760, - ID_AD5780, - ID_AD5781, - ID_AD5791, -}; - static int ad5791_spi_write(struct ad5791_state *st, u8 addr, u32 val) { st->data[0].d32 = cpu_to_be32(AD5791_CMD_WRITE | @@ -228,20 +231,6 @@ static int ad5780_get_lin_comp(unsigned int span) else return AD5780_LINCOMP_10_20; } -static const struct ad5791_chip_info ad5791_chip_info_tbl[] = { - [ID_AD5760] = { - .get_lin_comp = ad5780_get_lin_comp, - }, - [ID_AD5780] = { - .get_lin_comp = ad5780_get_lin_comp, - }, - [ID_AD5781] = { - .get_lin_comp = ad5791_get_lin_comp, - }, - [ID_AD5791] = { - .get_lin_comp = ad5791_get_lin_comp, - }, -}; static int ad5791_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -289,30 +278,34 @@ static const struct iio_chan_spec_ext_info ad5791_ext_info[] = { { }, }; -#define AD5791_CHAN(bits, _shift) { \ - .type = IIO_VOLTAGE, \ - .output = 1, \ - .indexed = 1, \ - .address = AD5791_ADDR_DAC0, \ - .channel = 0, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_OFFSET), \ - .scan_type = { \ - .sign = 'u', \ - .realbits = (bits), \ - .storagebits = 24, \ - .shift = (_shift), \ - }, \ - .ext_info = ad5791_ext_info, \ +#define AD5791_DEFINE_CHIP_INFO(_name, bits, _shift, _lin_comp) \ +static const struct ad5791_chip_info _name##_chip_info = { \ + .name = #_name, \ + .get_lin_comp = &(_lin_comp), \ + .channel = { \ + .type = IIO_VOLTAGE, \ + .output = 1, \ + .indexed = 1, \ + .address = AD5791_ADDR_DAC0, \ + .channel = 0, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 24, \ + .shift = (_shift), \ + }, \ + .ext_info = ad5791_ext_info, \ + }, \ } -static const struct iio_chan_spec ad5791_channels[] = { - [ID_AD5760] = AD5791_CHAN(16, 4), - [ID_AD5780] = AD5791_CHAN(18, 2), - [ID_AD5781] = AD5791_CHAN(18, 2), - [ID_AD5791] = AD5791_CHAN(20, 0) -}; +AD5791_DEFINE_CHIP_INFO(ad5760, 16, 4, ad5780_get_lin_comp); +AD5791_DEFINE_CHIP_INFO(ad5780, 18, 2, ad5780_get_lin_comp); +AD5791_DEFINE_CHIP_INFO(ad5781, 18, 2, ad5791_get_lin_comp); +AD5791_DEFINE_CHIP_INFO(ad5790, 20, 0, ad5791_get_lin_comp); +AD5791_DEFINE_CHIP_INFO(ad5791, 20, 0, ad5791_get_lin_comp); static int ad5791_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -341,7 +334,7 @@ static const struct iio_info ad5791_info = { static int ad5791_probe(struct spi_device *spi) { - struct ad5791_platform_data *pdata = spi->dev.platform_data; + const struct ad5791_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad5791_state *st; int ret, pos_voltage_uv = 0, neg_voltage_uv = 0; @@ -351,31 +344,21 @@ static int ad5791_probe(struct spi_device *spi) if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); - st->reg_vdd = devm_regulator_get(&spi->dev, "vdd"); - if (!IS_ERR(st->reg_vdd)) { - ret = regulator_enable(st->reg_vdd); - if (ret) - return ret; - - ret = regulator_get_voltage(st->reg_vdd); - if (ret < 0) - goto error_disable_reg_pos; - - pos_voltage_uv = ret; - } - st->reg_vss = devm_regulator_get(&spi->dev, "vss"); - if (!IS_ERR(st->reg_vss)) { - ret = regulator_enable(st->reg_vss); - if (ret) - goto error_disable_reg_pos; + st->gpio_reset = devm_gpiod_get_optional(&spi->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(st->gpio_reset)) + return PTR_ERR(st->gpio_reset); - ret = regulator_get_voltage(st->reg_vss); - if (ret < 0) - goto error_disable_reg_neg; + st->gpio_clear = devm_gpiod_get_optional(&spi->dev, "clear", + GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_clear)) + return PTR_ERR(st->gpio_clear); - neg_voltage_uv = ret; - } + st->gpio_ldac = devm_gpiod_get_optional(&spi->dev, "ldac", + GPIOD_OUT_HIGH); + if (IS_ERR(st->gpio_ldac)) + return PTR_ERR(st->gpio_ldac); st->pwr_down = true; st->spi = spi; @@ -386,7 +369,17 @@ static int ad5791_probe(struct spi_device *spi) use_rbuf_gain2 = device_property_read_bool(&spi->dev, "adi,rbuf-gain2-en"); - if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) { + pos_voltage_uv = devm_regulator_get_enable_read_voltage(&spi->dev, "vdd"); + if (pos_voltage_uv < 0 && pos_voltage_uv != -ENODEV) + return dev_err_probe(&spi->dev, pos_voltage_uv, + "failed to get vdd voltage\n"); + + neg_voltage_uv = devm_regulator_get_enable_read_voltage(&spi->dev, "vss"); + if (neg_voltage_uv < 0 && neg_voltage_uv != -ENODEV) + return dev_err_probe(&spi->dev, neg_voltage_uv, + "failed to get vss voltage\n"); + + if (neg_voltage_uv >= 0 && pos_voltage_uv >= 0) { st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000; st->vref_neg_mv = neg_voltage_uv / 1000; } else if (pdata) { @@ -396,13 +389,18 @@ static int ad5791_probe(struct spi_device *spi) dev_warn(&spi->dev, "reference voltage unspecified\n"); } - ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); - if (ret) - goto error_disable_reg_neg; - - st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi) - ->driver_data]; + if (st->gpio_reset) { + fsleep(20); + gpiod_set_value_cansleep(st->gpio_reset, 0); + } else { + ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); + if (ret) + return dev_err_probe(&spi->dev, ret, "fail to reset\n"); + } + st->chip_info = spi_get_device_match_data(spi); + if (!st->chip_info) + return dev_err_probe(&spi->dev, -EINVAL, "no chip info\n"); st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv)) | (use_rbuf_gain2 ? 0 : AD5791_CTRL_RBUF) | @@ -411,59 +409,42 @@ static int ad5791_probe(struct spi_device *spi) ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl | AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); if (ret) - goto error_disable_reg_neg; + return dev_err_probe(&spi->dev, ret, "fail to write ctrl register\n"); - spi_set_drvdata(spi, indio_dev); indio_dev->info = &ad5791_info; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels - = &ad5791_channels[spi_get_device_id(spi)->driver_data]; + indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; - indio_dev->name = spi_get_device_id(st->spi)->name; - ret = iio_device_register(indio_dev); - if (ret) - goto error_disable_reg_neg; - - return 0; - -error_disable_reg_neg: - if (!IS_ERR(st->reg_vss)) - regulator_disable(st->reg_vss); -error_disable_reg_pos: - if (!IS_ERR(st->reg_vdd)) - regulator_disable(st->reg_vdd); - return ret; + indio_dev->name = st->chip_info->name; + return devm_iio_device_register(&spi->dev, indio_dev); } -static void ad5791_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad5791_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg_vdd)) - regulator_disable(st->reg_vdd); - - if (!IS_ERR(st->reg_vss)) - regulator_disable(st->reg_vss); -} +static const struct of_device_id ad5791_of_match[] = { + { .compatible = "adi,ad5760", .data = &ad5760_chip_info }, + { .compatible = "adi,ad5780", .data = &ad5780_chip_info }, + { .compatible = "adi,ad5781", .data = &ad5781_chip_info }, + { .compatible = "adi,ad5790", .data = &ad5790_chip_info }, + { .compatible = "adi,ad5791", .data = &ad5791_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(of, ad5791_of_match); static const struct spi_device_id ad5791_id[] = { - {"ad5760", ID_AD5760}, - {"ad5780", ID_AD5780}, - {"ad5781", ID_AD5781}, - {"ad5790", ID_AD5791}, - {"ad5791", ID_AD5791}, - {} + { "ad5760", (kernel_ulong_t)&ad5760_chip_info }, + { "ad5780", (kernel_ulong_t)&ad5780_chip_info }, + { "ad5781", (kernel_ulong_t)&ad5781_chip_info }, + { "ad5790", (kernel_ulong_t)&ad5790_chip_info }, + { "ad5791", (kernel_ulong_t)&ad5791_chip_info }, + { } }; MODULE_DEVICE_TABLE(spi, ad5791_id); static struct spi_driver ad5791_driver = { .driver = { .name = "ad5791", + .of_match_table = ad5791_of_match, }, .probe = ad5791_probe, - .remove = ad5791_remove, .id_table = ad5791_id, }; module_spi_driver(ad5791_driver); diff --git a/drivers/iio/dac/ad8460.c b/drivers/iio/dac/ad8460.c new file mode 100644 index 0000000000000000000000000000000000000000..535ee3105af6b1d726cf6b3545886498c329f706 --- /dev/null +++ b/drivers/iio/dac/ad8460.c @@ -0,0 +1,951 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AD8460 Waveform generator DAC Driver + * + * Copyright (C) 2024 Analog Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define AD8460_CTRL_REG(x) (x) +#define AD8460_HVDAC_DATA_WORD(x) (0x60 + (2 * (x))) + +#define AD8460_HV_RESET_MSK BIT(7) +#define AD8460_HV_SLEEP_MSK BIT(4) +#define AD8460_WAVE_GEN_MODE_MSK BIT(0) + +#define AD8460_HVDAC_SLEEP_MSK BIT(3) + +#define AD8460_FAULT_ARM_MSK BIT(7) +#define AD8460_FAULT_LIMIT_MSK GENMASK(6, 0) + +#define AD8460_APG_MODE_ENABLE_MSK BIT(5) +#define AD8460_PATTERN_DEPTH_MSK GENMASK(3, 0) + +#define AD8460_QUIESCENT_CURRENT_MSK GENMASK(7, 0) + +#define AD8460_SHUTDOWN_FLAG_MSK BIT(7) + +#define AD8460_DATA_BYTE_LOW_MSK GENMASK(7, 0) +#define AD8460_DATA_BYTE_HIGH_MSK GENMASK(5, 0) +#define AD8460_DATA_BYTE_FULL_MSK GENMASK(13, 0) + +#define AD8460_DEFAULT_FAULT_PROTECT 0x00 +#define AD8460_DATA_BYTE_WORD_LENGTH 2 +#define AD8460_NUM_DATA_WORDS 16 +#define AD8460_NOMINAL_VOLTAGE_SPAN 80 +#define AD8460_MIN_EXT_RESISTOR_OHMS 2000 +#define AD8460_MAX_EXT_RESISTOR_OHMS 20000 +#define AD8460_MIN_VREFIO_UV 120000 +#define AD8460_MAX_VREFIO_UV 1200000 +#define AD8460_ABS_MAX_OVERVOLTAGE_UV 55000000 +#define AD8460_ABS_MAX_OVERCURRENT_UA 1000000 +#define AD8460_MAX_OVERTEMPERATURE_MC 150000 +#define AD8460_MIN_OVERTEMPERATURE_MC 20000 +#define AD8460_CURRENT_LIMIT_CONV(x) ((x) / 15625) +#define AD8460_VOLTAGE_LIMIT_CONV(x) ((x) / 1953000) +#define AD8460_TEMP_LIMIT_CONV(x) (((x) + 266640) / 6510) + +enum ad8460_fault_type { + AD8460_OVERCURRENT_SRC, + AD8460_OVERCURRENT_SNK, + AD8460_OVERVOLTAGE_POS, + AD8460_OVERVOLTAGE_NEG, + AD8460_OVERTEMPERATURE, +}; + +struct ad8460_state { + struct spi_device *spi; + struct regmap *regmap; + struct iio_channel *tmp_adc_channel; + struct clk *sync_clk; + /* lock to protect against multiple access to the device and shared data */ + struct mutex lock; + int refio_1p2v_mv; + u32 ext_resistor_ohms; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + __le16 spi_tx_buf __aligned(IIO_DMA_MINALIGN); +}; + +static int ad8460_hv_reset(struct ad8460_state *state) +{ + int ret; + + ret = regmap_set_bits(state->regmap, AD8460_CTRL_REG(0x00), + AD8460_HV_RESET_MSK); + if (ret) + return ret; + + fsleep(20); + + return regmap_clear_bits(state->regmap, AD8460_CTRL_REG(0x00), + AD8460_HV_RESET_MSK); +} + +static int ad8460_reset(const struct ad8460_state *state) +{ + struct device *dev = &state->spi->dev; + struct gpio_desc *reset; + + reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(reset)) + return dev_err_probe(dev, PTR_ERR(reset), + "Failed to get reset gpio"); + if (reset) { + /* minimum duration of 10ns */ + ndelay(10); + gpiod_set_value_cansleep(reset, 1); + return 0; + } + + /* bring all registers to their default state */ + return regmap_write(state->regmap, AD8460_CTRL_REG(0x03), 1); +} + +static int ad8460_enable_apg_mode(struct ad8460_state *state, int val) +{ + int ret; + + ret = regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x02), + AD8460_APG_MODE_ENABLE_MSK, + FIELD_PREP(AD8460_APG_MODE_ENABLE_MSK, val)); + if (ret) + return ret; + + return regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x00), + AD8460_WAVE_GEN_MODE_MSK, + FIELD_PREP(AD8460_WAVE_GEN_MODE_MSK, val)); +} + +static int ad8460_read_shutdown_flag(struct ad8460_state *state, u64 *flag) +{ + int ret, val; + + ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x0E), &val); + if (ret) + return ret; + + *flag = FIELD_GET(AD8460_SHUTDOWN_FLAG_MSK, val); + return 0; +} + +static int ad8460_get_hvdac_word(struct ad8460_state *state, int index, int *val) +{ + int ret; + + ret = regmap_bulk_read(state->regmap, AD8460_HVDAC_DATA_WORD(index), + &state->spi_tx_buf, AD8460_DATA_BYTE_WORD_LENGTH); + if (ret) + return ret; + + *val = le16_to_cpu(state->spi_tx_buf); + + return ret; +} + +static int ad8460_set_hvdac_word(struct ad8460_state *state, int index, int val) +{ + state->spi_tx_buf = cpu_to_le16(FIELD_PREP(AD8460_DATA_BYTE_FULL_MSK, val)); + + return regmap_bulk_write(state->regmap, AD8460_HVDAC_DATA_WORD(index), + &state->spi_tx_buf, AD8460_DATA_BYTE_WORD_LENGTH); +} + +static ssize_t ad8460_dac_input_read(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, char *buf) +{ + struct ad8460_state *state = iio_priv(indio_dev); + unsigned int reg; + int ret; + + ret = ad8460_get_hvdac_word(state, private, ®); + if (ret) + return ret; + + return sysfs_emit(buf, "%u\n", reg); +} + +static ssize_t ad8460_dac_input_write(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ad8460_state *state = iio_priv(indio_dev); + unsigned int reg; + int ret; + + ret = kstrtou32(buf, 10, ®); + if (ret) + return ret; + + guard(mutex)(&state->lock); + + return ad8460_set_hvdac_word(state, private, reg); +} + +static ssize_t ad8460_read_symbol(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, char *buf) +{ + struct ad8460_state *state = iio_priv(indio_dev); + unsigned int reg; + int ret; + + ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x02), ®); + if (ret) + return ret; + + return sysfs_emit(buf, "%lu\n", FIELD_GET(AD8460_PATTERN_DEPTH_MSK, reg)); +} + +static ssize_t ad8460_write_symbol(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ad8460_state *state = iio_priv(indio_dev); + uint16_t sym; + int ret; + + ret = kstrtou16(buf, 10, &sym); + if (ret) + return ret; + + guard(mutex)(&state->lock); + + return regmap_update_bits(state->regmap, + AD8460_CTRL_REG(0x02), + AD8460_PATTERN_DEPTH_MSK, + FIELD_PREP(AD8460_PATTERN_DEPTH_MSK, sym)); +} + +static ssize_t ad8460_read_toggle_en(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, char *buf) +{ + struct ad8460_state *state = iio_priv(indio_dev); + unsigned int reg; + int ret; + + ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x02), ®); + if (ret) + return ret; + + return sysfs_emit(buf, "%ld\n", FIELD_GET(AD8460_APG_MODE_ENABLE_MSK, reg)); +} + +static ssize_t ad8460_write_toggle_en(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ad8460_state *state = iio_priv(indio_dev); + bool toggle_en; + int ret; + + ret = kstrtobool(buf, &toggle_en); + if (ret) + return ret; + + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) + return ad8460_enable_apg_mode(state, toggle_en); + unreachable(); +} + +static ssize_t ad8460_read_powerdown(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, char *buf) +{ + struct ad8460_state *state = iio_priv(indio_dev); + unsigned int reg; + int ret; + + ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x01), ®); + if (ret) + return ret; + + return sysfs_emit(buf, "%ld\n", FIELD_GET(AD8460_HVDAC_SLEEP_MSK, reg)); +} + +static ssize_t ad8460_write_powerdown(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ad8460_state *state = iio_priv(indio_dev); + bool pwr_down; + u64 sdn_flag; + int ret; + + ret = kstrtobool(buf, &pwr_down); + if (ret) + return ret; + + guard(mutex)(&state->lock); + + /* + * If powerdown is set, HVDAC is enabled and the HV driver is + * enabled via HV_RESET in case it is in shutdown mode, + * If powerdown is cleared, HVDAC is set to shutdown state + * as well as the HV driver. Quiescent current decreases and ouput is + * floating (high impedance). + */ + + ret = regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x01), + AD8460_HVDAC_SLEEP_MSK, + FIELD_PREP(AD8460_HVDAC_SLEEP_MSK, pwr_down)); + if (ret) + return ret; + + if (!pwr_down) { + ret = ad8460_read_shutdown_flag(state, &sdn_flag); + if (ret) + return ret; + + if (sdn_flag) { + ret = ad8460_hv_reset(state); + if (ret) + return ret; + } + } + + ret = regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x00), + AD8460_HV_SLEEP_MSK, + FIELD_PREP(AD8460_HV_SLEEP_MSK, !pwr_down)); + if (ret) + return ret; + + return len; +} + +static const char * const ad8460_powerdown_modes[] = { + "three_state", +}; + +static int ad8460_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + return 0; +} + +static int ad8460_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int type) +{ + return 0; +} + +static int ad8460_set_sample(struct ad8460_state *state, int val) +{ + int ret; + + ret = ad8460_enable_apg_mode(state, 1); + if (ret) + return ret; + + guard(mutex)(&state->lock); + ret = ad8460_set_hvdac_word(state, 0, val); + if (ret) + return ret; + + return regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x02), + AD8460_PATTERN_DEPTH_MSK, + FIELD_PREP(AD8460_PATTERN_DEPTH_MSK, 0)); +} + +static int ad8460_set_fault_threshold(struct ad8460_state *state, + enum ad8460_fault_type fault, + unsigned int threshold) +{ + return regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x08 + fault), + AD8460_FAULT_LIMIT_MSK, + FIELD_PREP(AD8460_FAULT_LIMIT_MSK, threshold)); +} + +static int ad8460_get_fault_threshold(struct ad8460_state *state, + enum ad8460_fault_type fault, + unsigned int *threshold) +{ + unsigned int val; + int ret; + + ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x08 + fault), &val); + if (ret) + return ret; + + *threshold = FIELD_GET(AD8460_FAULT_LIMIT_MSK, val); + + return ret; +} + +static int ad8460_set_fault_threshold_en(struct ad8460_state *state, + enum ad8460_fault_type fault, bool en) +{ + return regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x08 + fault), + AD8460_FAULT_ARM_MSK, + FIELD_PREP(AD8460_FAULT_ARM_MSK, en)); +} + +static int ad8460_get_fault_threshold_en(struct ad8460_state *state, + enum ad8460_fault_type fault, bool *en) +{ + unsigned int val; + int ret; + + ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x08 + fault), &val); + if (ret) + return ret; + + *en = FIELD_GET(AD8460_FAULT_ARM_MSK, val); + + return 0; +} + +static int ad8460_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long mask) +{ + struct ad8460_state *state = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_VOLTAGE: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) + return ad8460_set_sample(state, val); + unreachable(); + case IIO_CURRENT: + return regmap_write(state->regmap, AD8460_CTRL_REG(0x04), + FIELD_PREP(AD8460_QUIESCENT_CURRENT_MSK, val)); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int ad8460_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct ad8460_state *state = iio_priv(indio_dev); + int data, ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_VOLTAGE: + scoped_guard(mutex, &state->lock) { + ret = ad8460_get_hvdac_word(state, 0, &data); + if (ret) + return ret; + } + *val = data; + return IIO_VAL_INT; + case IIO_CURRENT: + ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x04), + &data); + if (ret) + return ret; + *val = data; + return IIO_VAL_INT; + case IIO_TEMP: + ret = iio_read_channel_raw(state->tmp_adc_channel, &data); + if (ret) + return ret; + *val = data; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SAMP_FREQ: + *val = clk_get_rate(state->sync_clk); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* + * vCONV = vNOMINAL_SPAN * (DAC_CODE / 2**14) - 40V + * vMAX = vNOMINAL_SPAN * (2**14 / 2**14) - 40V + * vMIN = vNOMINAL_SPAN * (0 / 2**14) - 40V + * vADJ = vCONV * (2000 / rSET) * (vREF / 1.2) + * vSPAN = vADJ_MAX - vADJ_MIN + * See datasheet page 49, section FULL-SCALE REDUCTION + */ + *val = AD8460_NOMINAL_VOLTAGE_SPAN * 2000 * state->refio_1p2v_mv; + *val2 = state->ext_resistor_ohms * 1200; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } +} + +static int ad8460_select_fault_type(int chan_type, enum iio_event_direction dir) +{ + switch (chan_type) { + case IIO_VOLTAGE: + switch (dir) { + case IIO_EV_DIR_RISING: + return AD8460_OVERVOLTAGE_POS; + case IIO_EV_DIR_FALLING: + return AD8460_OVERVOLTAGE_NEG; + default: + return -EINVAL; + } + case IIO_CURRENT: + switch (dir) { + case IIO_EV_DIR_RISING: + return AD8460_OVERCURRENT_SRC; + case IIO_EV_DIR_FALLING: + return AD8460_OVERCURRENT_SNK; + default: + return -EINVAL; + } + case IIO_TEMP: + switch (dir) { + case IIO_EV_DIR_RISING: + return AD8460_OVERTEMPERATURE; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int ad8460_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val, int val2) +{ + struct ad8460_state *state = iio_priv(indio_dev); + int fault; + + if (type != IIO_EV_TYPE_THRESH) + return -EINVAL; + + if (info != IIO_EV_INFO_VALUE) + return -EINVAL; + + fault = ad8460_select_fault_type(chan->type, dir); + if (fault < 0) + return fault; + + return ad8460_set_fault_threshold(state, fault, val); +} + +static int ad8460_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int *val, int *val2) +{ + struct ad8460_state *state = iio_priv(indio_dev); + int fault; + + if (type != IIO_EV_TYPE_THRESH) + return -EINVAL; + + if (info != IIO_EV_INFO_VALUE) + return -EINVAL; + + fault = ad8460_select_fault_type(chan->type, dir); + if (fault < 0) + return fault; + + return ad8460_get_fault_threshold(state, fault, val); +} + +static int ad8460_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, bool val) +{ + struct ad8460_state *state = iio_priv(indio_dev); + int fault; + + if (type != IIO_EV_TYPE_THRESH) + return -EINVAL; + + fault = ad8460_select_fault_type(chan->type, dir); + if (fault < 0) + return fault; + + return ad8460_set_fault_threshold_en(state, fault, val); +} + +static int ad8460_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct ad8460_state *state = iio_priv(indio_dev); + int fault, ret; + bool en; + + if (type != IIO_EV_TYPE_THRESH) + return -EINVAL; + + fault = ad8460_select_fault_type(chan->type, dir); + if (fault < 0) + return fault; + + ret = ad8460_get_fault_threshold_en(state, fault, &en); + if (ret) + return ret; + + return en; +} + +static int ad8460_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad8460_state *state = iio_priv(indio_dev); + + if (readval) + return regmap_read(state->regmap, reg, readval); + + return regmap_write(state->regmap, reg, writeval); +} + +static int ad8460_buffer_preenable(struct iio_dev *indio_dev) +{ + struct ad8460_state *state = iio_priv(indio_dev); + + return ad8460_enable_apg_mode(state, 0); +} + +static int ad8460_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad8460_state *state = iio_priv(indio_dev); + + return ad8460_enable_apg_mode(state, 1); +} + +static const struct iio_buffer_setup_ops ad8460_buffer_setup_ops = { + .preenable = &ad8460_buffer_preenable, + .postdisable = &ad8460_buffer_postdisable, +}; + +static const struct iio_info ad8460_info = { + .read_raw = &ad8460_read_raw, + .write_raw = &ad8460_write_raw, + .write_event_value = &ad8460_write_event_value, + .read_event_value = &ad8460_read_event_value, + .write_event_config = &ad8460_write_event_config, + .read_event_config = &ad8460_read_event_config, + .debugfs_reg_access = &ad8460_reg_access, +}; + +static const struct iio_enum ad8460_powerdown_mode_enum = { + .items = ad8460_powerdown_modes, + .num_items = ARRAY_SIZE(ad8460_powerdown_modes), + .get = ad8460_get_powerdown_mode, + .set = ad8460_set_powerdown_mode, +}; + +#define AD8460_CHAN_EXT_INFO(_name, _what, _read, _write) { \ + .name = (_name), \ + .read = (_read), \ + .write = (_write), \ + .private = (_what), \ + .shared = IIO_SEPARATE, \ +} + +static const struct iio_chan_spec_ext_info ad8460_ext_info[] = { + AD8460_CHAN_EXT_INFO("raw0", 0, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw1", 1, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw2", 2, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw3", 3, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw4", 4, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw5", 5, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw6", 6, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw7", 7, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw8", 8, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw9", 9, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw10", 10, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw11", 11, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw12", 12, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw13", 13, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw14", 14, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("raw15", 15, ad8460_dac_input_read, + ad8460_dac_input_write), + AD8460_CHAN_EXT_INFO("toggle_en", 0, ad8460_read_toggle_en, + ad8460_write_toggle_en), + AD8460_CHAN_EXT_INFO("symbol", 0, ad8460_read_symbol, + ad8460_write_symbol), + AD8460_CHAN_EXT_INFO("powerdown", 0, ad8460_read_powerdown, + ad8460_write_powerdown), + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad8460_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, + &ad8460_powerdown_mode_enum), + { } +}; + +static const struct iio_event_spec ad8460_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + +#define AD8460_VOLTAGE_CHAN { \ + .type = IIO_VOLTAGE, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .output = 1, \ + .indexed = 1, \ + .channel = 0, \ + .scan_index = 0, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 14, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ + .ext_info = ad8460_ext_info, \ + .event_spec = ad8460_events, \ + .num_event_specs = ARRAY_SIZE(ad8460_events), \ +} + +#define AD8460_CURRENT_CHAN { \ + .type = IIO_CURRENT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .output = 1, \ + .indexed = 1, \ + .channel = 0, \ + .scan_index = -1, \ + .event_spec = ad8460_events, \ + .num_event_specs = ARRAY_SIZE(ad8460_events), \ +} + +#define AD8460_TEMP_CHAN { \ + .type = IIO_TEMP, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .indexed = 1, \ + .channel = 0, \ + .scan_index = -1, \ + .event_spec = ad8460_events, \ + .num_event_specs = 1, \ +} + +static const struct iio_chan_spec ad8460_channels[] = { + AD8460_VOLTAGE_CHAN, + AD8460_CURRENT_CHAN, +}; + +static const struct iio_chan_spec ad8460_channels_with_tmp_adc[] = { + AD8460_VOLTAGE_CHAN, + AD8460_CURRENT_CHAN, + AD8460_TEMP_CHAN, +}; + +static const struct regmap_config ad8460_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x7F, +}; + +static const char * const ad8460_supplies[] = { + "avdd_3p3v", "dvdd_3p3v", "vcc_5v", "hvcc", "hvee", "vref_5v" +}; + +static int ad8460_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct ad8460_state *state; + struct iio_dev *indio_dev; + u32 tmp[2], temp; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state)); + if (!indio_dev) + return -ENOMEM; + + state = iio_priv(indio_dev); + + indio_dev->name = "ad8460"; + indio_dev->info = &ad8460_info; + + state->spi = spi; + + state->regmap = devm_regmap_init_spi(spi, &ad8460_regmap_config); + if (IS_ERR(state->regmap)) + return dev_err_probe(dev, PTR_ERR(state->regmap), + "Failed to initialize regmap"); + + ret = devm_mutex_init(dev, &state->lock); + if (ret) + return ret; + + state->sync_clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(state->sync_clk)) + return dev_err_probe(dev, PTR_ERR(state->sync_clk), + "Failed to get sync clk\n"); + + state->tmp_adc_channel = devm_iio_channel_get(dev, "ad8460-tmp"); + if (IS_ERR(state->tmp_adc_channel)) { + if (PTR_ERR(state->tmp_adc_channel) == -EPROBE_DEFER) + return -EPROBE_DEFER; + indio_dev->channels = ad8460_channels; + indio_dev->num_channels = ARRAY_SIZE(ad8460_channels); + } else { + indio_dev->channels = ad8460_channels_with_tmp_adc; + indio_dev->num_channels = ARRAY_SIZE(ad8460_channels_with_tmp_adc); + } + + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad8460_supplies), + ad8460_supplies); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable power supplies\n"); + + ret = devm_regulator_get_enable_read_voltage(dev, "refio_1p2v"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(dev, ret, "Failed to get reference voltage\n"); + + state->refio_1p2v_mv = ret == -ENODEV ? 1200 : ret / 1000; + + if (!in_range(state->refio_1p2v_mv, AD8460_MIN_VREFIO_UV / 1000, + AD8460_MAX_VREFIO_UV / 1000)) + return dev_err_probe(dev, -EINVAL, + "Invalid ref voltage range(%u mV) [%u mV, %u mV]\n", + state->refio_1p2v_mv, + AD8460_MIN_VREFIO_UV / 1000, + AD8460_MAX_VREFIO_UV / 1000); + + ret = device_property_read_u32(dev, "adi,external-resistor-ohms", + &state->ext_resistor_ohms); + if (ret) + state->ext_resistor_ohms = 2000; + else if (!in_range(state->ext_resistor_ohms, AD8460_MIN_EXT_RESISTOR_OHMS, + AD8460_MAX_EXT_RESISTOR_OHMS)) + return dev_err_probe(dev, -EINVAL, + "Invalid resistor set range(%u) [%u, %u]\n", + state->ext_resistor_ohms, + AD8460_MIN_EXT_RESISTOR_OHMS, + AD8460_MAX_EXT_RESISTOR_OHMS); + + ret = device_property_read_u32_array(dev, "adi,range-microamp", + tmp, ARRAY_SIZE(tmp)); + if (!ret) { + if (in_range(tmp[1], 0, AD8460_ABS_MAX_OVERCURRENT_UA)) + regmap_write(state->regmap, AD8460_CTRL_REG(0x08), + FIELD_PREP(AD8460_FAULT_ARM_MSK, 1) | + AD8460_CURRENT_LIMIT_CONV(tmp[1])); + + if (in_range(tmp[0], -AD8460_ABS_MAX_OVERCURRENT_UA, 0)) + regmap_write(state->regmap, AD8460_CTRL_REG(0x09), + FIELD_PREP(AD8460_FAULT_ARM_MSK, 1) | + AD8460_CURRENT_LIMIT_CONV(abs(tmp[0]))); + } + + ret = device_property_read_u32_array(dev, "adi,range-microvolt", + tmp, ARRAY_SIZE(tmp)); + if (!ret) { + if (in_range(tmp[1], 0, AD8460_ABS_MAX_OVERVOLTAGE_UV)) + regmap_write(state->regmap, AD8460_CTRL_REG(0x0A), + FIELD_PREP(AD8460_FAULT_ARM_MSK, 1) | + AD8460_VOLTAGE_LIMIT_CONV(tmp[1])); + + if (in_range(tmp[0], -AD8460_ABS_MAX_OVERVOLTAGE_UV, 0)) + regmap_write(state->regmap, AD8460_CTRL_REG(0x0B), + FIELD_PREP(AD8460_FAULT_ARM_MSK, 1) | + AD8460_VOLTAGE_LIMIT_CONV(abs(tmp[0]))); + } + + ret = device_property_read_u32(dev, "adi,max-millicelsius", &temp); + if (!ret) { + if (in_range(temp, AD8460_MIN_OVERTEMPERATURE_MC, + AD8460_MAX_OVERTEMPERATURE_MC)) + regmap_write(state->regmap, AD8460_CTRL_REG(0x0C), + FIELD_PREP(AD8460_FAULT_ARM_MSK, 1) | + AD8460_TEMP_LIMIT_CONV(abs(temp))); + } + + ret = ad8460_reset(state); + if (ret) + return ret; + + /* Enables DAC by default */ + ret = regmap_clear_bits(state->regmap, AD8460_CTRL_REG(0x01), + AD8460_HVDAC_SLEEP_MSK); + if (ret) + return ret; + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->setup_ops = &ad8460_buffer_setup_ops; + + ret = devm_iio_dmaengine_buffer_setup_ext(dev, indio_dev, "tx", + IIO_BUFFER_DIRECTION_OUT); + if (ret) + return dev_err_probe(dev, ret, + "Failed to get DMA buffer\n"); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id ad8460_of_match[] = { + { .compatible = "adi,ad8460" }, + { } +}; +MODULE_DEVICE_TABLE(of, ad8460_of_match); + +static const struct spi_device_id ad8460_spi_match[] = { + { .name = "ad8460" }, + { } +}; +MODULE_DEVICE_TABLE(spi, ad8460_spi_match); + +static struct spi_driver ad8460_driver = { + .driver = { + .name = "ad8460", + .of_match_table = ad8460_of_match, + }, + .probe = ad8460_probe, + .id_table = ad8460_spi_match, +}; +module_spi_driver(ad8460_driver); + +MODULE_AUTHOR("Mariel Tinaco "); MODULE_AUTHOR("Nuno Sa "); MODULE_DESCRIPTION("Analog Devices AD9739 DAC"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_BACKEND); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index 0cb00f3bec0453e56e1317d12fef3573bcc4621a..b143f7ed6847277aeb49094627d90e5d95eed71c 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -29,44 +29,77 @@ #include #include +#include "ad3552r-hs.h" + /* * Register definitions: * https://wiki.analog.com/resources/fpga/docs/axi_dac_ip#register_map */ /* Base controls */ -#define AXI_DAC_REG_CONFIG 0x0c -#define AXI_DDS_DISABLE BIT(6) +#define AXI_DAC_CONFIG_REG 0x0c +#define AXI_DAC_CONFIG_DDS_DISABLE BIT(6) /* DAC controls */ -#define AXI_DAC_REG_RSTN 0x0040 -#define AXI_DAC_RSTN_CE_N BIT(2) -#define AXI_DAC_RSTN_MMCM_RSTN BIT(1) -#define AXI_DAC_RSTN_RSTN BIT(0) -#define AXI_DAC_REG_CNTRL_1 0x0044 -#define AXI_DAC_SYNC BIT(0) -#define AXI_DAC_REG_CNTRL_2 0x0048 -#define ADI_DAC_R1_MODE BIT(4) -#define AXI_DAC_DRP_STATUS 0x0074 -#define AXI_DAC_DRP_LOCKED BIT(17) +#define AXI_DAC_RSTN_REG 0x0040 +#define AXI_DAC_RSTN_CE_N BIT(2) +#define AXI_DAC_RSTN_MMCM_RSTN BIT(1) +#define AXI_DAC_RSTN_RSTN BIT(0) +#define AXI_DAC_CNTRL_1_REG 0x0044 +#define AXI_DAC_CNTRL_1_SYNC BIT(0) +#define AXI_DAC_CNTRL_2_REG 0x0048 +#define AXI_DAC_CNTRL_2_SDR_DDR_N BIT(16) +#define AXI_DAC_CNTRL_2_SYMB_8B BIT(14) +#define ADI_DAC_CNTRL_2_R1_MODE BIT(5) +#define AXI_DAC_CNTRL_2_UNSIGNED_DATA BIT(4) +#define AXI_DAC_STATUS_1_REG 0x0054 +#define AXI_DAC_STATUS_2_REG 0x0058 +#define AXI_DAC_DRP_STATUS_REG 0x0074 +#define AXI_DAC_DRP_STATUS_DRP_LOCKED BIT(17) +#define AXI_DAC_CUSTOM_RD_REG 0x0080 +#define AXI_DAC_CUSTOM_WR_REG 0x0084 +#define AXI_DAC_CUSTOM_WR_DATA_8 GENMASK(23, 16) +#define AXI_DAC_CUSTOM_WR_DATA_16 GENMASK(23, 8) +#define AXI_DAC_UI_STATUS_REG 0x0088 +#define AXI_DAC_UI_STATUS_IF_BUSY BIT(4) +#define AXI_DAC_CUSTOM_CTRL_REG 0x008C +#define AXI_DAC_CUSTOM_CTRL_ADDRESS GENMASK(31, 24) +#define AXI_DAC_CUSTOM_CTRL_SYNCED_TRANSFER BIT(2) +#define AXI_DAC_CUSTOM_CTRL_STREAM BIT(1) +#define AXI_DAC_CUSTOM_CTRL_TRANSFER_DATA BIT(0) + +#define AXI_DAC_CUSTOM_CTRL_STREAM_ENABLE (AXI_DAC_CUSTOM_CTRL_TRANSFER_DATA | \ + AXI_DAC_CUSTOM_CTRL_STREAM) + /* DAC Channel controls */ -#define AXI_DAC_REG_CHAN_CNTRL_1(c) (0x0400 + (c) * 0x40) -#define AXI_DAC_REG_CHAN_CNTRL_3(c) (0x0408 + (c) * 0x40) -#define AXI_DAC_SCALE_SIGN BIT(15) -#define AXI_DAC_SCALE_INT BIT(14) -#define AXI_DAC_SCALE GENMASK(14, 0) -#define AXI_DAC_REG_CHAN_CNTRL_2(c) (0x0404 + (c) * 0x40) -#define AXI_DAC_REG_CHAN_CNTRL_4(c) (0x040c + (c) * 0x40) -#define AXI_DAC_PHASE GENMASK(31, 16) -#define AXI_DAC_FREQUENCY GENMASK(15, 0) -#define AXI_DAC_REG_CHAN_CNTRL_7(c) (0x0418 + (c) * 0x40) -#define AXI_DAC_DATA_SEL GENMASK(3, 0) +#define AXI_DAC_CHAN_CNTRL_1_REG(c) (0x0400 + (c) * 0x40) +#define AXI_DAC_CHAN_CNTRL_3_REG(c) (0x0408 + (c) * 0x40) +#define AXI_DAC_CHAN_CNTRL_3_SCALE_SIGN BIT(15) +#define AXI_DAC_CHAN_CNTRL_3_SCALE_INT BIT(14) +#define AXI_DAC_CHAN_CNTRL_3_SCALE GENMASK(14, 0) +#define AXI_DAC_CHAN_CNTRL_2_REG(c) (0x0404 + (c) * 0x40) +#define AXI_DAC_CHAN_CNTRL_2_PHASE GENMASK(31, 16) +#define AXI_DAC_CHAN_CNTRL_2_FREQUENCY GENMASK(15, 0) +#define AXI_DAC_CHAN_CNTRL_4_REG(c) (0x040c + (c) * 0x40) +#define AXI_DAC_CHAN_CNTRL_7_REG(c) (0x0418 + (c) * 0x40) +#define AXI_DAC_CHAN_CNTRL_7_DATA_SEL GENMASK(3, 0) + +#define AXI_DAC_RD_ADDR(x) (BIT(7) | (x)) /* 360 degrees in rad */ -#define AXI_DAC_2_PI_MEGA 6283190 +#define AXI_DAC_2_PI_MEGA 6283190 + enum { AXI_DAC_DATA_INTERNAL_TONE, AXI_DAC_DATA_DMA = 2, + AXI_DAC_DATA_INTERNAL_RAMP_16BIT = 11, +}; + +struct axi_dac_info { + unsigned int version; + const struct iio_backend_info *backend_info; + bool has_dac_clk; + bool has_child_nodes; }; struct axi_dac_state { @@ -77,9 +110,11 @@ struct axi_dac_state { * data/variables. */ struct mutex lock; + const struct axi_dac_info *info; u64 dac_clk; u32 reg_config; bool int_tone; + int dac_clk_rate; }; static int axi_dac_enable(struct iio_backend *back) @@ -89,7 +124,7 @@ static int axi_dac_enable(struct iio_backend *back) int ret; guard(mutex)(&st->lock); - ret = regmap_set_bits(st->regmap, AXI_DAC_REG_RSTN, + ret = regmap_set_bits(st->regmap, AXI_DAC_RSTN_REG, AXI_DAC_RSTN_MMCM_RSTN); if (ret) return ret; @@ -98,12 +133,14 @@ static int axi_dac_enable(struct iio_backend *back) * designs really use it but if they don't we still get the lock bit * set. So let's do it all the time so the code is generic. */ - ret = regmap_read_poll_timeout(st->regmap, AXI_DAC_DRP_STATUS, __val, - __val & AXI_DAC_DRP_LOCKED, 100, 1000); + ret = regmap_read_poll_timeout(st->regmap, AXI_DAC_DRP_STATUS_REG, + __val, + __val & AXI_DAC_DRP_STATUS_DRP_LOCKED, + 100, 1000); if (ret) return ret; - return regmap_set_bits(st->regmap, AXI_DAC_REG_RSTN, + return regmap_set_bits(st->regmap, AXI_DAC_RSTN_REG, AXI_DAC_RSTN_RSTN | AXI_DAC_RSTN_MMCM_RSTN); } @@ -112,7 +149,7 @@ static void axi_dac_disable(struct iio_backend *back) struct axi_dac_state *st = iio_backend_get_priv(back); guard(mutex)(&st->lock); - regmap_write(st->regmap, AXI_DAC_REG_RSTN, 0); + regmap_write(st->regmap, AXI_DAC_RSTN_REG, 0); } static struct iio_buffer *axi_dac_request_buffer(struct iio_backend *back, @@ -155,15 +192,15 @@ static int __axi_dac_frequency_get(struct axi_dac_state *st, unsigned int chan, } if (tone_2) - reg = AXI_DAC_REG_CHAN_CNTRL_4(chan); + reg = AXI_DAC_CHAN_CNTRL_4_REG(chan); else - reg = AXI_DAC_REG_CHAN_CNTRL_2(chan); + reg = AXI_DAC_CHAN_CNTRL_2_REG(chan); ret = regmap_read(st->regmap, reg, &raw); if (ret) return ret; - raw = FIELD_GET(AXI_DAC_FREQUENCY, raw); + raw = FIELD_GET(AXI_DAC_CHAN_CNTRL_2_FREQUENCY, raw); *freq = DIV_ROUND_CLOSEST_ULL(raw * st->dac_clk, BIT(16)); return 0; @@ -194,17 +231,18 @@ static int axi_dac_scale_get(struct axi_dac_state *st, u32 reg, raw; if (tone_2) - reg = AXI_DAC_REG_CHAN_CNTRL_3(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_3_REG(chan->channel); else - reg = AXI_DAC_REG_CHAN_CNTRL_1(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_1_REG(chan->channel); ret = regmap_read(st->regmap, reg, &raw); if (ret) return ret; - sign = FIELD_GET(AXI_DAC_SCALE_SIGN, raw); - raw = FIELD_GET(AXI_DAC_SCALE, raw); - scale = DIV_ROUND_CLOSEST_ULL((u64)raw * MEGA, AXI_DAC_SCALE_INT); + sign = FIELD_GET(AXI_DAC_CHAN_CNTRL_3_SCALE_SIGN, raw); + raw = FIELD_GET(AXI_DAC_CHAN_CNTRL_3_SCALE, raw); + scale = DIV_ROUND_CLOSEST_ULL((u64)raw * MEGA, + AXI_DAC_CHAN_CNTRL_3_SCALE_INT); vals[0] = scale / MEGA; vals[1] = scale % MEGA; @@ -227,15 +265,15 @@ static int axi_dac_phase_get(struct axi_dac_state *st, int ret, vals[2]; if (tone_2) - reg = AXI_DAC_REG_CHAN_CNTRL_4(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_4_REG(chan->channel); else - reg = AXI_DAC_REG_CHAN_CNTRL_2(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_2_REG(chan->channel); ret = regmap_read(st->regmap, reg, &raw); if (ret) return ret; - raw = FIELD_GET(AXI_DAC_PHASE, raw); + raw = FIELD_GET(AXI_DAC_CHAN_CNTRL_2_PHASE, raw); phase = DIV_ROUND_CLOSEST_ULL((u64)raw * AXI_DAC_2_PI_MEGA, U16_MAX); vals[0] = phase / MEGA; @@ -260,18 +298,20 @@ static int __axi_dac_frequency_set(struct axi_dac_state *st, unsigned int chan, } if (tone_2) - reg = AXI_DAC_REG_CHAN_CNTRL_4(chan); + reg = AXI_DAC_CHAN_CNTRL_4_REG(chan); else - reg = AXI_DAC_REG_CHAN_CNTRL_2(chan); + reg = AXI_DAC_CHAN_CNTRL_2_REG(chan); raw = DIV64_U64_ROUND_CLOSEST((u64)freq * BIT(16), sample_rate); - ret = regmap_update_bits(st->regmap, reg, AXI_DAC_FREQUENCY, raw); + ret = regmap_update_bits(st->regmap, reg, + AXI_DAC_CHAN_CNTRL_2_FREQUENCY, raw); if (ret) return ret; /* synchronize channels */ - return regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_1, AXI_DAC_SYNC); + return regmap_set_bits(st->regmap, AXI_DAC_CNTRL_1_REG, + AXI_DAC_CNTRL_1_SYNC); } static int axi_dac_frequency_set(struct axi_dac_state *st, @@ -312,16 +352,16 @@ static int axi_dac_scale_set(struct axi_dac_state *st, /* format is 1.1.14 (sign, integer and fractional bits) */ if (scale < 0) { - raw = FIELD_PREP(AXI_DAC_SCALE_SIGN, 1); + raw = FIELD_PREP(AXI_DAC_CHAN_CNTRL_3_SCALE_SIGN, 1); scale *= -1; } - raw |= div_u64((u64)scale * AXI_DAC_SCALE_INT, MEGA); + raw |= div_u64((u64)scale * AXI_DAC_CHAN_CNTRL_3_SCALE_INT, MEGA); if (tone_2) - reg = AXI_DAC_REG_CHAN_CNTRL_3(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_3_REG(chan->channel); else - reg = AXI_DAC_REG_CHAN_CNTRL_1(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_1_REG(chan->channel); guard(mutex)(&st->lock); ret = regmap_write(st->regmap, reg, raw); @@ -329,7 +369,8 @@ static int axi_dac_scale_set(struct axi_dac_state *st, return ret; /* synchronize channels */ - ret = regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_1, AXI_DAC_SYNC); + ret = regmap_set_bits(st->regmap, AXI_DAC_CNTRL_1_REG, + AXI_DAC_CNTRL_1_SYNC); if (ret) return ret; @@ -355,18 +396,19 @@ static int axi_dac_phase_set(struct axi_dac_state *st, raw = DIV_ROUND_CLOSEST_ULL((u64)phase * U16_MAX, AXI_DAC_2_PI_MEGA); if (tone_2) - reg = AXI_DAC_REG_CHAN_CNTRL_4(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_4_REG(chan->channel); else - reg = AXI_DAC_REG_CHAN_CNTRL_2(chan->channel); + reg = AXI_DAC_CHAN_CNTRL_2_REG(chan->channel); guard(mutex)(&st->lock); - ret = regmap_update_bits(st->regmap, reg, AXI_DAC_PHASE, - FIELD_PREP(AXI_DAC_PHASE, raw)); + ret = regmap_update_bits(st->regmap, reg, AXI_DAC_CHAN_CNTRL_2_PHASE, + FIELD_PREP(AXI_DAC_CHAN_CNTRL_2_PHASE, raw)); if (ret) return ret; /* synchronize channels */ - ret = regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_1, AXI_DAC_SYNC); + ret = regmap_set_bits(st->regmap, AXI_DAC_CNTRL_1_REG, + AXI_DAC_CNTRL_1_SYNC); if (ret) return ret; @@ -437,7 +479,7 @@ static int axi_dac_extend_chan(struct iio_backend *back, if (chan->type != IIO_ALTVOLTAGE) return -EINVAL; - if (st->reg_config & AXI_DDS_DISABLE) + if (st->reg_config & AXI_DAC_CONFIG_DDS_DISABLE) /* nothing to extend */ return 0; @@ -454,13 +496,19 @@ static int axi_dac_data_source_set(struct iio_backend *back, unsigned int chan, switch (data) { case IIO_BACKEND_INTERNAL_CONTINUOUS_WAVE: return regmap_update_bits(st->regmap, - AXI_DAC_REG_CHAN_CNTRL_7(chan), - AXI_DAC_DATA_SEL, + AXI_DAC_CHAN_CNTRL_7_REG(chan), + AXI_DAC_CHAN_CNTRL_7_DATA_SEL, AXI_DAC_DATA_INTERNAL_TONE); case IIO_BACKEND_EXTERNAL: return regmap_update_bits(st->regmap, - AXI_DAC_REG_CHAN_CNTRL_7(chan), - AXI_DAC_DATA_SEL, AXI_DAC_DATA_DMA); + AXI_DAC_CHAN_CNTRL_7_REG(chan), + AXI_DAC_CHAN_CNTRL_7_DATA_SEL, + AXI_DAC_DATA_DMA); + case IIO_BACKEND_INTERNAL_RAMP_16BIT: + return regmap_update_bits(st->regmap, + AXI_DAC_CHAN_CNTRL_7_REG(chan), + AXI_DAC_CHAN_CNTRL_7_DATA_SEL, + AXI_DAC_DATA_INTERNAL_RAMP_16BIT); default: return -EINVAL; } @@ -475,7 +523,7 @@ static int axi_dac_set_sample_rate(struct iio_backend *back, unsigned int chan, if (!sample_rate) return -EINVAL; - if (st->reg_config & AXI_DDS_DISABLE) + if (st->reg_config & AXI_DAC_CONFIG_DDS_DISABLE) /* sample_rate has no meaning if DDS is disabled */ return 0; @@ -518,6 +566,184 @@ static int axi_dac_reg_access(struct iio_backend *back, unsigned int reg, return regmap_write(st->regmap, reg, writeval); } +static int axi_dac_ddr_enable(struct iio_backend *back) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + return regmap_clear_bits(st->regmap, AXI_DAC_CNTRL_2_REG, + AXI_DAC_CNTRL_2_SDR_DDR_N); +} + +static int axi_dac_ddr_disable(struct iio_backend *back) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + return regmap_set_bits(st->regmap, AXI_DAC_CNTRL_2_REG, + AXI_DAC_CNTRL_2_SDR_DDR_N); +} + +static int axi_dac_data_stream_enable(struct iio_backend *back) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + return regmap_set_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG, + AXI_DAC_CUSTOM_CTRL_STREAM_ENABLE); +} + +static int axi_dac_data_stream_disable(struct iio_backend *back) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + return regmap_clear_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG, + AXI_DAC_CUSTOM_CTRL_STREAM_ENABLE); +} + +static int axi_dac_data_transfer_addr(struct iio_backend *back, u32 address) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + if (address > FIELD_MAX(AXI_DAC_CUSTOM_CTRL_ADDRESS)) + return -EINVAL; + + /* + * Sample register address, when the DAC is configured, or stream + * start address when the FSM is in stream state. + */ + return regmap_update_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG, + AXI_DAC_CUSTOM_CTRL_ADDRESS, + FIELD_PREP(AXI_DAC_CUSTOM_CTRL_ADDRESS, + address)); +} + +static int axi_dac_data_format_set(struct iio_backend *back, unsigned int ch, + const struct iio_backend_data_fmt *data) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + switch (data->type) { + case IIO_BACKEND_DATA_UNSIGNED: + return regmap_clear_bits(st->regmap, AXI_DAC_CNTRL_2_REG, + AXI_DAC_CNTRL_2_UNSIGNED_DATA); + default: + return -EINVAL; + } +} + +static int __axi_dac_bus_reg_write(struct iio_backend *back, u32 reg, + u32 val, size_t data_size) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + int ret; + u32 ival; + + /* + * Both AXI_DAC_CNTRL_2_REG and AXI_DAC_CUSTOM_WR_REG need to know + * the data size. So keeping data size control here only, + * since data size is mandatory for the current transfer. + * DDR state handled separately by specific backend calls, + * generally all raw register writes are SDR. + */ + if (data_size == sizeof(u16)) + ival = FIELD_PREP(AXI_DAC_CUSTOM_WR_DATA_16, val); + else + ival = FIELD_PREP(AXI_DAC_CUSTOM_WR_DATA_8, val); + + ret = regmap_write(st->regmap, AXI_DAC_CUSTOM_WR_REG, ival); + if (ret) + return ret; + + if (data_size == sizeof(u8)) + ret = regmap_set_bits(st->regmap, AXI_DAC_CNTRL_2_REG, + AXI_DAC_CNTRL_2_SYMB_8B); + else + ret = regmap_clear_bits(st->regmap, AXI_DAC_CNTRL_2_REG, + AXI_DAC_CNTRL_2_SYMB_8B); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG, + AXI_DAC_CUSTOM_CTRL_ADDRESS, + FIELD_PREP(AXI_DAC_CUSTOM_CTRL_ADDRESS, reg)); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG, + AXI_DAC_CUSTOM_CTRL_TRANSFER_DATA, + AXI_DAC_CUSTOM_CTRL_TRANSFER_DATA); + if (ret) + return ret; + + ret = regmap_read_poll_timeout(st->regmap, + AXI_DAC_UI_STATUS_REG, ival, + FIELD_GET(AXI_DAC_UI_STATUS_IF_BUSY, ival) == 0, + 10, 100 * KILO); + if (ret == -ETIMEDOUT) + dev_err(st->dev, "AXI read timeout\n"); + + /* Cleaning always AXI_DAC_CUSTOM_CTRL_TRANSFER_DATA */ + return regmap_clear_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG, + AXI_DAC_CUSTOM_CTRL_TRANSFER_DATA); +} + +static int axi_dac_bus_reg_write(struct iio_backend *back, u32 reg, + u32 val, size_t data_size) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + guard(mutex)(&st->lock); + return __axi_dac_bus_reg_write(back, reg, val, data_size); +} + +static int axi_dac_bus_reg_read(struct iio_backend *back, u32 reg, u32 *val, + size_t data_size) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + int ret; + + guard(mutex)(&st->lock); + + /* + * SPI, we write with read flag, then we read just at the AXI + * io address space to get data read. + */ + ret = __axi_dac_bus_reg_write(back, AXI_DAC_RD_ADDR(reg), 0, + data_size); + if (ret) + return ret; + + return regmap_read(st->regmap, AXI_DAC_CUSTOM_RD_REG, val); +} + +static void axi_dac_child_remove(void *data) +{ + platform_device_unregister(data); +} + +static int axi_dac_create_platform_device(struct axi_dac_state *st, + struct fwnode_handle *child) +{ + struct ad3552r_hs_platform_data pdata = { + .bus_reg_read = axi_dac_bus_reg_read, + .bus_reg_write = axi_dac_bus_reg_write, + .bus_sample_data_clock_hz = st->dac_clk_rate, + }; + struct platform_device_info pi = { + .parent = st->dev, + .name = fwnode_get_name(child), + .id = PLATFORM_DEVID_AUTO, + .fwnode = child, + .data = &pdata, + .size_data = sizeof(pdata), + }; + struct platform_device *pdev; + + pdev = platform_device_register_full(&pi); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return devm_add_action_or_reset(st->dev, axi_dac_child_remove, pdev); +} + static const struct iio_backend_ops axi_dac_generic_ops = { .enable = axi_dac_enable, .disable = axi_dac_disable, @@ -531,11 +757,30 @@ static const struct iio_backend_ops axi_dac_generic_ops = { .debugfs_reg_access = iio_backend_debugfs_ptr(axi_dac_reg_access), }; +static const struct iio_backend_ops axi_ad3552r_ops = { + .enable = axi_dac_enable, + .disable = axi_dac_disable, + .request_buffer = axi_dac_request_buffer, + .free_buffer = axi_dac_free_buffer, + .data_source_set = axi_dac_data_source_set, + .ddr_enable = axi_dac_ddr_enable, + .ddr_disable = axi_dac_ddr_disable, + .data_stream_enable = axi_dac_data_stream_enable, + .data_stream_disable = axi_dac_data_stream_disable, + .data_format_set = axi_dac_data_format_set, + .data_transfer_addr = axi_dac_data_transfer_addr, +}; + static const struct iio_backend_info axi_dac_generic = { .name = "axi-dac", .ops = &axi_dac_generic_ops, }; +static const struct iio_backend_info axi_ad3552r = { + .name = "axi-ad3552r", + .ops = &axi_ad3552r_ops, +}; + static const struct regmap_config axi_dac_regmap_config = { .val_bits = 32, .reg_bits = 32, @@ -545,7 +790,6 @@ static const struct regmap_config axi_dac_regmap_config = { static int axi_dac_probe(struct platform_device *pdev) { - const unsigned int *expected_ver; struct axi_dac_state *st; void __iomem *base; unsigned int ver; @@ -556,14 +800,29 @@ static int axi_dac_probe(struct platform_device *pdev) if (!st) return -ENOMEM; - expected_ver = device_get_match_data(&pdev->dev); - if (!expected_ver) + st->info = device_get_match_data(&pdev->dev); + if (!st->info) return -ENODEV; + clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(clk)) { + /* Backward compat., old fdt versions without clock-names. */ + clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk), + "failed to get clock\n"); + } - clk = devm_clk_get_enabled(&pdev->dev, NULL); - if (IS_ERR(clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk), - "failed to get clock\n"); + if (st->info->has_dac_clk) { + struct clk *dac_clk; + + dac_clk = devm_clk_get_enabled(&pdev->dev, "dac_clk"); + if (IS_ERR(dac_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(dac_clk), + "failed to get dac_clk clock\n"); + + /* We only care about the streaming mode rate */ + st->dac_clk_rate = clk_get_rate(dac_clk) / 2; + } base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) @@ -580,7 +839,7 @@ static int axi_dac_probe(struct platform_device *pdev) * Force disable the core. Up to the frontend to enable us. And we can * still read/write registers... */ - ret = regmap_write(st->regmap, AXI_DAC_REG_RSTN, 0); + ret = regmap_write(st->regmap, AXI_DAC_RSTN_REG, 0); if (ret) return ret; @@ -588,12 +847,13 @@ static int axi_dac_probe(struct platform_device *pdev) if (ret) return ret; - if (ADI_AXI_PCORE_VER_MAJOR(ver) != ADI_AXI_PCORE_VER_MAJOR(*expected_ver)) { + if (ADI_AXI_PCORE_VER_MAJOR(ver) != + ADI_AXI_PCORE_VER_MAJOR(st->info->version)) { dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", - ADI_AXI_PCORE_VER_MAJOR(*expected_ver), - ADI_AXI_PCORE_VER_MINOR(*expected_ver), - ADI_AXI_PCORE_VER_PATCH(*expected_ver), + ADI_AXI_PCORE_VER_MAJOR(st->info->version), + ADI_AXI_PCORE_VER_MINOR(st->info->version), + ADI_AXI_PCORE_VER_PATCH(st->info->version), ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), ADI_AXI_PCORE_VER_PATCH(ver)); @@ -601,7 +861,7 @@ static int axi_dac_probe(struct platform_device *pdev) } /* Let's get the core read only configuration */ - ret = regmap_read(st->regmap, AXI_DAC_REG_CONFIG, &st->reg_config); + ret = regmap_read(st->regmap, AXI_DAC_CONFIG_REG, &st->reg_config); if (ret) return ret; @@ -613,16 +873,40 @@ static int axi_dac_probe(struct platform_device *pdev) * want independent channels let's override the core's default value and * set the R1_MODE bit. */ - ret = regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_2, ADI_DAC_R1_MODE); + ret = regmap_set_bits(st->regmap, AXI_DAC_CNTRL_2_REG, + ADI_DAC_CNTRL_2_R1_MODE); if (ret) return ret; mutex_init(&st->lock); - ret = devm_iio_backend_register(&pdev->dev, &axi_dac_generic, st); + + ret = devm_iio_backend_register(&pdev->dev, st->info->backend_info, st); if (ret) return dev_err_probe(&pdev->dev, ret, "failed to register iio backend\n"); + device_for_each_child_node_scoped(&pdev->dev, child) { + int val; + + if (!st->info->has_child_nodes) + return dev_err_probe(&pdev->dev, -EINVAL, + "invalid fdt axi-dac compatible."); + + /* Processing only reg 0 node */ + ret = fwnode_property_read_u32(child, "reg", &val); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "invalid reg property."); + if (val != 0) + return dev_err_probe(&pdev->dev, -EINVAL, + "invalid node address."); + + ret = axi_dac_create_platform_device(st, child); + if (ret) + return dev_err_probe(&pdev->dev, -EINVAL, + "cannot create device."); + } + dev_info(&pdev->dev, "AXI DAC IP core (%d.%.2d.%c) probed\n", ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), @@ -631,10 +915,21 @@ static int axi_dac_probe(struct platform_device *pdev) return 0; } -static unsigned int axi_dac_9_1_b_info = ADI_AXI_PCORE_VER(9, 1, 'b'); +static const struct axi_dac_info dac_generic = { + .version = ADI_AXI_PCORE_VER(9, 1, 'b'), + .backend_info = &axi_dac_generic, +}; + +static const struct axi_dac_info dac_ad3552r = { + .version = ADI_AXI_PCORE_VER(9, 1, 'b'), + .backend_info = &axi_ad3552r, + .has_dac_clk = true, + .has_child_nodes = true, +}; static const struct of_device_id axi_dac_of_match[] = { - { .compatible = "adi,axi-dac-9.1.b", .data = &axi_dac_9_1_b_info }, + { .compatible = "adi,axi-dac-9.1.b", .data = &dac_generic }, + { .compatible = "adi,axi-ad3552r", .data = &dac_ad3552r }, {} }; MODULE_DEVICE_TABLE(of, axi_dac_of_match); @@ -651,5 +946,5 @@ module_platform_driver(axi_dac_driver); MODULE_AUTHOR("Nuno Sa "); MODULE_DESCRIPTION("Analog Devices Generic AXI DAC IP core driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_DMAENGINE_BUFFER); -MODULE_IMPORT_NS(IIO_BACKEND); +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER"); +MODULE_IMPORT_NS("IIO_BACKEND"); diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c index 7332064d0852d979620f90066fb027f6f68f8c95..f36f10bfb6be7863a56b911b5f58671ef530c977 100644 --- a/drivers/iio/dac/dpot-dac.c +++ b/drivers/iio/dac/dpot-dac.c @@ -243,7 +243,7 @@ MODULE_DEVICE_TABLE(of, dpot_dac_match); static struct platform_driver dpot_dac_driver = { .probe = dpot_dac_probe, - .remove_new = dpot_dac_remove, + .remove = dpot_dac_remove, .driver = { .name = "iio-dpot-dac", .of_match_table = dpot_dac_match, diff --git a/drivers/iio/dac/lpc18xx_dac.c b/drivers/iio/dac/lpc18xx_dac.c index b3aa4443a6a4849e1b311a8aa1e8ec5fbea30fa2..2332b0c22691522d44407a51544d60292a833de0 100644 --- a/drivers/iio/dac/lpc18xx_dac.c +++ b/drivers/iio/dac/lpc18xx_dac.c @@ -184,9 +184,9 @@ static const struct of_device_id lpc18xx_dac_match[] = { MODULE_DEVICE_TABLE(of, lpc18xx_dac_match); static struct platform_driver lpc18xx_dac_driver = { - .probe = lpc18xx_dac_probe, - .remove_new = lpc18xx_dac_remove, - .driver = { + .probe = lpc18xx_dac_probe, + .remove = lpc18xx_dac_remove, + .driver = { .name = "lpc18xx-dac", .of_match_table = lpc18xx_dac_match, }, diff --git a/drivers/iio/dac/m62332.c b/drivers/iio/dac/m62332.c index ae53baccec91493d15107aea9dbadddd5c31edd9..3497513854d7d24724af944f9ee452ab48a083ff 100644 --- a/drivers/iio/dac/m62332.c +++ b/drivers/iio/dac/m62332.c @@ -201,7 +201,7 @@ static int m62332_probe(struct i2c_client *client) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &m62332_info; - ret = iio_map_array_register(indio_dev, client->dev.platform_data); + ret = iio_map_array_register(indio_dev, dev_get_platdata(&client->dev)); if (ret < 0) return ret; diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 685980184d3c82ed16728ace493ed3cf545bd7a7..84336736a47bddd51130b54a8b33092235ecced1 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -143,10 +143,10 @@ static const struct iio_chan_spec max517_channels[] = { static int max517_probe(struct i2c_client *client) { + const struct max517_platform_data *platform_data = dev_get_platdata(&client->dev); const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max517_data *data; struct iio_dev *indio_dev; - struct max517_platform_data *platform_data = client->dev.platform_data; int chan; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); diff --git a/drivers/iio/dac/stm32-dac-core.c b/drivers/iio/dac/stm32-dac-core.c index 2d567073996b7971e0ffcf9820aa07bc1c4e7646..95ed5197d16f563ab68eefebec41a30f8c191b02 100644 --- a/drivers/iio/dac/stm32-dac-core.c +++ b/drivers/iio/dac/stm32-dac-core.c @@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, stm32_dac_of_match); static struct platform_driver stm32_dac_driver = { .probe = stm32_dac_probe, - .remove_new = stm32_dac_remove, + .remove = stm32_dac_remove, .driver = { .name = "stm32-dac-core", .of_match_table = stm32_dac_of_match, diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c index 5a722f307e7e305fe4b0fd959af45fa663d3a948..3bfb368b3a234022ef88ee25e8d19fb2dbc7531e 100644 --- a/drivers/iio/dac/stm32-dac.c +++ b/drivers/iio/dac/stm32-dac.c @@ -398,7 +398,7 @@ MODULE_DEVICE_TABLE(of, stm32_dac_of_match); static struct platform_driver stm32_dac_driver = { .probe = stm32_dac_probe, - .remove_new = stm32_dac_remove, + .remove = stm32_dac_remove, .driver = { .name = "stm32-dac", .of_match_table = stm32_dac_of_match, diff --git a/drivers/iio/dac/vf610_dac.c b/drivers/iio/dac/vf610_dac.c index de73bc5a1c93c9ec839a45448e98b855cf2b5215..82a078fa98ad9a86d1d09b456a93321d197b3d0e 100644 --- a/drivers/iio/dac/vf610_dac.c +++ b/drivers/iio/dac/vf610_dac.c @@ -272,7 +272,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(vf610_dac_pm_ops, vf610_dac_suspend, static struct platform_driver vf610_dac_driver = { .probe = vf610_dac_probe, - .remove_new = vf610_dac_remove, + .remove = vf610_dac_remove, .driver = { .name = "vf610-dac", .of_match_table = vf610_dac_match, diff --git a/drivers/iio/dummy/iio_simple_dummy.h b/drivers/iio/dummy/iio_simple_dummy.h index a91622ac54e06e037502fbc956f0bd7c35de7509..8246f25dbad04f2bb612177631ebc1bedfc1f1e9 100644 --- a/drivers/iio/dummy/iio_simple_dummy.h +++ b/drivers/iio/dummy/iio_simple_dummy.h @@ -60,7 +60,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state); + bool state); int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, diff --git a/drivers/iio/dummy/iio_simple_dummy_events.c b/drivers/iio/dummy/iio_simple_dummy_events.c index 63a2b844be50834e232f653bbb893dee29171c4c..b51ec21b6309a28358845614a8a433bc7e2f7715 100644 --- a/drivers/iio/dummy/iio_simple_dummy_events.c +++ b/drivers/iio/dummy/iio_simple_dummy_events.c @@ -53,7 +53,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct iio_dummy_state *st = iio_priv(indio_dev); @@ -183,36 +183,34 @@ static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private) switch (st->regs->reg_data) { case 0: iio_push_event(indio_dev, - IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0, - IIO_EV_DIR_RISING, - IIO_EV_TYPE_THRESH, 0, 0, 0), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), st->event_timestamp); break; case 1: if (st->activity_running > st->event_val) iio_push_event(indio_dev, - IIO_EVENT_CODE(IIO_ACTIVITY, 0, - IIO_MOD_RUNNING, - IIO_EV_DIR_RISING, - IIO_EV_TYPE_THRESH, - 0, 0, 0), + IIO_MOD_EVENT_CODE(IIO_ACTIVITY, 0, + IIO_MOD_RUNNING, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), st->event_timestamp); break; case 2: if (st->activity_walking < st->event_val) iio_push_event(indio_dev, - IIO_EVENT_CODE(IIO_ACTIVITY, 0, - IIO_MOD_WALKING, - IIO_EV_DIR_FALLING, - IIO_EV_TYPE_THRESH, - 0, 0, 0), + IIO_MOD_EVENT_CODE(IIO_ACTIVITY, 0, + IIO_MOD_WALKING, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), st->event_timestamp); break; case 3: iio_push_event(indio_dev, - IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, - IIO_EV_DIR_NONE, - IIO_EV_TYPE_CHANGE, 0, 0, 0), + IIO_UNMOD_EVENT_CODE(IIO_STEPS, 0, + IIO_EV_TYPE_CHANGE, + IIO_EV_DIR_NONE), st->event_timestamp); break; default: diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index b391c6e27ab0dc5c7cac05116670533c04040077..b1554ced7a26b8c331e833f3125a9927e8ace289 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -970,7 +970,7 @@ static int ad9523_setup(struct iio_dev *indio_dev) static int ad9523_probe(struct spi_device *spi) { - struct ad9523_platform_data *pdata = spi->dev.platform_data; + struct ad9523_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad9523_state *st; int ret; diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index e13e64a5164c14eac7c888634227f473eca7e61c..61828e61e27589b68ca729cac9cfa9c3b83da9a1 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -603,7 +603,7 @@ static int adf4350_probe(struct spi_device *spi) if (pdata == NULL) return -EINVAL; } else { - pdata = spi->dev.platform_data; + pdata = dev_get_platdata(&spi->dev); } if (!pdata) { diff --git a/drivers/iio/frequency/adf4371.c b/drivers/iio/frequency/adf4371.c index b270884648265ab9e84832bf030651e45b51db47..d752507e0c9862c9761324108f3e8af548bc852f 100644 --- a/drivers/iio/frequency/adf4371.c +++ b/drivers/iio/frequency/adf4371.c @@ -4,6 +4,7 @@ * * Copyright 2019 Analog Devices Inc. */ +#include "linux/dev_printk.h" #include #include #include @@ -150,6 +151,7 @@ static const struct regmap_config adf4371_regmap_config = { }; struct adf4371_chip_info { + const char *name; unsigned int num_channels; const struct iio_chan_spec *channels; }; @@ -157,7 +159,6 @@ struct adf4371_chip_info { struct adf4371_state { struct spi_device *spi; struct regmap *regmap; - struct clk *clkin; /* * Lock for accessing device registers. Some operations require * multiple consecutive R/W operations, during which the device @@ -444,15 +445,16 @@ static const struct iio_chan_spec adf4371_chan[] = { ADF4371_CHANNEL(ADF4371_CH_RF32), }; -static const struct adf4371_chip_info adf4371_chip_info[] = { - [ADF4371] = { - .channels = adf4371_chan, - .num_channels = 4, - }, - [ADF4372] = { - .channels = adf4371_chan, - .num_channels = 3, - } +static const struct adf4371_chip_info adf4371_chip_info = { + .name = "adf4371", + .channels = adf4371_chan, + .num_channels = 4, +}; + +static const struct adf4371_chip_info adf4372_chip_info = { + .name = "adf4372", + .channels = adf4371_chan, + .num_channels = 3, }; static int adf4371_reg_access(struct iio_dev *indio_dev, @@ -542,10 +544,10 @@ static int adf4371_setup(struct adf4371_state *st) static int adf4371_probe(struct spi_device *spi) { - const struct spi_device_id *id = spi_get_device_id(spi); struct iio_dev *indio_dev; struct adf4371_state *st; struct regmap *regmap; + struct clk *clkin; int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); @@ -553,50 +555,49 @@ static int adf4371_probe(struct spi_device *spi) return -ENOMEM; regmap = devm_regmap_init_spi(spi, &adf4371_regmap_config); - if (IS_ERR(regmap)) { - dev_err(&spi->dev, "Error initializing spi regmap: %ld\n", - PTR_ERR(regmap)); - return PTR_ERR(regmap); - } + if (IS_ERR(regmap)) + return dev_err_probe(&spi->dev, PTR_ERR(regmap), + "Error initializing spi regmap\n"); st = iio_priv(indio_dev); - spi_set_drvdata(spi, indio_dev); st->spi = spi; st->regmap = regmap; mutex_init(&st->lock); - st->chip_info = &adf4371_chip_info[id->driver_data]; - indio_dev->name = id->name; + st->chip_info = spi_get_device_match_data(spi); + if (!st->chip_info) + return -ENODEV; + + indio_dev->name = st->chip_info->name; indio_dev->info = &adf4371_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = st->chip_info->channels; indio_dev->num_channels = st->chip_info->num_channels; - st->clkin = devm_clk_get_enabled(&spi->dev, "clkin"); - if (IS_ERR(st->clkin)) - return PTR_ERR(st->clkin); + clkin = devm_clk_get_enabled(&spi->dev, "clkin"); + if (IS_ERR(clkin)) + return dev_err_probe(&spi->dev, PTR_ERR(clkin), + "Failed to get clkin\n"); - st->clkin_freq = clk_get_rate(st->clkin); + st->clkin_freq = clk_get_rate(clkin); ret = adf4371_setup(st); - if (ret < 0) { - dev_err(&spi->dev, "ADF4371 setup failed\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(&spi->dev, ret, "ADF4371 setup failed\n"); return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id adf4371_id_table[] = { - { "adf4371", ADF4371 }, - { "adf4372", ADF4372 }, + { "adf4371", (kernel_ulong_t)&adf4371_chip_info }, + { "adf4372", (kernel_ulong_t)&adf4372_chip_info }, {} }; MODULE_DEVICE_TABLE(spi, adf4371_id_table); static const struct of_device_id adf4371_of_match[] = { - { .compatible = "adi,adf4371" }, - { .compatible = "adi,adf4372" }, + { .compatible = "adi,adf4371", .data = &adf4371_chip_info }, + { .compatible = "adi,adf4372", .data = &adf4372_chip_info}, { }, }; MODULE_DEVICE_TABLE(of, adf4371_of_match); diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 97b86c4a53a6190611615d695108a2f30c1ea0d6..3e193ee0fb6144c9c06eb8bd8769685607c451fc 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig @@ -27,7 +27,7 @@ config ADIS16136 select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for the Analog Devices ADIS16133, ADIS16135, - ADIS16136 gyroscope devices. + ADIS16136, ADIS16137 gyroscope devices. config ADIS16260 tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver" diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index da83adc684d0b66985f167f77f0197eec066732d..369c7428e1efeda23ac6c9938592c76d6e822166 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -583,4 +583,4 @@ module_spi_driver(adis16136_driver); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("Analog Devices ADIS16133/ADIS16135/ADIS16136 gyroscope driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c index 495b64a27061726fbcbf712463355c5af1337aa3..c151fbb59ffe884a3ecefa8e1004e518e46c93c0 100644 --- a/drivers/iio/gyro/adis16260.c +++ b/drivers/iio/gyro/adis16260.c @@ -430,4 +430,4 @@ module_spi_driver(adis16260_driver); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); MODULE_DESCRIPTION("Analog Devices ADIS16260/5 Digital Gyroscope Sensor"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 10728d5ccae398d15c1d51e0380306042675d5c0..ba877d067afb7a7bd0d350edd8f2be86fe673c69 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -444,7 +443,7 @@ static int bmg160_setup_new_data_interrupt(struct bmg160_data *data, static int bmg160_get_bw(struct bmg160_data *data, int *val) { - struct device *dev = regmap_get_device(data->regmap); + struct device *dev = regmap_get_device(data->regmap); int i; unsigned int bw_bits; int ret; @@ -749,7 +748,7 @@ static int bmg160_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct bmg160_data *data = iio_priv(indio_dev); int ret; @@ -1055,17 +1054,6 @@ static const struct iio_buffer_setup_ops bmg160_buffer_setup_ops = { .postdisable = bmg160_buffer_postdisable, }; -static const char *bmg160_match_acpi_device(struct device *dev) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - - return dev_name(dev); -} - int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) { @@ -1098,9 +1086,6 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, mutex_init(&data->mutex); - if (ACPI_HANDLE(dev)) - name = bmg160_match_acpi_device(dev); - indio_dev->channels = bmg160_channels; indio_dev->num_channels = ARRAY_SIZE(bmg160_channels); indio_dev->name = name; diff --git a/drivers/iio/gyro/bmg160_i2c.c b/drivers/iio/gyro/bmg160_i2c.c index 672d0b720f610a73aa8dabf77658a9d9e9eebf2e..9c5d7e8ee99cc699581abbc186c0424e244153ca 100644 --- a/drivers/iio/gyro/bmg160_i2c.c +++ b/drivers/iio/gyro/bmg160_i2c.c @@ -17,7 +17,7 @@ static int bmg160_i2c_probe(struct i2c_client *client) { const struct i2c_device_id *id = i2c_client_get_device_id(client); struct regmap *regmap; - const char *name = NULL; + const char *name; regmap = devm_regmap_init_i2c(client, &bmg160_regmap_i2c_conf); if (IS_ERR(regmap)) { @@ -28,6 +28,8 @@ static int bmg160_i2c_probe(struct i2c_client *client) if (id) name = id->name; + else + name = iio_get_acpi_device_name(&client->dev); return bmg160_core_probe(&client->dev, regmap, client->irq, name); } @@ -39,8 +41,6 @@ static void bmg160_i2c_remove(struct i2c_client *client) static const struct acpi_device_id bmg160_acpi_match[] = { {"BMG0160", 0}, - {"BMI055B", 0}, - {"BMI088B", 0}, {}, }; diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index c28d17ca6f5ee03601886dd53a31d63875e317e9..0391c78c2f186fa2ed9a728c31cbebe044ab9a6f 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -849,8 +849,7 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data) if (!data->dready_trig) return -ENOMEM; - irq_trig = irqd_get_trigger_type(irq_get_irq_data(data->irq)); - + irq_trig = irq_get_trigger_type(data->irq); if (irq_trig == IRQF_TRIGGER_RISING) { ret = regmap_field_write(data->regmap_fields[F_IPOL], 1); if (ret < 0) @@ -998,7 +997,7 @@ pm_disable: return ret; } -EXPORT_SYMBOL_NS_GPL(fxas21002c_core_probe, IIO_FXAS21002C); +EXPORT_SYMBOL_NS_GPL(fxas21002c_core_probe, "IIO_FXAS21002C"); void fxas21002c_core_remove(struct device *dev) { @@ -1009,7 +1008,7 @@ void fxas21002c_core_remove(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_suspended(dev); } -EXPORT_SYMBOL_NS_GPL(fxas21002c_core_remove, IIO_FXAS21002C); +EXPORT_SYMBOL_NS_GPL(fxas21002c_core_remove, "IIO_FXAS21002C"); static int fxas21002c_suspend(struct device *dev) { diff --git a/drivers/iio/gyro/fxas21002c_i2c.c b/drivers/iio/gyro/fxas21002c_i2c.c index b1318a1ea41bfc6400a84dccb7033196d497ff33..43c6b30794873d1491555021740275e9e67fedf8 100644 --- a/drivers/iio/gyro/fxas21002c_i2c.c +++ b/drivers/iio/gyro/fxas21002c_i2c.c @@ -65,4 +65,4 @@ module_i2c_driver(fxas21002c_i2c_driver); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("FXAS21002C I2C Gyro driver"); -MODULE_IMPORT_NS(IIO_FXAS21002C); +MODULE_IMPORT_NS("IIO_FXAS21002C"); diff --git a/drivers/iio/gyro/fxas21002c_spi.c b/drivers/iio/gyro/fxas21002c_spi.c index 4f633826547c20f2cf6ffd39793f45803685e6f1..d62efe50b69763b181cef2d6ca94cfeabce92ce0 100644 --- a/drivers/iio/gyro/fxas21002c_spi.c +++ b/drivers/iio/gyro/fxas21002c_spi.c @@ -66,4 +66,4 @@ module_spi_driver(fxas21002c_spi_driver); MODULE_AUTHOR("Rui Miguel Silva "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("FXAS21002C SPI Gyro driver"); -MODULE_IMPORT_NS(IIO_FXAS21002C); +MODULE_IMPORT_NS("IIO_FXAS21002C"); diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index 59a38bf9459bd0450e93f863118b9954a7020b7a..54b6f6fbdcaa12abac3bab53c72c14464eeaa568 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -27,7 +27,7 @@ struct gyro_3d_state { struct hid_sensor_hub_attribute_info gyro[GYRO_3D_CHANNEL_MAX]; struct { u32 gyro_val[GYRO_3D_CHANNEL_MAX]; - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -279,11 +279,11 @@ static int gyro_3d_parse_report(struct platform_device *pdev, /* Function to initialize the processing for usage id */ static int hid_gyro_3d_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret = 0; static const char *name = "gyro_3d"; struct iio_dev *indio_dev; struct gyro_3d_state *gyro_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*gyro_state)); if (!indio_dev) @@ -361,7 +361,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_gyro_3d_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct gyro_3d_state *gyro_state = iio_priv(indio_dev); @@ -386,11 +386,11 @@ static struct platform_driver hid_gyro_3d_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_gyro_3d_probe, - .remove_new = hid_gyro_3d_remove, + .remove = hid_gyro_3d_remove, }; module_platform_driver(hid_gyro_3d_platform_driver); MODULE_DESCRIPTION("HID Sensor Gyroscope 3D"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index 35af68b41408fdb9b0c349b46c02584ad13f97fb..b6883e8b2a8b567aa13848e08e213007dfbca4c2 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -1059,12 +1059,12 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq) /* Check if IRQ is open drain */ mpu3050->irq_opendrain = device_property_read_bool(dev, "drive-open-drain"); - irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq)); /* * Configure the interrupt generator hardware to supply whatever * the interrupt is configured for, edges low/high level low/high, * we can provide it all. */ + irq_trig = irq_get_trigger_type(irq); switch (irq_trig) { case IRQF_TRIGGER_RISING: dev_info(&indio_dev->dev, diff --git a/drivers/iio/gyro/ssp_gyro_sensor.c b/drivers/iio/gyro/ssp_gyro_sensor.c index d332474bc484339f3f1ca3683645df98f2e55862..d9b41cf8d79941e20a45a10dc80c88388e1873a2 100644 --- a/drivers/iio/gyro/ssp_gyro_sensor.c +++ b/drivers/iio/gyro/ssp_gyro_sensor.c @@ -141,4 +141,4 @@ module_platform_driver(ssp_gyro_driver); MODULE_AUTHOR("Karol Wrona "); MODULE_DESCRIPTION("Samsung sensorhub gyroscopes driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_SSP_SENSORS); +MODULE_IMPORT_NS("IIO_SSP_SENSORS"); diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index eaa35da42b332ba882f33e10f76212b381cbc387..7fd82cd707c7658cefd616778f6e4374155d34c3 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -465,7 +465,7 @@ const struct st_sensor_settings *st_gyro_get_settings(const char *name) return &st_gyro_sensors_settings[index]; } -EXPORT_SYMBOL_NS(st_gyro_get_settings, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_gyro_get_settings, "IIO_ST_SENSORS"); int st_gyro_common_probe(struct iio_dev *indio_dev) { @@ -511,9 +511,9 @@ int st_gyro_common_probe(struct iio_dev *indio_dev) return devm_iio_device_register(parent, indio_dev); } -EXPORT_SYMBOL_NS(st_gyro_common_probe, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_gyro_common_probe, "IIO_ST_SENSORS"); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 5a10a3556ab054fd3871f2636c595ef6f0c98dfc..d4b11bdba66693cf1343d20fedad32450ebee3be 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -119,4 +119,4 @@ module_i2c_driver(st_gyro_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics gyroscopes i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index 22aaabe48e4a16d9f76888ebb62d5a5ed3619b24..811f712711f5ef7725a96422c81ab31d4dcdbb49 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c @@ -124,4 +124,4 @@ module_spi_driver(st_gyro_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics gyroscopes spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c index bf6d2636a85e7c343e1ec37bba5554b050093e86..a40e1eb6e98c26dce76c188542a70eec7d0f872e 100644 --- a/drivers/iio/humidity/hid-sensor-humidity.c +++ b/drivers/iio/humidity/hid-sensor-humidity.c @@ -18,7 +18,7 @@ struct hid_humidity_state { struct hid_sensor_hub_attribute_info humidity_attr; struct { s32 humidity_data; - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -287,11 +287,11 @@ static struct platform_driver hid_humidity_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_humidity_probe, - .remove_new = hid_humidity_remove, + .remove = hid_humidity_remove, }; module_platform_driver(hid_humidity_platform_driver); MODULE_DESCRIPTION("HID Environmental humidity sensor"); MODULE_AUTHOR("Song Hongyan "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/humidity/hts221_buffer.c b/drivers/iio/humidity/hts221_buffer.c index 11ef38994a955bc94b10d05e6b7cea12d95fcaa2..4d03db19063eae21517c035787ee19d6e9b27c31 100644 --- a/drivers/iio/humidity/hts221_buffer.c +++ b/drivers/iio/humidity/hts221_buffer.c @@ -81,8 +81,7 @@ int hts221_allocate_trigger(struct iio_dev *iio_dev) unsigned long irq_type; int err; - irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); - + irq_type = irq_get_trigger_type(hw->irq); switch (irq_type) { case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c index 87627d116eff05d678ebb855acb11a27d9ded80d..0be11470730c6cac9aeadd4aa9878f35cd8bbecd 100644 --- a/drivers/iio/humidity/hts221_core.c +++ b/drivers/iio/humidity/hts221_core.c @@ -649,7 +649,7 @@ int hts221_probe(struct device *dev, int irq, const char *name, return devm_iio_device_register(hw->dev, iio_dev); } -EXPORT_SYMBOL_NS(hts221_probe, IIO_HTS221); +EXPORT_SYMBOL_NS(hts221_probe, "IIO_HTS221"); static int hts221_suspend(struct device *dev) { diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c index 5cb263e0ef5ac8bfcd5de7fed9b0cef66fc52910..87a8e3c8d277275c065f081c19e6e620cbfef8f5 100644 --- a/drivers/iio/humidity/hts221_i2c.c +++ b/drivers/iio/humidity/hts221_i2c.c @@ -73,4 +73,4 @@ module_i2c_driver(hts221_driver); MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_DESCRIPTION("STMicroelectronics hts221 i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_HTS221); +MODULE_IMPORT_NS("IIO_HTS221"); diff --git a/drivers/iio/humidity/hts221_spi.c b/drivers/iio/humidity/hts221_spi.c index fc4adb68faf6cf0105584714873590bbbfbe07ca..00154b9d66b5d590b4484786174b407a222bfa11 100644 --- a/drivers/iio/humidity/hts221_spi.c +++ b/drivers/iio/humidity/hts221_spi.c @@ -66,4 +66,4 @@ module_spi_driver(hts221_driver); MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_DESCRIPTION("STMicroelectronics hts221 spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_HTS221); +MODULE_IMPORT_NS("IIO_HTS221"); diff --git a/drivers/iio/humidity/htu21.c b/drivers/iio/humidity/htu21.c index 39e886075299ea4648cc1e140fbe019e7823719e..6402e393edb875771c9313dd9ff33d7d9c74ce0f 100644 --- a/drivers/iio/humidity/htu21.c +++ b/drivers/iio/humidity/htu21.c @@ -258,4 +258,4 @@ MODULE_DESCRIPTION("Measurement-Specialties htu21 temperature and humidity drive MODULE_AUTHOR("William Markezana "); MODULE_AUTHOR("Ludovic Tancerel "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MEAS_SPEC_SENSORS); +MODULE_IMPORT_NS("IIO_MEAS_SPEC_SENSORS"); diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig index 782fb80e44c234911d07a56a1cad11eaed029303..ca0efecb5b5c1bfc8119a36890f968b61b2d662c 100644 --- a/drivers/iio/imu/Kconfig +++ b/drivers/iio/imu/Kconfig @@ -53,6 +53,7 @@ config ADIS16480 ADIS16485, ADIS16488 inertial sensors. source "drivers/iio/imu/bmi160/Kconfig" +source "drivers/iio/imu/bmi270/Kconfig" source "drivers/iio/imu/bmi323/Kconfig" source "drivers/iio/imu/bno055/Kconfig" @@ -96,6 +97,20 @@ config KMX61 source "drivers/iio/imu/inv_icm42600/Kconfig" source "drivers/iio/imu/inv_mpu6050/Kconfig" + +config SMI240 + tristate "Bosch Sensor SMI240 Inertial Measurement Unit" + depends on SPI + select REGMAP_SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + If you say yes here you get support for SMI240 IMU on SPI with + accelerometer and gyroscope. + + This driver can also be built as a module. If so, the module will be + called smi240. + source "drivers/iio/imu/st_lsm6dsx/Kconfig" source "drivers/iio/imu/st_lsm9ds0/Kconfig" diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile index 7e2d7d5c3b7bc7e76dfd00ff8437cb3c640e8a54..04c77c2c4df8c232d20d467bbd906b424227fa5d 100644 --- a/drivers/iio/imu/Makefile +++ b/drivers/iio/imu/Makefile @@ -15,6 +15,7 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o obj-y += bmi160/ +obj-y += bmi270/ obj-y += bmi323/ obj-y += bno055/ @@ -27,5 +28,7 @@ obj-y += inv_mpu6050/ obj-$(CONFIG_KMX61) += kmx61.o +obj-$(CONFIG_SMI240) += smi240.o + obj-y += st_lsm6dsx/ obj-y += st_lsm9ds0/ diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index 99410733c1ca7455abca1e3fc00a952b4ddc675c..494171844812760b0b9039316806a0c8e083f50b 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -115,7 +115,7 @@ int __adis_write_reg(struct adis *adis, unsigned int reg, unsigned int value, return ret; } -EXPORT_SYMBOL_NS_GPL(__adis_write_reg, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(__adis_write_reg, "IIO_ADISLIB"); /** * __adis_read_reg() - read N bytes from register (unlocked version) @@ -206,7 +206,7 @@ int __adis_read_reg(struct adis *adis, unsigned int reg, unsigned int *val, return ret; } -EXPORT_SYMBOL_NS_GPL(__adis_read_reg, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(__adis_read_reg, "IIO_ADISLIB"); /** * __adis_update_bits_base() - ADIS Update bits function - Unlocked version * @adis: The adis device @@ -231,7 +231,7 @@ int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask, return __adis_write_reg(adis, reg, __val, size); } -EXPORT_SYMBOL_NS_GPL(__adis_update_bits_base, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(__adis_update_bits_base, "IIO_ADISLIB"); #ifdef CONFIG_DEBUG_FS @@ -253,7 +253,7 @@ int adis_debugfs_reg_access(struct iio_dev *indio_dev, unsigned int reg, return adis_write_reg_16(adis, reg, writeval); } -EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB); +EXPORT_SYMBOL_NS(adis_debugfs_reg_access, "IIO_ADISLIB"); #endif @@ -294,7 +294,7 @@ int __adis_enable_irq(struct adis *adis, bool enable) return __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); } -EXPORT_SYMBOL_NS(__adis_enable_irq, IIO_ADISLIB); +EXPORT_SYMBOL_NS(__adis_enable_irq, "IIO_ADISLIB"); /** * __adis_check_status() - Check the device for error conditions (unlocked) @@ -326,7 +326,7 @@ int __adis_check_status(struct adis *adis) return -EIO; } -EXPORT_SYMBOL_NS_GPL(__adis_check_status, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(__adis_check_status, "IIO_ADISLIB"); /** * __adis_reset() - Reset the device (unlocked version) @@ -350,7 +350,7 @@ int __adis_reset(struct adis *adis) return 0; } -EXPORT_SYMBOL_NS_GPL(__adis_reset, IIO_ADIS_LIB); +EXPORT_SYMBOL_NS_GPL(__adis_reset, "IIO_ADIS_LIB"); static int adis_self_test(struct adis *adis) { @@ -441,7 +441,7 @@ int __adis_initial_startup(struct adis *adis) return 0; } -EXPORT_SYMBOL_NS_GPL(__adis_initial_startup, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(__adis_initial_startup, "IIO_ADISLIB"); /** * adis_single_conversion() - Performs a single sample conversion @@ -486,7 +486,7 @@ int adis_single_conversion(struct iio_dev *indio_dev, return IIO_VAL_INT; } -EXPORT_SYMBOL_NS_GPL(adis_single_conversion, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(adis_single_conversion, "IIO_ADISLIB"); /** * adis_init() - Initialize adis device structure @@ -529,7 +529,7 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev, return 0; } -EXPORT_SYMBOL_NS_GPL(adis_init, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(adis_init, "IIO_ADISLIB"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Lars-Peter Clausen "); diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index 6484ab8aff55198a2d97bda10da2f4d56b7137fa..3086dd53620382d25c5b0c35aa1b3aeea8cc722d 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -1228,4 +1228,4 @@ module_spi_driver(adis16400_driver); MODULE_AUTHOR("Manuel Stahl "); MODULE_DESCRIPTION("Analog Devices ADIS16400/5 IMU SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c index eaa38dd6201fdb64d207571619b65e3ca5a092d6..ecf74046fde1f87a69fc2d57268fc64ab7c9a9ef 100644 --- a/drivers/iio/imu/adis16460.c +++ b/drivers/iio/imu/adis16460.c @@ -418,4 +418,4 @@ module_spi_driver(adis16460_driver); MODULE_AUTHOR("Dragos Bogdan "); MODULE_DESCRIPTION("Analog Devices ADIS16460 IMU driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c index 88efe728b61bfe077965d1ed0ebc8d8df81feb64..df8c6cd911694a29f6e68dd6eedeb16f497d732e 100644 --- a/drivers/iio/imu/adis16475.c +++ b/drivers/iio/imu/adis16475.c @@ -2107,4 +2107,4 @@ module_spi_driver(adis16475_driver); MODULE_AUTHOR("Nuno Sa "); MODULE_DESCRIPTION("Analog Devices ADIS16475 IMU driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index 294181f2fcb31483b3b5149fe75998cd7fe400ef..0a5d13d2240eee27a24ee9fae2f8b0d04a39dde9 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -1794,4 +1794,4 @@ module_spi_driver(adis16480_driver); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("Analog Devices ADIS16480 IMU driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index b7c1cc04492a8e89e0a50882016d18bb4e81781f..fdfc0538734c5e781be9fd5b7183f3dfb51830b9 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -124,7 +124,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, return 0; } -EXPORT_SYMBOL_NS_GPL(adis_update_scan_mode, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(adis_update_scan_mode, "IIO_ADISLIB"); static int adis_paging_trigger_handler(struct adis *adis) { @@ -222,4 +222,4 @@ devm_adis_setup_buffer_and_trigger_with_attrs(struct adis *adis, struct iio_dev return devm_add_action_or_reset(&adis->spi->dev, adis_buffer_cleanup, adis); } -EXPORT_SYMBOL_NS_GPL(devm_adis_setup_buffer_and_trigger_with_attrs, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(devm_adis_setup_buffer_and_trigger_with_attrs, "IIO_ADISLIB"); diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index a8740b043cfe55e36c1b9cc58cce6c62aeac6408..d76e13cbac680331e3712a4e02ea96d2efe638f0 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -102,5 +102,5 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) return devm_iio_trigger_register(&adis->spi->dev, adis->trig); } -EXPORT_SYMBOL_NS_GPL(devm_adis_probe_trigger, IIO_ADISLIB); +EXPORT_SYMBOL_NS_GPL(devm_adis_probe_trigger, "IIO_ADISLIB"); diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index 495e8a74ac676e499f937a63d85999f3b82c7330..0423ef6f9571e500070b5c749ae693fcf76623a8 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -149,7 +149,7 @@ const struct regmap_config bmi160_regmap_config = { .reg_bits = 8, .val_bits = 8, }; -EXPORT_SYMBOL_NS(bmi160_regmap_config, IIO_BMI160); +EXPORT_SYMBOL_NS(bmi160_regmap_config, "IIO_BMI160"); struct bmi160_regs { u8 data; /* LSB byte register for X-axis */ @@ -638,7 +638,7 @@ int bmi160_enable_irq(struct regmap *regmap, bool enable) BMI160_DRDY_INT_EN, enable_bit, BMI160_NORMAL_WRITE_USLEEP); } -EXPORT_SYMBOL_NS(bmi160_enable_irq, IIO_BMI160); +EXPORT_SYMBOL_NS(bmi160_enable_irq, "IIO_BMI160"); static int bmi160_get_irq(struct fwnode_handle *fwnode, enum bmi160_int_pin *pin) { @@ -690,18 +690,9 @@ static int bmi160_config_device_irq(struct iio_dev *indio_dev, int irq_type, static int bmi160_setup_irq(struct iio_dev *indio_dev, int irq, enum bmi160_int_pin pin) { - struct irq_data *desc; - u32 irq_type; + u32 irq_type = irq_get_trigger_type(irq); int ret; - desc = irq_get_irq_data(irq); - if (!desc) { - dev_err(&indio_dev->dev, "Could not find IRQ %d\n", irq); - return -EINVAL; - } - - irq_type = irqd_get_trigger_type(desc); - ret = bmi160_config_device_irq(indio_dev, irq_type, pin); if (ret) return ret; @@ -897,7 +888,7 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(bmi160_core_probe, IIO_BMI160); +EXPORT_SYMBOL_NS_GPL(bmi160_core_probe, "IIO_BMI160"); MODULE_AUTHOR("Daniel Baluta "); MODULE_DESCRIPTION("Bosch BMI160 driver"); diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c index 3aa5d748f9b68240256967594785520ae6d9d27c..214503fa4af56ea9b2640b0e2b1c4aa01269426b 100644 --- a/drivers/iio/imu/bmi160/bmi160_i2c.c +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c @@ -80,4 +80,4 @@ module_i2c_driver(bmi160_i2c_driver); MODULE_AUTHOR("Daniel Baluta "); MODULE_DESCRIPTION("BMI160 I2C driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_BMI160); +MODULE_IMPORT_NS("IIO_BMI160"); diff --git a/drivers/iio/imu/bmi160/bmi160_spi.c b/drivers/iio/imu/bmi160/bmi160_spi.c index 9f40500132f7bec45b2fcf7bdd49604c5e9f2f49..8fbaab22db812369a66564fff698653c1e0e32d0 100644 --- a/drivers/iio/imu/bmi160/bmi160_spi.c +++ b/drivers/iio/imu/bmi160/bmi160_spi.c @@ -68,4 +68,4 @@ module_spi_driver(bmi160_spi_driver); MODULE_AUTHOR("Daniel Baluta +#include + +struct device; +struct bmi270_data { + struct device *dev; + struct regmap *regmap; + const struct bmi270_chip_info *chip_info; + + /* + * Where IIO_DMA_MINALIGN may be larger than 8 bytes, align to + * that to ensure a DMA safe buffer. + */ + struct { + __le16 channels[6]; + aligned_s64 timestamp; + } data __aligned(IIO_DMA_MINALIGN); +}; + +struct bmi270_chip_info { + const char *name; + int chip_id; + const char *fw_name; +}; + +extern const struct regmap_config bmi270_regmap_config; +extern const struct bmi270_chip_info bmi260_chip_info; +extern const struct bmi270_chip_info bmi270_chip_info; + +int bmi270_core_probe(struct device *dev, struct regmap *regmap, + const struct bmi270_chip_info *chip_info); + +#endif /* BMI270_H_ */ diff --git a/drivers/iio/imu/bmi270/bmi270_core.c b/drivers/iio/imu/bmi270/bmi270_core.c new file mode 100644 index 0000000000000000000000000000000000000000..7fec52e0b48624f07031b63a9caf6c318f33f5dc --- /dev/null +++ b/drivers/iio/imu/bmi270/bmi270_core.c @@ -0,0 +1,734 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "bmi270.h" + +#define BMI270_CHIP_ID_REG 0x00 + +/* Checked to prevent sending incompatible firmware to BMI160 devices */ +#define BMI160_CHIP_ID_VAL 0xD1 + +#define BMI260_CHIP_ID_VAL 0x27 +#define BMI270_CHIP_ID_VAL 0x24 +#define BMI270_CHIP_ID_MSK GENMASK(7, 0) + +#define BMI270_ACCEL_X_REG 0x0c +#define BMI270_ANG_VEL_X_REG 0x12 + +#define BMI270_INTERNAL_STATUS_REG 0x21 +#define BMI270_INTERNAL_STATUS_MSG_MSK GENMASK(3, 0) +#define BMI270_INTERNAL_STATUS_MSG_INIT_OK 0x01 + +#define BMI270_INTERNAL_STATUS_AXES_REMAP_ERR_MSK BIT(5) +#define BMI270_INTERNAL_STATUS_ODR_50HZ_ERR_MSK BIT(6) + +#define BMI270_ACC_CONF_REG 0x40 +#define BMI270_ACC_CONF_ODR_MSK GENMASK(3, 0) +#define BMI270_ACC_CONF_ODR_100HZ 0x08 +#define BMI270_ACC_CONF_BWP_MSK GENMASK(6, 4) +#define BMI270_ACC_CONF_BWP_NORMAL_MODE 0x02 +#define BMI270_ACC_CONF_FILTER_PERF_MSK BIT(7) + +#define BMI270_ACC_CONF_RANGE_REG 0x41 +#define BMI270_ACC_CONF_RANGE_MSK GENMASK(1, 0) + +#define BMI270_GYR_CONF_REG 0x42 +#define BMI270_GYR_CONF_ODR_MSK GENMASK(3, 0) +#define BMI270_GYR_CONF_ODR_200HZ 0x09 +#define BMI270_GYR_CONF_BWP_MSK GENMASK(5, 4) +#define BMI270_GYR_CONF_BWP_NORMAL_MODE 0x02 +#define BMI270_GYR_CONF_NOISE_PERF_MSK BIT(6) +#define BMI270_GYR_CONF_FILTER_PERF_MSK BIT(7) + +#define BMI270_GYR_CONF_RANGE_REG 0x43 +#define BMI270_GYR_CONF_RANGE_MSK GENMASK(2, 0) + +#define BMI270_INIT_CTRL_REG 0x59 +#define BMI270_INIT_CTRL_LOAD_DONE_MSK BIT(0) + +#define BMI270_INIT_DATA_REG 0x5e + +#define BMI270_PWR_CONF_REG 0x7c +#define BMI270_PWR_CONF_ADV_PWR_SAVE_MSK BIT(0) +#define BMI270_PWR_CONF_FIFO_WKUP_MSK BIT(1) +#define BMI270_PWR_CONF_FUP_EN_MSK BIT(2) + +#define BMI270_PWR_CTRL_REG 0x7d +#define BMI270_PWR_CTRL_AUX_EN_MSK BIT(0) +#define BMI270_PWR_CTRL_GYR_EN_MSK BIT(1) +#define BMI270_PWR_CTRL_ACCEL_EN_MSK BIT(2) +#define BMI270_PWR_CTRL_TEMP_EN_MSK BIT(3) + +#define BMI260_INIT_DATA_FILE "bmi260-init-data.fw" +#define BMI270_INIT_DATA_FILE "bmi270-init-data.fw" + +enum bmi270_scan { + BMI270_SCAN_ACCEL_X, + BMI270_SCAN_ACCEL_Y, + BMI270_SCAN_ACCEL_Z, + BMI270_SCAN_GYRO_X, + BMI270_SCAN_GYRO_Y, + BMI270_SCAN_GYRO_Z, + BMI270_SCAN_TIMESTAMP, +}; + +static const unsigned long bmi270_avail_scan_masks[] = { + (BIT(BMI270_SCAN_ACCEL_X) | + BIT(BMI270_SCAN_ACCEL_Y) | + BIT(BMI270_SCAN_ACCEL_Z) | + BIT(BMI270_SCAN_GYRO_X) | + BIT(BMI270_SCAN_GYRO_Y) | + BIT(BMI270_SCAN_GYRO_Z)), + 0 +}; + +const struct bmi270_chip_info bmi260_chip_info = { + .name = "bmi260", + .chip_id = BMI260_CHIP_ID_VAL, + .fw_name = BMI260_INIT_DATA_FILE, +}; +EXPORT_SYMBOL_NS_GPL(bmi260_chip_info, "IIO_BMI270"); + +const struct bmi270_chip_info bmi270_chip_info = { + .name = "bmi270", + .chip_id = BMI270_CHIP_ID_VAL, + .fw_name = BMI270_INIT_DATA_FILE, +}; +EXPORT_SYMBOL_NS_GPL(bmi270_chip_info, "IIO_BMI270"); + +enum bmi270_sensor_type { + BMI270_ACCEL = 0, + BMI270_GYRO, +}; + +struct bmi270_scale { + int scale; + int uscale; +}; + +struct bmi270_odr { + int odr; + int uodr; +}; + +static const struct bmi270_scale bmi270_accel_scale[] = { + { 0, 598 }, + { 0, 1197 }, + { 0, 2394 }, + { 0, 4788 }, +}; + +static const struct bmi270_scale bmi270_gyro_scale[] = { + { 0, 1065 }, + { 0, 532 }, + { 0, 266 }, + { 0, 133 }, + { 0, 66 }, +}; + +struct bmi270_scale_item { + const struct bmi270_scale *tbl; + int num; +}; + +static const struct bmi270_scale_item bmi270_scale_table[] = { + [BMI270_ACCEL] = { + .tbl = bmi270_accel_scale, + .num = ARRAY_SIZE(bmi270_accel_scale), + }, + [BMI270_GYRO] = { + .tbl = bmi270_gyro_scale, + .num = ARRAY_SIZE(bmi270_gyro_scale), + }, +}; + +static const struct bmi270_odr bmi270_accel_odr[] = { + { 0, 781250 }, + { 1, 562500 }, + { 3, 125000 }, + { 6, 250000 }, + { 12, 500000 }, + { 25, 0 }, + { 50, 0 }, + { 100, 0 }, + { 200, 0 }, + { 400, 0 }, + { 800, 0 }, + { 1600, 0 }, +}; + +static const u8 bmi270_accel_odr_vals[] = { + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0A, + 0x0B, + 0x0C, +}; + +static const struct bmi270_odr bmi270_gyro_odr[] = { + { 25, 0 }, + { 50, 0 }, + { 100, 0 }, + { 200, 0 }, + { 400, 0 }, + { 800, 0 }, + { 1600, 0 }, + { 3200, 0 }, +}; + +static const u8 bmi270_gyro_odr_vals[] = { + 0x06, + 0x07, + 0x08, + 0x09, + 0x0A, + 0x0B, + 0x0C, + 0x0D, +}; + +struct bmi270_odr_item { + const struct bmi270_odr *tbl; + const u8 *vals; + int num; +}; + +static const struct bmi270_odr_item bmi270_odr_table[] = { + [BMI270_ACCEL] = { + .tbl = bmi270_accel_odr, + .vals = bmi270_accel_odr_vals, + .num = ARRAY_SIZE(bmi270_accel_odr), + }, + [BMI270_GYRO] = { + .tbl = bmi270_gyro_odr, + .vals = bmi270_gyro_odr_vals, + .num = ARRAY_SIZE(bmi270_gyro_odr), + }, +}; + +static int bmi270_set_scale(struct bmi270_data *data, int chan_type, int uscale) +{ + int i; + int reg, mask; + struct bmi270_scale_item bmi270_scale_item; + + switch (chan_type) { + case IIO_ACCEL: + reg = BMI270_ACC_CONF_RANGE_REG; + mask = BMI270_ACC_CONF_RANGE_MSK; + bmi270_scale_item = bmi270_scale_table[BMI270_ACCEL]; + break; + case IIO_ANGL_VEL: + reg = BMI270_GYR_CONF_RANGE_REG; + mask = BMI270_GYR_CONF_RANGE_MSK; + bmi270_scale_item = bmi270_scale_table[BMI270_GYRO]; + break; + default: + return -EINVAL; + } + + for (i = 0; i < bmi270_scale_item.num; i++) { + if (bmi270_scale_item.tbl[i].uscale != uscale) + continue; + + return regmap_update_bits(data->regmap, reg, mask, i); + } + + return -EINVAL; +} + +static int bmi270_get_scale(struct bmi270_data *bmi270_device, int chan_type, + int *uscale) +{ + int ret; + unsigned int val; + struct bmi270_scale_item bmi270_scale_item; + + switch (chan_type) { + case IIO_ACCEL: + ret = regmap_read(bmi270_device->regmap, + BMI270_ACC_CONF_RANGE_REG, &val); + if (ret) + return ret; + + val = FIELD_GET(BMI270_ACC_CONF_RANGE_MSK, val); + bmi270_scale_item = bmi270_scale_table[BMI270_ACCEL]; + break; + case IIO_ANGL_VEL: + ret = regmap_read(bmi270_device->regmap, + BMI270_GYR_CONF_RANGE_REG, &val); + if (ret) + return ret; + + val = FIELD_GET(BMI270_GYR_CONF_RANGE_MSK, val); + bmi270_scale_item = bmi270_scale_table[BMI270_GYRO]; + break; + default: + return -EINVAL; + } + + if (val >= bmi270_scale_item.num) + return -EINVAL; + + *uscale = bmi270_scale_item.tbl[val].uscale; + return 0; +} + +static int bmi270_set_odr(struct bmi270_data *data, int chan_type, int odr, + int uodr) +{ + int i; + int reg, mask; + struct bmi270_odr_item bmi270_odr_item; + + switch (chan_type) { + case IIO_ACCEL: + reg = BMI270_ACC_CONF_REG; + mask = BMI270_ACC_CONF_ODR_MSK; + bmi270_odr_item = bmi270_odr_table[BMI270_ACCEL]; + break; + case IIO_ANGL_VEL: + reg = BMI270_GYR_CONF_REG; + mask = BMI270_GYR_CONF_ODR_MSK; + bmi270_odr_item = bmi270_odr_table[BMI270_GYRO]; + break; + default: + return -EINVAL; + } + + for (i = 0; i < bmi270_odr_item.num; i++) { + if (bmi270_odr_item.tbl[i].odr != odr || + bmi270_odr_item.tbl[i].uodr != uodr) + continue; + + return regmap_update_bits(data->regmap, reg, mask, + bmi270_odr_item.vals[i]); + } + + return -EINVAL; +} + +static int bmi270_get_odr(struct bmi270_data *data, int chan_type, int *odr, + int *uodr) +{ + int i, val, ret; + struct bmi270_odr_item bmi270_odr_item; + + switch (chan_type) { + case IIO_ACCEL: + ret = regmap_read(data->regmap, BMI270_ACC_CONF_REG, &val); + if (ret) + return ret; + + val = FIELD_GET(BMI270_ACC_CONF_ODR_MSK, val); + bmi270_odr_item = bmi270_odr_table[BMI270_ACCEL]; + break; + case IIO_ANGL_VEL: + ret = regmap_read(data->regmap, BMI270_GYR_CONF_REG, &val); + if (ret) + return ret; + + val = FIELD_GET(BMI270_GYR_CONF_ODR_MSK, val); + bmi270_odr_item = bmi270_odr_table[BMI270_GYRO]; + break; + default: + return -EINVAL; + } + + for (i = 0; i < bmi270_odr_item.num; i++) { + if (val != bmi270_odr_item.vals[i]) + continue; + + *odr = bmi270_odr_item.tbl[i].odr; + *uodr = bmi270_odr_item.tbl[i].uodr; + return 0; + } + + return -EINVAL; +} + +static irqreturn_t bmi270_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct bmi270_data *bmi270_device = iio_priv(indio_dev); + int ret; + + ret = regmap_bulk_read(bmi270_device->regmap, BMI270_ACCEL_X_REG, + &bmi270_device->data.channels, + sizeof(bmi270_device->data.channels)); + + if (ret) + goto done; + + iio_push_to_buffers_with_timestamp(indio_dev, &bmi270_device->data, + pf->timestamp); +done: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static int bmi270_get_data(struct bmi270_data *bmi270_device, + int chan_type, int axis, int *val) +{ + __le16 sample; + int reg; + int ret; + + switch (chan_type) { + case IIO_ACCEL: + reg = BMI270_ACCEL_X_REG + (axis - IIO_MOD_X) * 2; + break; + case IIO_ANGL_VEL: + reg = BMI270_ANG_VEL_X_REG + (axis - IIO_MOD_X) * 2; + break; + default: + return -EINVAL; + } + + ret = regmap_bulk_read(bmi270_device->regmap, reg, &sample, sizeof(sample)); + if (ret) + return ret; + + *val = sign_extend32(le16_to_cpu(sample), 15); + + return 0; +} + +static int bmi270_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret; + struct bmi270_data *bmi270_device = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = bmi270_get_data(bmi270_device, chan->type, chan->channel2, val); + if (ret) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + ret = bmi270_get_scale(bmi270_device, chan->type, val2); + return ret ? ret : IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = bmi270_get_odr(bmi270_device, chan->type, val, val2); + return ret ? ret : IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int bmi270_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct bmi270_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return bmi270_set_scale(data, chan->type, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + return bmi270_set_odr(data, chan->type, val, val2); + default: + return -EINVAL; + } +} + +static int bmi270_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *type = IIO_VAL_INT_PLUS_MICRO; + switch (chan->type) { + case IIO_ANGL_VEL: + *vals = (const int *)bmi270_gyro_scale; + *length = ARRAY_SIZE(bmi270_gyro_scale) * 2; + return IIO_AVAIL_LIST; + case IIO_ACCEL: + *vals = (const int *)bmi270_accel_scale; + *length = ARRAY_SIZE(bmi270_accel_scale) * 2; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SAMP_FREQ: + *type = IIO_VAL_INT_PLUS_MICRO; + switch (chan->type) { + case IIO_ANGL_VEL: + *vals = (const int *)bmi270_gyro_odr; + *length = ARRAY_SIZE(bmi270_gyro_odr) * 2; + return IIO_AVAIL_LIST; + case IIO_ACCEL: + *vals = (const int *)bmi270_accel_odr; + *length = ARRAY_SIZE(bmi270_accel_odr) * 2; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static const struct iio_info bmi270_info = { + .read_raw = bmi270_read_raw, + .write_raw = bmi270_write_raw, + .read_avail = bmi270_read_avail, +}; + +#define BMI270_ACCEL_CHANNEL(_axis) { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = BMI270_SCAN_ACCEL_##_axis, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +#define BMI270_ANG_VEL_CHANNEL(_axis) { \ + .type = IIO_ANGL_VEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = BMI270_SCAN_GYRO_##_axis, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ +} + +static const struct iio_chan_spec bmi270_channels[] = { + BMI270_ACCEL_CHANNEL(X), + BMI270_ACCEL_CHANNEL(Y), + BMI270_ACCEL_CHANNEL(Z), + BMI270_ANG_VEL_CHANNEL(X), + BMI270_ANG_VEL_CHANNEL(Y), + BMI270_ANG_VEL_CHANNEL(Z), + IIO_CHAN_SOFT_TIMESTAMP(BMI270_SCAN_TIMESTAMP), +}; + +static int bmi270_validate_chip_id(struct bmi270_data *bmi270_device) +{ + int chip_id; + int ret; + struct device *dev = bmi270_device->dev; + struct regmap *regmap = bmi270_device->regmap; + + ret = regmap_read(regmap, BMI270_CHIP_ID_REG, &chip_id); + if (ret) + return dev_err_probe(dev, ret, "Failed to read chip id"); + + /* + * Some manufacturers use "BMI0160" for both the BMI160 and + * BMI260. If the device is actually a BMI160, the bmi160 + * driver should handle it and this driver should not. + */ + if (chip_id == BMI160_CHIP_ID_VAL) + return -ENODEV; + + if (chip_id != bmi270_device->chip_info->chip_id) + dev_info(dev, "Unexpected chip id 0x%x", chip_id); + + if (chip_id == bmi260_chip_info.chip_id) + bmi270_device->chip_info = &bmi260_chip_info; + else if (chip_id == bmi270_chip_info.chip_id) + bmi270_device->chip_info = &bmi270_chip_info; + + return 0; +} + +static int bmi270_write_calibration_data(struct bmi270_data *bmi270_device) +{ + int ret; + int status = 0; + const struct firmware *init_data; + struct device *dev = bmi270_device->dev; + struct regmap *regmap = bmi270_device->regmap; + + ret = regmap_clear_bits(regmap, BMI270_PWR_CONF_REG, + BMI270_PWR_CONF_ADV_PWR_SAVE_MSK); + if (ret) + return dev_err_probe(dev, ret, + "Failed to write power configuration"); + + /* + * After disabling advanced power save, all registers are accessible + * after a 450us delay. This delay is specified in table A of the + * datasheet. + */ + usleep_range(450, 1000); + + ret = regmap_clear_bits(regmap, BMI270_INIT_CTRL_REG, + BMI270_INIT_CTRL_LOAD_DONE_MSK); + if (ret) + return dev_err_probe(dev, ret, + "Failed to prepare device to load init data"); + + ret = request_firmware(&init_data, + bmi270_device->chip_info->fw_name, dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to load init data file"); + + ret = regmap_bulk_write(regmap, BMI270_INIT_DATA_REG, + init_data->data, init_data->size); + release_firmware(init_data); + if (ret) + return dev_err_probe(dev, ret, "Failed to write init data"); + + ret = regmap_set_bits(regmap, BMI270_INIT_CTRL_REG, + BMI270_INIT_CTRL_LOAD_DONE_MSK); + if (ret) + return dev_err_probe(dev, ret, + "Failed to stop device initialization"); + + /* + * Wait at least 140ms for the device to complete configuration. + * This delay is specified in table C of the datasheet. + */ + usleep_range(140000, 160000); + + ret = regmap_read(regmap, BMI270_INTERNAL_STATUS_REG, &status); + if (ret) + return dev_err_probe(dev, ret, "Failed to read internal status"); + + if (status != BMI270_INTERNAL_STATUS_MSG_INIT_OK) + return dev_err_probe(dev, -ENODEV, "Device failed to initialize"); + + return 0; +} + +static int bmi270_configure_imu(struct bmi270_data *bmi270_device) +{ + int ret; + struct device *dev = bmi270_device->dev; + struct regmap *regmap = bmi270_device->regmap; + + ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG, + BMI270_PWR_CTRL_AUX_EN_MSK | + BMI270_PWR_CTRL_GYR_EN_MSK | + BMI270_PWR_CTRL_ACCEL_EN_MSK); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope"); + + ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG, + FIELD_PREP(BMI270_ACC_CONF_ODR_MSK, + BMI270_ACC_CONF_ODR_100HZ) | + FIELD_PREP(BMI270_ACC_CONF_BWP_MSK, + BMI270_ACC_CONF_BWP_NORMAL_MODE) | + BMI270_PWR_CONF_ADV_PWR_SAVE_MSK); + if (ret) + return dev_err_probe(dev, ret, "Failed to configure accelerometer"); + + ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG, + FIELD_PREP(BMI270_GYR_CONF_ODR_MSK, + BMI270_GYR_CONF_ODR_200HZ) | + FIELD_PREP(BMI270_GYR_CONF_BWP_MSK, + BMI270_GYR_CONF_BWP_NORMAL_MODE) | + BMI270_PWR_CONF_ADV_PWR_SAVE_MSK); + if (ret) + return dev_err_probe(dev, ret, "Failed to configure gyroscope"); + + /* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */ + ret = regmap_write(regmap, BMI270_PWR_CONF_REG, + BMI270_PWR_CONF_FIFO_WKUP_MSK); + if (ret) + return dev_err_probe(dev, ret, "Failed to set power configuration"); + + return 0; +} + +static int bmi270_chip_init(struct bmi270_data *bmi270_device) +{ + int ret; + + ret = bmi270_validate_chip_id(bmi270_device); + if (ret) + return ret; + + ret = bmi270_write_calibration_data(bmi270_device); + if (ret) + return ret; + + return bmi270_configure_imu(bmi270_device); +} + +int bmi270_core_probe(struct device *dev, struct regmap *regmap, + const struct bmi270_chip_info *chip_info) +{ + int ret; + struct bmi270_data *bmi270_device; + struct iio_dev *indio_dev; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*bmi270_device)); + if (!indio_dev) + return -ENOMEM; + + bmi270_device = iio_priv(indio_dev); + bmi270_device->dev = dev; + bmi270_device->regmap = regmap; + bmi270_device->chip_info = chip_info; + + ret = bmi270_chip_init(bmi270_device); + if (ret) + return ret; + + indio_dev->channels = bmi270_channels; + indio_dev->num_channels = ARRAY_SIZE(bmi270_channels); + indio_dev->name = chip_info->name; + indio_dev->available_scan_masks = bmi270_avail_scan_masks; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &bmi270_info; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + bmi270_trigger_handler, NULL); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} +EXPORT_SYMBOL_NS_GPL(bmi270_core_probe, "IIO_BMI270"); + +MODULE_AUTHOR("Alex Lanzano"); +MODULE_DESCRIPTION("BMI270 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/imu/bmi270/bmi270_i2c.c b/drivers/iio/imu/bmi270/bmi270_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..44699ab589097eaa0eec5f2172245496ed031185 --- /dev/null +++ b/drivers/iio/imu/bmi270/bmi270_i2c.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +#include +#include +#include +#include +#include + +#include "bmi270.h" + +static const struct regmap_config bmi270_i2c_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int bmi270_i2c_probe(struct i2c_client *client) +{ + struct regmap *regmap; + struct device *dev = &client->dev; + const struct bmi270_chip_info *chip_info; + + chip_info = i2c_get_match_data(client); + if (!chip_info) + return -ENODEV; + + regmap = devm_regmap_init_i2c(client, &bmi270_i2c_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to init i2c regmap"); + + return bmi270_core_probe(dev, regmap, chip_info); +} + +static const struct i2c_device_id bmi270_i2c_id[] = { + { "bmi260", (kernel_ulong_t)&bmi260_chip_info }, + { "bmi270", (kernel_ulong_t)&bmi270_chip_info }, + { } +}; + +static const struct acpi_device_id bmi270_acpi_match[] = { + /* GPD Win Mini, Aya Neo AIR Pro, OXP Mini Pro, etc. */ + { "BMI0160", (kernel_ulong_t)&bmi260_chip_info }, + { } +}; + +static const struct of_device_id bmi270_of_match[] = { + { .compatible = "bosch,bmi260", .data = &bmi260_chip_info }, + { .compatible = "bosch,bmi270", .data = &bmi270_chip_info }, + { } +}; + +static struct i2c_driver bmi270_i2c_driver = { + .driver = { + .name = "bmi270_i2c", + .acpi_match_table = bmi270_acpi_match, + .of_match_table = bmi270_of_match, + }, + .probe = bmi270_i2c_probe, + .id_table = bmi270_i2c_id, +}; +module_i2c_driver(bmi270_i2c_driver); + +MODULE_AUTHOR("Alex Lanzano"); +MODULE_DESCRIPTION("BMI270 driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_BMI270"); diff --git a/drivers/iio/imu/bmi270/bmi270_spi.c b/drivers/iio/imu/bmi270/bmi270_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..88a77aba5e4f7d6f36d508a6490ff79ffcf2d5df --- /dev/null +++ b/drivers/iio/imu/bmi270/bmi270_spi.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +#include +#include +#include +#include +#include + +#include "bmi270.h" + +/* + * The following two functions are taken from the BMI323 spi driver code. + * In section 6.4 of the BMI270 data it specifies that after a read + * operation the first data byte from the device is a dummy byte + */ +static int bmi270_regmap_spi_read(void *spi, const void *reg_buf, + size_t reg_size, void *val_buf, + size_t val_size) +{ + return spi_write_then_read(spi, reg_buf, reg_size, val_buf, val_size); +} + +static int bmi270_regmap_spi_write(void *spi, const void *data, + size_t count) +{ + u8 *data_buff = (u8 *)data; + + /* + * Remove the extra pad byte since its only needed for the read + * operation + */ + data_buff[1] = data_buff[0]; + return spi_write_then_read(spi, data_buff + 1, count - 1, NULL, 0); +} + +static const struct regmap_bus bmi270_regmap_bus = { + .read = bmi270_regmap_spi_read, + .write = bmi270_regmap_spi_write, +}; + +static const struct regmap_config bmi270_spi_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .pad_bits = 8, + .read_flag_mask = BIT(7), +}; + +static int bmi270_spi_probe(struct spi_device *spi) +{ + struct regmap *regmap; + struct device *dev = &spi->dev; + const struct bmi270_chip_info *chip_info; + + chip_info = spi_get_device_match_data(spi); + if (!chip_info) + return -ENODEV; + + regmap = devm_regmap_init(dev, &bmi270_regmap_bus, dev, + &bmi270_spi_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to init i2c regmap"); + + return bmi270_core_probe(dev, regmap, chip_info); +} + +static const struct spi_device_id bmi270_spi_id[] = { + { "bmi260", (kernel_ulong_t)&bmi260_chip_info }, + { "bmi270", (kernel_ulong_t)&bmi270_chip_info }, + { } +}; + +static const struct of_device_id bmi270_of_match[] = { + { .compatible = "bosch,bmi260", .data = &bmi260_chip_info }, + { .compatible = "bosch,bmi270", .data = &bmi270_chip_info }, + { } +}; + +static struct spi_driver bmi270_spi_driver = { + .driver = { + .name = "bmi270", + .of_match_table = bmi270_of_match, + }, + .probe = bmi270_spi_probe, + .id_table = bmi270_spi_id, +}; +module_spi_driver(bmi270_spi_driver); + +MODULE_AUTHOR("Alex Lanzano"); +MODULE_DESCRIPTION("BMI270 driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_BMI270"); diff --git a/drivers/iio/imu/bmi323/bmi323.h b/drivers/iio/imu/bmi323/bmi323.h index 209bccb1f335cfb5a4f8b009cc20b8fe2fe93071..b4cfe92600a4fedd7b53a0d538338150b4c751e8 100644 --- a/drivers/iio/imu/bmi323/bmi323.h +++ b/drivers/iio/imu/bmi323/bmi323.h @@ -141,7 +141,6 @@ #define BMI323_STEP_SC1_REG 0x10 #define BMI323_STEP_SC1_WTRMRK_MSK GENMASK(9, 0) #define BMI323_STEP_SC1_RST_CNT_MSK BIT(10) -#define BMI323_STEP_SC1_REG 0x10 #define BMI323_STEP_LEN 2 /* Tap gesture config registers */ diff --git a/drivers/iio/imu/bmi323/bmi323_core.c b/drivers/iio/imu/bmi323/bmi323_core.c index e1f3b0d778be03013042e606a160f40689acf22e..f7d7f4442e65f5ee10d20f2f1b0ad5386c82f0b6 100644 --- a/drivers/iio/imu/bmi323/bmi323_core.c +++ b/drivers/iio/imu/bmi323/bmi323_core.c @@ -467,7 +467,7 @@ static int bmi323_feature_engine_events(struct bmi323_data *data, BMI323_FEAT_IO_STATUS_MSK); } -static int bmi323_step_wtrmrk_en(struct bmi323_data *data, int state) +static int bmi323_step_wtrmrk_en(struct bmi323_data *data, bool state) { enum bmi323_irq_pin step_irq; int ret; @@ -484,7 +484,7 @@ static int bmi323_step_wtrmrk_en(struct bmi323_data *data, int state) ret = bmi323_update_ext_reg(data, BMI323_STEP_SC1_REG, BMI323_STEP_SC1_WTRMRK_MSK, FIELD_PREP(BMI323_STEP_SC1_WTRMRK_MSK, - state ? 1 : 0)); + state)); if (ret) return ret; @@ -506,7 +506,7 @@ static int bmi323_motion_config_reg(enum iio_event_direction dir) } static int bmi323_motion_event_en(struct bmi323_data *data, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { unsigned int state_value = state ? BMI323_FEAT_XYZ_MSK : 0; int config, ret, msk, raw, field_value; @@ -570,7 +570,7 @@ static int bmi323_motion_event_en(struct bmi323_data *data, } static int bmi323_tap_event_en(struct bmi323_data *data, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { enum bmi323_irq_pin tap_irq; int ret, tap_enabled; @@ -785,7 +785,7 @@ static const struct attribute_group bmi323_event_attribute_group = { static int bmi323_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct bmi323_data *data = iio_priv(indio_dev); @@ -1881,7 +1881,6 @@ static int bmi323_trigger_probe(struct bmi323_data *data, struct fwnode_handle *fwnode; enum bmi323_irq_pin irq_pin; int ret, irq, irq_type; - struct irq_data *desc; fwnode = dev_fwnode(data->dev); if (!fwnode) @@ -1898,12 +1897,7 @@ static int bmi323_trigger_probe(struct bmi323_data *data, irq_pin = BMI323_IRQ_INT2; } - desc = irq_get_irq_data(irq); - if (!desc) - return dev_err_probe(data->dev, -EINVAL, - "Could not find IRQ %d\n", irq); - - irq_type = irqd_get_trigger_type(desc); + irq_type = irq_get_trigger_type(irq); switch (irq_type) { case IRQF_TRIGGER_RISING: latch = false; @@ -2170,7 +2164,7 @@ int bmi323_core_probe(struct device *dev) return bmi323_fifo_disable(data); } -EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); +EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, "IIO_BMI323"); static int bmi323_core_runtime_suspend(struct device *dev) { @@ -2298,7 +2292,7 @@ const struct dev_pm_ops bmi323_core_pm_ops = { RUNTIME_PM_OPS(bmi323_core_runtime_suspend, bmi323_core_runtime_resume, NULL) }; -EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323); +EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, "IIO_BMI323"); MODULE_DESCRIPTION("Bosch BMI323 IMU driver"); MODULE_AUTHOR("Jagath Jog J "); diff --git a/drivers/iio/imu/bmi323/bmi323_i2c.c b/drivers/iio/imu/bmi323/bmi323_i2c.c index 0ba5d69d8329aed0efccad7def00c3af7574a281..8457fe304db8492a287b7aa3c5fdce1cd9006566 100644 --- a/drivers/iio/imu/bmi323/bmi323_i2c.c +++ b/drivers/iio/imu/bmi323/bmi323_i2c.c @@ -140,4 +140,4 @@ module_i2c_driver(bmi323_i2c_driver); MODULE_DESCRIPTION("Bosch BMI323 IMU driver"); MODULE_AUTHOR("Jagath Jog J "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_BMI323); +MODULE_IMPORT_NS("IIO_BMI323"); diff --git a/drivers/iio/imu/bmi323/bmi323_spi.c b/drivers/iio/imu/bmi323/bmi323_spi.c index 9de3ade78d714d19170400ca3f2bb9bf5d7d7c96..fd56ab6207500d01af6c10a03ab26a296cb49ff1 100644 --- a/drivers/iio/imu/bmi323/bmi323_spi.c +++ b/drivers/iio/imu/bmi323/bmi323_spi.c @@ -90,4 +90,4 @@ module_spi_driver(bmi323_spi_driver); MODULE_DESCRIPTION("Bosch BMI323 IMU driver"); MODULE_AUTHOR("Jagath Jog J "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_BMI323); +MODULE_IMPORT_NS("IIO_BMI323"); diff --git a/drivers/iio/imu/bno055/bno055.c b/drivers/iio/imu/bno055/bno055.c index ea6519b22b2f34cccbfe259ac3c1edae1b524933..0728d38260a1c9dd218569ee870bd62c833e9906 100644 --- a/drivers/iio/imu/bno055/bno055.c +++ b/drivers/iio/imu/bno055/bno055.c @@ -292,7 +292,7 @@ const struct regmap_config bno055_regmap_config = { .readable_reg = bno055_regmap_readable, .cache_type = REGCACHE_RBTREE, }; -EXPORT_SYMBOL_NS_GPL(bno055_regmap_config, IIO_BNO055); +EXPORT_SYMBOL_NS_GPL(bno055_regmap_config, "IIO_BNO055"); /* must be called in configuration mode */ static int bno055_calibration_load(struct bno055_priv *priv, const u8 *data, int len) @@ -1678,7 +1678,7 @@ int bno055_probe(struct device *dev, struct regmap *regmap, return 0; } -EXPORT_SYMBOL_NS_GPL(bno055_probe, IIO_BNO055); +EXPORT_SYMBOL_NS_GPL(bno055_probe, "IIO_BNO055"); MODULE_AUTHOR("Andrea Merello "); MODULE_DESCRIPTION("Bosch BNO055 driver"); diff --git a/drivers/iio/imu/bno055/bno055_i2c.c b/drivers/iio/imu/bno055/bno055_i2c.c index cf3dd62a83ba8a00ca3636d34bf96bceacfe3036..f49d0905ee3384b8d83a27a09e81fe982295a8b5 100644 --- a/drivers/iio/imu/bno055/bno055_i2c.c +++ b/drivers/iio/imu/bno055/bno055_i2c.c @@ -53,5 +53,5 @@ module_i2c_driver(bno055_driver); MODULE_AUTHOR("Andrea Merello"); MODULE_DESCRIPTION("Bosch BNO055 I2C interface"); -MODULE_IMPORT_NS(IIO_BNO055); +MODULE_IMPORT_NS("IIO_BNO055"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/imu/bno055/bno055_ser_core.c b/drivers/iio/imu/bno055/bno055_ser_core.c index da7873bfd3487511a756cb5b71bb4d42da8aca93..48669dabb37ba84a281c61962f0d79a36e5fcbcf 100644 --- a/drivers/iio/imu/bno055/bno055_ser_core.c +++ b/drivers/iio/imu/bno055/bno055_ser_core.c @@ -556,5 +556,5 @@ module_serdev_device_driver(bno055_ser_driver); MODULE_AUTHOR("Andrea Merello "); MODULE_DESCRIPTION("Bosch BNO055 serdev interface"); -MODULE_IMPORT_NS(IIO_BNO055); +MODULE_IMPORT_NS("IIO_BNO055"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/imu/fxos8700_core.c b/drivers/iio/imu/fxos8700_core.c index 6d189c4b9ff962e0a241680e2d075a002ff69c39..281ebfd9c15a85be8bf5ef6263fbf4f4f2a18ab0 100644 --- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -8,7 +8,6 @@ */ #include #include -#include #include #include diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c index 56ac198142500a2e1fc40b62cdd465cc736d8bf0..7968aa27f9fd798f206e72891f1c9b483811dea2 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -200,7 +200,6 @@ static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev, { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev); - struct inv_sensors_timestamp *ts = &accel_st->ts; struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; unsigned int fifo_en = 0; unsigned int sleep_temp = 0; @@ -229,7 +228,6 @@ static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev, } /* update data FIFO write */ - inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); out_unlock: diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index c3924cc6190ee4ad101621f22349b7804a35fa3b..561d245c1d6446251934aa8529caaf6f00710017 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -85,7 +85,7 @@ const struct regmap_config inv_icm42600_regmap_config = { .rd_noinc_table = inv_icm42600_regmap_rd_noinc_accesses, .cache_type = REGCACHE_RBTREE, }; -EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, IIO_ICM42600); +EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, "IIO_ICM42600"); struct inv_icm42600_hw { uint8_t whoami; @@ -673,7 +673,6 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, { struct device *dev = regmap_get_device(regmap); struct inv_icm42600_state *st; - struct irq_data *irq_desc; int irq_type; bool open_drain; int ret; @@ -683,14 +682,7 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, return -ENODEV; } - /* get irq properties, set trigger falling by default */ - irq_desc = irq_get_irq_data(irq); - if (!irq_desc) { - dev_err(dev, "could not find IRQ %d\n", irq); - return -EINVAL; - } - - irq_type = irqd_get_trigger_type(irq_desc); + irq_type = irq_get_trigger_type(irq); if (!irq_type) irq_type = IRQF_TRIGGER_FALLING; @@ -773,7 +765,7 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev); } -EXPORT_SYMBOL_NS_GPL(inv_icm42600_core_probe, IIO_ICM42600); +EXPORT_SYMBOL_NS_GPL(inv_icm42600_core_probe, "IIO_ICM42600"); /* * Suspend saves sensors state and turns everything off. @@ -896,4 +888,4 @@ EXPORT_NS_GPL_DEV_PM_OPS(inv_icm42600_pm_ops, IIO_ICM42600) = { MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx device driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP); +MODULE_IMPORT_NS("IIO_INV_SENSORS_TIMESTAMP"); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c index 938af5b640b00f58d2b8185f752c4755edfb0d25..c6bb68bf5e1449d4b961ac962311cbc5aa3c0a97 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -99,8 +99,6 @@ static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); - struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev); - struct inv_sensors_timestamp *ts = &gyro_st->ts; struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; unsigned int fifo_en = 0; unsigned int sleep_gyro = 0; @@ -128,7 +126,6 @@ static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev, } /* update data FIFO write */ - inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); out_unlock: diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c index ebb31b385881e1a835b7ab81ad7582a729a10d5f..04e440fe023aa3869529b0f0be003ea0544bfb8d 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c @@ -71,6 +71,22 @@ static int inv_icm42600_probe(struct i2c_client *client) inv_icm42600_i2c_bus_setup); } +/* + * device id table is used to identify what device can be + * supported by this driver + */ +static const struct i2c_device_id inv_icm42600_id[] = { + { "icm42600", INV_CHIP_ICM42600 }, + { "icm42602", INV_CHIP_ICM42602 }, + { "icm42605", INV_CHIP_ICM42605 }, + { "icm42686", INV_CHIP_ICM42686 }, + { "icm42622", INV_CHIP_ICM42622 }, + { "icm42688", INV_CHIP_ICM42688 }, + { "icm42631", INV_CHIP_ICM42631 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, inv_icm42600_id); + static const struct of_device_id inv_icm42600_of_matches[] = { { .compatible = "invensense,icm42600", @@ -104,6 +120,7 @@ static struct i2c_driver inv_icm42600_driver = { .of_match_table = inv_icm42600_of_matches, .pm = pm_ptr(&inv_icm42600_pm_ops), }, + .id_table = inv_icm42600_id, .probe = inv_icm42600_probe, }; module_i2c_driver(inv_icm42600_driver); @@ -111,4 +128,4 @@ module_i2c_driver(inv_icm42600_driver); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx I2C driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ICM42600); +MODULE_IMPORT_NS("IIO_ICM42600"); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c index eae5ff7a3cc102e2487f6310d18cb55745df77b0..c55d8e672183dd79a0912e6a7ccde4b6ad054dd2 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c @@ -67,6 +67,22 @@ static int inv_icm42600_probe(struct spi_device *spi) inv_icm42600_spi_bus_setup); } +/* + * device id table is used to identify what device can be + * supported by this driver + */ +static const struct spi_device_id inv_icm42600_id[] = { + { "icm42600", INV_CHIP_ICM42600 }, + { "icm42602", INV_CHIP_ICM42602 }, + { "icm42605", INV_CHIP_ICM42605 }, + { "icm42686", INV_CHIP_ICM42686 }, + { "icm42622", INV_CHIP_ICM42622 }, + { "icm42688", INV_CHIP_ICM42688 }, + { "icm42631", INV_CHIP_ICM42631 }, + { } +}; +MODULE_DEVICE_TABLE(spi, inv_icm42600_id); + static const struct of_device_id inv_icm42600_of_matches[] = { { .compatible = "invensense,icm42600", @@ -100,6 +116,7 @@ static struct spi_driver inv_icm42600_driver = { .of_match_table = inv_icm42600_of_matches, .pm = pm_ptr(&inv_icm42600_pm_ops), }, + .id_table = inv_icm42600_id, .probe = inv_icm42600_probe, }; module_spi_driver(inv_icm42600_driver); @@ -107,4 +124,4 @@ module_spi_driver(inv_icm42600_driver); MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx SPI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_ICM42600); +MODULE_IMPORT_NS("IIO_ICM42600"); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c index f7bce428d9eb45c2e68add02ee31697241dabfc5..373e59f6d91a5b058e739023b2c46c5826e88ec0 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c @@ -10,6 +10,8 @@ #include #include #include +#include + #include "inv_mpu_iio.h" enum inv_mpu_product_name { @@ -102,14 +104,11 @@ static int inv_mpu_process_acpi_config(struct i2c_client *client, unsigned short *secondary_addr) { struct acpi_device *adev = ACPI_COMPANION(&client->dev); - const struct acpi_device_id *id; u32 i2c_addr = 0; LIST_HEAD(resources); int ret; - id = acpi_match_device(client->dev.driver->acpi_match_table, - &client->dev); - if (!id) + if (!is_acpi_device_node(dev_fwnode(&client->dev))) return -ENODEV; ret = acpi_dev_get_resources(adev, &resources, @@ -118,8 +117,8 @@ static int inv_mpu_process_acpi_config(struct i2c_client *client, return ret; acpi_dev_free_resource_list(&resources); - *primary_addr = i2c_addr & 0x0000ffff; - *secondary_addr = (i2c_addr & 0xffff0000) >> 16; + *primary_addr = lower_16_bits(i2c_addr); + *secondary_addr = upper_16_bits(i2c_addr); return 0; } diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 14d95f34e981c8b71dd0892fbeb12735a8857d6c..844b611b825a961375193b726e9722c7a0d0887f 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -286,6 +286,24 @@ static const struct inv_mpu6050_hw hw_info[] = { .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME}, }, + { + .whoami = INV_IAM20680HP_WHOAMI_VALUE, + .name = "IAM20680HP", + .reg = ®_set_6500, + .config = &chip_config_6500, + .fifo_size = 4 * 1024, + .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, + .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME}, + }, + { + .whoami = INV_IAM20680HT_WHOAMI_VALUE, + .name = "IAM20680HT", + .reg = ®_set_6500, + .config = &chip_config_6500, + .fifo_size = 4 * 1024, + .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, + .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME}, + }, }; static int inv_mpu6050_pwr_mgmt_1_write(struct inv_mpu6050_state *st, bool sleep, @@ -510,6 +528,8 @@ static int inv_mpu6050_set_accel_lpf_regs(struct inv_mpu6050_state *st, return 0; case INV_ICM20689: case INV_ICM20690: + case INV_IAM20680HT: + case INV_IAM20680HP: /* set FIFO size to maximum value */ val |= INV_ICM20689_BITS_FIFO_SIZE_MAX; break; @@ -1153,24 +1173,21 @@ static int inv_mpu6050_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct inv_mpu6050_state *st = iio_priv(indio_dev); - int enable; /* support only WoM (accel roc rising) event */ if (chan->type != IIO_ACCEL || type != IIO_EV_TYPE_ROC || dir != IIO_EV_DIR_RISING) return -EINVAL; - enable = !!state; - guard(mutex)(&st->lock); - if (st->chip_config.wom_en == enable) + if (st->chip_config.wom_en == state) return 0; - return inv_mpu6050_enable_wom(st, enable); + return inv_mpu6050_enable_wom(st, state); } static int inv_mpu6050_read_event_value(struct iio_dev *indio_dev, @@ -1859,7 +1876,6 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, struct inv_mpu6050_platform_data *pdata; struct device *dev = regmap_get_device(regmap); int result; - struct irq_data *desc; int irq_type; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); @@ -1893,13 +1909,7 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, } if (irq > 0) { - desc = irq_get_irq_data(irq); - if (!desc) { - dev_err(dev, "Could not find IRQ %d\n", irq); - return -EINVAL; - } - - irq_type = irqd_get_trigger_type(desc); + irq_type = irq_get_trigger_type(irq); if (!irq_type) irq_type = IRQF_TRIGGER_RISING; } else { @@ -2082,7 +2092,7 @@ error_power_off: inv_mpu6050_set_power_itg(st, false); return result; } -EXPORT_SYMBOL_NS_GPL(inv_mpu_core_probe, IIO_MPU6050); +EXPORT_SYMBOL_NS_GPL(inv_mpu_core_probe, "IIO_MPU6050"); static int inv_mpu_resume(struct device *dev) { @@ -2233,4 +2243,4 @@ EXPORT_NS_GPL_DEV_PM_OPS(inv_mpu_pmops, IIO_MPU6050) = { MODULE_AUTHOR("Invensense Corporation"); MODULE_DESCRIPTION("Invensense device MPU6050 driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP); +MODULE_IMPORT_NS("IIO_INV_SENSORS_TIMESTAMP"); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index 0e03137fb3d40d4753989522cf5168ef358a1014..307a06f4df2e2fb61d67a11dce8e01f901ffc128 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -188,6 +188,8 @@ static const struct i2c_device_id inv_mpu_id[] = { {"icm20602", INV_ICM20602}, {"icm20690", INV_ICM20690}, {"iam20680", INV_IAM20680}, + {"iam20680hp", INV_IAM20680HP}, + {"iam20680ht", INV_IAM20680HT}, {} }; @@ -254,6 +256,14 @@ static const struct of_device_id inv_of_match[] = { .compatible = "invensense,iam20680", .data = (void *)INV_IAM20680 }, + { + .compatible = "invensense,iam20680hp", + .data = (void *)INV_IAM20680HP + }, + { + .compatible = "invensense,iam20680ht", + .data = (void *)INV_IAM20680HT + }, { } }; MODULE_DEVICE_TABLE(of, inv_of_match); @@ -281,4 +291,4 @@ module_i2c_driver(inv_mpu_driver); MODULE_AUTHOR("Invensense Corporation"); MODULE_DESCRIPTION("Invensense device MPU6050 driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_MPU6050); +MODULE_IMPORT_NS("IIO_MPU6050"); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index e1c0c51468761ab18188a224e44e09f919d81f9a..a6862cf426396cbaf3452bb3451cd58e4f30a4ec 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -85,6 +85,8 @@ enum inv_devices { INV_ICM20602, INV_ICM20690, INV_IAM20680, + INV_IAM20680HP, + INV_IAM20680HT, INV_NUM_PARTS }; @@ -424,6 +426,8 @@ struct inv_mpu6050_state { #define INV_ICM20602_WHOAMI_VALUE 0x12 #define INV_ICM20690_WHOAMI_VALUE 0x20 #define INV_IAM20680_WHOAMI_VALUE 0xA9 +#define INV_IAM20680HP_WHOAMI_VALUE 0xF8 +#define INV_IAM20680HT_WHOAMI_VALUE 0xFA /* scan element definition for generic MPU6xxx devices */ enum inv_mpu6050_scan { diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c index 05451ca1580b637a66a30efe82fbd2a2b63e55d5..ab415874d6994844c94302fa3cd45f05d2e50d45 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c @@ -80,6 +80,8 @@ static const struct spi_device_id inv_mpu_id[] = { {"icm20602", INV_ICM20602}, {"icm20690", INV_ICM20690}, {"iam20680", INV_IAM20680}, + {"iam20680hp", INV_IAM20680HP}, + {"iam20680ht", INV_IAM20680HT}, {} }; @@ -142,6 +144,14 @@ static const struct of_device_id inv_of_match[] = { .compatible = "invensense,iam20680", .data = (void *)INV_IAM20680 }, + { + .compatible = "invensense,iam20680hp", + .data = (void *)INV_IAM20680HP + }, + { + .compatible = "invensense,iam20680ht", + .data = (void *)INV_IAM20680HT + }, { } }; MODULE_DEVICE_TABLE(of, inv_of_match); @@ -168,4 +178,4 @@ module_spi_driver(inv_mpu_driver); MODULE_AUTHOR("Adriana Reus "); MODULE_DESCRIPTION("Invensense device MPU6000 driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_MPU6050); +MODULE_IMPORT_NS("IIO_MPU6050"); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c index 3bfeabab0ec4f6fa28fbbcd47afe92af5b8a58e2..5b1088cc3704f1ad1288a0d65b2f957b91455d7f 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c @@ -112,7 +112,6 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable) if (enable) { /* reset timestamping */ inv_sensors_timestamp_reset(&st->timestamp); - inv_sensors_timestamp_apply_odr(&st->timestamp, 0, 0, 0); /* reset FIFO */ d = st->chip_config.user_ctrl | INV_MPU6050_BIT_FIFO_RST; ret = regmap_write(st->map, st->reg->user_ctrl, d); diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index c61c012e25bbaac3e014e5df2f375df37fbde1de..324c38764656ad74e2bbdc54824b4321db3c0b81 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -7,12 +7,13 @@ * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F). */ -#include #include -#include #include +#include +#include #include #include + #include #include #include @@ -941,7 +942,7 @@ static int kmx61_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct kmx61_data *data = kmx61_get_data(indio_dev); int ret = 0; @@ -1217,16 +1218,6 @@ err: return IRQ_HANDLED; } -static const char *kmx61_match_acpi_device(struct device *dev) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - return dev_name(dev); -} - static struct iio_dev *kmx61_indiodev_setup(struct kmx61_data *data, const struct iio_info *info, const struct iio_chan_spec *chan, @@ -1293,8 +1284,6 @@ static int kmx61_probe(struct i2c_client *client) if (id) name = id->name; - else if (ACPI_HANDLE(&client->dev)) - name = kmx61_match_acpi_device(&client->dev); else return -ENODEV; @@ -1496,13 +1485,6 @@ static const struct dev_pm_ops kmx61_pm_ops = { RUNTIME_PM_OPS(kmx61_runtime_suspend, kmx61_runtime_resume, NULL) }; -static const struct acpi_device_id kmx61_acpi_match[] = { - {"KMX61021", 0}, - {} -}; - -MODULE_DEVICE_TABLE(acpi, kmx61_acpi_match); - static const struct i2c_device_id kmx61_id[] = { { "kmx611021" }, {} @@ -1513,7 +1495,6 @@ MODULE_DEVICE_TABLE(i2c, kmx61_id); static struct i2c_driver kmx61_driver = { .driver = { .name = KMX61_DRV_NAME, - .acpi_match_table = kmx61_acpi_match, .pm = pm_ptr(&kmx61_pm_ops), }, .probe = kmx61_probe, diff --git a/drivers/iio/imu/smi240.c b/drivers/iio/imu/smi240.c new file mode 100644 index 0000000000000000000000000000000000000000..4492c4d013bd6a22c76f51a427c6fa0e240edf3b --- /dev/null +++ b/drivers/iio/imu/smi240.c @@ -0,0 +1,621 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 +/* + * Copyright (c) 2024 Robert Bosch GmbH. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define SMI240_CHIP_ID 0x0024 + +#define SMI240_SOFT_CONFIG_EOC_MASK BIT(0) +#define SMI240_SOFT_CONFIG_GYR_BW_MASK BIT(1) +#define SMI240_SOFT_CONFIG_ACC_BW_MASK BIT(2) +#define SMI240_SOFT_CONFIG_BITE_AUTO_MASK BIT(3) +#define SMI240_SOFT_CONFIG_BITE_REP_MASK GENMASK(6, 4) + +#define SMI240_CHIP_ID_REG 0x00 +#define SMI240_SOFT_CONFIG_REG 0x0A +#define SMI240_TEMP_CUR_REG 0x10 +#define SMI240_ACCEL_X_CUR_REG 0x11 +#define SMI240_GYRO_X_CUR_REG 0x14 +#define SMI240_DATA_CAP_FIRST_REG 0x17 +#define SMI240_CMD_REG 0x2F + +#define SMI240_SOFT_RESET_CMD 0xB6 + +#define SMI240_BITE_SEQUENCE_DELAY_US 140000 +#define SMI240_FILTER_FLUSH_DELAY_US 60000 +#define SMI240_DIGITAL_STARTUP_DELAY_US 120000 +#define SMI240_MECH_STARTUP_DELAY_US 100000 + +#define SMI240_BUS_ID 0x00 +#define SMI240_CRC_INIT 0x05 +#define SMI240_CRC_POLY 0x0B +#define SMI240_CRC_MASK GENMASK(2, 0) + +#define SMI240_READ_SD_BIT_MASK BIT(31) +#define SMI240_READ_DATA_MASK GENMASK(19, 4) +#define SMI240_READ_CS_BIT_MASK BIT(3) + +#define SMI240_WRITE_BUS_ID_MASK GENMASK(31, 30) +#define SMI240_WRITE_ADDR_MASK GENMASK(29, 22) +#define SMI240_WRITE_BIT_MASK BIT(21) +#define SMI240_WRITE_CAP_BIT_MASK BIT(20) +#define SMI240_WRITE_DATA_MASK GENMASK(18, 3) + +/* T°C = (temp / 256) + 25 */ +#define SMI240_TEMP_OFFSET 6400 /* 25 * 256 */ +#define SMI240_TEMP_SCALE 3906250 /* (1 / 256) * 1e9 */ + +#define SMI240_ACCEL_SCALE 500 /* (1 / 2000) * 1e6 */ +#define SMI240_GYRO_SCALE 10000 /* (1 / 100) * 1e6 */ + +#define SMI240_LOW_BANDWIDTH_HZ 50 +#define SMI240_HIGH_BANDWIDTH_HZ 400 + +#define SMI240_BUILT_IN_SELF_TEST_COUNT 3 + +#define SMI240_DATA_CHANNEL(_type, _axis, _index) { \ + .type = _type, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ +} + +#define SMI240_TEMP_CHANNEL(_index) { \ + .type = IIO_TEMP, \ + .modified = 1, \ + .channel2 = IIO_MOD_TEMP_OBJECT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_OFFSET) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ +} + +enum capture_mode { SMI240_CAPTURE_OFF = 0, SMI240_CAPTURE_ON = 1 }; + +struct smi240_data { + struct regmap *regmap; + u16 accel_filter_freq; + u16 anglvel_filter_freq; + u8 built_in_self_test_count; + enum capture_mode capture; + /* + * Ensure natural alignment for timestamp if present. + * Channel size: 2 bytes. + * Max length needed: 2 * 3 channels + temp channel + 2 bytes padding + 8 byte ts. + * If fewer channels are enabled, less space may be needed, as + * long as the timestamp is still aligned to 8 bytes. + */ + s16 buf[12] __aligned(8); + + __be32 spi_buf __aligned(IIO_DMA_MINALIGN); +}; + +enum { + SMI240_TEMP_OBJECT, + SMI240_SCAN_ACCEL_X, + SMI240_SCAN_ACCEL_Y, + SMI240_SCAN_ACCEL_Z, + SMI240_SCAN_GYRO_X, + SMI240_SCAN_GYRO_Y, + SMI240_SCAN_GYRO_Z, + SMI240_SCAN_TIMESTAMP, +}; + +static const struct iio_chan_spec smi240_channels[] = { + SMI240_TEMP_CHANNEL(SMI240_TEMP_OBJECT), + SMI240_DATA_CHANNEL(IIO_ACCEL, X, SMI240_SCAN_ACCEL_X), + SMI240_DATA_CHANNEL(IIO_ACCEL, Y, SMI240_SCAN_ACCEL_Y), + SMI240_DATA_CHANNEL(IIO_ACCEL, Z, SMI240_SCAN_ACCEL_Z), + SMI240_DATA_CHANNEL(IIO_ANGL_VEL, X, SMI240_SCAN_GYRO_X), + SMI240_DATA_CHANNEL(IIO_ANGL_VEL, Y, SMI240_SCAN_GYRO_Y), + SMI240_DATA_CHANNEL(IIO_ANGL_VEL, Z, SMI240_SCAN_GYRO_Z), + IIO_CHAN_SOFT_TIMESTAMP(SMI240_SCAN_TIMESTAMP), +}; + +static const int smi240_low_pass_freqs[] = { SMI240_LOW_BANDWIDTH_HZ, + SMI240_HIGH_BANDWIDTH_HZ }; + +static u8 smi240_crc3(u32 data, u8 init, u8 poly) +{ + u8 crc = init; + u8 do_xor; + s8 i = 31; + + do { + do_xor = crc & 0x04; + crc <<= 1; + crc |= 0x01 & (data >> i); + if (do_xor) + crc ^= poly; + + crc &= SMI240_CRC_MASK; + } while (--i >= 0); + + return crc; +} + +static bool smi240_sensor_data_is_valid(u32 data) +{ + if (smi240_crc3(data, SMI240_CRC_INIT, SMI240_CRC_POLY) != 0) + return false; + + if (FIELD_GET(SMI240_READ_SD_BIT_MASK, data) & + FIELD_GET(SMI240_READ_CS_BIT_MASK, data)) + return false; + + return true; +} + +static int smi240_regmap_spi_read(void *context, const void *reg_buf, + size_t reg_size, void *val_buf, + size_t val_size) +{ + int ret; + u32 request, response; + u16 *val = val_buf; + struct spi_device *spi = context; + struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev); + struct smi240_data *iio_priv_data = iio_priv(indio_dev); + + if (reg_size != 1 || val_size != 2) + return -EINVAL; + + request = FIELD_PREP(SMI240_WRITE_BUS_ID_MASK, SMI240_BUS_ID); + request |= FIELD_PREP(SMI240_WRITE_CAP_BIT_MASK, iio_priv_data->capture); + request |= FIELD_PREP(SMI240_WRITE_ADDR_MASK, *(u8 *)reg_buf); + request |= smi240_crc3(request, SMI240_CRC_INIT, SMI240_CRC_POLY); + + iio_priv_data->spi_buf = cpu_to_be32(request); + + /* + * SMI240 module consists of a 32Bit Out Of Frame (OOF) + * SPI protocol, where the slave interface responds to + * the Master request in the next frame. + * CS signal must toggle (> 700 ns) between the frames. + */ + ret = spi_write(spi, &iio_priv_data->spi_buf, sizeof(request)); + if (ret) + return ret; + + ret = spi_read(spi, &iio_priv_data->spi_buf, sizeof(response)); + if (ret) + return ret; + + response = be32_to_cpu(iio_priv_data->spi_buf); + + if (!smi240_sensor_data_is_valid(response)) + return -EIO; + + *val = FIELD_GET(SMI240_READ_DATA_MASK, response); + + return 0; +} + +static int smi240_regmap_spi_write(void *context, const void *data, + size_t count) +{ + u8 reg_addr; + u16 reg_data; + u32 request; + const u8 *data_ptr = data; + struct spi_device *spi = context; + struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev); + struct smi240_data *iio_priv_data = iio_priv(indio_dev); + + if (count < 2) + return -EINVAL; + + reg_addr = data_ptr[0]; + memcpy(®_data, &data_ptr[1], sizeof(reg_data)); + + request = FIELD_PREP(SMI240_WRITE_BUS_ID_MASK, SMI240_BUS_ID); + request |= FIELD_PREP(SMI240_WRITE_BIT_MASK, 1); + request |= FIELD_PREP(SMI240_WRITE_ADDR_MASK, reg_addr); + request |= FIELD_PREP(SMI240_WRITE_DATA_MASK, reg_data); + request |= smi240_crc3(request, SMI240_CRC_INIT, SMI240_CRC_POLY); + + iio_priv_data->spi_buf = cpu_to_be32(request); + + return spi_write(spi, &iio_priv_data->spi_buf, sizeof(request)); +} + +static const struct regmap_bus smi240_regmap_bus = { + .read = smi240_regmap_spi_read, + .write = smi240_regmap_spi_write, +}; + +static const struct regmap_config smi240_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +}; + +static int smi240_soft_reset(struct smi240_data *data) +{ + int ret; + + ret = regmap_write(data->regmap, SMI240_CMD_REG, SMI240_SOFT_RESET_CMD); + if (ret) + return ret; + fsleep(SMI240_DIGITAL_STARTUP_DELAY_US); + + return 0; +} + +static int smi240_soft_config(struct smi240_data *data) +{ + int ret; + u8 acc_bw, gyr_bw; + u16 request; + + switch (data->accel_filter_freq) { + case SMI240_LOW_BANDWIDTH_HZ: + acc_bw = 0x1; + break; + case SMI240_HIGH_BANDWIDTH_HZ: + acc_bw = 0x0; + break; + default: + return -EINVAL; + } + + switch (data->anglvel_filter_freq) { + case SMI240_LOW_BANDWIDTH_HZ: + gyr_bw = 0x1; + break; + case SMI240_HIGH_BANDWIDTH_HZ: + gyr_bw = 0x0; + break; + default: + return -EINVAL; + } + + request = FIELD_PREP(SMI240_SOFT_CONFIG_EOC_MASK, 1); + request |= FIELD_PREP(SMI240_SOFT_CONFIG_GYR_BW_MASK, gyr_bw); + request |= FIELD_PREP(SMI240_SOFT_CONFIG_ACC_BW_MASK, acc_bw); + request |= FIELD_PREP(SMI240_SOFT_CONFIG_BITE_AUTO_MASK, 1); + request |= FIELD_PREP(SMI240_SOFT_CONFIG_BITE_REP_MASK, + data->built_in_self_test_count - 1); + + ret = regmap_write(data->regmap, SMI240_SOFT_CONFIG_REG, request); + if (ret) + return ret; + + fsleep(SMI240_MECH_STARTUP_DELAY_US + + data->built_in_self_test_count * SMI240_BITE_SEQUENCE_DELAY_US + + SMI240_FILTER_FLUSH_DELAY_US); + + return 0; +} + +static int smi240_get_low_pass_filter_freq(struct smi240_data *data, + int chan_type, int *val) +{ + switch (chan_type) { + case IIO_ACCEL: + *val = data->accel_filter_freq; + return 0; + case IIO_ANGL_VEL: + *val = data->anglvel_filter_freq; + return 0; + default: + return -EINVAL; + } +} + +static int smi240_get_data(struct smi240_data *data, int chan_type, int axis, + int *val) +{ + u8 reg; + int ret, sample; + + switch (chan_type) { + case IIO_TEMP: + reg = SMI240_TEMP_CUR_REG; + break; + case IIO_ACCEL: + reg = SMI240_ACCEL_X_CUR_REG + (axis - IIO_MOD_X); + break; + case IIO_ANGL_VEL: + reg = SMI240_GYRO_X_CUR_REG + (axis - IIO_MOD_X); + break; + default: + return -EINVAL; + } + + ret = regmap_read(data->regmap, reg, &sample); + if (ret) + return ret; + + *val = sign_extend32(sample, 15); + + return 0; +} + +static irqreturn_t smi240_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct smi240_data *data = iio_priv(indio_dev); + int base = SMI240_DATA_CAP_FIRST_REG, i = 0; + int ret, chan, sample; + + data->capture = SMI240_CAPTURE_ON; + + iio_for_each_active_channel(indio_dev, chan) { + ret = regmap_read(data->regmap, base + chan, &sample); + data->capture = SMI240_CAPTURE_OFF; + if (ret) + goto out; + data->buf[i++] = sample; + } + + iio_push_to_buffers_with_timestamp(indio_dev, data->buf, pf->timestamp); + +out: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static int smi240_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, const int **vals, + int *type, int *length, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + *vals = smi240_low_pass_freqs; + *length = ARRAY_SIZE(smi240_low_pass_freqs); + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int smi240_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + int ret; + struct smi240_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = smi240_get_data(data, chan->type, chan->channel2, val); + iio_device_release_direct_mode(indio_dev); + if (ret) + return ret; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + ret = smi240_get_low_pass_filter_freq(data, chan->type, val); + if (ret) + return ret; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_TEMP: + *val = SMI240_TEMP_SCALE / GIGA; + *val2 = SMI240_TEMP_SCALE % GIGA; + return IIO_VAL_INT_PLUS_NANO; + case IIO_ACCEL: + *val = 0; + *val2 = SMI240_ACCEL_SCALE; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_ANGL_VEL: + *val = 0; + *val2 = SMI240_GYRO_SCALE; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + + case IIO_CHAN_INFO_OFFSET: + if (chan->type == IIO_TEMP) { + *val = SMI240_TEMP_OFFSET; + return IIO_VAL_INT; + } else { + return -EINVAL; + } + + default: + return -EINVAL; + } +} + +static int smi240_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long mask) +{ + int ret, i; + struct smi240_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + for (i = 0; i < ARRAY_SIZE(smi240_low_pass_freqs); i++) { + if (val == smi240_low_pass_freqs[i]) + break; + } + + if (i == ARRAY_SIZE(smi240_low_pass_freqs)) + return -EINVAL; + + switch (chan->type) { + case IIO_ACCEL: + data->accel_filter_freq = val; + break; + case IIO_ANGL_VEL: + data->anglvel_filter_freq = val; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + /* Write access to soft config is locked until hard/soft reset */ + ret = smi240_soft_reset(data); + if (ret) + return ret; + + return smi240_soft_config(data); +} + +static int smi240_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, long info) +{ + switch (info) { + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_TEMP: + return IIO_VAL_INT_PLUS_NANO; + default: + return IIO_VAL_INT_PLUS_MICRO; + } + default: + return IIO_VAL_INT_PLUS_MICRO; + } +} + +static int smi240_init(struct smi240_data *data) +{ + int ret; + + data->accel_filter_freq = SMI240_HIGH_BANDWIDTH_HZ; + data->anglvel_filter_freq = SMI240_HIGH_BANDWIDTH_HZ; + data->built_in_self_test_count = SMI240_BUILT_IN_SELF_TEST_COUNT; + + ret = smi240_soft_reset(data); + if (ret) + return ret; + + return smi240_soft_config(data); +} + +static const struct iio_info smi240_info = { + .read_avail = smi240_read_avail, + .read_raw = smi240_read_raw, + .write_raw = smi240_write_raw, + .write_raw_get_fmt = smi240_write_raw_get_fmt, +}; + +static int smi240_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct iio_dev *indio_dev; + struct regmap *regmap; + struct smi240_data *data; + int ret, response; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + regmap = devm_regmap_init(dev, &smi240_regmap_bus, dev, + &smi240_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to initialize SPI Regmap\n"); + + data = iio_priv(indio_dev); + dev_set_drvdata(dev, indio_dev); + data->regmap = regmap; + data->capture = SMI240_CAPTURE_OFF; + + ret = regmap_read(data->regmap, SMI240_CHIP_ID_REG, &response); + if (ret) + return dev_err_probe(dev, ret, "Read chip id failed\n"); + + if (response != SMI240_CHIP_ID) + dev_info(dev, "Unknown chip id: 0x%04x\n", response); + + ret = smi240_init(data); + if (ret) + return dev_err_probe(dev, ret, + "Device initialization failed\n"); + + indio_dev->channels = smi240_channels; + indio_dev->num_channels = ARRAY_SIZE(smi240_channels); + indio_dev->name = "smi240"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &smi240_info; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + smi240_trigger_handler, NULL); + if (ret) + return dev_err_probe(dev, ret, + "Setup triggered buffer failed\n"); + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Register IIO device failed\n"); + + return 0; +} + +static const struct spi_device_id smi240_spi_id[] = { + { "smi240" }, + { } +}; +MODULE_DEVICE_TABLE(spi, smi240_spi_id); + +static const struct of_device_id smi240_of_match[] = { + { .compatible = "bosch,smi240" }, + { } +}; +MODULE_DEVICE_TABLE(of, smi240_of_match); + +static struct spi_driver smi240_spi_driver = { + .probe = smi240_probe, + .id_table = smi240_spi_id, + .driver = { + .of_match_table = smi240_of_match, + .name = "smi240", + }, +}; +module_spi_driver(smi240_spi_driver); + +MODULE_AUTHOR("Markus Lochmann "); +MODULE_AUTHOR("Stefan Gutmann "); +MODULE_DESCRIPTION("Bosch SMI240 SPI driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index a3b93566533bc06106be437d416249cb5aa326b2..c225b246c8a552ab4bd4285b3140f06155ba3fb5 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -447,7 +447,7 @@ struct st_lsm6dsx_hw { /* Ensure natural alignment of buffer elements */ struct { __le16 channels[3]; - s64 ts __aligned(8); + aligned_s64 ts; } scan[ST_LSM6DSX_ID_MAX]; }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index ed02679297252ad68e10e11a65d4c7fedbe0d5d6..4fdcc2acc94ed0f594116b9141ce85f7c4449a58 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -1865,7 +1865,7 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, return err; } -static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) +static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, bool state) { const struct st_lsm6dsx_reg *reg; unsigned int data; @@ -1959,7 +1959,7 @@ static int st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); struct st_lsm6dsx_hw *hw = sensor->hw; @@ -2132,14 +2132,11 @@ st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, const struct st_lsm6dsx_reg **drdy_reg) { struct device *dev = hw->dev; + const struct st_sensors_platform_data *pdata = dev_get_platdata(dev); int err = 0, drdy_pin; - if (device_property_read_u32(dev, "st,drdy-int-pin", &drdy_pin) < 0) { - struct st_sensors_platform_data *pdata; - - pdata = (struct st_sensors_platform_data *)dev->platform_data; + if (device_property_read_u32(dev, "st,drdy-int-pin", &drdy_pin) < 0) drdy_pin = pdata ? pdata->drdy_int_pin : 1; - } switch (drdy_pin) { case 1: @@ -2162,14 +2159,13 @@ st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) { const struct st_lsm6dsx_shub_settings *hub_settings; - struct st_sensors_platform_data *pdata; struct device *dev = hw->dev; + const struct st_sensors_platform_data *pdata = dev_get_platdata(dev); unsigned int data; int err = 0; hub_settings = &hw->settings->shub_settings; - pdata = (struct st_sensors_platform_data *)dev->platform_data; if (device_property_read_bool(dev, "st,pullups") || (pdata && pdata->pullups)) { if (hub_settings->pullup_en.sec_page) { @@ -2524,15 +2520,14 @@ static irqreturn_t st_lsm6dsx_sw_trigger_handler_thread(int irq, static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) { - struct st_sensors_platform_data *pdata; const struct st_lsm6dsx_reg *reg; struct device *dev = hw->dev; + const struct st_sensors_platform_data *pdata = dev_get_platdata(dev); unsigned long irq_type; bool irq_active_low; int err; - irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); - + irq_type = irq_get_trigger_type(hw->irq); switch (irq_type) { case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: @@ -2554,7 +2549,6 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) if (err < 0) return err; - pdata = (struct st_sensors_platform_data *)dev->platform_data; if (device_property_read_bool(dev, "drive-open-drain") || (pdata && pdata->open_drain)) { reg = &hw->settings->irq_config.od; @@ -2639,7 +2633,7 @@ static int st_lsm6dsx_init_regulators(struct device *dev) int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, struct regmap *regmap) { - struct st_sensors_platform_data *pdata = dev->platform_data; + const struct st_sensors_platform_data *pdata = dev_get_platdata(dev); const struct st_lsm6dsx_shub_settings *hub_settings; struct st_lsm6dsx_hw *hw; const char *name = NULL; @@ -2730,7 +2724,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, return 0; } -EXPORT_SYMBOL_NS(st_lsm6dsx_probe, IIO_LSM6DSX); +EXPORT_SYMBOL_NS(st_lsm6dsx_probe, "IIO_LSM6DSX"); static int st_lsm6dsx_suspend(struct device *dev) { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index cddf41cc0ca97f59b9891d543b5807a3ab03811a..25e1de89b6e49fe28b337c1d79087c491a25878b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -193,4 +193,4 @@ MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_LSM6DSX); +MODULE_IMPORT_NS("IIO_LSM6DSX"); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i3c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i3c.c index 3b0c8b19c448168385bebeb7508f5f70402782ef..6952d901316fcef4231f88217b0b67b0fc9a4d5d 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i3c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i3c.c @@ -54,4 +54,4 @@ module_i3c_driver(st_lsm6dsx_driver); MODULE_AUTHOR("Vitor Soares "); MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx i3c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_LSM6DSX); +MODULE_IMPORT_NS("IIO_LSM6DSX"); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index c122c8831365a4ffa4544d347946d51ba96ee001..4b4b6d45524fb8779039e123c1f2a5ed1d7cf846 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -181,4 +181,4 @@ MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_LSM6DSX); +MODULE_IMPORT_NS("IIO_LSM6DSX"); diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c index 10c1b2ba7a3d93050b07bd6edd234a80e6e43132..8f4a67edb335b2dc6f764933503a90c9fc928a57 100644 --- a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c @@ -88,9 +88,9 @@ int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap) /* Setup magnetometer device */ return st_lsm9ds0_probe_magn(lsm9ds0, regmap); } -EXPORT_SYMBOL_NS_GPL(st_lsm9ds0_probe, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS_GPL(st_lsm9ds0_probe, "IIO_ST_SENSORS"); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU core driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c index d03cec3b24fed0ab0c132130d37b3d9598e39ebb..0732cfa258c4a79b03fa8368f3acd5b08a788f26 100644 --- a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c @@ -91,4 +91,4 @@ module_i2c_driver(st_lsm9ds0_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU I2C driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c index 69e9135795a3796be8ad30176292740554fc5b63..43ec57c1e604b19919c016bc4bc4d4fd561bfef7 100644 --- a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c +++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c @@ -83,4 +83,4 @@ module_spi_driver(st_lsm9ds0_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("STMicroelectronics LSM9DS0 IMU SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/industrialio-acpi.c b/drivers/iio/industrialio-acpi.c index 981b75d4078020263b10f1993215eff814f4c442..d67a43843799882c3e4c2cd17cb702e433758439 100644 --- a/drivers/iio/industrialio-acpi.c +++ b/drivers/iio/industrialio-acpi.c @@ -2,7 +2,8 @@ /* IIO ACPI helper functions */ #include -#include +#include +#include #include #include @@ -28,17 +29,21 @@ bool iio_read_acpi_mount_matrix(struct device *dev, char *acpi_method) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_device *adev = ACPI_COMPANION(dev); char *str; union acpi_object *obj, *elements; + acpi_handle handle; acpi_status status; int i, j, val[3]; bool ret = false; - if (!adev || !acpi_has_method(adev->handle, acpi_method)) + handle = ACPI_HANDLE(dev); + if (!handle) return false; - status = acpi_evaluate_object(adev->handle, acpi_method, NULL, &buffer); + if (!acpi_has_method(handle, acpi_method)) + return false; + + status = acpi_evaluate_object(handle, acpi_method, NULL, &buffer); if (ACPI_FAILURE(status)) { dev_err(dev, "Failed to get ACPI mount matrix: %d\n", status); return false; @@ -83,3 +88,38 @@ out_free_buffer: return ret; } EXPORT_SYMBOL_GPL(iio_read_acpi_mount_matrix); + +/** + * iio_get_acpi_device_name_and_data() - Return ACPI device instance name and driver data + * @dev: Device structure + * @data: Optional pointer to return driver data + * + * When device was enumerated by ACPI ID matching, the user might + * want to set description for the physical chip. In such cases + * the ACPI device instance name might be used. This call may be + * performed to retrieve this information. + * + * NOTE: This helper function exists only for backward compatibility, + * do not use in a new code! + * + * Returns: ACPI device instance name or %NULL. + */ +const char *iio_get_acpi_device_name_and_data(struct device *dev, const void **data) +{ + const struct acpi_device_id *id; + acpi_handle handle; + + handle = ACPI_HANDLE(dev); + if (!handle) + return NULL; + + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) + return NULL; + + if (data) + *data = (const void *)id->driver_data; + + return dev_name(dev); +} +EXPORT_SYMBOL_GPL(iio_get_acpi_device_name_and_data); diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c index 20b3b5212da76a311552c9cdbaa6daca7a98b4cd..363281272035209f7cf462bbfc3b406449321490 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -230,7 +230,7 @@ void iio_backend_debugfs_add(struct iio_backend *back, debugfs_create_file("name", 0400, back_d, back, &iio_backend_debugfs_name_fops); } -EXPORT_SYMBOL_NS_GPL(iio_backend_debugfs_add, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_debugfs_add, "IIO_BACKEND"); /** * iio_backend_debugfs_print_chan_status - Print channel status @@ -256,7 +256,7 @@ ssize_t iio_backend_debugfs_print_chan_status(struct iio_backend *back, return iio_backend_op_call(back, debugfs_print_chan_status, chan, buf, len); } -EXPORT_SYMBOL_NS_GPL(iio_backend_debugfs_print_chan_status, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_debugfs_print_chan_status, "IIO_BACKEND"); /** * iio_backend_chan_enable - Enable a backend channel @@ -270,7 +270,7 @@ int iio_backend_chan_enable(struct iio_backend *back, unsigned int chan) { return iio_backend_op_call(back, chan_enable, chan); } -EXPORT_SYMBOL_NS_GPL(iio_backend_chan_enable, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_chan_enable, "IIO_BACKEND"); /** * iio_backend_chan_disable - Disable a backend channel @@ -284,7 +284,7 @@ int iio_backend_chan_disable(struct iio_backend *back, unsigned int chan) { return iio_backend_op_call(back, chan_disable, chan); } -EXPORT_SYMBOL_NS_GPL(iio_backend_chan_disable, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_chan_disable, "IIO_BACKEND"); static void __iio_backend_disable(void *back) { @@ -299,7 +299,7 @@ void iio_backend_disable(struct iio_backend *back) { __iio_backend_disable(back); } -EXPORT_SYMBOL_NS_GPL(iio_backend_disable, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_disable, "IIO_BACKEND"); /** * iio_backend_enable - Backend enable @@ -312,7 +312,7 @@ int iio_backend_enable(struct iio_backend *back) { return iio_backend_op_call(back, enable); } -EXPORT_SYMBOL_NS_GPL(iio_backend_enable, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_enable, "IIO_BACKEND"); /** * devm_iio_backend_enable - Device managed backend enable @@ -332,7 +332,7 @@ int devm_iio_backend_enable(struct device *dev, struct iio_backend *back) return devm_add_action_or_reset(dev, __iio_backend_disable, back); } -EXPORT_SYMBOL_NS_GPL(devm_iio_backend_enable, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(devm_iio_backend_enable, "IIO_BACKEND"); /** * iio_backend_data_format_set - Configure the channel data format @@ -354,7 +354,7 @@ int iio_backend_data_format_set(struct iio_backend *back, unsigned int chan, return iio_backend_op_call(back, data_format_set, chan, data); } -EXPORT_SYMBOL_NS_GPL(iio_backend_data_format_set, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_data_format_set, "IIO_BACKEND"); /** * iio_backend_data_source_set - Select data source @@ -376,7 +376,7 @@ int iio_backend_data_source_set(struct iio_backend *back, unsigned int chan, return iio_backend_op_call(back, data_source_set, chan, data); } -EXPORT_SYMBOL_NS_GPL(iio_backend_data_source_set, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_data_source_set, "IIO_BACKEND"); /** * iio_backend_set_sampling_freq - Set channel sampling rate @@ -392,7 +392,7 @@ int iio_backend_set_sampling_freq(struct iio_backend *back, unsigned int chan, { return iio_backend_op_call(back, set_sample_rate, chan, sample_rate_hz); } -EXPORT_SYMBOL_NS_GPL(iio_backend_set_sampling_freq, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_set_sampling_freq, "IIO_BACKEND"); /** * iio_backend_test_pattern_set - Configure a test pattern @@ -415,7 +415,7 @@ int iio_backend_test_pattern_set(struct iio_backend *back, return iio_backend_op_call(back, test_pattern_set, chan, pattern); } -EXPORT_SYMBOL_NS_GPL(iio_backend_test_pattern_set, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_test_pattern_set, "IIO_BACKEND"); /** * iio_backend_chan_status - Get the channel status @@ -434,7 +434,7 @@ int iio_backend_chan_status(struct iio_backend *back, unsigned int chan, { return iio_backend_op_call(back, chan_status, chan, error); } -EXPORT_SYMBOL_NS_GPL(iio_backend_chan_status, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_chan_status, "IIO_BACKEND"); /** * iio_backend_iodelay_set - Set digital I/O delay @@ -457,7 +457,7 @@ int iio_backend_iodelay_set(struct iio_backend *back, unsigned int lane, { return iio_backend_op_call(back, iodelay_set, lane, taps); } -EXPORT_SYMBOL_NS_GPL(iio_backend_iodelay_set, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_iodelay_set, "IIO_BACKEND"); /** * iio_backend_data_sample_trigger - Control when to sample data @@ -478,7 +478,7 @@ int iio_backend_data_sample_trigger(struct iio_backend *back, return iio_backend_op_call(back, data_sample_trigger, trigger); } -EXPORT_SYMBOL_NS_GPL(iio_backend_data_sample_trigger, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_data_sample_trigger, "IIO_BACKEND"); static void iio_backend_free_buffer(void *arg) { @@ -523,7 +523,7 @@ int devm_iio_backend_request_buffer(struct device *dev, return devm_add_action_or_reset(dev, iio_backend_free_buffer, pair); } -EXPORT_SYMBOL_NS_GPL(devm_iio_backend_request_buffer, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(devm_iio_backend_request_buffer, "IIO_BACKEND"); /** * iio_backend_read_raw - Read a channel attribute from a backend device. @@ -542,7 +542,7 @@ int iio_backend_read_raw(struct iio_backend *back, { return iio_backend_op_call(back, read_raw, chan, val, val2, mask); } -EXPORT_SYMBOL_NS_GPL(iio_backend_read_raw, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_read_raw, "IIO_BACKEND"); static struct iio_backend *iio_backend_from_indio_dev_parent(const struct device *dev) { @@ -604,7 +604,7 @@ ssize_t iio_backend_ext_info_get(struct iio_dev *indio_dev, uintptr_t private, return iio_backend_op_call(back, ext_info_get, private, chan, buf); } -EXPORT_SYMBOL_NS_GPL(iio_backend_ext_info_get, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_ext_info_get, "IIO_BACKEND"); /** * iio_backend_ext_info_set - IIO ext_info write callback @@ -634,7 +634,7 @@ ssize_t iio_backend_ext_info_set(struct iio_dev *indio_dev, uintptr_t private, return iio_backend_op_call(back, ext_info_set, private, chan, buf, len); } -EXPORT_SYMBOL_NS_GPL(iio_backend_ext_info_set, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_ext_info_set, "IIO_BACKEND"); /** * iio_backend_extend_chan_spec - Extend an IIO channel @@ -677,7 +677,7 @@ int iio_backend_extend_chan_spec(struct iio_backend *back, return 0; } -EXPORT_SYMBOL_NS_GPL(iio_backend_extend_chan_spec, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_extend_chan_spec, "IIO_BACKEND"); static void iio_backend_release(void *arg) { @@ -718,6 +718,84 @@ static int __devm_iio_backend_get(struct device *dev, struct iio_backend *back) return 0; } +/** + * iio_backend_ddr_enable - Enable interface DDR (Double Data Rate) mode + * @back: Backend device + * + * Enable DDR, data is generated by the IP at each front (raising and falling) + * of the bus clock signal. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_ddr_enable(struct iio_backend *back) +{ + return iio_backend_op_call(back, ddr_enable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_ddr_enable, "IIO_BACKEND"); + +/** + * iio_backend_ddr_disable - Disable interface DDR (Double Data Rate) mode + * @back: Backend device + * + * Disable DDR, setting into SDR mode (Single Data Rate). + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_ddr_disable(struct iio_backend *back) +{ + return iio_backend_op_call(back, ddr_disable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_ddr_disable, "IIO_BACKEND"); + +/** + * iio_backend_data_stream_enable - Enable data stream + * @back: Backend device + * + * Enable data stream over the bus interface. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_data_stream_enable(struct iio_backend *back) +{ + return iio_backend_op_call(back, data_stream_enable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_data_stream_enable, "IIO_BACKEND"); + +/** + * iio_backend_data_stream_disable - Disable data stream + * @back: Backend device + * + * Disable data stream over the bus interface. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_data_stream_disable(struct iio_backend *back) +{ + return iio_backend_op_call(back, data_stream_disable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_data_stream_disable, "IIO_BACKEND"); + +/** + * iio_backend_data_transfer_addr - Set data address. + * @back: Backend device + * @address: Data register address + * + * Some devices may need to inform the backend about an address + * where to read or write the data. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_data_transfer_addr(struct iio_backend *back, u32 address) +{ + return iio_backend_op_call(back, data_transfer_addr, address); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_data_transfer_addr, "IIO_BACKEND"); + static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, const char *name, struct fwnode_handle *fwnode) { @@ -737,8 +815,8 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con } fwnode_back = fwnode_find_reference(fwnode, "io-backends", index); - if (IS_ERR(fwnode)) - return dev_err_cast_probe(dev, fwnode, + if (IS_ERR(fwnode_back)) + return dev_err_cast_probe(dev, fwnode_back, "Cannot get Firmware reference\n"); guard(mutex)(&iio_back_lock); @@ -775,7 +853,7 @@ struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name) { return __devm_iio_backend_fwnode_get(dev, name, dev_fwnode(dev)); } -EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, "IIO_BACKEND"); /** * devm_iio_backend_fwnode_get - Device managed backend firmware node get @@ -794,7 +872,7 @@ struct iio_backend *devm_iio_backend_fwnode_get(struct device *dev, { return __devm_iio_backend_fwnode_get(dev, name, fwnode); } -EXPORT_SYMBOL_NS_GPL(devm_iio_backend_fwnode_get, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(devm_iio_backend_fwnode_get, "IIO_BACKEND"); /** * __devm_iio_backend_get_from_fwnode_lookup - Device managed fwnode backend device get @@ -829,7 +907,7 @@ __devm_iio_backend_get_from_fwnode_lookup(struct device *dev, return ERR_PTR(-EPROBE_DEFER); } -EXPORT_SYMBOL_NS_GPL(__devm_iio_backend_get_from_fwnode_lookup, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(__devm_iio_backend_get_from_fwnode_lookup, "IIO_BACKEND"); /** * iio_backend_get_priv - Get driver private data @@ -839,7 +917,7 @@ void *iio_backend_get_priv(const struct iio_backend *back) { return back->priv; } -EXPORT_SYMBOL_NS_GPL(iio_backend_get_priv, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(iio_backend_get_priv, "IIO_BACKEND"); static void iio_backend_unregister(void *arg) { @@ -888,7 +966,7 @@ int devm_iio_backend_register(struct device *dev, return devm_add_action_or_reset(dev, iio_backend_unregister, back); } -EXPORT_SYMBOL_NS_GPL(devm_iio_backend_register, IIO_BACKEND); +EXPORT_SYMBOL_NS_GPL(devm_iio_backend_register, "IIO_BACKEND"); MODULE_AUTHOR("Nuno Sa "); MODULE_DESCRIPTION("Framework to handle complex IIO aggregate devices"); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 8104696cd47509682123fddad5e7a616cdb7dbfc..2708f87df7198f7ac79dd533f7502db44535638a 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -36,7 +36,7 @@ #define DMABUF_ENQUEUE_TIMEOUT_MS 5000 -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); struct iio_dmabuf_priv { struct list_head entry; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 6a6568d4a2cb3a3f63381d5a6f25a2881b3ba2ed..a2117ad1337d55468c0f21c274fcbedd352c97ff 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -95,6 +95,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_DELTA_VELOCITY] = "deltavelocity", [IIO_COLORTEMP] = "colortemp", [IIO_CHROMATICITY] = "chromaticity", + [IIO_ATTENTION] = "attention", }; static const char * const iio_modifier_names[] = { @@ -1665,7 +1666,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) indio_dev = &iio_dev_opaque->indio_dev; if (sizeof_priv) - indio_dev->priv = (char *)iio_dev_opaque + + ACCESS_PRIVATE(indio_dev, priv) = (char *)iio_dev_opaque + ALIGN(sizeof(*iio_dev_opaque), IIO_DMA_MINALIGN); indio_dev->dev.parent = parent; diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c index 5f131bc1a01e97100fa58174c379bb921753918a..3b5a998150623ba43c2f015c2c5d8a757743b893 100644 --- a/drivers/iio/industrialio-gts-helper.c +++ b/drivers/iio/industrialio-gts-helper.c @@ -134,7 +134,7 @@ int iio_gts_total_gain_to_scale(struct iio_gts *gts, int total_gain, return iio_gts_delinearize(tmp, NANO, scale_int, scale_nano); } -EXPORT_SYMBOL_NS_GPL(iio_gts_total_gain_to_scale, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_total_gain_to_scale, "IIO_GTS_HELPER"); /** * iio_gts_purge_avail_scale_table - free-up the available scale tables @@ -167,7 +167,7 @@ static int iio_gts_gain_cmp(const void *a, const void *b) static int gain_to_scaletables(struct iio_gts *gts, int **gains, int **scales) { - int ret, i, j, new_idx, time_idx; + int i, j, new_idx, time_idx, ret = 0; int *all_gains; size_t gain_bytes; @@ -205,7 +205,7 @@ static int gain_to_scaletables(struct iio_gts *gts, int **gains, int **scales) memcpy(all_gains, gains[time_idx], gain_bytes); new_idx = gts->num_hwgain; - while (time_idx--) { + while (time_idx-- > 0) { for (j = 0; j < gts->num_hwgain; j++) { int candidate = gains[time_idx][j]; int chk; @@ -622,7 +622,7 @@ int devm_iio_init_iio_gts(struct device *dev, int max_scale_int, int max_scale_n return devm_iio_gts_build_avail_tables(dev, gts); } -EXPORT_SYMBOL_NS_GPL(devm_iio_init_iio_gts, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(devm_iio_init_iio_gts, "IIO_GTS_HELPER"); /** * iio_gts_all_avail_scales - helper for listing all available scales @@ -645,7 +645,7 @@ int iio_gts_all_avail_scales(struct iio_gts *gts, const int **vals, int *type, return IIO_AVAIL_LIST; } -EXPORT_SYMBOL_NS_GPL(iio_gts_all_avail_scales, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_all_avail_scales, "IIO_GTS_HELPER"); /** * iio_gts_avail_scales_for_time - list scales for integration time @@ -679,7 +679,7 @@ int iio_gts_avail_scales_for_time(struct iio_gts *gts, int time, return IIO_AVAIL_LIST; } -EXPORT_SYMBOL_NS_GPL(iio_gts_avail_scales_for_time, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_avail_scales_for_time, "IIO_GTS_HELPER"); /** * iio_gts_avail_times - helper for listing available integration times @@ -702,7 +702,7 @@ int iio_gts_avail_times(struct iio_gts *gts, const int **vals, int *type, return IIO_AVAIL_LIST; } -EXPORT_SYMBOL_NS_GPL(iio_gts_avail_times, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_avail_times, "IIO_GTS_HELPER"); /** * iio_gts_find_sel_by_gain - find selector corresponding to a HW-gain @@ -722,7 +722,7 @@ int iio_gts_find_sel_by_gain(struct iio_gts *gts, int gain) return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(iio_gts_find_sel_by_gain, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_find_sel_by_gain, "IIO_GTS_HELPER"); /** * iio_gts_find_gain_by_sel - find HW-gain corresponding to a selector @@ -742,7 +742,7 @@ int iio_gts_find_gain_by_sel(struct iio_gts *gts, int sel) return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(iio_gts_find_gain_by_sel, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_find_gain_by_sel, "IIO_GTS_HELPER"); /** * iio_gts_get_min_gain - find smallest valid HW-gain @@ -765,7 +765,7 @@ int iio_gts_get_min_gain(struct iio_gts *gts) return min; } -EXPORT_SYMBOL_NS_GPL(iio_gts_get_min_gain, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_get_min_gain, "IIO_GTS_HELPER"); /** * iio_find_closest_gain_low - Find the closest lower matching gain @@ -826,7 +826,7 @@ int iio_find_closest_gain_low(struct iio_gts *gts, int gain, bool *in_range) return gts->hwgain_table[best].gain; } -EXPORT_SYMBOL_NS_GPL(iio_find_closest_gain_low, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_find_closest_gain_low, "IIO_GTS_HELPER"); static int iio_gts_get_int_time_gain_multiplier_by_sel(struct iio_gts *gts, int sel) @@ -913,7 +913,7 @@ int iio_gts_find_gain_sel_for_scale_using_time(struct iio_gts *gts, int time_sel return 0; } -EXPORT_SYMBOL_NS_GPL(iio_gts_find_gain_sel_for_scale_using_time, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_find_gain_sel_for_scale_using_time, "IIO_GTS_HELPER"); static int iio_gts_get_total_gain(struct iio_gts *gts, int gain, int time) { @@ -975,7 +975,7 @@ int iio_gts_get_scale(struct iio_gts *gts, int gain, int time, int *scale_int, return iio_gts_delinearize(lin_scale, NANO, scale_int, scale_nano); } -EXPORT_SYMBOL_NS_GPL(iio_gts_get_scale, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_get_scale, "IIO_GTS_HELPER"); /** * iio_gts_find_new_gain_sel_by_old_gain_time - compensate for time change @@ -1032,7 +1032,7 @@ int iio_gts_find_new_gain_sel_by_old_gain_time(struct iio_gts *gts, return 0; } -EXPORT_SYMBOL_NS_GPL(iio_gts_find_new_gain_sel_by_old_gain_time, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_find_new_gain_sel_by_old_gain_time, "IIO_GTS_HELPER"); /** * iio_gts_find_new_gain_by_old_gain_time - compensate for time change @@ -1084,7 +1084,7 @@ int iio_gts_find_new_gain_by_old_gain_time(struct iio_gts *gts, int old_gain, return 0; } -EXPORT_SYMBOL_NS_GPL(iio_gts_find_new_gain_by_old_gain_time, IIO_GTS_HELPER); +EXPORT_SYMBOL_NS_GPL(iio_gts_find_new_gain_by_old_gain_time, "IIO_GTS_HELPER"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Matti Vaittinen "); diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 151099be2863c63003f4d894d4d1a2556fe38c8f..136b225b6bc8a128c5406b9e982f3668beafe142 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -20,7 +20,7 @@ struct iio_map_internal { struct iio_dev *indio_dev; - struct iio_map *map; + const struct iio_map *map; struct list_head l; }; @@ -42,7 +42,7 @@ static int iio_map_array_unregister_locked(struct iio_dev *indio_dev) return ret; } -int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps) +int iio_map_array_register(struct iio_dev *indio_dev, const struct iio_map *maps) { struct iio_map_internal *mapi; int i = 0; @@ -86,7 +86,8 @@ static void iio_map_array_unregister_cb(void *indio_dev) iio_map_array_unregister(indio_dev); } -int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev, struct iio_map *maps) +int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev, + const struct iio_map *maps) { int ret; @@ -269,7 +270,7 @@ struct iio_channel *fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode, return ERR_PTR(-ENODEV); } - chan = __fwnode_iio_channel_get_by_name(fwnode, name); + chan = __fwnode_iio_channel_get_by_name(parent, name); if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV) { fwnode_handle_put(parent); return chan; diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index f2f3e414849ab12a7c0ea2b08e9a3310eb18ebb7..29ffa84919273d64b8464ab8bbf59661b0102f97 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -248,7 +248,6 @@ config SENSORS_ISL29018 tristate "Intersil 29018 light and proximity sensor" depends on I2C select REGMAP_I2C - default n help If you say yes here you get support for ambient light sensing and proximity infrared sensing from Intersil ISL29018. @@ -476,7 +475,7 @@ config OPT3001 depends on I2C help If you say Y or M here, you get support for Texas Instruments - OPT3001 Ambient Light Sensor. + OPT3001 Ambient Light Sensor, OPT3002 Light-to-Digital Sensor. If built as a dynamically linked module, it will be called opt3001. @@ -670,13 +669,24 @@ config VCNL4035 To compile this driver as a module, choose M here: the module will be called vcnl4035. +config VEML3235 + tristate "VEML3235 ambient light sensor" + select REGMAP_I2C + depends on I2C + help + Say Y here if you want to build a driver for the Vishay VEML3235 + ambient light sensor. + + To compile this driver as a module, choose M here: the + module will be called veml3235. + config VEML6030 - tristate "VEML6030 ambient light sensor" + tristate "VEML6030 and VEML6035 ambient light sensors" select REGMAP_I2C depends on I2C help Say Y here if you want to build a driver for the Vishay VEML6030 - ambient light sensor (ALS). + and VEML6035 ambient light sensors (ALS). To compile this driver as a module, choose M here: the module will be called veml6030. diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 321010fc0b938a9a7fed6d7ec41c718f56fc83a6..f14a3744271242f04fe7849b47308397ac2c9939 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_TSL4531) += tsl4531.o obj-$(CONFIG_US5182D) += us5182d.o obj-$(CONFIG_VCNL4000) += vcnl4000.o obj-$(CONFIG_VCNL4035) += vcnl4035.o +obj-$(CONFIG_VEML3235) += veml3235.o obj-$(CONFIG_VEML6030) += veml6030.o obj-$(CONFIG_VEML6040) += veml6040.o obj-$(CONFIG_VEML6070) += veml6070.o diff --git a/drivers/iio/light/adux1020.c b/drivers/iio/light/adux1020.c index 2e0170be077aef9aa194fab51afbb33aec02e513..593d614b1689b2504c2c1e539a27cb39ce8812af 100644 --- a/drivers/iio/light/adux1020.c +++ b/drivers/iio/light/adux1020.c @@ -502,7 +502,8 @@ fail: static int adux1020_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, + bool state) { struct adux1020_data *data = iio_priv(indio_dev); int ret, mask; @@ -526,12 +527,11 @@ static int adux1020_write_event_config(struct iio_dev *indio_dev, mask = ADUX1020_PROX_OFF1_INT; if (state) - state = 0; + ret = regmap_clear_bits(data->regmap, + ADUX1020_REG_INT_MASK, mask); else - state = mask; - - ret = regmap_update_bits(data->regmap, ADUX1020_REG_INT_MASK, - mask, state); + ret = regmap_set_bits(data->regmap, + ADUX1020_REG_INT_MASK, mask); if (ret < 0) goto fail; diff --git a/drivers/iio/light/al3010.c b/drivers/iio/light/al3010.c index 53569587ccb7ba4a6bf0806d21b0fdeb43421d16..7cbb8b203300907a88f4a0ab87da89cabdd087f3 100644 --- a/drivers/iio/light/al3010.c +++ b/drivers/iio/light/al3010.c @@ -87,7 +87,12 @@ static int al3010_init(struct al3010_data *data) int ret; ret = al3010_set_pwr(data->client, true); + if (ret < 0) + return ret; + ret = devm_add_action_or_reset(&data->client->dev, + al3010_set_pwr_off, + data); if (ret < 0) return ret; @@ -190,12 +195,6 @@ static int al3010_probe(struct i2c_client *client) return ret; } - ret = devm_add_action_or_reset(&client->dev, - al3010_set_pwr_off, - data); - if (ret < 0) - return ret; - return devm_iio_device_register(&client->dev, indio_dev); } diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c index 11f2ab4ca261813aff04b8c25d4595a531fb43cb..938d76f7e3129cedf2f9b8a9d25cc2eebfb4a020 100644 --- a/drivers/iio/light/apds9300.c +++ b/drivers/iio/light/apds9300.c @@ -46,10 +46,10 @@ struct apds9300_data { struct i2c_client *client; struct mutex mutex; - int power_state; + bool power_state; int thresh_low; int thresh_hi; - int intr_en; + bool intr_en; }; /* Lux calculation */ @@ -148,7 +148,7 @@ static int apds9300_set_thresh_hi(struct apds9300_data *data, int value) return 0; } -static int apds9300_set_intr_state(struct apds9300_data *data, int state) +static int apds9300_set_intr_state(struct apds9300_data *data, bool state) { int ret; u8 cmd; @@ -169,7 +169,7 @@ static int apds9300_set_intr_state(struct apds9300_data *data, int state) return 0; } -static int apds9300_set_power_state(struct apds9300_data *data, int state) +static int apds9300_set_power_state(struct apds9300_data *data, bool state) { int ret; u8 cmd; @@ -221,7 +221,7 @@ static int apds9300_chip_init(struct apds9300_data *data) * Disable interrupt to ensure thai it is doesn't enable * i.e. after device soft reset */ - ret = apds9300_set_intr_state(data, 0); + ret = apds9300_set_intr_state(data, false); if (ret < 0) goto err; @@ -321,7 +321,7 @@ static int apds9300_read_interrupt_config(struct iio_dev *indio_dev, static int apds9300_write_interrupt_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct apds9300_data *data = iio_priv(indio_dev); int ret; @@ -459,8 +459,8 @@ static void apds9300_remove(struct i2c_client *client) iio_device_unregister(indio_dev); /* Ensure that power off and interrupts are disabled */ - apds9300_set_intr_state(data, 0); - apds9300_set_power_state(data, 0); + apds9300_set_intr_state(data, false); + apds9300_set_power_state(data, false); } static int apds9300_suspend(struct device *dev) @@ -470,7 +470,7 @@ static int apds9300_suspend(struct device *dev) int ret; mutex_lock(&data->mutex); - ret = apds9300_set_power_state(data, 0); + ret = apds9300_set_power_state(data, false); mutex_unlock(&data->mutex); return ret; @@ -483,7 +483,7 @@ static int apds9300_resume(struct device *dev) int ret; mutex_lock(&data->mutex); - ret = apds9300_set_power_state(data, 1); + ret = apds9300_set_power_state(data, true); mutex_unlock(&data->mutex); return ret; diff --git a/drivers/iio/light/apds9306.c b/drivers/iio/light/apds9306.c index 079e02be1005210ddd30b384ffa1ff7feeb098d7..69a0d609cffc91cc3daba160f309f511270be385 100644 --- a/drivers/iio/light/apds9306.c +++ b/drivers/iio/light/apds9306.c @@ -1071,7 +1071,7 @@ static int apds9306_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct apds9306_data *data = iio_priv(indio_dev); struct apds9306_regfields *rf = &data->rf; @@ -1125,10 +1125,7 @@ static int apds9306_write_event_config(struct iio_dev *indio_dev, } } case IIO_EV_TYPE_THRESH_ADAPTIVE: - if (state) - return regmap_field_write(rf->int_thresh_var_en, 1); - else - return regmap_field_write(rf->int_thresh_var_en, 0); + return regmap_field_write(rf->int_thresh_var_en, state); default: return -EINVAL; } @@ -1358,4 +1355,4 @@ module_i2c_driver(apds9306_driver); MODULE_AUTHOR("Subhajit Ghosh "); MODULE_DESCRIPTION("APDS9306 Ambient Light Sensor driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_GTS_HELPER); +MODULE_IMPORT_NS("IIO_GTS_HELPER"); diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index 3c14e4c30805e1b596ef2380f94e6aa3e92082b1..d30441d3370309fce9d6c717d42b829ff1db3174 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -133,8 +133,8 @@ struct apds9960_data { struct regmap_field *reg_enable_pxs; /* state */ - int als_int; - int pxs_int; + bool als_int; + bool pxs_int; int gesture_mode_running; /* gain values */ @@ -749,21 +749,17 @@ static int apds9960_read_event_config(struct iio_dev *indio_dev, default: return -EINVAL; } - - return 0; } static int apds9960_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct apds9960_data *data = iio_priv(indio_dev); int ret; - state = !!state; - switch (chan->type) { case IIO_PROXIMITY: if (data->pxs_int == state) diff --git a/drivers/iio/light/bh1745.c b/drivers/iio/light/bh1745.c index 2e458e9d5d85308fb6a13d9dbd845fa03b56a40e..56e32689bb97a8b450dd492e5836f58db409b2a5 100644 --- a/drivers/iio/light/bh1745.c +++ b/drivers/iio/light/bh1745.c @@ -638,46 +638,42 @@ static int bh1745_read_event_config(struct iio_dev *indio_dev, static int bh1745_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct bh1745_data *data = iio_priv(indio_dev); int value; - if (state == 0) + if (!state) return regmap_clear_bits(data->regmap, BH1745_INTR, BH1745_INTR_ENABLE); - if (state == 1) { - /* Latch is always enabled when enabling interrupt */ - value = BH1745_INTR_ENABLE; + /* Latch is always enabled when enabling interrupt */ + value = BH1745_INTR_ENABLE; - switch (chan->channel2) { - case IIO_MOD_LIGHT_RED: - return regmap_write(data->regmap, BH1745_INTR, - value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, - BH1745_INTR_SOURCE_RED)); + switch (chan->channel2) { + case IIO_MOD_LIGHT_RED: + return regmap_write(data->regmap, BH1745_INTR, + value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, + BH1745_INTR_SOURCE_RED)); - case IIO_MOD_LIGHT_GREEN: - return regmap_write(data->regmap, BH1745_INTR, - value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, - BH1745_INTR_SOURCE_GREEN)); + case IIO_MOD_LIGHT_GREEN: + return regmap_write(data->regmap, BH1745_INTR, + value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, + BH1745_INTR_SOURCE_GREEN)); - case IIO_MOD_LIGHT_BLUE: - return regmap_write(data->regmap, BH1745_INTR, - value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, - BH1745_INTR_SOURCE_BLUE)); + case IIO_MOD_LIGHT_BLUE: + return regmap_write(data->regmap, BH1745_INTR, + value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, + BH1745_INTR_SOURCE_BLUE)); - case IIO_MOD_LIGHT_CLEAR: - return regmap_write(data->regmap, BH1745_INTR, - value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, - BH1745_INTR_SOURCE_CLEAR)); + case IIO_MOD_LIGHT_CLEAR: + return regmap_write(data->regmap, BH1745_INTR, + value | FIELD_PREP(BH1745_INTR_SOURCE_MASK, + BH1745_INTR_SOURCE_CLEAR)); - default: - return -EINVAL; - } + default: + return -EINVAL; } - - return -EINVAL; } static int bh1745_read_avail(struct iio_dev *indio_dev, @@ -903,4 +899,4 @@ module_i2c_driver(bh1745_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mudit Sharma "); MODULE_DESCRIPTION("BH1745 colour sensor driver"); -MODULE_IMPORT_NS(IIO_GTS_HELPER); +MODULE_IMPORT_NS("IIO_GTS_HELPER"); diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index 9df85b3999fa88e4e7e0a6c2692de1ea748bb82b..aeae0566ec12a582dcce6f75401cd57195717f6c 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -217,8 +217,7 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181) cm32181->lux_per_bit = CM32181_LUX_PER_BIT; cm32181->lux_per_bit_base_it = CM32181_LUX_PER_BIT_BASE_IT; - if (ACPI_HANDLE(cm32181->dev)) - cm32181_acpi_parse_cpm_tables(cm32181); + cm32181_acpi_parse_cpm_tables(cm32181); /* Initialize registers*/ for_each_set_bit(i, &cm32181->init_regs_bitmap, CM32181_CONF_REG_NUM) { diff --git a/drivers/iio/light/cm3605.c b/drivers/iio/light/cm3605.c index 22a63a89f289a28fccd310547031542bdd2c9bc2..675c0fd44db45a7c32b98c21be61e1d5d4a0e081 100644 --- a/drivers/iio/light/cm3605.c +++ b/drivers/iio/light/cm3605.c @@ -318,7 +318,7 @@ static struct platform_driver cm3605_driver = { .pm = pm_sleep_ptr(&cm3605_dev_pm_ops), }, .probe = cm3605_probe, - .remove_new = cm3605_remove, + .remove = cm3605_remove, }; module_platform_driver(cm3605_driver); diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index a4a1505534c015e3146c00de3e38966ffd712a5b..ae3fc3299eec6c30149bbfcb638d5c0001c30ed9 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -529,7 +529,7 @@ static int cm36651_write_prox_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct cm36651_data *cm36651 = iio_priv(indio_dev); int cmd, ret; diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index f8b1d7dd6f5fc69da12cf37ad286112555e4919f..d56ee217fe538c8babb5df510932bd6e67c59ea6 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -340,7 +340,7 @@ static int gp2ap002_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct gp2ap002 *gp2ap002 = iio_priv(indio_dev); diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index 81e718cdeae32d60581cb490148f4f1c0bd695c7..1a352c88598e5d701256aa8659a7f9683bce56f9 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -1159,7 +1159,7 @@ static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct gp2ap020a00f_data *data = iio_priv(indio_dev); enum gp2ap020a00f_cmd cmd; diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 260281194f61324e6fa20a6cb96851db68de115a..aa4c72d4849e1339416688b9d167382b15e08210 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -31,7 +31,7 @@ struct als_state { struct iio_chan_spec channels[CHANNEL_SCAN_INDEX_MAX + 1]; struct { u32 illum[CHANNEL_SCAN_INDEX_MAX]; - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -356,11 +356,11 @@ static int als_parse_report(struct platform_device *pdev, /* Function to initialize the processing for usage id */ static int hid_als_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret = 0; static const char *name = "als"; struct iio_dev *indio_dev; struct als_state *als_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state)); if (!indio_dev) @@ -438,7 +438,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_als_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct als_state *als_state = iio_priv(indio_dev); @@ -467,11 +467,11 @@ static struct platform_driver hid_als_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_als_probe, - .remove_new = hid_als_remove, + .remove = hid_als_remove, }; module_platform_driver(hid_als_platform_driver); MODULE_DESCRIPTION("HID Sensor ALS"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index 26c481d2998c1f56ab02967c622b9a1ef050751c..c83acbd7827592717a735a6e3de906e45b1c41c4 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c @@ -13,16 +13,32 @@ #include #include "../common/hid-sensors/hid-sensor-trigger.h" -#define CHANNEL_SCAN_INDEX_PRESENCE 0 +static const u32 prox_usage_ids[] = { + HID_USAGE_SENSOR_HUMAN_PRESENCE, + HID_USAGE_SENSOR_HUMAN_PROXIMITY, + HID_USAGE_SENSOR_HUMAN_ATTENTION, +}; + +#define MAX_CHANNELS ARRAY_SIZE(prox_usage_ids) + +enum { + HID_HUMAN_PRESENCE, + HID_HUMAN_PROXIMITY, + HID_HUMAN_ATTENTION, +}; struct prox_state { struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; - struct hid_sensor_hub_attribute_info prox_attr; - u32 human_presence; + struct hid_sensor_hub_attribute_info prox_attr[MAX_CHANNELS]; + struct iio_chan_spec channels[MAX_CHANNELS]; + u32 channel2usage[MAX_CHANNELS]; + u32 human_presence[MAX_CHANNELS]; int scale_pre_decml; int scale_post_decml; int scale_precision; + unsigned long scan_mask[2]; /* One entry plus one terminator. */ + int num_channels; }; static const u32 prox_sensitivity_addresses[] = { @@ -30,17 +46,24 @@ static const u32 prox_sensitivity_addresses[] = { HID_USAGE_SENSOR_DATA_PRESENCE, }; -/* Channel definitions */ -static const struct iio_chan_spec prox_channels[] = { - { - .type = IIO_PROXIMITY, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | - BIT(IIO_CHAN_INFO_SCALE) | - BIT(IIO_CHAN_INFO_SAMP_FREQ) | - BIT(IIO_CHAN_INFO_HYSTERESIS), - .scan_index = CHANNEL_SCAN_INDEX_PRESENCE, +#define PROX_CHANNEL(_is_proximity, _channel) \ + {\ + .type = _is_proximity ? IIO_PROXIMITY : IIO_ATTENTION,\ + .info_mask_separate = _is_proximity ? BIT(IIO_CHAN_INFO_RAW) :\ + BIT(IIO_CHAN_INFO_PROCESSED),\ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |\ + BIT(IIO_CHAN_INFO_SCALE) |\ + BIT(IIO_CHAN_INFO_SAMP_FREQ) |\ + BIT(IIO_CHAN_INFO_HYSTERESIS),\ + .indexed = _is_proximity,\ + .channel = _channel,\ } + +/* Channel definitions (same order as prox_usage_ids) */ +static const struct iio_chan_spec prox_channels[] = { + PROX_CHANNEL(true, HID_HUMAN_PRESENCE), + PROX_CHANNEL(true, HID_HUMAN_PROXIMITY), + PROX_CHANNEL(false, 0), }; /* Adjust channel real bits based on report descriptor */ @@ -62,7 +85,7 @@ static int prox_read_raw(struct iio_dev *indio_dev, { struct prox_state *prox_state = iio_priv(indio_dev); struct hid_sensor_hub_device *hsdev; - int report_id = -1; + int report_id; u32 address; int ret_type; s32 min; @@ -71,29 +94,23 @@ static int prox_read_raw(struct iio_dev *indio_dev, *val2 = 0; switch (mask) { case IIO_CHAN_INFO_RAW: - switch (chan->scan_index) { - case CHANNEL_SCAN_INDEX_PRESENCE: - report_id = prox_state->prox_attr.report_id; - min = prox_state->prox_attr.logical_minimum; - address = HID_USAGE_SENSOR_HUMAN_PRESENCE; - hsdev = prox_state->common_attributes.hsdev; - break; - default: - report_id = -1; - break; - } - if (report_id >= 0) { - hid_sensor_power_state(&prox_state->common_attributes, - true); - *val = sensor_hub_input_attr_get_raw_value( - hsdev, hsdev->usage, address, report_id, - SENSOR_HUB_SYNC, min < 0); - hid_sensor_power_state(&prox_state->common_attributes, - false); - } else { - *val = 0; + if (chan->scan_index >= prox_state->num_channels) return -EINVAL; - } + address = prox_state->channel2usage[chan->scan_index]; + report_id = prox_state->prox_attr[chan->scan_index].report_id; + hsdev = prox_state->common_attributes.hsdev; + min = prox_state->prox_attr[chan->scan_index].logical_minimum; + hid_sensor_power_state(&prox_state->common_attributes, true); + *val = sensor_hub_input_attr_get_raw_value(hsdev, + hsdev->usage, + address, + report_id, + SENSOR_HUB_SYNC, + min < 0); + if (prox_state->channel2usage[chan->scan_index] == + HID_USAGE_SENSOR_HUMAN_ATTENTION) + *val *= 100; + hid_sensor_power_state(&prox_state->common_attributes, false); ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SCALE: @@ -103,7 +120,7 @@ static int prox_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_OFFSET: *val = hid_sensor_convert_exponent( - prox_state->prox_attr.unit_expo); + prox_state->prox_attr[chan->scan_index].unit_expo); ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: @@ -153,14 +170,6 @@ static const struct iio_info prox_info = { .write_raw = &prox_write_raw, }; -/* Function to push data to buffer */ -static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data, - int len) -{ - dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - iio_push_to_buffers(indio_dev, data); -} - /* Callback handler to send event after all samples are received and captured */ static int prox_proc_event(struct hid_sensor_hub_device *hsdev, unsigned usage_id, @@ -170,10 +179,10 @@ static int prox_proc_event(struct hid_sensor_hub_device *hsdev, struct prox_state *prox_state = iio_priv(indio_dev); dev_dbg(&indio_dev->dev, "prox_proc_event\n"); - if (atomic_read(&prox_state->common_attributes.data_ready)) - hid_sensor_push_data(indio_dev, - &prox_state->human_presence, - sizeof(prox_state->human_presence)); + if (atomic_read(&prox_state->common_attributes.data_ready)) { + dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); + iio_push_to_buffers(indio_dev, &prox_state->human_presence); + } return 0; } @@ -186,58 +195,77 @@ static int prox_capture_sample(struct hid_sensor_hub_device *hsdev, { struct iio_dev *indio_dev = platform_get_drvdata(priv); struct prox_state *prox_state = iio_priv(indio_dev); - int ret = -EINVAL; - - switch (usage_id) { - case HID_USAGE_SENSOR_HUMAN_PRESENCE: - switch (raw_len) { - case 1: - prox_state->human_presence = *(u8 *)raw_data; - return 0; - case 4: - prox_state->human_presence = *(u32 *)raw_data; - return 0; - default: + int multiplier = 1; + int chan; + + for (chan = 0; chan < prox_state->num_channels; chan++) + if (prox_state->channel2usage[chan] == usage_id) break; - } - break; + if (chan == prox_state->num_channels) + return -EINVAL; + + if (usage_id == HID_USAGE_SENSOR_HUMAN_ATTENTION) + multiplier = 100; + + switch (raw_len) { + case 1: + prox_state->human_presence[chan] = *(u8 *)raw_data * multiplier; + return 0; + case 4: + prox_state->human_presence[chan] = *(u32 *)raw_data * multiplier; + return 0; } - return ret; + return -EINVAL; } /* Parse report which is specific to an usage id*/ static int prox_parse_report(struct platform_device *pdev, struct hid_sensor_hub_device *hsdev, - struct iio_chan_spec *channels, - unsigned usage_id, struct prox_state *st) { + struct iio_chan_spec *channels = st->channels; + int index = 0; int ret; + int i; + + for (i = 0; i < MAX_CHANNELS; i++) { + u32 usage_id = prox_usage_ids[i]; + + ret = sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, + hsdev->usage, + usage_id, + &st->prox_attr[index]); + if (ret < 0) + continue; + st->channel2usage[index] = usage_id; + st->scan_mask[0] |= BIT(index); + channels[index] = prox_channels[i]; + channels[index].scan_index = index; + prox_adjust_channel_bit_mask(channels, index, + st->prox_attr[index].size); + dev_dbg(&pdev->dev, "prox %x:%x\n", st->prox_attr[index].index, + st->prox_attr[index].report_id); + index++; + } - ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT, - usage_id, - HID_USAGE_SENSOR_HUMAN_PRESENCE, - &st->prox_attr); - if (ret < 0) + if (!index) return ret; - prox_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_PRESENCE, - st->prox_attr.size); - dev_dbg(&pdev->dev, "prox %x:%x\n", st->prox_attr.index, - st->prox_attr.report_id); + st->num_channels = index; - return ret; + return 0; } /* Function to initialize the processing for usage id */ static int hid_prox_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret = 0; static const char *name = "prox"; struct iio_dev *indio_dev; struct prox_state *prox_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct prox_state)); @@ -258,22 +286,15 @@ static int hid_prox_probe(struct platform_device *pdev) return ret; } - indio_dev->channels = devm_kmemdup(&pdev->dev, prox_channels, - sizeof(prox_channels), GFP_KERNEL); - if (!indio_dev->channels) { - dev_err(&pdev->dev, "failed to duplicate channels\n"); - return -ENOMEM; - } - - ret = prox_parse_report(pdev, hsdev, - (struct iio_chan_spec *)indio_dev->channels, - hsdev->usage, prox_state); + ret = prox_parse_report(pdev, hsdev, prox_state); if (ret) { dev_err(&pdev->dev, "failed to setup attributes\n"); return ret; } - indio_dev->num_channels = ARRAY_SIZE(prox_channels); + indio_dev->num_channels = prox_state->num_channels; + indio_dev->channels = prox_state->channels; + indio_dev->available_scan_masks = prox_state->scan_mask; indio_dev->info = &prox_info; indio_dev->name = name; indio_dev->modes = INDIO_DIRECT_MODE; @@ -315,7 +336,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_prox_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct prox_state *prox_state = iio_priv(indio_dev); @@ -344,11 +365,11 @@ static struct platform_driver hid_prox_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_prox_probe, - .remove_new = hid_prox_remove, + .remove = hid_prox_remove, }; module_platform_driver(hid_prox_platform_driver); MODULE_DESCRIPTION("HID Sensor Proximity"); MODULE_AUTHOR("Archana Patni "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/light/iqs621-als.c b/drivers/iio/light/iqs621-als.c index 6de33feada3a36f0656e9bdf5289560a49358b5a..b9f230210f0731b82139191366f2309f835c0b6d 100644 --- a/drivers/iio/light/iqs621-als.c +++ b/drivers/iio/light/iqs621-als.c @@ -271,7 +271,7 @@ static int iqs621_als_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct iqs621_als_private *iqs621_als = iio_priv(indio_dev); struct iqs62x_core *iqs62x = iqs621_als->iqs62x; diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index 8dfc750e68c02f1a90a01ad4e838761719240c71..201eae1c45892b5941265593b0a76caffe8b0c77 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -8,17 +8,18 @@ * Copyright (c) 2010, NVIDIA Corporation. */ -#include #include #include +#include +#include #include #include #include #include #include + #include #include -#include #define ISL29018_CONV_TIME_MS 100 @@ -687,20 +688,6 @@ static const struct isl29018_chip_info isl29018_chip_info_tbl[] = { }, }; -static const char *isl29018_match_acpi_device(struct device *dev, int *data) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - - if (!id) - return NULL; - - *data = (int)id->driver_data; - - return dev_name(dev); -} - static void isl29018_disable_regulator_action(void *_data) { struct isl29018_chip *chip = _data; @@ -716,9 +703,10 @@ static int isl29018_probe(struct i2c_client *client) const struct i2c_device_id *id = i2c_client_get_device_id(client); struct isl29018_chip *chip; struct iio_dev *indio_dev; + const void *ddata = NULL; + const char *name; + int dev_id; int err; - const char *name = NULL; - int dev_id = 0; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); if (!indio_dev) @@ -731,11 +719,11 @@ static int isl29018_probe(struct i2c_client *client) if (id) { name = id->name; dev_id = id->driver_data; + } else { + name = iio_get_acpi_device_name_and_data(&client->dev, &ddata); + dev_id = (intptr_t)ddata; } - if (ACPI_HANDLE(&client->dev)) - name = isl29018_match_acpi_device(&client->dev, &dev_id); - mutex_init(&chip->lock); chip->type = dev_id; @@ -832,15 +820,13 @@ static int isl29018_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume); -#ifdef CONFIG_ACPI static const struct acpi_device_id isl29018_acpi_match[] = { {"ISL29018", isl29018}, {"ISL29023", isl29023}, {"ISL29035", isl29035}, - {}, + {} }; MODULE_DEVICE_TABLE(acpi, isl29018_acpi_match); -#endif static const struct i2c_device_id isl29018_id[] = { {"isl29018", isl29018}, @@ -854,14 +840,14 @@ static const struct of_device_id isl29018_of_match[] = { { .compatible = "isil,isl29018", }, { .compatible = "isil,isl29023", }, { .compatible = "isil,isl29035", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, isl29018_of_match); static struct i2c_driver isl29018_driver = { .driver = { .name = "isl29018", - .acpi_match_table = ACPI_PTR(isl29018_acpi_match), + .acpi_match_table = isl29018_acpi_match, .pm = pm_sleep_ptr(&isl29018_pm_ops), .of_match_table = isl29018_of_match, }, diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index 7800f7fa51b76f9ad45adeb00ed5c4c13b4bf5f6..99f0b903018cf885d7755e6096dd86ded4dcdbe5 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c @@ -754,7 +754,7 @@ static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val) } static int lm3533_als_setup(struct lm3533_als *als, - struct lm3533_als_platform_data *pdata) + const struct lm3533_als_platform_data *pdata) { int ret; @@ -828,8 +828,8 @@ static const struct iio_info lm3533_als_info = { static int lm3533_als_probe(struct platform_device *pdev) { + const struct lm3533_als_platform_data *pdata; struct lm3533 *lm3533; - struct lm3533_als_platform_data *pdata; struct lm3533_als *als; struct iio_dev *indio_dev; int ret; @@ -838,7 +838,7 @@ static int lm3533_als_probe(struct platform_device *pdev) if (!lm3533) return -EINVAL; - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "no platform data\n"); return -EINVAL; @@ -912,7 +912,7 @@ static struct platform_driver lm3533_als_driver = { .name = "lm3533-als", }, .probe = lm3533_als_probe, - .remove_new = lm3533_als_remove, + .remove = lm3533_als_remove, }; module_platform_driver(lm3533_als_driver); diff --git a/drivers/iio/light/ltr390.c b/drivers/iio/light/ltr390.c index 4f6975e63a8fe152c1eed53a661593760611555a..df664f36090301e21d6e2f92035198e15e018712 100644 --- a/drivers/iio/light/ltr390.c +++ b/drivers/iio/light/ltr390.c @@ -18,14 +18,18 @@ * - Interrupt support */ +#include +#include #include +#include +#include #include #include #include #include -#include #include +#include #include @@ -33,18 +37,27 @@ #define LTR390_ALS_UVS_MEAS_RATE 0x04 #define LTR390_ALS_UVS_GAIN 0x05 #define LTR390_PART_ID 0x06 +#define LTR390_MAIN_STATUS 0x07 #define LTR390_ALS_DATA 0x0D #define LTR390_UVS_DATA 0x10 #define LTR390_INT_CFG 0x19 +#define LTR390_INT_PST 0x1A +#define LTR390_THRESH_UP 0x21 +#define LTR390_THRESH_LOW 0x24 #define LTR390_PART_NUMBER_ID 0xb -#define LTR390_ALS_UVS_GAIN_MASK 0x07 -#define LTR390_ALS_UVS_INT_TIME_MASK 0x70 +#define LTR390_ALS_UVS_GAIN_MASK GENMASK(2, 0) +#define LTR390_ALS_UVS_MEAS_RATE_MASK GENMASK(2, 0) +#define LTR390_ALS_UVS_INT_TIME_MASK GENMASK(6, 4) #define LTR390_ALS_UVS_INT_TIME(x) FIELD_PREP(LTR390_ALS_UVS_INT_TIME_MASK, (x)) +#define LTR390_INT_PST_MASK GENMASK(7, 4) +#define LTR390_INT_PST_VAL(x) FIELD_PREP(LTR390_INT_PST_MASK, (x)) #define LTR390_SW_RESET BIT(4) #define LTR390_UVS_MODE BIT(3) #define LTR390_SENSOR_ENABLE BIT(1) +#define LTR390_LS_INT_EN BIT(2) +#define LTR390_LS_INT_SEL_UVS BIT(5) #define LTR390_FRACTIONAL_PRECISION 100 @@ -70,6 +83,11 @@ enum ltr390_mode { LTR390_SET_UVS_MODE, }; +enum ltr390_meas_rate { + LTR390_GET_FREQ, + LTR390_GET_PERIOD, +}; + struct ltr390_data { struct regmap *regmap; struct i2c_client *client; @@ -87,6 +105,18 @@ static const struct regmap_config ltr390_regmap_config = { .val_bits = 8, }; +/* Sampling frequency is in mili Hz and mili Seconds */ +static const int ltr390_samp_freq_table[][2] = { + [0] = { 40000, 25 }, + [1] = { 20000, 50 }, + [2] = { 10000, 100 }, + [3] = { 5000, 200 }, + [4] = { 2000, 500 }, + [5] = { 1000, 1000 }, + [6] = { 500, 2000 }, + [7] = { 500, 2000 }, +}; + static int ltr390_register_read(struct ltr390_data *data, u8 register_address) { struct device *dev = &data->client->dev; @@ -135,6 +165,19 @@ static int ltr390_counts_per_uvi(struct ltr390_data *data) return DIV_ROUND_CLOSEST(23 * data->gain * data->int_time_us, 10 * orig_gain * orig_int_time); } +static int ltr390_get_samp_freq_or_period(struct ltr390_data *data, + enum ltr390_meas_rate option) +{ + int ret, value; + + ret = regmap_read(data->regmap, LTR390_ALS_UVS_MEAS_RATE, &value); + if (ret < 0) + return ret; + value = FIELD_GET(LTR390_ALS_UVS_MEAS_RATE_MASK, value); + + return ltr390_samp_freq_table[value][option]; +} + static int ltr390_read_raw(struct iio_dev *iio_device, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -191,6 +234,10 @@ static int ltr390_read_raw(struct iio_dev *iio_device, *val = data->int_time_us; return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + *val = ltr390_get_samp_freq_or_period(data, LTR390_GET_FREQ); + return IIO_VAL_INT; + default: return -EINVAL; } @@ -199,6 +246,24 @@ static int ltr390_read_raw(struct iio_dev *iio_device, /* integration time in us */ static const int ltr390_int_time_map_us[] = { 400000, 200000, 100000, 50000, 25000, 12500 }; static const int ltr390_gain_map[] = { 1, 3, 6, 9, 18 }; +static const int ltr390_freq_map[] = { 40000, 20000, 10000, 5000, 2000, 1000, 500, 500 }; + +static const struct iio_event_spec ltr390_event_spec[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_PERIOD), + } +}; static const struct iio_chan_spec ltr390_channels[] = { /* UV sensor */ @@ -206,16 +271,24 @@ static const struct iio_chan_spec ltr390_channels[] = { .type = IIO_UVINDEX, .scan_index = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), - .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SCALE) + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .event_spec = ltr390_event_spec, + .num_event_specs = ARRAY_SIZE(ltr390_event_spec), }, /* ALS sensor */ { .type = IIO_LIGHT, .scan_index = 1, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), - .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SCALE) + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .event_spec = ltr390_event_spec, + .num_event_specs = ARRAY_SIZE(ltr390_event_spec), }, }; @@ -264,6 +337,23 @@ static int ltr390_set_int_time(struct ltr390_data *data, int val) return -EINVAL; } +static int ltr390_set_samp_freq(struct ltr390_data *data, int val) +{ + int idx; + + for (idx = 0; idx < ARRAY_SIZE(ltr390_samp_freq_table); idx++) { + if (ltr390_samp_freq_table[idx][0] != val) + continue; + + guard(mutex)(&data->lock); + return regmap_update_bits(data->regmap, + LTR390_ALS_UVS_MEAS_RATE, + LTR390_ALS_UVS_MEAS_RATE_MASK, idx); + } + + return -EINVAL; +} + static int ltr390_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, const int **vals, int *type, int *length, long mask) { @@ -278,6 +368,11 @@ static int ltr390_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec con *type = IIO_VAL_INT; *vals = ltr390_int_time_map_us; return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + *length = ARRAY_SIZE(ltr390_freq_map); + *type = IIO_VAL_INT; + *vals = ltr390_freq_map; + return IIO_AVAIL_LIST; default: return -EINVAL; } @@ -301,6 +396,191 @@ static int ltr390_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec cons return ltr390_set_int_time(data, val); + case IIO_CHAN_INFO_SAMP_FREQ: + if (val2 != 0) + return -EINVAL; + + return ltr390_set_samp_freq(data, val); + + default: + return -EINVAL; + } +} + +static int ltr390_read_intr_prst(struct ltr390_data *data, int *val) +{ + int ret, prst, samp_period; + + samp_period = ltr390_get_samp_freq_or_period(data, LTR390_GET_PERIOD); + ret = regmap_read(data->regmap, LTR390_INT_PST, &prst); + if (ret < 0) + return ret; + *val = prst * samp_period; + + return IIO_VAL_INT; +} + +static int ltr390_write_intr_prst(struct ltr390_data *data, int val) +{ + int ret, samp_period, new_val; + + samp_period = ltr390_get_samp_freq_or_period(data, LTR390_GET_PERIOD); + + /* persist period should be greater than or equal to samp period */ + if (val < samp_period) + return -EINVAL; + + new_val = DIV_ROUND_UP(val, samp_period); + if (new_val < 0 || new_val > 0x0f) + return -EINVAL; + + guard(mutex)(&data->lock); + ret = regmap_update_bits(data->regmap, + LTR390_INT_PST, + LTR390_INT_PST_MASK, + LTR390_INT_PST_VAL(new_val)); + if (ret) + return ret; + + return 0; +} + +static int ltr390_read_threshold(struct iio_dev *indio_dev, + enum iio_event_direction dir, + int *val, int *val2) +{ + struct ltr390_data *data = iio_priv(indio_dev); + int ret; + + switch (dir) { + case IIO_EV_DIR_RISING: + ret = ltr390_register_read(data, LTR390_THRESH_UP); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + + case IIO_EV_DIR_FALLING: + ret = ltr390_register_read(data, LTR390_THRESH_LOW); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int ltr390_write_threshold(struct iio_dev *indio_dev, + enum iio_event_direction dir, + int val, int val2) +{ + struct ltr390_data *data = iio_priv(indio_dev); + + guard(mutex)(&data->lock); + switch (dir) { + case IIO_EV_DIR_RISING: + return regmap_bulk_write(data->regmap, LTR390_THRESH_UP, &val, 3); + + case IIO_EV_DIR_FALLING: + return regmap_bulk_write(data->regmap, LTR390_THRESH_LOW, &val, 3); + + default: + return -EINVAL; + } +} + +static int ltr390_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + switch (info) { + case IIO_EV_INFO_VALUE: + return ltr390_read_threshold(indio_dev, dir, val, val2); + + case IIO_EV_INFO_PERIOD: + return ltr390_read_intr_prst(iio_priv(indio_dev), val); + + default: + return -EINVAL; + } +} + +static int ltr390_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + switch (info) { + case IIO_EV_INFO_VALUE: + if (val2 != 0) + return -EINVAL; + + return ltr390_write_threshold(indio_dev, dir, val, val2); + + case IIO_EV_INFO_PERIOD: + if (val2 != 0) + return -EINVAL; + + return ltr390_write_intr_prst(iio_priv(indio_dev), val); + + default: + return -EINVAL; + } +} + +static int ltr390_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct ltr390_data *data = iio_priv(indio_dev); + int ret, status; + + ret = regmap_read(data->regmap, LTR390_INT_CFG, &status); + if (ret < 0) + return ret; + + return FIELD_GET(LTR390_LS_INT_EN, status); +} + +static int ltr390_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + struct ltr390_data *data = iio_priv(indio_dev); + int ret; + + if (!state) + return regmap_clear_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_EN); + + guard(mutex)(&data->lock); + ret = regmap_set_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_EN); + if (ret < 0) + return ret; + + switch (chan->type) { + case IIO_LIGHT: + ret = ltr390_set_mode(data, LTR390_SET_ALS_MODE); + if (ret < 0) + return ret; + + return regmap_clear_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_SEL_UVS); + + case IIO_UVINDEX: + ret = ltr390_set_mode(data, LTR390_SET_UVS_MODE); + if (ret < 0) + return ret; + + return regmap_set_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_SEL_UVS); + default: return -EINVAL; } @@ -310,8 +590,44 @@ static const struct iio_info ltr390_info = { .read_raw = ltr390_read_raw, .write_raw = ltr390_write_raw, .read_avail = ltr390_read_avail, + .read_event_value = ltr390_read_event_value, + .read_event_config = ltr390_read_event_config, + .write_event_value = ltr390_write_event_value, + .write_event_config = ltr390_write_event_config, }; +static irqreturn_t ltr390_interrupt_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct ltr390_data *data = iio_priv(indio_dev); + int ret, status; + + /* Reading the status register to clear the interrupt flag, Datasheet pg: 17*/ + ret = regmap_read(data->regmap, LTR390_MAIN_STATUS, &status); + if (ret < 0) + return ret; + + switch (data->mode) { + case LTR390_SET_ALS_MODE: + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(indio_dev)); + break; + + case LTR390_SET_UVS_MODE: + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_UVINDEX, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(indio_dev)); + break; + } + + return IRQ_HANDLED; +} + static int ltr390_probe(struct i2c_client *client) { struct ltr390_data *data; @@ -365,9 +681,40 @@ static int ltr390_probe(struct i2c_client *client) if (ret) return dev_err_probe(dev, ret, "failed to enable the sensor\n"); + if (client->irq) { + ret = devm_request_threaded_irq(dev, client->irq, + NULL, ltr390_interrupt_handler, + IRQF_ONESHOT, + "ltr390_thresh_event", + indio_dev); + if (ret) + return dev_err_probe(dev, ret, + "request irq (%d) failed\n", client->irq); + } + return devm_iio_device_register(dev, indio_dev); } +static int ltr390_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ltr390_data *data = iio_priv(indio_dev); + + return regmap_clear_bits(data->regmap, LTR390_MAIN_CTRL, + LTR390_SENSOR_ENABLE); +} + +static int ltr390_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ltr390_data *data = iio_priv(indio_dev); + + return regmap_set_bits(data->regmap, LTR390_MAIN_CTRL, + LTR390_SENSOR_ENABLE); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(ltr390_pm_ops, ltr390_suspend, ltr390_resume); + static const struct i2c_device_id ltr390_id[] = { { "ltr390" }, { /* Sentinel */ } @@ -384,6 +731,7 @@ static struct i2c_driver ltr390_driver = { .driver = { .name = "ltr390", .of_match_table = ltr390_of_table, + .pm = pm_sleep_ptr(<r390_pm_ops), }, .probe = ltr390_probe, .id_table = ltr390_id, diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 8c516ede911619bb4ee8f8a823f242b7aaa6af55..604f5f900a2ecb8e0529b129ddca9e36ec292126 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -1078,15 +1077,11 @@ static int ltr501_read_event_config(struct iio_dev *indio_dev, static int ltr501_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct ltr501_data *data = iio_priv(indio_dev); int ret; - /* only 1 and 0 are valid inputs */ - if (state != 1 && state != 0) - return -EINVAL; - switch (chan->type) { case IIO_INTENSITY: mutex_lock(&data->lock_als); @@ -1422,17 +1417,6 @@ static int ltr501_powerdown(struct ltr501_data *data) data->ps_contr & ~LTR501_CONTR_ACTIVE); } -static const char *ltr501_match_acpi_device(struct device *dev, int *chip_idx) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - *chip_idx = id->driver_data; - return dev_name(dev); -} - static int ltr501_probe(struct i2c_client *client) { const struct i2c_device_id *id = i2c_client_get_device_id(client); @@ -1440,8 +1424,10 @@ static int ltr501_probe(struct i2c_client *client) struct ltr501_data *data; struct iio_dev *indio_dev; struct regmap *regmap; - int ret, partid, chip_idx = 0; - const char *name = NULL; + const void *ddata = NULL; + int partid, chip_idx; + const char *name; + int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) @@ -1523,11 +1509,12 @@ static int ltr501_probe(struct i2c_client *client) if (id) { name = id->name; chip_idx = id->driver_data; - } else if (ACPI_HANDLE(&client->dev)) { - name = ltr501_match_acpi_device(&client->dev, &chip_idx); } else { - return -ENODEV; + name = iio_get_acpi_device_name_and_data(&client->dev, &ddata); + chip_idx = (intptr_t)ddata; } + if (!name) + return -ENODEV; data->chip_info = <r501_chip_info_tbl[chip_idx]; @@ -1610,9 +1597,9 @@ static int ltr501_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(ltr501_pm_ops, ltr501_suspend, ltr501_resume); static const struct acpi_device_id ltr_acpi_match[] = { - { "LTER0501", ltr501 }, - { "LTER0559", ltr559 }, { "LTER0301", ltr301 }, + /* https://www.catalog.update.microsoft.com/Search.aspx?q=lter0303 */ + { "LTER0303", ltr303 }, { }, }; MODULE_DEVICE_TABLE(acpi, ltr_acpi_match); diff --git a/drivers/iio/light/ltrf216a.c b/drivers/iio/light/ltrf216a.c index 37eecff571b96b858545dd04d9648888026d797e..dbec1e7cfeb8636c1204f7b23103b7a8ad1a51ed 100644 --- a/drivers/iio/light/ltrf216a.c +++ b/drivers/iio/light/ltrf216a.c @@ -561,6 +561,7 @@ MODULE_DEVICE_TABLE(i2c, ltrf216a_id); static const struct of_device_id ltrf216a_of_match[] = { { .compatible = "liteon,ltr308", .data = <r308_chip_info }, { .compatible = "liteon,ltrf216a", .data = <rf216a_chip_info }, + /* For Valve's Steamdeck device, an ACPI platform using PRP0001 */ { .compatible = "ltr,ltrf216a", .data = <rf216a_chip_info }, {} }; diff --git a/drivers/iio/light/max44009.c b/drivers/iio/light/max44009.c index 3b92362675dc96fd37272bb5c25c20717b8c25b0..8cd7f5664e5b1a13aceb3aaeac3f6eef14a1eaac 100644 --- a/drivers/iio/light/max44009.c +++ b/drivers/iio/light/max44009.c @@ -422,7 +422,7 @@ static int max44009_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct max44009_data *data = iio_priv(indio_dev); int ret; diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c index 176e54bb48c33b2445ecfd80351b3953fd610ee9..65b295877b41588d40234ca7681bfee291e937c2 100644 --- a/drivers/iio/light/opt3001.c +++ b/drivers/iio/light/opt3001.c @@ -70,6 +70,35 @@ #define OPT3001_RESULT_READY_SHORT 150 #define OPT3001_RESULT_READY_LONG 1000 +struct opt3001_scale { + int val; + int val2; +}; + +struct opt3001_chip_info { + const struct iio_chan_spec (*channels)[2]; + enum iio_chan_type chan_type; + int num_channels; + + const struct opt3001_scale (*scales)[12]; + /* + * Factor as specified by conversion equation in datasheet. + * eg. 0.01 (scaled to integer 10) for opt3001. + */ + int factor_whole; + /* + * Factor to compensate for potentially scaled factor_whole. + */ + int factor_integer; + /* + * Factor used to align decimal part of proccessed value to six decimal + * places. + */ + int factor_decimal; + + bool has_id; +}; + struct opt3001 { struct i2c_client *client; struct device *dev; @@ -79,6 +108,7 @@ struct opt3001 { bool result_ready; wait_queue_head_t result_ready_queue; u16 result; + const struct opt3001_chip_info *chip_info; u32 int_time; u32 mode; @@ -92,11 +122,6 @@ struct opt3001 { bool use_irq; }; -struct opt3001_scale { - int val; - int val2; -}; - static const struct opt3001_scale opt3001_scales[] = { { .val = 40, @@ -148,21 +173,68 @@ static const struct opt3001_scale opt3001_scales[] = { }, }; +static const struct opt3001_scale opt3002_scales[] = { + { + .val = 4914, + .val2 = 0, + }, + { + .val = 9828, + .val2 = 0, + }, + { + .val = 19656, + .val2 = 0, + }, + { + .val = 39312, + .val2 = 0, + }, + { + .val = 78624, + .val2 = 0, + }, + { + .val = 157248, + .val2 = 0, + }, + { + .val = 314496, + .val2 = 0, + }, + { + .val = 628992, + .val2 = 0, + }, + { + .val = 1257984, + .val2 = 0, + }, + { + .val = 2515968, + .val2 = 0, + }, + { + .val = 5031936, + .val2 = 0, + }, + { + .val = 10063872, + .val2 = 0, + }, +}; + static int opt3001_find_scale(const struct opt3001 *opt, int val, int val2, u8 *exponent) { int i; - - for (i = 0; i < ARRAY_SIZE(opt3001_scales); i++) { - const struct opt3001_scale *scale = &opt3001_scales[i]; - + for (i = 0; i < ARRAY_SIZE(*opt->chip_info->scales); i++) { + const struct opt3001_scale *scale = &(*opt->chip_info->scales)[i]; /* - * Combine the integer and micro parts for comparison - * purposes. Use milli lux precision to avoid 32-bit integer - * overflows. + * Compare the integer and micro parts to determine value scale. */ - if ((val * 1000 + val2 / 1000) <= - (scale->val * 1000 + scale->val2 / 1000)) { + if (val < scale->val || + (val == scale->val && val2 <= scale->val2)) { *exponent = i; return 0; } @@ -174,11 +246,14 @@ static int opt3001_find_scale(const struct opt3001 *opt, int val, static void opt3001_to_iio_ret(struct opt3001 *opt, u8 exponent, u16 mantissa, int *val, int *val2) { - int lux; + int ret; + int whole = opt->chip_info->factor_whole; + int integer = opt->chip_info->factor_integer; + int decimal = opt->chip_info->factor_decimal; - lux = 10 * (mantissa << exponent); - *val = lux / 1000; - *val2 = (lux - (*val * 1000)) * 1000; + ret = whole * (mantissa << exponent); + *val = ret / integer; + *val2 = (ret - (*val * integer)) * decimal; } static void opt3001_set_mode(struct opt3001 *opt, u16 *reg, u16 mode) @@ -225,7 +300,18 @@ static const struct iio_chan_spec opt3001_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(1), }; -static int opt3001_get_lux(struct opt3001 *opt, int *val, int *val2) +static const struct iio_chan_spec opt3002_channels[] = { + { + .type = IIO_INTENSITY, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_INT_TIME), + .event_spec = opt3001_event_spec, + .num_event_specs = ARRAY_SIZE(opt3001_event_spec), + }, + IIO_CHAN_SOFT_TIMESTAMP(1), +}; + +static int opt3001_get_processed(struct opt3001 *opt, int *val, int *val2) { int ret; u16 mantissa; @@ -397,14 +483,15 @@ static int opt3001_read_raw(struct iio_dev *iio, if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) return -EBUSY; - if (chan->type != IIO_LIGHT) + if (chan->type != opt->chip_info->chan_type) return -EINVAL; mutex_lock(&opt->lock); switch (mask) { + case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: - ret = opt3001_get_lux(opt, val, val2); + ret = opt3001_get_processed(opt, val, val2); break; case IIO_CHAN_INFO_INT_TIME: ret = opt3001_get_int_time(opt, val, val2); @@ -428,7 +515,7 @@ static int opt3001_write_raw(struct iio_dev *iio, if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) return -EBUSY; - if (chan->type != IIO_LIGHT) + if (chan->type != opt->chip_info->chan_type) return -EINVAL; if (mask != IIO_CHAN_INFO_INT_TIME) @@ -479,6 +566,9 @@ static int opt3001_write_event_value(struct iio_dev *iio, { struct opt3001 *opt = iio_priv(iio); int ret; + int whole; + int integer; + int decimal; u16 mantissa; u16 value; @@ -497,7 +587,12 @@ static int opt3001_write_event_value(struct iio_dev *iio, goto err; } - mantissa = (((val * 1000) + (val2 / 1000)) / 10) >> exponent; + whole = opt->chip_info->factor_whole; + integer = opt->chip_info->factor_integer; + decimal = opt->chip_info->factor_decimal; + + mantissa = (((val * integer) + (val2 / decimal)) / whole) >> exponent; + value = (exponent << 12) | mantissa; switch (dir) { @@ -539,7 +634,7 @@ static int opt3001_read_event_config(struct iio_dev *iio, static int opt3001_write_event_config(struct iio_dev *iio, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct opt3001 *opt = iio_priv(iio); int ret; @@ -610,7 +705,7 @@ static int opt3001_read_id(struct opt3001 *opt) ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_DEVICE_ID); if (ret < 0) { dev_err(opt->dev, "failed to read register %02x\n", - OPT3001_DEVICE_ID); + OPT3001_DEVICE_ID); return ret; } @@ -692,6 +787,7 @@ static irqreturn_t opt3001_irq(int irq, void *_iio) struct opt3001 *opt = iio_priv(iio); int ret; bool wake_result_ready_queue = false; + enum iio_chan_type chan_type = opt->chip_info->chan_type; if (!opt->ok_to_ignore_lock) mutex_lock(&opt->lock); @@ -707,13 +803,13 @@ static irqreturn_t opt3001_irq(int irq, void *_iio) OPT3001_CONFIGURATION_M_CONTINUOUS) { if (ret & OPT3001_CONFIGURATION_FH) iio_push_event(iio, - IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, + IIO_UNMOD_EVENT_CODE(chan_type, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), iio_get_time_ns(iio)); if (ret & OPT3001_CONFIGURATION_FL) iio_push_event(iio, - IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, + IIO_UNMOD_EVENT_CODE(chan_type, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), iio_get_time_ns(iio)); @@ -755,22 +851,25 @@ static int opt3001_probe(struct i2c_client *client) opt = iio_priv(iio); opt->client = client; opt->dev = dev; + opt->chip_info = i2c_get_match_data(client); mutex_init(&opt->lock); init_waitqueue_head(&opt->result_ready_queue); i2c_set_clientdata(client, iio); - ret = opt3001_read_id(opt); - if (ret) - return ret; + if (opt->chip_info->has_id) { + ret = opt3001_read_id(opt); + if (ret) + return ret; + } ret = opt3001_configure(opt); if (ret) return ret; iio->name = client->name; - iio->channels = opt3001_channels; - iio->num_channels = ARRAY_SIZE(opt3001_channels); + iio->channels = *opt->chip_info->channels; + iio->num_channels = opt->chip_info->num_channels; iio->modes = INDIO_DIRECT_MODE; iio->info = &opt3001_info; @@ -825,14 +924,38 @@ static void opt3001_remove(struct i2c_client *client) } } +static const struct opt3001_chip_info opt3001_chip_information = { + .channels = &opt3001_channels, + .chan_type = IIO_LIGHT, + .num_channels = ARRAY_SIZE(opt3001_channels), + .scales = &opt3001_scales, + .factor_whole = 10, + .factor_integer = 1000, + .factor_decimal = 1000, + .has_id = true, +}; + +static const struct opt3001_chip_info opt3002_chip_information = { + .channels = &opt3002_channels, + .chan_type = IIO_INTENSITY, + .num_channels = ARRAY_SIZE(opt3002_channels), + .scales = &opt3002_scales, + .factor_whole = 12, + .factor_integer = 10, + .factor_decimal = 100000, + .has_id = false, +}; + static const struct i2c_device_id opt3001_id[] = { - { "opt3001" }, + { "opt3001", (kernel_ulong_t)&opt3001_chip_information }, + { "opt3002", (kernel_ulong_t)&opt3002_chip_information }, { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(i2c, opt3001_id); static const struct of_device_id opt3001_of_match[] = { - { .compatible = "ti,opt3001" }, + { .compatible = "ti,opt3001", .data = &opt3001_chip_information }, + { .compatible = "ti,opt3002", .data = &opt3002_chip_information }, { } }; MODULE_DEVICE_TABLE(of, opt3001_of_match); diff --git a/drivers/iio/light/rohm-bu27008.c b/drivers/iio/light/rohm-bu27008.c index 0f010eff1981fbc4f7271d3329b12ecd3a0a8bfd..fa35dd32700ce3acacd854735ca84ad5151254e7 100644 --- a/drivers/iio/light/rohm-bu27008.c +++ b/drivers/iio/light/rohm-bu27008.c @@ -1632,4 +1632,4 @@ module_i2c_driver(bu27008_i2c_driver); MODULE_DESCRIPTION("ROHM BU27008 and BU27010 colour sensor driver"); MODULE_AUTHOR("Matti Vaittinen "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_GTS_HELPER); +MODULE_IMPORT_NS("IIO_GTS_HELPER"); diff --git a/drivers/iio/light/rohm-bu27034.c b/drivers/iio/light/rohm-bu27034.c index 76711c3cdf7c02f01c422e25c496064bddb5cc3f..4f591c2278f21f0a157a232800c89f59d02eece4 100644 --- a/drivers/iio/light/rohm-bu27034.c +++ b/drivers/iio/light/rohm-bu27034.c @@ -1350,4 +1350,4 @@ module_i2c_driver(bu27034_i2c_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Matti Vaittinen "); MODULE_DESCRIPTION("ROHM BU27034 ambient light sensor driver"); -MODULE_IMPORT_NS(IIO_GTS_HELPER); +MODULE_IMPORT_NS("IIO_GTS_HELPER"); diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index 78c08e0bd0776a28aa81942e60bbc2ba97f798a4..56f5fbbf79ac702c627073b938d922e6b37b2827 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -438,18 +438,6 @@ static irqreturn_t rpr0521_drdy_irq_thread(int irq, void *private) return IRQ_NONE; } -static irqreturn_t rpr0521_trigger_consumer_store_time(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - - /* Other trigger polls store time here. */ - if (!iio_trigger_using_own(indio_dev)) - pf->timestamp = iio_get_time_ns(indio_dev); - - return IRQ_WAKE_THREAD; -} - static irqreturn_t rpr0521_trigger_consumer_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -1016,7 +1004,7 @@ static int rpr0521_probe(struct i2c_client *client) /* Trigger consumer setup */ ret = devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev, - rpr0521_trigger_consumer_store_time, + iio_pollfunc_store_time, rpr0521_trigger_consumer_handler, &rpr0521_buffer_setup_ops); if (ret < 0) { diff --git a/drivers/iio/light/st_uvis25_core.c b/drivers/iio/light/st_uvis25_core.c index fba3997574bbf4620f2826be1e34ddd26675c17a..40a810000df0662dab89bcb8b1531a3435cdd967 100644 --- a/drivers/iio/light/st_uvis25_core.c +++ b/drivers/iio/light/st_uvis25_core.c @@ -174,8 +174,7 @@ static int st_uvis25_allocate_trigger(struct iio_dev *iio_dev) unsigned long irq_type; int err; - irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); - + irq_type = irq_get_trigger_type(hw->irq); switch (irq_type) { case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: @@ -323,7 +322,7 @@ int st_uvis25_probe(struct device *dev, int irq, struct regmap *regmap) return devm_iio_device_register(dev, iio_dev); } -EXPORT_SYMBOL_NS(st_uvis25_probe, IIO_UVIS25); +EXPORT_SYMBOL_NS(st_uvis25_probe, "IIO_UVIS25"); static int st_uvis25_suspend(struct device *dev) { diff --git a/drivers/iio/light/st_uvis25_i2c.c b/drivers/iio/light/st_uvis25_i2c.c index 6bc2ddfb77ca633361682b3637f2c45e558a0f6f..f54282476d11d60db7b991c428cd5a2084ede2cb 100644 --- a/drivers/iio/light/st_uvis25_i2c.c +++ b/drivers/iio/light/st_uvis25_i2c.c @@ -65,4 +65,4 @@ module_i2c_driver(st_uvis25_driver); MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_DESCRIPTION("STMicroelectronics uvis25 i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_UVIS25); +MODULE_IMPORT_NS("IIO_UVIS25"); diff --git a/drivers/iio/light/st_uvis25_spi.c b/drivers/iio/light/st_uvis25_spi.c index 86a232320d7d7107d2fdb5fdad867163a265c7ea..18edc6a5a4a4fe98a62727e4ec02997abe13a756 100644 --- a/drivers/iio/light/st_uvis25_spi.c +++ b/drivers/iio/light/st_uvis25_spi.c @@ -66,4 +66,4 @@ module_spi_driver(st_uvis25_driver); MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_DESCRIPTION("STMicroelectronics uvis25 spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_UVIS25); +MODULE_IMPORT_NS("IIO_UVIS25"); diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index ed20b67145463d253a0dff28a4c1c3e02e710319..b81cc44db43c377ad8a8cc61c4430decb187181d 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -324,15 +324,12 @@ static int stk3310_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { int ret; struct stk3310_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; - if (state < 0 || state > 7) - return -EINVAL; - /* Set INT_PS value */ mutex_lock(&data->lock); ret = regmap_field_write(data->reg_int_ps, state); diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index 04452b4664f306339db42657c03e08bfc0ffff11..4186aac04902e6b12ee7978ef19c3b47faf773f7 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -327,7 +327,7 @@ static int tcs3472_read_event_config(struct iio_dev *indio_dev, static int tcs3472_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct tcs3472_data *data = iio_priv(indio_dev); int ret = 0; diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 1a6f514bced6e0bd542c14a279071d5820a462c8..f1fe7640fce63bddad57fbe7809ee60bbfd44e1f 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -630,7 +630,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private) static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct tsl2563_chip *chip = iio_priv(indio_dev); int ret = 0; diff --git a/drivers/iio/light/tsl2591.c b/drivers/iio/light/tsl2591.c index 850c2465992fa0d83430236825ce94051a104272..b81ca6f73f92732dc66a9be35c9dbed5088e8da1 100644 --- a/drivers/iio/light/tsl2591.c +++ b/drivers/iio/light/tsl2591.c @@ -985,7 +985,7 @@ static int tsl2591_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct tsl2591_chip *chip = iio_priv(indio_dev); struct i2c_client *client = chip->client; diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c index cab468a82b616a23394977da1d8822d29d8941d3..349afdcbe30dd0c4c0fbabaa16ff7832e407e8ee 100644 --- a/drivers/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -1081,14 +1081,14 @@ static int tsl2772_write_interrupt_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int val) + bool val) { struct tsl2772_chip *chip = iio_priv(indio_dev); if (chan->type == IIO_INTENSITY) - chip->settings.als_interrupt_en = val ? true : false; + chip->settings.als_interrupt_en = val; else - chip->settings.prox_interrupt_en = val ? true : false; + chip->settings.prox_interrupt_en = val; return tsl2772_invoke_change(indio_dev); } diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index de6967ac3b0b3be02a96f3eb05aa58c49b0c87c7..c83114aed6b23f1d68068105b7c145bedf005b36 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -627,7 +627,7 @@ static int us5182d_read_event_config(struct iio_dev *indio_dev, static int us5182d_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct us5182d_data *data = iio_priv(indio_dev); int ret; diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index 4e3641ff2ed446262c12380e520d3d220865c00c..e19199b17f2ef7ebd022c211605418711b8220d2 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -1456,7 +1456,7 @@ static int vcnl4010_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { switch (chan->type) { case IIO_PROXIMITY: @@ -1501,7 +1501,8 @@ static int vcnl4040_read_event_config(struct iio_dev *indio_dev, static int vcnl4040_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, + bool state) { int ret = -EINVAL; u16 val, mask; diff --git a/drivers/iio/light/veml3235.c b/drivers/iio/light/veml3235.c new file mode 100644 index 0000000000000000000000000000000000000000..66361c3012a3d9f30a79630d51f329dacfb141bc --- /dev/null +++ b/drivers/iio/light/veml3235.c @@ -0,0 +1,495 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * VEML3235 Ambient Light Sensor + * + * Copyright (c) 2024, Javier Carrasco + * + * Datasheet: https://www.vishay.com/docs/80131/veml3235.pdf + * Appnote-80222: https://www.vishay.com/docs/80222/designingveml3235.pdf + */ + +#include +#include +#include +#include +#include +#include +#include + +#define VEML3235_REG_CONF 0x00 +#define VEML3235_REG_WH_DATA 0x04 +#define VEML3235_REG_ALS_DATA 0x05 +#define VEML3235_REG_ID 0x09 + +#define VEML3235_CONF_SD BIT(0) +#define VEML3235_CONF_SD0 BIT(15) + +struct veml3235_rf { + struct regmap_field *it; + struct regmap_field *gain; + struct regmap_field *id; +}; + +struct veml3235_data { + struct i2c_client *client; + struct device *dev; + struct regmap *regmap; + struct veml3235_rf rf; +}; + +static const int veml3235_it_times[][2] = { + { 0, 50000 }, + { 0, 100000 }, + { 0, 200000 }, + { 0, 400000 }, + { 0, 800000 }, +}; + +static const int veml3235_scale_vals[] = { 1, 2, 4, 8 }; + +static int veml3235_power_on(struct veml3235_data *data) +{ + int ret; + + ret = regmap_clear_bits(data->regmap, VEML3235_REG_CONF, + VEML3235_CONF_SD | VEML3235_CONF_SD0); + if (ret) + return ret; + + /* Wait 4 ms to let processor & oscillator start correctly */ + fsleep(4000); + + return 0; +} + +static int veml3235_shut_down(struct veml3235_data *data) +{ + return regmap_set_bits(data->regmap, VEML3235_REG_CONF, + VEML3235_CONF_SD | VEML3235_CONF_SD0); +} + +static void veml3235_shut_down_action(void *data) +{ + veml3235_shut_down(data); +} + +enum veml3235_chan { + CH_ALS, + CH_WHITE, +}; + +static const struct iio_chan_spec veml3235_channels[] = { + { + .type = IIO_LIGHT, + .channel = CH_ALS, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + }, + { + .type = IIO_INTENSITY, + .channel = CH_WHITE, + .modified = 1, + .channel2 = IIO_MOD_LIGHT_BOTH, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static const struct regmap_config veml3235_regmap_config = { + .name = "veml3235_regmap", + .reg_bits = 8, + .val_bits = 16, + .max_register = VEML3235_REG_ID, + .val_format_endian = REGMAP_ENDIAN_LITTLE, +}; + +static int veml3235_get_it(struct veml3235_data *data, int *val, int *val2) +{ + int ret, reg; + + ret = regmap_field_read(data->rf.it, ®); + if (ret) + return ret; + + switch (reg) { + case 0: + *val2 = 50000; + break; + case 1: + *val2 = 100000; + break; + case 2: + *val2 = 200000; + break; + case 3: + *val2 = 400000; + break; + case 4: + *val2 = 800000; + break; + default: + return -EINVAL; + } + + *val = 0; + + return IIO_VAL_INT_PLUS_MICRO; +} + +static int veml3235_set_it(struct iio_dev *indio_dev, int val, int val2) +{ + struct veml3235_data *data = iio_priv(indio_dev); + int ret, new_it; + + if (val) + return -EINVAL; + + switch (val2) { + case 50000: + new_it = 0x00; + break; + case 100000: + new_it = 0x01; + break; + case 200000: + new_it = 0x02; + break; + case 400000: + new_it = 0x03; + break; + case 800000: + new_it = 0x04; + break; + default: + return -EINVAL; + } + + ret = regmap_field_write(data->rf.it, new_it); + if (ret) { + dev_err(data->dev, + "failed to update integration time: %d\n", ret); + return ret; + } + + return 0; +} + +static int veml3235_set_gain(struct iio_dev *indio_dev, int val, int val2) +{ + struct veml3235_data *data = iio_priv(indio_dev); + int ret, new_gain; + + if (val2 != 0) + return -EINVAL; + + switch (val) { + case 1: + new_gain = 0x00; + break; + case 2: + new_gain = 0x01; + break; + case 4: + new_gain = 0x03; + break; + case 8: + new_gain = 0x07; + break; + default: + return -EINVAL; + } + + ret = regmap_field_write(data->rf.gain, new_gain); + if (ret) { + dev_err(data->dev, "failed to set gain: %d\n", ret); + return ret; + } + + return 0; +} + +static int veml3235_get_gain(struct veml3235_data *data, int *val) +{ + int ret, reg; + + ret = regmap_field_read(data->rf.gain, ®); + if (ret) { + dev_err(data->dev, "failed to read gain %d\n", ret); + return ret; + } + + switch (reg & 0x03) { + case 0: + *val = 1; + break; + case 1: + *val = 2; + break; + case 3: + *val = 4; + break; + default: + return -EINVAL; + } + + /* Double gain */ + if (reg & 0x04) + *val *= 2; + + return IIO_VAL_INT; +} + +static int veml3235_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct veml3235_data *data = iio_priv(indio_dev); + struct regmap *regmap = data->regmap; + int ret, reg; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_LIGHT: + ret = regmap_read(regmap, VEML3235_REG_ALS_DATA, ®); + if (ret < 0) + return ret; + + *val = reg; + return IIO_VAL_INT; + case IIO_INTENSITY: + ret = regmap_read(regmap, VEML3235_REG_WH_DATA, ®); + if (ret < 0) + return ret; + + *val = reg; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_INT_TIME: + return veml3235_get_it(data, val, val2); + case IIO_CHAN_INFO_SCALE: + return veml3235_get_gain(data, val); + default: + return -EINVAL; + } +} + +static int veml3235_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + *vals = (int *)&veml3235_it_times; + *length = 2 * ARRAY_SIZE(veml3235_it_times); + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *vals = (int *)&veml3235_scale_vals; + *length = ARRAY_SIZE(veml3235_scale_vals); + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int veml3235_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + return veml3235_set_it(indio_dev, val, val2); + case IIO_CHAN_INFO_SCALE: + return veml3235_set_gain(indio_dev, val, val2); + } + + return -EINVAL; +} + +static void veml3235_read_id(struct veml3235_data *data) +{ + int ret, reg; + + ret = regmap_field_read(data->rf.id, ®); + if (ret) { + dev_info(data->dev, "failed to read ID\n"); + return; + } + + if (reg != 0x35) + dev_info(data->dev, "Unknown ID %d\n", reg); +} + +static const struct reg_field veml3235_rf_it = + REG_FIELD(VEML3235_REG_CONF, 4, 6); + +static const struct reg_field veml3235_rf_gain = + REG_FIELD(VEML3235_REG_CONF, 11, 13); + +static const struct reg_field veml3235_rf_id = + REG_FIELD(VEML3235_REG_ID, 0, 7); + +static int veml3235_regfield_init(struct veml3235_data *data) +{ + struct regmap *regmap = data->regmap; + struct device *dev = data->dev; + struct regmap_field *rm_field; + struct veml3235_rf *rf = &data->rf; + + rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_it); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->it = rm_field; + + rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_gain); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->gain = rm_field; + + rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_id); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->id = rm_field; + + return 0; +} + +static int veml3235_hw_init(struct iio_dev *indio_dev) +{ + struct veml3235_data *data = iio_priv(indio_dev); + struct device *dev = data->dev; + int ret; + + /* Set gain to 1 and integration time to 100 ms */ + ret = regmap_field_write(data->rf.gain, 0x00); + if (ret) + return dev_err_probe(data->dev, ret, "failed to set gain\n"); + + ret = regmap_field_write(data->rf.it, 0x01); + if (ret) + return dev_err_probe(data->dev, ret, + "failed to set integration time\n"); + + ret = veml3235_power_on(data); + if (ret) + return dev_err_probe(dev, ret, "failed to power on\n"); + + return devm_add_action_or_reset(dev, veml3235_shut_down_action, data); +} + +static const struct iio_info veml3235_info = { + .read_raw = veml3235_read_raw, + .read_avail = veml3235_read_avail, + .write_raw = veml3235_write_raw, +}; + +static int veml3235_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct veml3235_data *data; + struct iio_dev *indio_dev; + struct regmap *regmap; + int ret; + + regmap = devm_regmap_init_i2c(client, &veml3235_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "failed to setup regmap\n"); + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + data->dev = dev; + data->regmap = regmap; + + ret = veml3235_regfield_init(data); + if (ret) + return dev_err_probe(dev, ret, "failed to init regfield\n"); + + ret = devm_regulator_get_enable(dev, "vdd"); + if (ret) + return dev_err_probe(dev, ret, "failed to enable regulator\n"); + + indio_dev->name = "veml3235"; + indio_dev->channels = veml3235_channels; + indio_dev->num_channels = ARRAY_SIZE(veml3235_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &veml3235_info; + + veml3235_read_id(data); + + ret = veml3235_hw_init(indio_dev); + if (ret < 0) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static int veml3235_runtime_suspend(struct device *dev) +{ + struct veml3235_data *data = iio_priv(dev_get_drvdata(dev)); + int ret; + + ret = veml3235_shut_down(data); + if (ret < 0) + dev_err(data->dev, "failed to suspend: %d\n", ret); + + return ret; +} + +static int veml3235_runtime_resume(struct device *dev) +{ + struct veml3235_data *data = iio_priv(dev_get_drvdata(dev)); + int ret; + + ret = veml3235_power_on(data); + if (ret < 0) + dev_err(data->dev, "failed to resume: %d\n", ret); + + return ret; +} + +static DEFINE_RUNTIME_DEV_PM_OPS(veml3235_pm_ops, veml3235_runtime_suspend, + veml3235_runtime_resume, NULL); + +static const struct of_device_id veml3235_of_match[] = { + { .compatible = "vishay,veml3235" }, + { } +}; +MODULE_DEVICE_TABLE(of, veml3235_of_match); + +static const struct i2c_device_id veml3235_id[] = { + { "veml3235" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, veml3235_id); + +static struct i2c_driver veml3235_driver = { + .driver = { + .name = "veml3235", + .of_match_table = veml3235_of_match, + .pm = pm_ptr(&veml3235_pm_ops), + }, + .probe = veml3235_probe, + .id_table = veml3235_id, +}; +module_i2c_driver(veml3235_driver); + +MODULE_AUTHOR("Javier Carrasco "); +MODULE_DESCRIPTION("VEML3235 Ambient Light Sensor"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c index 621428885455c0591b93411fe146d7b5ec92357b..ccb43dfd5cf782fe9cd99f022732a65741a034e2 100644 --- a/drivers/iio/light/veml6030.c +++ b/drivers/iio/light/veml6030.c @@ -1,19 +1,30 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * VEML6030 Ambient Light Sensor + * VEML6030, VMEL6035 and VEML7700 Ambient Light Sensors * * Copyright (c) 2019, Rishi Gupta * + * VEML6030: * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf * Appnote-84367: https://www.vishay.com/docs/84367/designingveml6030.pdf + * + * VEML6035: + * Datasheet: https://www.vishay.com/docs/84889/veml6035.pdf + * Appnote-84944: https://www.vishay.com/docs/84944/designingveml6035.pdf + * + * VEML7700: + * Datasheet: https://www.vishay.com/docs/84286/veml7700.pdf + * Appnote-84323: https://www.vishay.com/docs/84323/designingveml7700.pdf */ +#include #include #include #include #include #include #include +#include #include #include #include @@ -38,16 +49,35 @@ #define VEML6030_ALS_INT_EN BIT(1) #define VEML6030_ALS_SD BIT(0) +#define VEML6035_GAIN_M GENMASK(12, 10) +#define VEML6035_GAIN BIT(10) +#define VEML6035_DG BIT(11) +#define VEML6035_SENS BIT(12) +#define VEML6035_INT_CHAN BIT(3) +#define VEML6035_CHAN_EN BIT(2) + +struct veml603x_chip { + const char *name; + const int(*scale_vals)[][2]; + const int num_scale_vals; + const struct iio_chan_spec *channels; + const int num_channels; + int (*hw_init)(struct iio_dev *indio_dev, struct device *dev); + int (*set_info)(struct iio_dev *indio_dev); + int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2); + int (*get_als_gain)(struct iio_dev *indio_dev, int *val, int *val2); +}; + /* * The resolution depends on both gain and integration time. The * cur_resolution stores one of the resolution mentioned in the * table during startup and gets updated whenever integration time * or gain is changed. * - * Table 'resolution and maximum detection range' in appnote 84367 + * Table 'resolution and maximum detection range' in the appnotes * is visualized as a 2D array. The cur_gain stores index of gain - * in this table (0-3) while the cur_integration_time holds index - * of integration time (0-5). + * in this table (0-3 for VEML6030, 0-5 for VEML6035) while the + * cur_integration_time holds index of integration time (0-5). */ struct veml6030_data { struct i2c_client *client; @@ -55,27 +85,37 @@ struct veml6030_data { int cur_resolution; int cur_gain; int cur_integration_time; + const struct veml603x_chip *chip; }; -/* Integration time available in seconds */ -static IIO_CONST_ATTR(in_illuminance_integration_time_available, - "0.025 0.05 0.1 0.2 0.4 0.8"); +static const int veml6030_it_times[][2] = { + { 0, 25000 }, + { 0, 50000 }, + { 0, 100000 }, + { 0, 200000 }, + { 0, 400000 }, + { 0, 800000 }, +}; /* * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is - * ALS gain x (1/4), 1.0 = ALS gain x 1 and 2.0 is ALS gain x 2. + * ALS gain x (1/4), 0.5 is ALS gain x (1/2), 1.0 is ALS gain x 1, + * 2.0 is ALS gain x2, and 4.0 is ALS gain x 4. */ -static IIO_CONST_ATTR(in_illuminance_scale_available, - "0.125 0.25 1.0 2.0"); - -static struct attribute *veml6030_attributes[] = { - &iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr, - &iio_const_attr_in_illuminance_scale_available.dev_attr.attr, - NULL +static const int veml6030_scale_vals[][2] = { + { 0, 125000 }, + { 0, 250000 }, + { 1, 0 }, + { 2, 0 }, }; -static const struct attribute_group veml6030_attr_group = { - .attrs = veml6030_attributes, +static const int veml6035_scale_vals[][2] = { + { 0, 125000 }, + { 0, 250000 }, + { 0, 500000 }, + { 1, 0 }, + { 2, 0 }, + { 4, 0 }, }; /* @@ -143,14 +183,23 @@ static const struct attribute_group veml6030_event_attr_group = { static int veml6030_als_pwr_on(struct veml6030_data *data) { - return regmap_clear_bits(data->regmap, VEML6030_REG_ALS_CONF, - VEML6030_ALS_SD); + int ret; + + ret = regmap_clear_bits(data->regmap, VEML6030_REG_ALS_CONF, + VEML6030_ALS_SD); + if (ret) + return ret; + + /* Wait 4 ms to let processor & oscillator start correctly */ + fsleep(4000); + + return 0; } static int veml6030_als_shut_down(struct veml6030_data *data) { - return regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF, - VEML6030_ALS_SD, 1); + return regmap_set_bits(data->regmap, VEML6030_REG_ALS_CONF, + VEML6030_ALS_SD); } static void veml6030_als_shut_down_action(void *data) @@ -189,6 +238,8 @@ static const struct iio_chan_spec veml6030_channels[] = { BIT(IIO_CHAN_INFO_PROCESSED) | BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), .event_spec = veml6030_event_spec, .num_event_specs = ARRAY_SIZE(veml6030_event_spec), }, @@ -198,7 +249,34 @@ static const struct iio_chan_spec veml6030_channels[] = { .modified = 1, .channel2 = IIO_MOD_LIGHT_BOTH, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_PROCESSED), + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static const struct iio_chan_spec veml7700_channels[] = { + { + .type = IIO_LIGHT, + .channel = CH_ALS, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + }, + { + .type = IIO_INTENSITY, + .channel = CH_WHITE, + .modified = 1, + .channel2 = IIO_MOD_LIGHT_BOTH, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | + BIT(IIO_CHAN_INFO_SCALE), }, }; @@ -371,6 +449,21 @@ static int veml6030_write_persistence(struct iio_dev *indio_dev, return ret; } +/* + * Cache currently set gain & update resolution. For every + * increase in the gain to next level, resolution is halved + * and vice-versa. + */ +static void veml6030_update_gain_res(struct veml6030_data *data, int gain_idx) +{ + if (data->cur_gain < gain_idx) + data->cur_resolution <<= gain_idx - data->cur_gain; + else if (data->cur_gain > gain_idx) + data->cur_resolution >>= data->cur_gain - gain_idx; + + data->cur_gain = gain_idx; +} + static int veml6030_set_als_gain(struct iio_dev *indio_dev, int val, int val2) { @@ -401,19 +494,49 @@ static int veml6030_set_als_gain(struct iio_dev *indio_dev, return ret; } - /* - * Cache currently set gain & update resolution. For every - * increase in the gain to next level, resolution is halved - * and vice-versa. - */ - if (data->cur_gain < gain_idx) - data->cur_resolution <<= gain_idx - data->cur_gain; - else if (data->cur_gain > gain_idx) - data->cur_resolution >>= data->cur_gain - gain_idx; + veml6030_update_gain_res(data, gain_idx); - data->cur_gain = gain_idx; + return 0; +} - return ret; +static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2) +{ + int ret, new_gain, gain_idx; + struct veml6030_data *data = iio_priv(indio_dev); + + if (val == 0 && val2 == 125000) { + new_gain = VEML6035_SENS; + gain_idx = 5; + } else if (val == 0 && val2 == 250000) { + new_gain = VEML6035_SENS | VEML6035_GAIN; + gain_idx = 4; + } else if (val == 0 && val2 == 500000) { + new_gain = VEML6035_SENS | VEML6035_GAIN | + VEML6035_DG; + gain_idx = 3; + } else if (val == 1 && val2 == 0) { + new_gain = 0x0000; + gain_idx = 2; + } else if (val == 2 && val2 == 0) { + new_gain = VEML6035_GAIN; + gain_idx = 1; + } else if (val == 4 && val2 == 0) { + new_gain = VEML6035_GAIN | VEML6035_DG; + gain_idx = 0; + } else { + return -EINVAL; + } + + ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF, + VEML6035_GAIN_M, new_gain); + if (ret) { + dev_err(&data->client->dev, "can't set als gain %d\n", ret); + return ret; + } + + veml6030_update_gain_res(data, gain_idx); + + return 0; } static int veml6030_get_als_gain(struct iio_dev *indio_dev, @@ -453,6 +576,52 @@ static int veml6030_get_als_gain(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; } +static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2) +{ + int ret, reg; + struct veml6030_data *data = iio_priv(indio_dev); + + ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); + if (ret) { + dev_err(&data->client->dev, + "can't read als conf register %d\n", ret); + return ret; + } + + switch (FIELD_GET(VEML6035_GAIN_M, reg)) { + case 0: + *val = 1; + *val2 = 0; + break; + case 1: + case 2: + *val = 2; + *val2 = 0; + break; + case 3: + *val = 4; + *val2 = 0; + break; + case 4: + *val = 0; + *val2 = 125000; + break; + case 5: + case 6: + *val = 0; + *val2 = 250000; + break; + case 7: + *val = 0; + *val2 = 500000; + break; + default: + return -EINVAL; + } + + return IIO_VAL_INT_PLUS_MICRO; +} + static int veml6030_read_thresh(struct iio_dev *indio_dev, int *val, int *val2, int dir) { @@ -533,48 +702,54 @@ static int veml6030_read_raw(struct iio_dev *indio_dev, dev_err(dev, "can't read white data %d\n", ret); return ret; } - if (mask == IIO_CHAN_INFO_PROCESSED) { - *val = (reg * data->cur_resolution) / 10000; - *val2 = (reg * data->cur_resolution) % 10000; - return IIO_VAL_INT_PLUS_MICRO; - } *val = reg; return IIO_VAL_INT; default: return -EINVAL; } case IIO_CHAN_INFO_INT_TIME: - if (chan->type == IIO_LIGHT) - return veml6030_get_intgrn_tm(indio_dev, val, val2); - return -EINVAL; + return veml6030_get_intgrn_tm(indio_dev, val, val2); case IIO_CHAN_INFO_SCALE: - if (chan->type == IIO_LIGHT) - return veml6030_get_als_gain(indio_dev, val, val2); - return -EINVAL; + return data->chip->get_als_gain(indio_dev, val, val2); default: return -EINVAL; } } +static int veml6030_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct veml6030_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + *vals = (int *)&veml6030_it_times; + *length = 2 * ARRAY_SIZE(veml6030_it_times); + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *vals = (int *)*data->chip->scale_vals; + *length = 2 * data->chip->num_scale_vals; + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + } + + return -EINVAL; +} + static int veml6030_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { + struct veml6030_data *data = iio_priv(indio_dev); + switch (mask) { case IIO_CHAN_INFO_INT_TIME: - switch (chan->type) { - case IIO_LIGHT: - return veml6030_set_intgrn_tm(indio_dev, val, val2); - default: - return -EINVAL; - } + return veml6030_set_intgrn_tm(indio_dev, val, val2); case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_LIGHT: - return veml6030_set_als_gain(indio_dev, val, val2); - default: - return -EINVAL; - } + return data->chip->set_als_gain(indio_dev, val, val2); default: return -EINVAL; } @@ -646,14 +821,11 @@ static int veml6030_read_interrupt_config(struct iio_dev *indio_dev, */ static int veml6030_write_interrupt_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { int ret; struct veml6030_data *data = iio_priv(indio_dev); - if (state < 0 || state > 1) - return -EINVAL; - ret = veml6030_als_shut_down(data); if (ret < 0) { dev_err(&data->client->dev, @@ -673,19 +845,19 @@ static int veml6030_write_interrupt_config(struct iio_dev *indio_dev, static const struct iio_info veml6030_info = { .read_raw = veml6030_read_raw, + .read_avail = veml6030_read_avail, .write_raw = veml6030_write_raw, .read_event_value = veml6030_read_event_val, .write_event_value = veml6030_write_event_val, .read_event_config = veml6030_read_interrupt_config, .write_event_config = veml6030_write_interrupt_config, - .attrs = &veml6030_attr_group, .event_attrs = &veml6030_event_attr_group, }; static const struct iio_info veml6030_info_no_irq = { .read_raw = veml6030_read_raw, + .read_avail = veml6030_read_avail, .write_raw = veml6030_write_raw, - .attrs = &veml6030_attr_group, }; static irqreturn_t veml6030_event_handler(int irq, void *private) @@ -717,65 +889,82 @@ static irqreturn_t veml6030_event_handler(int irq, void *private) return IRQ_HANDLED; } +static int veml6030_set_info(struct iio_dev *indio_dev) +{ + struct veml6030_data *data = iio_priv(indio_dev); + struct i2c_client *client = data->client; + int ret; + + if (client->irq) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, veml6030_event_handler, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret < 0) + return dev_err_probe(&client->dev, ret, + "irq %d request failed\n", + client->irq); + + indio_dev->info = &veml6030_info; + } else { + indio_dev->info = &veml6030_info_no_irq; + } + + return 0; +} + +static int veml7700_set_info(struct iio_dev *indio_dev) +{ + indio_dev->info = &veml6030_info_no_irq; + + return 0; +} + /* * Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2, * persistence to 1 x integration time and the threshold * interrupt disabled by default. First shutdown the sensor, * update registers and then power on the sensor. */ -static int veml6030_hw_init(struct iio_dev *indio_dev) +static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev) { int ret, val; struct veml6030_data *data = iio_priv(indio_dev); - struct i2c_client *client = data->client; ret = veml6030_als_shut_down(data); - if (ret) { - dev_err(&client->dev, "can't shutdown als %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "can't shutdown als\n"); ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001); - if (ret) { - dev_err(&client->dev, "can't setup als configs %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "can't setup als configs\n"); ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_PSM, VEML6030_PSM | VEML6030_PSM_EN, 0x03); - if (ret) { - dev_err(&client->dev, "can't setup default PSM %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "can't setup default PSM\n"); ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, 0xFFFF); - if (ret) { - dev_err(&client->dev, "can't setup high threshold %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "can't setup high threshold\n"); ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, 0x0000); - if (ret) { - dev_err(&client->dev, "can't setup low threshold %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "can't setup low threshold\n"); ret = veml6030_als_pwr_on(data); - if (ret) { - dev_err(&client->dev, "can't poweron als %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "can't poweron als\n"); - /* Wait 4 ms to let processor & oscillator start correctly */ - usleep_range(4000, 4002); + ret = devm_add_action_or_reset(dev, veml6030_als_shut_down_action, data); + if (ret < 0) + return ret; /* Clear stale interrupt status bits if any during start */ ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val); - if (ret < 0) { - dev_err(&client->dev, - "can't clear als interrupt status %d\n", ret); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, + "can't clear als interrupt status\n"); /* Cache currently active measurement parameters */ data->cur_gain = 3; @@ -785,6 +974,62 @@ static int veml6030_hw_init(struct iio_dev *indio_dev) return ret; } +/* + * Set ALS gain to 1/8, integration time to 100 ms, ALS and WHITE + * channel enabled, ALS channel interrupt, PSM enabled, + * PSM_WAIT = 0.8 s, persistence to 1 x integration time and the + * threshold interrupt disabled by default. First shutdown the sensor, + * update registers and then power on the sensor. + */ +static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev) +{ + int ret, val; + struct veml6030_data *data = iio_priv(indio_dev); + + ret = veml6030_als_shut_down(data); + if (ret) + return dev_err_probe(dev, ret, "can't shutdown als\n"); + + ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, + VEML6035_SENS | VEML6035_CHAN_EN | VEML6030_ALS_SD); + if (ret) + return dev_err_probe(dev, ret, "can't setup als configs\n"); + + ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_PSM, + VEML6030_PSM | VEML6030_PSM_EN, 0x03); + if (ret) + return dev_err_probe(dev, ret, "can't setup default PSM\n"); + + ret = regmap_write(data->regmap, VEML6030_REG_ALS_WH, 0xFFFF); + if (ret) + return dev_err_probe(dev, ret, "can't setup high threshold\n"); + + ret = regmap_write(data->regmap, VEML6030_REG_ALS_WL, 0x0000); + if (ret) + return dev_err_probe(dev, ret, "can't setup low threshold\n"); + + ret = veml6030_als_pwr_on(data); + if (ret) + return dev_err_probe(dev, ret, "can't poweron als\n"); + + ret = devm_add_action_or_reset(dev, veml6030_als_shut_down_action, data); + if (ret < 0) + return ret; + + /* Clear stale interrupt status bits if any during start */ + ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val); + if (ret < 0) + return dev_err_probe(dev, ret, + "can't clear als interrupt status\n"); + + /* Cache currently active measurement parameters */ + data->cur_gain = 5; + data->cur_resolution = 1024; + data->cur_integration_time = 3; + + return 0; +} + static int veml6030_probe(struct i2c_client *client) { int ret; @@ -792,16 +1037,14 @@ static int veml6030_probe(struct i2c_client *client) struct iio_dev *indio_dev; struct regmap *regmap; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "i2c adapter doesn't support plain i2c\n"); - return -EOPNOTSUPP; - } + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return dev_err_probe(&client->dev, -EOPNOTSUPP, + "i2c adapter doesn't support plain i2c\n"); regmap = devm_regmap_init_i2c(client, &veml6030_regmap_config); - if (IS_ERR(regmap)) { - dev_err(&client->dev, "can't setup regmap\n"); - return PTR_ERR(regmap); - } + if (IS_ERR(regmap)) + return dev_err_probe(&client->dev, PTR_ERR(regmap), + "can't setup regmap\n"); indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) @@ -812,32 +1055,25 @@ static int veml6030_probe(struct i2c_client *client) data->client = client; data->regmap = regmap; - indio_dev->name = "veml6030"; - indio_dev->channels = veml6030_channels; - indio_dev->num_channels = ARRAY_SIZE(veml6030_channels); - indio_dev->modes = INDIO_DIRECT_MODE; + ret = devm_regulator_get_enable(&client->dev, "vdd"); + if (ret) + return dev_err_probe(&client->dev, ret, + "failed to enable regulator\n"); - if (client->irq) { - ret = devm_request_threaded_irq(&client->dev, client->irq, - NULL, veml6030_event_handler, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "veml6030", indio_dev); - if (ret < 0) { - dev_err(&client->dev, - "irq %d request failed\n", client->irq); - return ret; - } - indio_dev->info = &veml6030_info; - } else { - indio_dev->info = &veml6030_info_no_irq; - } + data->chip = i2c_get_match_data(client); + if (!data->chip) + return -EINVAL; + + indio_dev->name = data->chip->name; + indio_dev->channels = data->chip->channels; + indio_dev->num_channels = data->chip->num_channels; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = veml6030_hw_init(indio_dev); + ret = data->chip->set_info(indio_dev); if (ret < 0) return ret; - ret = devm_add_action_or_reset(&client->dev, - veml6030_als_shut_down_action, data); + ret = data->chip->hw_init(indio_dev, &client->dev); if (ret < 0) return ret; @@ -873,14 +1109,63 @@ static int veml6030_runtime_resume(struct device *dev) static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend, veml6030_runtime_resume, NULL); +static const struct veml603x_chip veml6030_chip = { + .name = "veml6030", + .scale_vals = &veml6030_scale_vals, + .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals), + .channels = veml6030_channels, + .num_channels = ARRAY_SIZE(veml6030_channels), + .hw_init = veml6030_hw_init, + .set_info = veml6030_set_info, + .set_als_gain = veml6030_set_als_gain, + .get_als_gain = veml6030_get_als_gain, +}; + +static const struct veml603x_chip veml6035_chip = { + .name = "veml6035", + .scale_vals = &veml6035_scale_vals, + .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals), + .channels = veml6030_channels, + .num_channels = ARRAY_SIZE(veml6030_channels), + .hw_init = veml6035_hw_init, + .set_info = veml6030_set_info, + .set_als_gain = veml6035_set_als_gain, + .get_als_gain = veml6035_get_als_gain, +}; + +static const struct veml603x_chip veml7700_chip = { + .name = "veml7700", + .scale_vals = &veml6030_scale_vals, + .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals), + .channels = veml7700_channels, + .num_channels = ARRAY_SIZE(veml7700_channels), + .hw_init = veml6030_hw_init, + .set_info = veml7700_set_info, + .set_als_gain = veml6030_set_als_gain, + .get_als_gain = veml6030_get_als_gain, +}; + static const struct of_device_id veml6030_of_match[] = { - { .compatible = "vishay,veml6030" }, + { + .compatible = "vishay,veml6030", + .data = &veml6030_chip, + }, + { + .compatible = "vishay,veml6035", + .data = &veml6035_chip, + }, + { + .compatible = "vishay,veml7700", + .data = &veml7700_chip, + }, { } }; MODULE_DEVICE_TABLE(of, veml6030_of_match); static const struct i2c_device_id veml6030_id[] = { - { "veml6030" }, + { "veml6030", (kernel_ulong_t)&veml6030_chip}, + { "veml6035", (kernel_ulong_t)&veml6035_chip}, + { "veml7700", (kernel_ulong_t)&veml7700_chip}, { } }; MODULE_DEVICE_TABLE(i2c, veml6030_id); diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c index f8321d346d7757b2264d2cddc35e96518a6cac15..6d4483c85f30cfe7bf8834ee8d4604ffa2af4b25 100644 --- a/drivers/iio/light/veml6070.c +++ b/drivers/iio/light/veml6070.c @@ -6,14 +6,16 @@ * * IIO driver for VEML6070 (7-bit I2C slave addresses 0x38 and 0x39) * - * TODO: integration time, ACK signal + * TODO: ACK signal */ +#include #include #include #include #include #include +#include #include #include @@ -28,50 +30,113 @@ #define VEML6070_COMMAND_RSRVD BIT(1) /* reserved, set to 1 */ #define VEML6070_COMMAND_SD BIT(0) /* shutdown mode when set */ -#define VEML6070_IT_10 0x04 /* integration time 1x */ +#define VEML6070_IT_05 0x00 +#define VEML6070_IT_10 0x01 +#define VEML6070_IT_20 0x02 +#define VEML6070_IT_40 0x03 + +#define VEML6070_MIN_RSET_KOHM 75 +#define VEML6070_MIN_IT_US 15625 /* Rset = 75 kohm, IT = 1/2 */ struct veml6070_data { struct i2c_client *client1; struct i2c_client *client2; u8 config; struct mutex lock; + u32 rset; + int it[4][2]; }; +static int veml6070_calc_it(struct device *dev, struct veml6070_data *data) +{ + int i, tmp_it; + + data->rset = 270000; + device_property_read_u32(dev, "vishay,rset-ohms", &data->rset); + + if (data->rset < 75000 || data->rset > 1200000) + return dev_err_probe(dev, -EINVAL, "Rset out of range\n"); + + /* + * convert to kohm to avoid overflows and work with the same units as + * in the datasheet and simplify UVI operations. + */ + data->rset /= KILO; + + tmp_it = VEML6070_MIN_IT_US * data->rset / VEML6070_MIN_RSET_KOHM; + for (i = 0; i < ARRAY_SIZE(data->it); i++) { + data->it[i][0] = (tmp_it << i) / MICRO; + data->it[i][1] = (tmp_it << i) % MICRO; + } + + return 0; +} + +static int veml6070_get_it(struct veml6070_data *data, int *val, int *val2) +{ + int it_idx = FIELD_GET(VEML6070_COMMAND_IT, data->config); + + *val = data->it[it_idx][0]; + *val2 = data->it[it_idx][1]; + + return IIO_VAL_INT_PLUS_MICRO; +} + +static int veml6070_set_it(struct veml6070_data *data, int val, int val2) +{ + int it_idx; + + for (it_idx = 0; it_idx < ARRAY_SIZE(data->it); it_idx++) { + if (data->it[it_idx][0] == val && data->it[it_idx][1] == val2) + break; + } + + if (it_idx >= ARRAY_SIZE(data->it)) + return -EINVAL; + + data->config = (data->config & ~VEML6070_COMMAND_IT) | + FIELD_PREP(VEML6070_COMMAND_IT, it_idx); + + return i2c_smbus_write_byte(data->client1, data->config); +} + static int veml6070_read(struct veml6070_data *data) { - int ret; + int ret, it_ms, val, val2; u8 msb, lsb; - mutex_lock(&data->lock); + guard(mutex)(&data->lock); /* disable shutdown */ ret = i2c_smbus_write_byte(data->client1, data->config & ~VEML6070_COMMAND_SD); if (ret < 0) - goto out; + return ret; - msleep(125 + 10); /* measurement takes up to 125 ms for IT 1x */ + veml6070_get_it(data, &val, &val2); + it_ms = val * MILLI + val2 / (MICRO / MILLI); + msleep(it_ms + 10); ret = i2c_smbus_read_byte(data->client2); /* read MSB, address 0x39 */ if (ret < 0) - goto out; + return ret; + msb = ret; ret = i2c_smbus_read_byte(data->client1); /* read LSB, address 0x38 */ if (ret < 0) - goto out; + return ret; + lsb = ret; /* shutdown again */ ret = i2c_smbus_write_byte(data->client1, data->config); if (ret < 0) - goto out; + return ret; ret = (msb << 8) | lsb; -out: - mutex_unlock(&data->lock); - return ret; + return 0; } static const struct iio_chan_spec veml6070_channels[] = { @@ -80,26 +145,37 @@ static const struct iio_chan_spec veml6070_channels[] = { .modified = 1, .channel2 = IIO_MOD_LIGHT_UV, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME), }, { .type = IIO_UVINDEX, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME), } }; -static int veml6070_to_uv_index(unsigned val) +static int veml6070_to_uv_index(struct veml6070_data *data, unsigned int val) { /* * conversion of raw UV intensity values to UV index depends on * integration time (IT) and value of the resistor connected to - * the RSET pin (default: 270 KOhm) + * the RSET pin. */ - unsigned uvi[11] = { + unsigned int uvi[11] = { 187, 373, 560, /* low */ 746, 933, 1120, /* moderate */ 1308, 1494, /* high */ 1681, 1868, 2054}; /* very high */ - int i; + int i, it_idx; + + it_idx = FIELD_GET(VEML6070_COMMAND_IT, data->config); + + if (!it_idx) + val = (val * 270 / data->rset) << 1; + else + val = (val * 270 / data->rset) >> (it_idx - 1); for (i = 0; i < ARRAY_SIZE(uvi); i++) if (val <= uvi[i]) @@ -122,10 +198,44 @@ static int veml6070_read_raw(struct iio_dev *indio_dev, if (ret < 0) return ret; if (mask == IIO_CHAN_INFO_PROCESSED) - *val = veml6070_to_uv_index(ret); + *val = veml6070_to_uv_index(data, ret); else *val = ret; return IIO_VAL_INT; + case IIO_CHAN_INFO_INT_TIME: + return veml6070_get_it(data, val, val2); + default: + return -EINVAL; + } +} + +static int veml6070_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct veml6070_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + *vals = (int *)data->it; + *length = 2 * ARRAY_SIZE(data->it); + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int veml6070_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct veml6070_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + return veml6070_set_it(data, val, val2); default: return -EINVAL; } @@ -133,8 +243,17 @@ static int veml6070_read_raw(struct iio_dev *indio_dev, static const struct iio_info veml6070_info = { .read_raw = veml6070_read_raw, + .read_avail = veml6070_read_avail, + .write_raw = veml6070_write_raw, }; +static void veml6070_i2c_unreg(void *p) +{ + struct veml6070_data *data = p; + + i2c_unregister_device(data->client2); +} + static int veml6070_probe(struct i2c_client *client) { struct veml6070_data *data; @@ -156,36 +275,30 @@ static int veml6070_probe(struct i2c_client *client) indio_dev->name = VEML6070_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB); - if (IS_ERR(data->client2)) { - dev_err(&client->dev, "i2c device for second chip address failed\n"); - return PTR_ERR(data->client2); - } - - data->config = VEML6070_IT_10 | VEML6070_COMMAND_RSRVD | - VEML6070_COMMAND_SD; - ret = i2c_smbus_write_byte(data->client1, data->config); + ret = veml6070_calc_it(&client->dev, data); if (ret < 0) - goto fail; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_regulator_get_enable(&client->dev, "vdd"); if (ret < 0) - goto fail; + return ret; - return ret; + data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB); + if (IS_ERR(data->client2)) + return dev_err_probe(&client->dev, PTR_ERR(data->client2), + "i2c device for second chip address failed\n"); -fail: - i2c_unregister_device(data->client2); - return ret; -} + data->config = FIELD_PREP(VEML6070_COMMAND_IT, VEML6070_IT_10) | + VEML6070_COMMAND_RSRVD | VEML6070_COMMAND_SD; + ret = i2c_smbus_write_byte(data->client1, data->config); + if (ret < 0) + return ret; -static void veml6070_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct veml6070_data *data = iio_priv(indio_dev); + ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data); + if (ret < 0) + return ret; - iio_device_unregister(indio_dev); - i2c_unregister_device(data->client2); + return devm_iio_device_register(&client->dev, indio_dev); } static const struct i2c_device_id veml6070_id[] = { @@ -194,12 +307,18 @@ static const struct i2c_device_id veml6070_id[] = { }; MODULE_DEVICE_TABLE(i2c, veml6070_id); +static const struct of_device_id veml6070_of_match[] = { + { .compatible = "vishay,veml6070" }, + { } +}; +MODULE_DEVICE_TABLE(of, veml6070_of_match); + static struct i2c_driver veml6070_driver = { .driver = { .name = VEML6070_DRV_NAME, + .of_match_table = veml6070_of_match, }, .probe = veml6070_probe, - .remove = veml6070_remove, .id_table = veml6070_id, }; diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c index a1b2b3c0b4c8895e0e2e07412194978998735441..6e2183a4243e55b95840cf2e0f0069b3b6e11502 100644 --- a/drivers/iio/light/vl6180.c +++ b/drivers/iio/light/vl6180.c @@ -25,6 +25,10 @@ #include #include +#include +#include +#include +#include #define VL6180_DRV_NAME "vl6180" @@ -38,7 +42,9 @@ #define VL6180_OUT_OF_RESET 0x016 #define VL6180_HOLD 0x017 #define VL6180_RANGE_START 0x018 +#define VL6180_RANGE_INTER_MEAS_TIME 0x01b #define VL6180_ALS_START 0x038 +#define VL6180_ALS_INTER_MEAS_TIME 0x03e #define VL6180_ALS_GAIN 0x03f #define VL6180_ALS_IT 0x040 @@ -84,8 +90,17 @@ struct vl6180_data { struct i2c_client *client; struct mutex lock; + struct completion completion; + struct iio_trigger *trig; unsigned int als_gain_milli; unsigned int als_it_ms; + unsigned int als_meas_rate; + unsigned int range_meas_rate; + + struct { + u16 chan[2]; + aligned_s64 timestamp; + } scan; }; enum { VL6180_ALS, VL6180_RANGE, VL6180_PROX }; @@ -207,29 +222,40 @@ static int vl6180_write_word(struct i2c_client *client, u16 cmd, u16 val) static int vl6180_measure(struct vl6180_data *data, int addr) { struct i2c_client *client = data->client; + unsigned long time_left; int tries = 20, ret; u16 value; mutex_lock(&data->lock); + reinit_completion(&data->completion); + /* Start single shot measurement */ ret = vl6180_write_byte(client, vl6180_chan_regs_table[addr].start_reg, VL6180_STARTSTOP); if (ret < 0) goto fail; - while (tries--) { - ret = vl6180_read_byte(client, VL6180_INTR_STATUS); - if (ret < 0) + if (client->irq) { + time_left = wait_for_completion_timeout(&data->completion, HZ / 10); + if (time_left == 0) { + ret = -ETIMEDOUT; goto fail; + } + } else { + while (tries--) { + ret = vl6180_read_byte(client, VL6180_INTR_STATUS); + if (ret < 0) + goto fail; + + if (ret & vl6180_chan_regs_table[addr].drdy_mask) + break; + msleep(20); + } - if (ret & vl6180_chan_regs_table[addr].drdy_mask) - break; - msleep(20); - } - - if (tries < 0) { - ret = -EIO; - goto fail; + if (tries < 0) { + ret = -EIO; + goto fail; + } } /* Read result value from appropriate registers */ @@ -258,20 +284,41 @@ static const struct iio_chan_spec vl6180_channels[] = { { .type = IIO_LIGHT, .address = VL6180_ALS, + .scan_index = VL6180_ALS, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + }, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SCALE) | - BIT(IIO_CHAN_INFO_HARDWAREGAIN), + BIT(IIO_CHAN_INFO_HARDWAREGAIN) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_DISTANCE, .address = VL6180_RANGE, + .scan_index = VL6180_RANGE, + .scan_type = { + .sign = 'u', + .realbits = 8, + .storagebits = 8, + }, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SCALE), + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_PROXIMITY, .address = VL6180_PROX, + .scan_index = VL6180_PROX, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + }, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - } + }, + IIO_CHAN_SOFT_TIMESTAMP(3), }; /* @@ -333,6 +380,18 @@ static int vl6180_read_raw(struct iio_dev *indio_dev, return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_SAMP_FREQ: + switch (chan->type) { + case IIO_DISTANCE: + *val = data->range_meas_rate; + return IIO_VAL_INT; + case IIO_LIGHT: + *val = data->als_meas_rate; + return IIO_VAL_INT; + default: + return -EINVAL; + } + default: return -EINVAL; } @@ -412,11 +471,23 @@ fail: return ret; } +static int vl6180_meas_reg_val_from_mhz(unsigned int mhz) +{ + unsigned int period = DIV_ROUND_CLOSEST(1000 * 1000, mhz); + unsigned int reg_val = 0; + + if (period > 10) + reg_val = period < 2550 ? (DIV_ROUND_CLOSEST(period, 10) - 1) : 254; + + return reg_val; +} + static int vl6180_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { struct vl6180_data *data = iio_priv(indio_dev); + unsigned int reg_val; switch (mask) { case IIO_CHAN_INFO_INT_TIME: @@ -427,18 +498,126 @@ static int vl6180_write_raw(struct iio_dev *indio_dev, return -EINVAL; return vl6180_set_als_gain(data, val, val2); + + case IIO_CHAN_INFO_SAMP_FREQ: + { + guard(mutex)(&data->lock); + switch (chan->type) { + case IIO_DISTANCE: + data->range_meas_rate = val; + reg_val = vl6180_meas_reg_val_from_mhz(val); + return vl6180_write_byte(data->client, + VL6180_RANGE_INTER_MEAS_TIME, reg_val); + + case IIO_LIGHT: + data->als_meas_rate = val; + reg_val = vl6180_meas_reg_val_from_mhz(val); + return vl6180_write_byte(data->client, + VL6180_ALS_INTER_MEAS_TIME, reg_val); + + default: + return -EINVAL; + } + } + default: return -EINVAL; } } +static irqreturn_t vl6180_threaded_irq(int irq, void *priv) +{ + struct iio_dev *indio_dev = priv; + struct vl6180_data *data = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev)) + iio_trigger_poll_nested(indio_dev->trig); + else + complete(&data->completion); + + return IRQ_HANDLED; +} + +static irqreturn_t vl6180_trigger_handler(int irq, void *priv) +{ + struct iio_poll_func *pf = priv; + struct iio_dev *indio_dev = pf->indio_dev; + struct vl6180_data *data = iio_priv(indio_dev); + s64 time_ns = iio_get_time_ns(indio_dev); + int ret, bit, i = 0; + + iio_for_each_active_channel(indio_dev, bit) { + if (vl6180_chan_regs_table[bit].word) + ret = vl6180_read_word(data->client, + vl6180_chan_regs_table[bit].value_reg); + else + ret = vl6180_read_byte(data->client, + vl6180_chan_regs_table[bit].value_reg); + + if (ret < 0) { + dev_err(&data->client->dev, + "failed to read from value regs: %d\n", ret); + return IRQ_HANDLED; + } + + data->scan.chan[i++] = ret; + } + + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, time_ns); + iio_trigger_notify_done(indio_dev->trig); + + /* Clear the interrupt flag after data read */ + ret = vl6180_write_byte(data->client, VL6180_INTR_CLEAR, + VL6180_CLEAR_ERROR | VL6180_CLEAR_ALS | VL6180_CLEAR_RANGE); + if (ret < 0) + dev_err(&data->client->dev, "failed to clear irq: %d\n", ret); + + return IRQ_HANDLED; +} + static const struct iio_info vl6180_info = { .read_raw = vl6180_read_raw, .write_raw = vl6180_write_raw, .attrs = &vl6180_attribute_group, + .validate_trigger = iio_validate_own_trigger, +}; + +static int vl6180_buffer_postenable(struct iio_dev *indio_dev) +{ + struct vl6180_data *data = iio_priv(indio_dev); + int bit; + + iio_for_each_active_channel(indio_dev, bit) + return vl6180_write_byte(data->client, + vl6180_chan_regs_table[bit].start_reg, + VL6180_MODE_CONT | VL6180_STARTSTOP); + + return -EINVAL; +} + +static int vl6180_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct vl6180_data *data = iio_priv(indio_dev); + int bit; + + iio_for_each_active_channel(indio_dev, bit) + return vl6180_write_byte(data->client, + vl6180_chan_regs_table[bit].start_reg, + VL6180_STARTSTOP); + + return -EINVAL; +} + +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { + .postenable = &vl6180_buffer_postenable, + .postdisable = &vl6180_buffer_postdisable, +}; + +static const struct iio_trigger_ops vl6180_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, }; -static int vl6180_init(struct vl6180_data *data) +static int vl6180_init(struct vl6180_data *data, struct iio_dev *indio_dev) { struct i2c_client *client = data->client; int ret; @@ -473,6 +652,26 @@ static int vl6180_init(struct vl6180_data *data) if (ret < 0) return ret; + ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL, + &vl6180_trigger_handler, + &iio_triggered_buffer_setup_ops); + if (ret) + return ret; + + /* Default Range inter-measurement time: 50ms or 20000 mHz */ + ret = vl6180_write_byte(client, VL6180_RANGE_INTER_MEAS_TIME, + vl6180_meas_reg_val_from_mhz(20000)); + if (ret < 0) + return ret; + data->range_meas_rate = 20000; + + /* Default ALS inter-measurement time: 10ms or 100000 mHz */ + ret = vl6180_write_byte(client, VL6180_ALS_INTER_MEAS_TIME, + vl6180_meas_reg_val_from_mhz(100000)); + if (ret < 0) + return ret; + data->als_meas_rate = 100000; + /* ALS integration time: 100ms */ data->als_it_ms = 100; ret = vl6180_write_word(client, VL6180_ALS_IT, VL6180_ALS_IT_100); @@ -513,10 +712,34 @@ static int vl6180_probe(struct i2c_client *client) indio_dev->name = VL6180_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - ret = vl6180_init(data); + ret = vl6180_init(data, indio_dev); if (ret < 0) return ret; + if (client->irq) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, vl6180_threaded_irq, + IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return dev_err_probe(&client->dev, ret, "devm_request_irq error \n"); + + init_completion(&data->completion); + + data->trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", + indio_dev->name, iio_device_id(indio_dev)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops = &vl6180_trigger_ops; + iio_trigger_set_drvdata(data->trig, indio_dev); + ret = devm_iio_trigger_register(&client->dev, data->trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(data->trig); + } + return devm_iio_device_register(&client->dev, indio_dev); } diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig index f69ac75500f99422dec300fdc612294353bcd2bf..7177cd1d67cb2efc0ae9cef90f7c7e360d2fadba 100644 --- a/drivers/iio/magnetometer/Kconfig +++ b/drivers/iio/magnetometer/Kconfig @@ -54,6 +54,19 @@ config AK09911 help Deprecated: AK09911 is now supported by AK8975 driver. +config ALS31300 + tristate "Allegro MicroSystems ALS31300 3-D Linear Hall Effect Sensor" + depends on I2C + select REGMAP_I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for the Allegro MicroSystems + ALS31300 Hall Effect Sensor through its I2C interface. + + To compile this driver as a module, choose M here: the + module will be called als31300. + config BMC150_MAGN tristate select IIO_BUFFER diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile index ec5c46fbf999b6403593de2c425079cf69a29cac..3e4c2ecd9adf865025d169a0d1d5feffd012e2f3 100644 --- a/drivers/iio/magnetometer/Makefile +++ b/drivers/iio/magnetometer/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_AF8133J) += af8133j.o obj-$(CONFIG_AK8974) += ak8974.o obj-$(CONFIG_AK8975) += ak8975.o +obj-$(CONFIG_ALS31300) += als31300.o obj-$(CONFIG_BMC150_MAGN) += bmc150_magn.o obj-$(CONFIG_BMC150_MAGN_I2C) += bmc150_magn_i2c.o obj-$(CONFIG_BMC150_MAGN_SPI) += bmc150_magn_spi.o diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index 961b1e0bfb138d8a16dbcaa5ec6cc43d1b0cfd8b..8306a18706accf3e5b1e2b29514903b2682c9f39 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -910,7 +910,7 @@ static int ak8974_probe(struct i2c_client *i2c) /* If we have a valid DRDY IRQ, make use of it */ if (irq > 0) { - irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq)); + irq_trig = irq_get_trigger_type(irq); if (irq_trig == IRQF_TRIGGER_RISING) { dev_info(&i2c->dev, "enable rising edge DRDY IRQ\n"); } else if (irq_trig == IRQF_TRIGGER_FALLING) { diff --git a/drivers/iio/magnetometer/als31300.c b/drivers/iio/magnetometer/als31300.c new file mode 100644 index 0000000000000000000000000000000000000000..87b60c4e81fa1c9d8d6e8b083c5bcb605baf8ee9 --- /dev/null +++ b/drivers/iio/magnetometer/als31300.c @@ -0,0 +1,494 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for the Allegro MicroSystems ALS31300 3-D Linear Hall Effect Sensor + * + * Copyright (c) 2024 Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The Allegro MicroSystems ALS31300 has an EEPROM space to configure how + * the device works and how the interrupt line behaves. + * Only the default setup with external trigger is supported. + * + * While the bindings supports declaring an interrupt line, those + * events are not supported. + * + * It should be possible to adapt the driver to the current + * device EEPROM setup at runtime. + */ + +#define ALS31300_EEPROM_CONFIG 0x02 +#define ALS31300_EEPROM_INTERRUPT 0x03 +#define ALS31300_EEPROM_CUSTOMER_1 0x0d +#define ALS31300_EEPROM_CUSTOMER_2 0x0e +#define ALS31300_EEPROM_CUSTOMER_3 0x0f +#define ALS31300_VOL_MODE 0x27 +#define ALS31300_VOL_MODE_LPDCM GENMASK(6, 4) +#define ALS31300_LPDCM_INACTIVE_0_5_MS 0 +#define ALS31300_LPDCM_INACTIVE_1_0_MS 1 +#define ALS31300_LPDCM_INACTIVE_5_0_MS 2 +#define ALS31300_LPDCM_INACTIVE_10_0_MS 3 +#define ALS31300_LPDCM_INACTIVE_50_0_MS 4 +#define ALS31300_LPDCM_INACTIVE_100_0_MS 5 +#define ALS31300_LPDCM_INACTIVE_500_0_MS 6 +#define ALS31300_LPDCM_INACTIVE_1000_0_MS 7 +#define ALS31300_VOL_MODE_SLEEP GENMASK(1, 0) +#define ALS31300_VOL_MODE_ACTIVE_MODE 0 +#define ALS31300_VOL_MODE_SLEEP_MODE 1 +#define ALS31300_VOL_MODE_LPDCM_MODE 2 +#define ALS31300_VOL_MSB 0x28 +#define ALS31300_VOL_MSB_TEMPERATURE GENMASK(5, 0) +#define ALS31300_VOL_MSB_INTERRUPT BIT(6) +#define ALS31300_VOL_MSB_NEW_DATA BIT(7) +#define ALS31300_VOL_MSB_Z_AXIS GENMASK(15, 8) +#define ALS31300_VOL_MSB_Y_AXIS GENMASK(23, 16) +#define ALS31300_VOL_MSB_X_AXIS GENMASK(31, 24) +#define ALS31300_VOL_LSB 0x29 +#define ALS31300_VOL_LSB_TEMPERATURE GENMASK(5, 0) +#define ALS31300_VOL_LSB_HALL_STATUS GENMASK(7, 7) +#define ALS31300_VOL_LSB_Z_AXIS GENMASK(11, 8) +#define ALS31300_VOL_LSB_Y_AXIS GENMASK(15, 12) +#define ALS31300_VOL_LSB_X_AXIS GENMASK(19, 16) +#define ALS31300_VOL_LSB_INTERRUPT_WRITE BIT(20) +#define ALS31300_CUSTOMER_ACCESS 0x35 + +#define ALS31300_DATA_X_GET(b) \ + sign_extend32(FIELD_GET(ALS31300_VOL_MSB_X_AXIS, b[0]) << 4 | \ + FIELD_GET(ALS31300_VOL_LSB_X_AXIS, b[1]), 11) +#define ALS31300_DATA_Y_GET(b) \ + sign_extend32(FIELD_GET(ALS31300_VOL_MSB_Y_AXIS, b[0]) << 4 | \ + FIELD_GET(ALS31300_VOL_LSB_Y_AXIS, b[1]), 11) +#define ALS31300_DATA_Z_GET(b) \ + sign_extend32(FIELD_GET(ALS31300_VOL_MSB_Z_AXIS, b[0]) << 4 | \ + FIELD_GET(ALS31300_VOL_LSB_Z_AXIS, b[1]), 11) +#define ALS31300_TEMPERATURE_GET(b) \ + (FIELD_GET(ALS31300_VOL_MSB_TEMPERATURE, b[0]) << 6 | \ + FIELD_GET(ALS31300_VOL_LSB_TEMPERATURE, b[1])) + +enum als31300_channels { + TEMPERATURE = 0, + AXIS_X, + AXIS_Y, + AXIS_Z, +}; + +struct als31300_variant_info { + u8 sensitivity; +}; + +struct als31300_data { + struct device *dev; + /* protects power on/off the device and access HW */ + struct mutex mutex; + const struct als31300_variant_info *variant_info; + struct regmap *map; +}; + +/* The whole measure is split into 2x32-bit registers, we need to read them both at once */ +static int als31300_get_measure(struct als31300_data *data, + u16 *t, s16 *x, s16 *y, s16 *z) +{ + u32 buf[2]; + int ret, err; + + guard(mutex)(&data->mutex); + + ret = pm_runtime_resume_and_get(data->dev); + if (ret) + return ret; + + /* + * Loop until data is valid, new data should have the + * ALS31300_VOL_MSB_NEW_DATA bit set to 1. + * Max update rate is 2KHz, wait up to 1ms. + */ + ret = read_poll_timeout(regmap_bulk_read, err, + err || FIELD_GET(ALS31300_VOL_MSB_NEW_DATA, buf[0]), + 20, USEC_PER_MSEC, false, + data->map, ALS31300_VOL_MSB, buf, ARRAY_SIZE(buf)); + /* Bail out on read_poll_timeout() error */ + if (ret) + goto out; + + /* Bail out on regmap_bulk_read() error */ + if (err) { + dev_err(data->dev, "read data failed, error %d\n", ret); + ret = err; + goto out; + } + + *t = ALS31300_TEMPERATURE_GET(buf); + *x = ALS31300_DATA_X_GET(buf); + *y = ALS31300_DATA_Y_GET(buf); + *z = ALS31300_DATA_Z_GET(buf); + +out: + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); + + return ret; +} + +static int als31300_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val, + int *val2, long mask) +{ + struct als31300_data *data = iio_priv(indio_dev); + s16 x, y, z; + u16 t; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + case IIO_CHAN_INFO_RAW: + ret = als31300_get_measure(data, &t, &x, &y, &z); + if (ret) + return ret; + + switch (chan->address) { + case TEMPERATURE: + *val = t; + return IIO_VAL_INT; + case AXIS_X: + *val = x; + return IIO_VAL_INT; + case AXIS_Y: + *val = y; + return IIO_VAL_INT; + case AXIS_Z: + *val = z; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_TEMP: + /* + * Fractional part of: + * 1000 * 302 * (value - 1708) + * temp = ---------------------------- + * 4096 + * to convert temperature in millicelcius. + */ + *val = MILLI * 302; + *val2 = 4096; + return IIO_VAL_FRACTIONAL; + case IIO_MAGN: + /* + * Devices are configured in factory + * with different sensitivities: + * - 500 GAUSS <-> 4 LSB/Gauss + * - 1000 GAUSS <-> 2 LSB/Gauss + * - 2000 GAUSS <-> 1 LSB/Gauss + * with translates by a division of the returned + * value to get Gauss value. + * The sensitivity cannot be read at runtime + * so the value depends on the model compatible + * or device id. + */ + *val = 1; + *val2 = data->variant_info->sensitivity; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_OFFSET: + switch (chan->type) { + case IIO_TEMP: + *val = -1708; + return IIO_VAL_INT; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static irqreturn_t als31300_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct als31300_data *data = iio_priv(indio_dev); + struct { + u16 temperature; + s16 channels[3]; + aligned_s64 timestamp; + } scan; + s16 x, y, z; + int ret; + u16 t; + + ret = als31300_get_measure(data, &t, &x, &y, &z); + if (ret) + goto trigger_out; + + scan.temperature = t; + scan.channels[0] = x; + scan.channels[1] = y; + scan.channels[2] = z; + iio_push_to_buffers_with_timestamp(indio_dev, &scan, + pf->timestamp); + +trigger_out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +#define ALS31300_AXIS_CHANNEL(axis, index) \ + { \ + .type = IIO_MAGN, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ + } + +static const struct iio_chan_spec als31300_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .address = TEMPERATURE, + .scan_index = TEMPERATURE, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_CPU, + }, + }, + ALS31300_AXIS_CHANNEL(X, AXIS_X), + ALS31300_AXIS_CHANNEL(Y, AXIS_Y), + ALS31300_AXIS_CHANNEL(Z, AXIS_Z), + IIO_CHAN_SOFT_TIMESTAMP(4), +}; + +static const struct iio_info als31300_info = { + .read_raw = als31300_read_raw, +}; + +static int als31300_set_operating_mode(struct als31300_data *data, + unsigned int val) +{ + int ret; + + ret = regmap_update_bits(data->map, ALS31300_VOL_MODE, + ALS31300_VOL_MODE_SLEEP, val); + if (ret) { + dev_err(data->dev, "failed to set operating mode (%pe)\n", ERR_PTR(ret)); + return ret; + } + + /* The time it takes to exit sleep mode is equivalent to Power-On Delay Time */ + if (val == ALS31300_VOL_MODE_ACTIVE_MODE) + fsleep(600); + + return 0; +} + +static void als31300_power_down(void *data) +{ + als31300_set_operating_mode(data, ALS31300_VOL_MODE_SLEEP_MODE); +} + +static const struct iio_buffer_setup_ops als31300_setup_ops = {}; + +static const unsigned long als31300_scan_masks[] = { GENMASK(3, 0), 0 }; + +static bool als31300_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == ALS31300_VOL_MSB || reg == ALS31300_VOL_LSB; +} + +static const struct regmap_config als31300_regmap_config = { + .reg_bits = 8, + .val_bits = 32, + .max_register = ALS31300_CUSTOMER_ACCESS, + .volatile_reg = als31300_volatile_reg, +}; + +static int als31300_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct als31300_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->dev = dev; + i2c_set_clientdata(i2c, indio_dev); + + ret = devm_mutex_init(dev, &data->mutex); + if (ret) + return ret; + + data->variant_info = i2c_get_match_data(i2c); + if (!data->variant_info) + return -EINVAL; + + data->map = devm_regmap_init_i2c(i2c, &als31300_regmap_config); + if (IS_ERR(data->map)) + return dev_err_probe(dev, PTR_ERR(data->map), + "failed to allocate register map\n"); + + ret = devm_regulator_get_enable(dev, "vcc"); + if (ret) + return dev_err_probe(dev, ret, "failed to enable regulator\n"); + + ret = als31300_set_operating_mode(data, ALS31300_VOL_MODE_ACTIVE_MODE); + if (ret) + return dev_err_probe(dev, ret, "failed to power on device\n"); + + ret = devm_add_action_or_reset(dev, als31300_power_down, data); + if (ret) + return dev_err_probe(dev, ret, "failed to add powerdown action\n"); + + indio_dev->info = &als31300_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = i2c->name; + indio_dev->channels = als31300_channels; + indio_dev->num_channels = ARRAY_SIZE(als31300_channels); + indio_dev->available_scan_masks = als31300_scan_masks; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + als31300_trigger_handler, + &als31300_setup_ops); + if (ret < 0) + return dev_err_probe(dev, ret, "iio triggered buffer setup failed\n"); + + ret = pm_runtime_set_active(dev); + if (ret < 0) + return ret; + + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + pm_runtime_get_noresume(dev); + pm_runtime_set_autosuspend_delay(dev, 200); + pm_runtime_use_autosuspend(dev); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "device register failed\n"); + + return 0; +} + +static int als31300_runtime_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct als31300_data *data = iio_priv(indio_dev); + + return als31300_set_operating_mode(data, ALS31300_VOL_MODE_SLEEP_MODE); +} + +static int als31300_runtime_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct als31300_data *data = iio_priv(indio_dev); + + return als31300_set_operating_mode(data, ALS31300_VOL_MODE_ACTIVE_MODE); +} + +static DEFINE_RUNTIME_DEV_PM_OPS(als31300_pm_ops, + als31300_runtime_suspend, als31300_runtime_resume, + NULL); + +static const struct als31300_variant_info al31300_variant_500 = { + .sensitivity = 4, +}; + +static const struct als31300_variant_info al31300_variant_1000 = { + .sensitivity = 2, +}; + +static const struct als31300_variant_info al31300_variant_2000 = { + .sensitivity = 1, +}; + +static const struct i2c_device_id als31300_id[] = { + { + .name = "als31300-500", + .driver_data = (kernel_ulong_t)&al31300_variant_500, + }, + { + .name = "als31300-1000", + .driver_data = (kernel_ulong_t)&al31300_variant_1000, + }, + { + .name = "als31300-2000", + .driver_data = (kernel_ulong_t)&al31300_variant_2000, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(i2c, als31300_id); + +static const struct of_device_id als31300_of_match[] = { + { + .compatible = "allegromicro,als31300-500", + .data = &al31300_variant_500, + }, + { + .compatible = "allegromicro,als31300-1000", + .data = &al31300_variant_1000, + }, + { + .compatible = "allegromicro,als31300-2000", + .data = &al31300_variant_2000, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, als31300_of_match); + +static struct i2c_driver als31300_driver = { + .driver = { + .name = "als31300", + .of_match_table = als31300_of_match, + .pm = pm_ptr(&als31300_pm_ops), + }, + .probe = als31300_probe, + .id_table = als31300_id, +}; +module_i2c_driver(als31300_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ALS31300 3-D Linear Hall Effect Driver"); +MODULE_AUTHOR("Neil Armstrong "); diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index 06d5a1ef1fbdf21912272fa64c13e5ee430021f2..7f545740178edfbb77e5cb4e6d297b9cb89908f8 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -226,7 +225,7 @@ const struct regmap_config bmc150_magn_regmap_config = { .writeable_reg = bmc150_magn_is_writeable_reg, .volatile_reg = bmc150_magn_is_volatile_reg, }; -EXPORT_SYMBOL_NS(bmc150_magn_regmap_config, IIO_BMC150_MAGN); +EXPORT_SYMBOL_NS(bmc150_magn_regmap_config, "IIO_BMC150_MAGN"); static int bmc150_magn_set_power_mode(struct bmc150_magn_data *data, enum bmc150_magn_power_modes mode, @@ -855,17 +854,6 @@ static const struct iio_buffer_setup_ops bmc150_magn_buffer_setup_ops = { .postdisable = bmc150_magn_buffer_postdisable, }; -static const char *bmc150_magn_match_acpi_device(struct device *dev) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - - return dev_name(dev); -} - int bmc150_magn_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) { @@ -894,9 +882,6 @@ int bmc150_magn_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; - if (!name && ACPI_HANDLE(dev)) - name = bmc150_magn_match_acpi_device(dev); - mutex_init(&data->mutex); ret = bmc150_magn_init(data); @@ -983,7 +968,7 @@ err_poweroff: bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true); return ret; } -EXPORT_SYMBOL_NS(bmc150_magn_probe, IIO_BMC150_MAGN); +EXPORT_SYMBOL_NS(bmc150_magn_probe, "IIO_BMC150_MAGN"); void bmc150_magn_remove(struct device *dev) { @@ -1009,7 +994,7 @@ void bmc150_magn_remove(struct device *dev) regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); } -EXPORT_SYMBOL_NS(bmc150_magn_remove, IIO_BMC150_MAGN); +EXPORT_SYMBOL_NS(bmc150_magn_remove, "IIO_BMC150_MAGN"); #ifdef CONFIG_PM static int bmc150_magn_runtime_suspend(struct device *dev) @@ -1077,7 +1062,7 @@ const struct dev_pm_ops bmc150_magn_pm_ops = { SET_RUNTIME_PM_OPS(bmc150_magn_runtime_suspend, bmc150_magn_runtime_resume, NULL) }; -EXPORT_SYMBOL_NS(bmc150_magn_pm_ops, IIO_BMC150_MAGN); +EXPORT_SYMBOL_NS(bmc150_magn_pm_ops, "IIO_BMC150_MAGN"); MODULE_AUTHOR("Irina Tirdea "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/magnetometer/bmc150_magn_i2c.c b/drivers/iio/magnetometer/bmc150_magn_i2c.c index a28d46d59875faefa588538f8d02faab5d61ecec..8cbeda924bdaa343f2a0507032d169a1010c70ea 100644 --- a/drivers/iio/magnetometer/bmc150_magn_i2c.c +++ b/drivers/iio/magnetometer/bmc150_magn_i2c.c @@ -38,14 +38,6 @@ static void bmc150_magn_i2c_remove(struct i2c_client *client) bmc150_magn_remove(&client->dev); } -static const struct acpi_device_id bmc150_magn_acpi_match[] = { - {"BMC150B", 0}, - {"BMC156B", 0}, - {"BMM150B", 0}, - {}, -}; -MODULE_DEVICE_TABLE(acpi, bmc150_magn_acpi_match); - static const struct i2c_device_id bmc150_magn_i2c_id[] = { { "bmc150_magn" }, { "bmc156_magn" }, @@ -67,7 +59,6 @@ static struct i2c_driver bmc150_magn_driver = { .driver = { .name = "bmc150_magn_i2c", .of_match_table = bmc150_magn_of_match, - .acpi_match_table = bmc150_magn_acpi_match, .pm = &bmc150_magn_pm_ops, }, .probe = bmc150_magn_i2c_probe, @@ -79,4 +70,4 @@ module_i2c_driver(bmc150_magn_driver); MODULE_AUTHOR("Daniel Baluta dev); int ret = 0; static char *name = "magn_3d"; struct iio_dev *indio_dev; struct magn_3d_state *magn_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; struct iio_chan_spec *channels; int chan_count = 0; @@ -549,7 +549,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_magn_3d_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct magn_3d_state *magn_state = iio_priv(indio_dev); @@ -574,11 +574,11 @@ static struct platform_driver hid_magn_3d_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_magn_3d_probe, - .remove_new = hid_magn_3d_remove, + .remove = hid_magn_3d_remove, }; module_platform_driver(hid_magn_3d_platform_driver); MODULE_DESCRIPTION("HID Sensor Magnetometer 3D"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c index c5521d61da2958f1f99879e9ad8693e01a2e7da6..2fc84310e2ccb237deca1262abbc81ced3f5a88e 100644 --- a/drivers/iio/magnetometer/hmc5843_core.c +++ b/drivers/iio/magnetometer/hmc5843_core.c @@ -669,7 +669,7 @@ buffer_setup_err: hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP); return ret; } -EXPORT_SYMBOL_NS(hmc5843_common_probe, IIO_HMC5843); +EXPORT_SYMBOL_NS(hmc5843_common_probe, "IIO_HMC5843"); void hmc5843_common_remove(struct device *dev) { @@ -681,7 +681,7 @@ void hmc5843_common_remove(struct device *dev) /* sleep mode to save power */ hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP); } -EXPORT_SYMBOL_NS(hmc5843_common_remove, IIO_HMC5843); +EXPORT_SYMBOL_NS(hmc5843_common_remove, "IIO_HMC5843"); MODULE_AUTHOR("Shubhrajyoti Datta "); MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 core driver"); diff --git a/drivers/iio/magnetometer/hmc5843_i2c.c b/drivers/iio/magnetometer/hmc5843_i2c.c index bdd2784a9f863b0c872501a93438aa7e2d074b98..657a309e2bd57898d7a15b0a01c1851281515842 100644 --- a/drivers/iio/magnetometer/hmc5843_i2c.c +++ b/drivers/iio/magnetometer/hmc5843_i2c.c @@ -103,4 +103,4 @@ module_i2c_driver(hmc5843_driver); MODULE_AUTHOR("Josef Gajdusek "); MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 i2c driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HMC5843); +MODULE_IMPORT_NS("IIO_HMC5843"); diff --git a/drivers/iio/magnetometer/hmc5843_spi.c b/drivers/iio/magnetometer/hmc5843_spi.c index c42d2e2a6a6ce1e73d94e6cd7bce95d1c523a2c7..b7fde331069d6a3d2f5cd2ecd636318d1e276222 100644 --- a/drivers/iio/magnetometer/hmc5843_spi.c +++ b/drivers/iio/magnetometer/hmc5843_spi.c @@ -100,4 +100,4 @@ module_spi_driver(hmc5843_driver); MODULE_AUTHOR("Josef Gajdusek "); MODULE_DESCRIPTION("HMC5983 SPI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HMC5843); +MODULE_IMPORT_NS("IIO_HMC5843"); diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c index baab918b38254ba3e8f5f0f1b7b7f544c16544fb..c99694a77a1418bcc5a8bd047552e7604e9ae559 100644 --- a/drivers/iio/magnetometer/rm3100-core.c +++ b/drivers/iio/magnetometer/rm3100-core.c @@ -100,7 +100,7 @@ const struct regmap_access_table rm3100_readable_table = { .yes_ranges = rm3100_readable_ranges, .n_yes_ranges = ARRAY_SIZE(rm3100_readable_ranges), }; -EXPORT_SYMBOL_NS_GPL(rm3100_readable_table, IIO_RM3100); +EXPORT_SYMBOL_NS_GPL(rm3100_readable_table, "IIO_RM3100"); static const struct regmap_range rm3100_writable_ranges[] = { regmap_reg_range(RM3100_W_REG_START, RM3100_W_REG_END), @@ -110,7 +110,7 @@ const struct regmap_access_table rm3100_writable_table = { .yes_ranges = rm3100_writable_ranges, .n_yes_ranges = ARRAY_SIZE(rm3100_writable_ranges), }; -EXPORT_SYMBOL_NS_GPL(rm3100_writable_table, IIO_RM3100); +EXPORT_SYMBOL_NS_GPL(rm3100_writable_table, "IIO_RM3100"); static const struct regmap_range rm3100_volatile_ranges[] = { regmap_reg_range(RM3100_V_REG_START, RM3100_V_REG_END), @@ -120,7 +120,7 @@ const struct regmap_access_table rm3100_volatile_table = { .yes_ranges = rm3100_volatile_ranges, .n_yes_ranges = ARRAY_SIZE(rm3100_volatile_ranges), }; -EXPORT_SYMBOL_NS_GPL(rm3100_volatile_table, IIO_RM3100); +EXPORT_SYMBOL_NS_GPL(rm3100_volatile_table, "IIO_RM3100"); static irqreturn_t rm3100_thread_fn(int irq, void *d) { @@ -604,7 +604,7 @@ int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq) return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(rm3100_common_probe, IIO_RM3100); +EXPORT_SYMBOL_NS_GPL(rm3100_common_probe, "IIO_RM3100"); MODULE_AUTHOR("Song Qiang "); MODULE_DESCRIPTION("PNI RM3100 3-axis magnetometer i2c driver"); diff --git a/drivers/iio/magnetometer/rm3100-i2c.c b/drivers/iio/magnetometer/rm3100-i2c.c index ac7276b3798c07290669f19ccac3f163fd15838f..a09a271b62c5d23f5010bb4fd3001db5f76b9077 100644 --- a/drivers/iio/magnetometer/rm3100-i2c.c +++ b/drivers/iio/magnetometer/rm3100-i2c.c @@ -52,4 +52,4 @@ module_i2c_driver(rm3100_driver); MODULE_AUTHOR("Song Qiang "); MODULE_DESCRIPTION("PNI RM3100 3-axis magnetometer i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_RM3100); +MODULE_IMPORT_NS("IIO_RM3100"); diff --git a/drivers/iio/magnetometer/rm3100-spi.c b/drivers/iio/magnetometer/rm3100-spi.c index 76dc9b66cd3c5233acd6df099b39f6efcc1fd501..dd6d48043740c12a45f1d10aa26c732128c7db27 100644 --- a/drivers/iio/magnetometer/rm3100-spi.c +++ b/drivers/iio/magnetometer/rm3100-spi.c @@ -62,4 +62,4 @@ module_spi_driver(rm3100_driver); MODULE_AUTHOR("Song Qiang "); MODULE_DESCRIPTION("PNI RM3100 3-axis magnetometer spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_RM3100); +MODULE_IMPORT_NS("IIO_RM3100"); diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 6cc0dfd31821b094735f04b0bc0e15319407a759..ef348d316c001e0326c196c181a433b45447f2cf 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -601,7 +601,7 @@ const struct st_sensor_settings *st_magn_get_settings(const char *name) return &st_magn_sensors_settings[index]; } -EXPORT_SYMBOL_NS(st_magn_get_settings, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_magn_get_settings, "IIO_ST_SENSORS"); int st_magn_common_probe(struct iio_dev *indio_dev) { @@ -648,9 +648,9 @@ int st_magn_common_probe(struct iio_dev *indio_dev) return devm_iio_device_register(parent, indio_dev); } -EXPORT_SYMBOL_NS(st_magn_common_probe, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_magn_common_probe, "IIO_ST_SENSORS"); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics magnetometers driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index 950826dd20bf5f16bf0f0c7b4f02ea2dc095de8c..1672b274768d4d6e9d609c7494d82d89e5d4ebff 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -119,4 +119,4 @@ module_i2c_driver(st_magn_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics magnetometers i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index f203e1f87eecbab6268110b814f78e102d3e6c39..fe4d0e63133c03c8fff68c37a23dce2ea2ad4e7b 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -111,4 +111,4 @@ module_spi_driver(st_magn_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics magnetometers spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c index 8943d5c78bc07383bc988f50a4c8fd1f3fae073d..429035b65c657acf5558ed10d289f56512fe2d28 100644 --- a/drivers/iio/orientation/hid-sensor-incl-3d.c +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c @@ -29,7 +29,7 @@ struct incl_3d_state { struct hid_sensor_hub_attribute_info incl[INCLI_3D_CHANNEL_MAX]; struct { u32 incl_val[INCLI_3D_CHANNEL_MAX]; - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -299,11 +299,11 @@ static int incl_3d_parse_report(struct platform_device *pdev, /* Function to initialize the processing for usage id */ static int hid_incl_3d_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret; static char *name = "incli_3d"; struct iio_dev *indio_dev; struct incl_3d_state *incl_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct incl_3d_state)); @@ -385,7 +385,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_incl_3d_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct incl_3d_state *incl_state = iio_priv(indio_dev); @@ -410,11 +410,11 @@ static struct platform_driver hid_incl_3d_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_incl_3d_probe, - .remove_new = hid_incl_3d_remove, + .remove = hid_incl_3d_remove, }; module_platform_driver(hid_incl_3d_platform_driver); MODULE_DESCRIPTION("HID Sensor Inclinometer 3D"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c index 5e8cadd5177ae7fa56f42cd93f9c6a92a219dbff..96f03988640c3148e7e66abd0ffe786f9b5b3b61 100644 --- a/drivers/iio/orientation/hid-sensor-rotation.c +++ b/drivers/iio/orientation/hid-sensor-rotation.c @@ -20,7 +20,7 @@ struct dev_rot_state { struct hid_sensor_hub_attribute_info quaternion; struct { s32 sampled_vals[4] __aligned(16); - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -230,11 +230,11 @@ static int dev_rot_parse_report(struct platform_device *pdev, /* Function to initialize the processing for usage id */ static int hid_dev_rot_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret; char *name; struct iio_dev *indio_dev; struct dev_rot_state *rot_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct dev_rot_state)); @@ -329,7 +329,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_dev_rot_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct dev_rot_state *rot_state = iio_priv(indio_dev); @@ -362,11 +362,11 @@ static struct platform_driver hid_dev_rot_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_dev_rot_probe, - .remove_new = hid_dev_rot_remove, + .remove = hid_dev_rot_remove, }; module_platform_driver(hid_dev_rot_platform_driver); MODULE_DESCRIPTION("HID Sensor Device Rotation"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/position/hid-sensor-custom-intel-hinge.c b/drivers/iio/position/hid-sensor-custom-intel-hinge.c index 76e173850a35496d14c3519970a461b512120865..423bbb8a3b38f27fbc3a8c843504c8381c94a6d6 100644 --- a/drivers/iio/position/hid-sensor-custom-intel-hinge.c +++ b/drivers/iio/position/hid-sensor-custom-intel-hinge.c @@ -39,7 +39,7 @@ struct hinge_state { const char *labels[CHANNEL_SCAN_INDEX_MAX]; struct { u32 hinge_val[3]; - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; @@ -263,9 +263,9 @@ static int hinge_parse_report(struct platform_device *pdev, /* Function to initialize the processing for usage id */ static int hid_hinge_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct hinge_state *st; struct iio_dev *indio_dev; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; int ret; int i; @@ -344,7 +344,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_hinge_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct hinge_state *st = iio_priv(indio_dev); @@ -369,11 +369,11 @@ static struct platform_driver hid_hinge_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_hinge_probe, - .remove_new = hid_hinge_remove, + .remove = hid_hinge_remove, }; module_platform_driver(hid_hinge_platform_driver); MODULE_DESCRIPTION("HID Sensor INTEL Hinge"); MODULE_AUTHOR("Ye Xiang "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/position/iqs624-pos.c b/drivers/iio/position/iqs624-pos.c index 4d7452314209fedd2e41e52764c6d036535cbbb1..8239239c6ee272f7dd6c4a615a29dd7f28d4be51 100644 --- a/drivers/iio/position/iqs624-pos.c +++ b/drivers/iio/position/iqs624-pos.c @@ -181,7 +181,7 @@ static int iqs624_pos_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct iqs624_pos_private *iqs624_pos = iio_priv(indio_dev); struct iqs62x_core *iqs62x = iqs624_pos->iqs62x; diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index a8b97b9b0461823aba119c485a9fa56ea373229a..5376605b69b43aef1e82ac49b41adfd4f16552ca 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -16,6 +16,11 @@ * https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp390-ds002.pdf * https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp581-ds004.pdf * + * Sensor API: + * https://github.com/boschsensortec/BME280_SensorAPI + * https://github.com/boschsensortec/BMP3_SensorAPI + * https://github.com/boschsensortec/BMP5_SensorAPI + * * Notice: * The link to the bmp180 datasheet points to an outdated version missing these changes: * - Changed document referral from ANP015 to BST-MPS-AN004-00 on page 26 @@ -37,12 +42,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -340,10 +347,19 @@ static int bmp280_read_calib(struct bmp280_data *data) return 0; } +/* + * These enums are used for indexing into the array of humidity parameters + * for BME280. Due to some weird indexing, unaligned BE/LE accesses co-exist in + * order to prepare the FIELD_{GET/PREP}() fields. Table 16 in Section 4.2.2 of + * the datasheet. + */ +enum { H2 = 0, H3 = 2, H4 = 3, H5 = 4, H6 = 6 }; + static int bme280_read_calib(struct bmp280_data *data) { struct bmp280_calib *calib = &data->calib.bmp280; struct device *dev = data->dev; + s16 h4_upper, h4_lower, tmp_1, tmp_2, tmp_3; unsigned int tmp; int ret; @@ -352,14 +368,6 @@ static int bme280_read_calib(struct bmp280_data *data) if (ret) return ret; - /* - * Read humidity calibration values. - * Due to some odd register addressing we cannot just - * do a big bulk read. Instead, we have to read each Hx - * value separately and sometimes do some bit shifting... - * Humidity data is only available on BME280. - */ - ret = regmap_read(data->regmap, BME280_REG_COMP_H1, &tmp); if (ret) { dev_err(dev, "failed to read H1 comp value\n"); @@ -368,43 +376,23 @@ static int bme280_read_calib(struct bmp280_data *data) calib->H1 = tmp; ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H2, - &data->le16, sizeof(data->le16)); + data->bme280_humid_cal_buf, + sizeof(data->bme280_humid_cal_buf)); if (ret) { - dev_err(dev, "failed to read H2 comp value\n"); + dev_err(dev, "failed to read humidity calibration values\n"); return ret; } - calib->H2 = sign_extend32(le16_to_cpu(data->le16), 15); - 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, BME280_REG_COMP_H4, - &data->be16, sizeof(data->be16)); - 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, BME280_REG_COMP_H5, - &data->le16, sizeof(data->le16)); - if (ret) { - dev_err(dev, "failed to read H5 comp value\n"); - return ret; - } - calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK, le16_to_cpu(data->le16)), 11); - - ret = regmap_read(data->regmap, BME280_REG_COMP_H6, &tmp); - if (ret) { - dev_err(dev, "failed to read H6 comp value\n"); - return ret; - } - calib->H6 = sign_extend32(tmp, 7); + calib->H2 = get_unaligned_le16(&data->bme280_humid_cal_buf[H2]); + calib->H3 = data->bme280_humid_cal_buf[H3]; + tmp_1 = get_unaligned_be16(&data->bme280_humid_cal_buf[H4]); + tmp_2 = FIELD_GET(BME280_COMP_H4_GET_MASK_UP, tmp_1); + h4_upper = FIELD_PREP(BME280_COMP_H4_PREP_MASK_UP, tmp_2); + h4_lower = FIELD_GET(BME280_COMP_H4_MASK_LOW, tmp_1); + calib->H4 = sign_extend32(h4_upper | h4_lower, 11); + tmp_3 = get_unaligned_le16(&data->bme280_humid_cal_buf[H5]); + calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK, tmp_3), 11); + calib->H6 = data->bme280_humid_cal_buf[H6]; return 0; } @@ -635,6 +623,14 @@ static int bmp280_read_raw_impl(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_PROCESSED: + ret = data->chip_info->set_mode(data, BMP280_FORCED); + if (ret) + return ret; + + ret = data->chip_info->wait_conv(data); + if (ret) + return ret; + switch (chan->type) { case IIO_HUMIDITYRELATIVE: ret = data->chip_info->read_humid(data, &chan_value); @@ -664,6 +660,14 @@ static int bmp280_read_raw_impl(struct iio_dev *indio_dev, return -EINVAL; } case IIO_CHAN_INFO_RAW: + ret = data->chip_info->set_mode(data, BMP280_FORCED); + if (ret) + return ret; + + ret = data->chip_info->wait_conv(data); + if (ret) + return ret; + switch (chan->type) { case IIO_HUMIDITYRELATIVE: ret = data->chip_info->read_humid(data, &chan_value); @@ -983,6 +987,92 @@ static const unsigned long bme280_avail_scan_masks[] = { 0 }; +static int bmp280_preinit(struct bmp280_data *data) +{ + struct device *dev = data->dev; + unsigned int reg; + int ret; + + ret = regmap_write(data->regmap, BMP280_REG_RESET, BMP280_RST_SOFT_CMD); + if (ret) + return dev_err_probe(dev, ret, "Failed to reset device.\n"); + + /* + * According to the datasheet in Chapter 1: Specification, Table 2, + * after resetting, the device uses the complete power-on sequence so + * it needs to wait for the defined start-up time. + */ + fsleep(data->start_up_time); + + ret = regmap_read(data->regmap, BMP280_REG_STATUS, ®); + if (ret) + return dev_err_probe(dev, ret, "Failed to read status register.\n"); + + if (reg & BMP280_REG_STATUS_IM_UPDATE) + return dev_err_probe(dev, -EIO, "Failed to copy NVM contents.\n"); + + return 0; +} + +static const u8 bmp280_operation_mode[] = { + [BMP280_SLEEP] = BMP280_MODE_SLEEP, + [BMP280_FORCED] = BMP280_MODE_FORCED, + [BMP280_NORMAL] = BMP280_MODE_NORMAL, +}; + +static int bmp280_set_mode(struct bmp280_data *data, enum bmp280_op_mode mode) +{ + int ret; + + ret = regmap_write_bits(data->regmap, BMP280_REG_CTRL_MEAS, + BMP280_MODE_MASK, bmp280_operation_mode[mode]); + if (ret) { + dev_err(data->dev, "failed to write ctrl_meas register.\n"); + return ret; + } + + data->op_mode = mode; + + return 0; +} + +static int bmp280_wait_conv(struct bmp280_data *data) +{ + unsigned int reg, meas_time_us; + int ret; + + /* Check if we are using a BME280 device */ + if (data->oversampling_humid) + meas_time_us = BMP280_PRESS_HUMID_MEAS_OFFSET + + BIT(data->oversampling_humid) * BMP280_MEAS_DUR; + + else + meas_time_us = 0; + + /* Pressure measurement time */ + meas_time_us += BMP280_PRESS_HUMID_MEAS_OFFSET + + BIT(data->oversampling_press) * BMP280_MEAS_DUR; + + /* Temperature measurement time */ + meas_time_us += BIT(data->oversampling_temp) * BMP280_MEAS_DUR; + + /* Waiting time according to the BM(P/E)2 Sensor API */ + fsleep(meas_time_us); + + ret = regmap_read(data->regmap, BMP280_REG_STATUS, ®); + if (ret) { + dev_err(data->dev, "failed to read status register.\n"); + return ret; + } + + if (reg & BMP280_REG_STATUS_MEAS_BIT) { + dev_err(data->dev, "Measurement cycle didn't complete.\n"); + return -EBUSY; + } + + return 0; +} + static int bmp280_chip_config(struct bmp280_data *data) { u8 osrs = FIELD_PREP(BMP280_OSRS_TEMP_MASK, data->oversampling_temp + 1) | @@ -993,7 +1083,7 @@ static int bmp280_chip_config(struct bmp280_data *data) BMP280_OSRS_TEMP_MASK | BMP280_OSRS_PRESS_MASK | BMP280_MODE_MASK, - osrs | BMP280_MODE_NORMAL); + osrs | BMP280_MODE_SLEEP); if (ret) { dev_err(data->dev, "failed to write ctrl_meas register\n"); return ret; @@ -1015,7 +1105,9 @@ static irqreturn_t bmp280_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmp280_data *data = iio_priv(indio_dev); - s32 adc_temp, adc_press, t_fine; + u32 adc_temp, adc_press, comp_press; + s32 t_fine, comp_temp; + s32 *chans = (s32 *)data->sensor_data; int ret; guard(mutex)(&data->lock); @@ -1035,7 +1127,7 @@ static irqreturn_t bmp280_trigger_handler(int irq, void *p) goto out; } - data->sensor_data[1] = bmp280_compensate_temp(data, adc_temp); + comp_temp = bmp280_compensate_temp(data, adc_temp); /* Pressure calculations */ adc_press = FIELD_GET(BMP280_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[0])); @@ -1045,10 +1137,12 @@ static irqreturn_t bmp280_trigger_handler(int irq, void *p) } t_fine = bmp280_calc_t_fine(data, adc_temp); + comp_press = bmp280_compensate_press(data, adc_press, t_fine); - data->sensor_data[0] = bmp280_compensate_press(data, adc_press, t_fine); + chans[0] = comp_press; + chans[1] = comp_temp; - iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data, + iio_push_to_buffers_with_timestamp(indio_dev, data->sensor_data, iio_get_time_ns(indio_dev)); out: @@ -1099,10 +1193,13 @@ const struct bmp280_chip_info bmp280_chip_info = { .read_temp = bmp280_read_temp, .read_press = bmp280_read_press, .read_calib = bmp280_read_calib, + .set_mode = bmp280_set_mode, + .wait_conv = bmp280_wait_conv, + .preinit = bmp280_preinit, .trigger_handler = bmp280_trigger_handler, }; -EXPORT_SYMBOL_NS(bmp280_chip_info, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp280_chip_info, "IIO_BMP280"); static int bme280_chip_config(struct bmp280_data *data) { @@ -1128,7 +1225,9 @@ static irqreturn_t bme280_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmp280_data *data = iio_priv(indio_dev); - s32 adc_temp, adc_press, adc_humidity, t_fine; + u32 adc_temp, adc_press, adc_humidity, comp_press, comp_humidity; + s32 t_fine, comp_temp; + s32 *chans = (s32 *)data->sensor_data; int ret; guard(mutex)(&data->lock); @@ -1148,7 +1247,7 @@ static irqreturn_t bme280_trigger_handler(int irq, void *p) goto out; } - data->sensor_data[1] = bmp280_compensate_temp(data, adc_temp); + comp_temp = bmp280_compensate_temp(data, adc_temp); /* Pressure calculations */ adc_press = FIELD_GET(BMP280_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[0])); @@ -1158,8 +1257,7 @@ static irqreturn_t bme280_trigger_handler(int irq, void *p) } t_fine = bmp280_calc_t_fine(data, adc_temp); - - data->sensor_data[0] = bmp280_compensate_press(data, adc_press, t_fine); + comp_press = bmp280_compensate_press(data, adc_press, t_fine); /* Humidity calculations */ adc_humidity = get_unaligned_be16(&data->buf[6]); @@ -1168,9 +1266,14 @@ static irqreturn_t bme280_trigger_handler(int irq, void *p) dev_err(data->dev, "reading humidity skipped\n"); goto out; } - data->sensor_data[2] = bme280_compensate_humidity(data, adc_humidity, t_fine); - iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data, + comp_humidity = bme280_compensate_humidity(data, adc_humidity, t_fine); + + chans[0] = comp_press; + chans[1] = comp_temp; + chans[2] = comp_humidity; + + iio_push_to_buffers_with_timestamp(indio_dev, data->sensor_data, iio_get_time_ns(indio_dev)); out: @@ -1179,6 +1282,63 @@ out: return IRQ_HANDLED; } +static int __bmp280_trigger_probe(struct iio_dev *indio_dev, + const struct iio_trigger_ops *trigger_ops, + int (*int_pin_config)(struct bmp280_data *data), + irq_handler_t irq_thread_handler) +{ + struct bmp280_data *data = iio_priv(indio_dev); + struct device *dev = data->dev; + u32 irq_type; + int ret, irq; + + irq = fwnode_irq_get(dev_fwnode(dev), 0); + if (irq < 0) + return dev_err_probe(dev, irq, "No interrupt found.\n"); + + irq_type = irq_get_trigger_type(irq); + switch (irq_type) { + case IRQF_TRIGGER_RISING: + data->trig_active_high = true; + break; + case IRQF_TRIGGER_FALLING: + data->trig_active_high = false; + break; + default: + return dev_err_probe(dev, -EINVAL, "Invalid interrupt type specified.\n"); + } + + data->trig_open_drain = + fwnode_property_read_bool(dev_fwnode(dev), "int-open-drain"); + + ret = int_pin_config(data); + if (ret) + return ret; + + data->trig = devm_iio_trigger_alloc(data->dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops = trigger_ops; + iio_trigger_set_drvdata(data->trig, data); + + ret = devm_request_threaded_irq(data->dev, irq, NULL, + irq_thread_handler, IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "request IRQ failed.\n"); + + ret = devm_iio_trigger_register(data->dev, data->trig); + if (ret) + return dev_err_probe(dev, ret, "iio trigger register failed.\n"); + + indio_dev->trig = iio_trigger_get(data->trig); + + return 0; +} + static const u8 bme280_chip_ids[] = { BME280_CHIP_ID }; static const int bme280_humid_coeffs[] = { 1000, 1024 }; @@ -1216,10 +1376,13 @@ const struct bmp280_chip_info bme280_chip_info = { .read_press = bmp280_read_press, .read_humid = bme280_read_humid, .read_calib = bme280_read_calib, + .set_mode = bmp280_set_mode, + .wait_conv = bmp280_wait_conv, + .preinit = bmp280_preinit, .trigger_handler = bme280_trigger_handler, }; -EXPORT_SYMBOL_NS(bme280_chip_info, IIO_BMP280); +EXPORT_SYMBOL_NS(bme280_chip_info, "IIO_BMP280"); /* * Helper function to send a command to BMP3XX sensors. @@ -1502,6 +1665,64 @@ static int bmp380_preinit(struct bmp280_data *data) return bmp380_cmd(data, BMP380_CMD_SOFT_RESET); } +static const u8 bmp380_operation_mode[] = { + [BMP280_SLEEP] = BMP380_MODE_SLEEP, + [BMP280_FORCED] = BMP380_MODE_FORCED, + [BMP280_NORMAL] = BMP380_MODE_NORMAL, +}; + +static int bmp380_set_mode(struct bmp280_data *data, enum bmp280_op_mode mode) +{ + int ret; + + ret = regmap_write_bits(data->regmap, BMP380_REG_POWER_CONTROL, + BMP380_MODE_MASK, + FIELD_PREP(BMP380_MODE_MASK, + bmp380_operation_mode[mode])); + if (ret) { + dev_err(data->dev, "failed to write power control register.\n"); + return ret; + } + + data->op_mode = mode; + + return 0; +} + +static int bmp380_wait_conv(struct bmp280_data *data) +{ + unsigned int reg; + int ret, meas_time_us; + + /* Offset measurement time */ + meas_time_us = BMP380_MEAS_OFFSET; + + /* Pressure measurement time */ + meas_time_us += BMP380_PRESS_MEAS_OFFSET + + BIT(data->oversampling_press) * BMP380_MEAS_DUR; + + /* Temperature measurement time */ + meas_time_us += BMP380_TEMP_MEAS_OFFSET + + BIT(data->oversampling_temp) * BMP380_MEAS_DUR; + + /* Measurement time defined in Datasheet Section 3.9.2 */ + fsleep(meas_time_us); + + ret = regmap_read(data->regmap, BMP380_REG_STATUS, ®); + if (ret) { + dev_err(data->dev, "failed to read status register.\n"); + return ret; + } + + if (!((reg & BMP380_STATUS_DRDY_PRESS_MASK) && + (reg & BMP380_STATUS_DRDY_TEMP_MASK))) { + dev_err(data->dev, "Measurement cycle didn't complete.\n"); + return -EBUSY; + } + + return 0; +} + static int bmp380_chip_config(struct bmp280_data *data) { bool change = false, aux; @@ -1545,14 +1766,12 @@ static int bmp380_chip_config(struct bmp280_data *data) change = change || aux; /* Set filter data */ - ret = regmap_update_bits_check(data->regmap, BMP380_REG_CONFIG, BMP380_FILTER_MASK, - FIELD_PREP(BMP380_FILTER_MASK, data->iir_filter_coeff), - &aux); + ret = regmap_update_bits(data->regmap, BMP380_REG_CONFIG, BMP380_FILTER_MASK, + FIELD_PREP(BMP380_FILTER_MASK, data->iir_filter_coeff)); if (ret) { dev_err(data->dev, "failed to write config register\n"); return ret; } - change = change || aux; if (change) { /* @@ -1564,17 +1783,19 @@ static int bmp380_chip_config(struct bmp280_data *data) * Resets sensor measurement loop toggling between sleep and * normal operating modes. */ - ret = regmap_write_bits(data->regmap, BMP380_REG_POWER_CONTROL, - BMP380_MODE_MASK, - FIELD_PREP(BMP380_MODE_MASK, BMP380_MODE_SLEEP)); + ret = bmp380_set_mode(data, BMP280_SLEEP); if (ret) { dev_err(data->dev, "failed to set sleep mode\n"); return ret; } - usleep_range(2000, 2500); - ret = regmap_write_bits(data->regmap, BMP380_REG_POWER_CONTROL, - BMP380_MODE_MASK, - FIELD_PREP(BMP380_MODE_MASK, BMP380_MODE_NORMAL)); + + /* + * According to the BMP3 Sensor API, the sensor needs 5ms + * in order to go to the sleep mode. + */ + fsleep(5 * USEC_PER_MSEC); + + ret = bmp380_set_mode(data, BMP280_NORMAL); if (ret) { dev_err(data->dev, "failed to set normal mode\n"); return ret; @@ -1600,7 +1821,77 @@ static int bmp380_chip_config(struct bmp280_data *data) } } - return 0; + /* Dummy read to empty data registers. */ + ret = bmp380_read_press(data, &tmp); + if (ret) + return ret; + + ret = bmp380_set_mode(data, BMP280_SLEEP); + if (ret) + dev_err(data->dev, "failed to set sleep mode.\n"); + + return ret; +} + +static int bmp380_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct bmp280_data *data = iio_trigger_get_drvdata(trig); + int ret; + + guard(mutex)(&data->lock); + + ret = regmap_update_bits(data->regmap, BMP380_REG_INT_CONTROL, + BMP380_INT_CTRL_DRDY_EN, + FIELD_PREP(BMP380_INT_CTRL_DRDY_EN, !!state)); + if (ret) + dev_err(data->dev, + "Could not %s interrupt.\n", str_enable_disable(state)); + return ret; +} + +static const struct iio_trigger_ops bmp380_trigger_ops = { + .set_trigger_state = &bmp380_data_rdy_trigger_set_state, +}; + +static int bmp380_int_pin_config(struct bmp280_data *data) +{ + int pin_drive_cfg = FIELD_PREP(BMP380_INT_CTRL_OPEN_DRAIN, + data->trig_open_drain); + int pin_level_cfg = FIELD_PREP(BMP380_INT_CTRL_LEVEL, + data->trig_active_high); + int ret, int_pin_cfg = pin_drive_cfg | pin_level_cfg; + + ret = regmap_update_bits(data->regmap, BMP380_REG_INT_CONTROL, + BMP380_INT_CTRL_SETTINGS_MASK, int_pin_cfg); + if (ret) + dev_err(data->dev, "Could not set interrupt settings.\n"); + + return ret; +} + +static irqreturn_t bmp380_irq_thread_handler(int irq, void *p) +{ + struct iio_dev *indio_dev = p; + struct bmp280_data *data = iio_priv(indio_dev); + unsigned int int_ctrl; + int ret; + + ret = regmap_read(data->regmap, BMP380_REG_INT_STATUS, &int_ctrl); + if (ret) + return IRQ_NONE; + + if (FIELD_GET(BMP380_INT_STATUS_DRDY, int_ctrl)) + iio_trigger_poll_nested(data->trig); + + return IRQ_HANDLED; +} + +static int bmp380_trigger_probe(struct iio_dev *indio_dev) +{ + return __bmp280_trigger_probe(indio_dev, &bmp380_trigger_ops, + bmp380_int_pin_config, + bmp380_irq_thread_handler); } static irqreturn_t bmp380_trigger_handler(int irq, void *p) @@ -1608,7 +1899,9 @@ static irqreturn_t bmp380_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmp280_data *data = iio_priv(indio_dev); - s32 adc_temp, adc_press, t_fine; + u32 adc_temp, adc_press, comp_press; + s32 t_fine, comp_temp; + s32 *chans = (s32 *)data->sensor_data; int ret; guard(mutex)(&data->lock); @@ -1628,7 +1921,7 @@ static irqreturn_t bmp380_trigger_handler(int irq, void *p) goto out; } - data->sensor_data[1] = bmp380_compensate_temp(data, adc_temp); + comp_temp = bmp380_compensate_temp(data, adc_temp); /* Pressure calculations */ adc_press = get_unaligned_le24(&data->buf[0]); @@ -1638,10 +1931,12 @@ static irqreturn_t bmp380_trigger_handler(int irq, void *p) } t_fine = bmp380_calc_t_fine(data, adc_temp); + comp_press = bmp380_compensate_press(data, adc_press, t_fine); - data->sensor_data[0] = bmp380_compensate_press(data, adc_press, t_fine); + chans[0] = comp_press; + chans[1] = comp_temp; - iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data, + iio_push_to_buffers_with_timestamp(indio_dev, data->sensor_data, iio_get_time_ns(indio_dev)); out: @@ -1692,11 +1987,14 @@ const struct bmp280_chip_info bmp380_chip_info = { .read_temp = bmp380_read_temp, .read_press = bmp380_read_press, .read_calib = bmp380_read_calib, + .set_mode = bmp380_set_mode, + .wait_conv = bmp380_wait_conv, .preinit = bmp380_preinit, + .trigger_probe = bmp380_trigger_probe, .trigger_handler = bmp380_trigger_handler, }; -EXPORT_SYMBOL_NS(bmp380_chip_info, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp380_chip_info, "IIO_BMP280"); static int bmp580_soft_reset(struct bmp280_data *data) { @@ -2079,6 +2377,70 @@ static int bmp580_preinit(struct bmp280_data *data) return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config)); } +static const u8 bmp580_operation_mode[] = { + [BMP280_SLEEP] = BMP580_MODE_SLEEP, + [BMP280_FORCED] = BMP580_MODE_FORCED, + [BMP280_NORMAL] = BMP580_MODE_NORMAL, +}; + +static int bmp580_set_mode(struct bmp280_data *data, enum bmp280_op_mode mode) +{ + struct device *dev = data->dev; + int ret; + + if (mode == BMP280_FORCED) { + ret = regmap_set_bits(data->regmap, BMP580_REG_DSP_CONFIG, + BMP580_DSP_IIR_FORCED_FLUSH); + if (ret) { + dev_err(dev, "Could not flush IIR filter constants.\n"); + return ret; + } + } + + ret = regmap_write_bits(data->regmap, BMP580_REG_ODR_CONFIG, + BMP580_MODE_MASK, + FIELD_PREP(BMP580_MODE_MASK, + bmp580_operation_mode[mode])); + if (ret) { + dev_err(dev, "failed to write power control register.\n"); + return ret; + } + + data->op_mode = mode; + + return 0; +} + +static int bmp580_wait_conv(struct bmp280_data *data) +{ + /* + * Taken from datasheet, Section 2 "Specification, Table 3 "Electrical + * characteristics. + */ + static const int time_conv_press[] = { + 0, 1050, 1785, 3045, 5670, 10920, 21420, 42420, + 84420, + }; + static const int time_conv_temp[] = { + 0, 1050, 1105, 1575, 2205, 3465, 6090, 11340, + 21840, + }; + int meas_time_us; + + meas_time_us = 4 * USEC_PER_MSEC + + time_conv_temp[data->oversampling_temp] + + time_conv_press[data->oversampling_press]; + + /* + * Measurement time mentioned in Chapter 2, Table 4 of the datasheet. + * The extra 4ms is the required mode change to start of measurement + * time. + */ + fsleep(meas_time_us); + + return 0; +} + static int bmp580_chip_config(struct bmp280_data *data) { bool change = false, aux; @@ -2141,26 +2503,13 @@ static int bmp580_chip_config(struct bmp280_data *data) reg_val = FIELD_PREP(BMP580_DSP_IIR_PRESS_MASK, data->iir_filter_coeff) | FIELD_PREP(BMP580_DSP_IIR_TEMP_MASK, data->iir_filter_coeff); - ret = regmap_update_bits_check(data->regmap, BMP580_REG_DSP_IIR, - BMP580_DSP_IIR_PRESS_MASK | - BMP580_DSP_IIR_TEMP_MASK, - reg_val, &aux); + ret = regmap_update_bits(data->regmap, BMP580_REG_DSP_IIR, + BMP580_DSP_IIR_PRESS_MASK | BMP580_DSP_IIR_TEMP_MASK, + reg_val); if (ret) { dev_err(data->dev, "failed to write config register\n"); return ret; } - change = change || aux; - - /* Restore sensor to normal operation mode */ - ret = regmap_write_bits(data->regmap, BMP580_REG_ODR_CONFIG, - BMP580_MODE_MASK, - FIELD_PREP(BMP580_MODE_MASK, BMP580_MODE_NORMAL)); - if (ret) { - dev_err(data->dev, "failed to set normal mode\n"); - return ret; - } - /* From datasheet's table 4: electrical characteristics */ - usleep_range(3000, 3500); if (change) { /* @@ -2185,12 +2534,80 @@ static int bmp580_chip_config(struct bmp280_data *data) return 0; } +static int bmp580_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct bmp280_data *data = iio_trigger_get_drvdata(trig); + int ret; + + guard(mutex)(&data->lock); + + ret = regmap_update_bits(data->regmap, BMP580_REG_INT_CONFIG, + BMP580_INT_CONFIG_INT_EN, + FIELD_PREP(BMP580_INT_CONFIG_INT_EN, !!state)); + if (ret) + dev_err(data->dev, + "Could not %s interrupt.\n", str_enable_disable(state)); + return ret; +} + +static const struct iio_trigger_ops bmp580_trigger_ops = { + .set_trigger_state = &bmp580_data_rdy_trigger_set_state, +}; + +static int bmp580_int_pin_config(struct bmp280_data *data) +{ + int pin_drive_cfg = FIELD_PREP(BMP580_INT_CONFIG_OPEN_DRAIN, + data->trig_open_drain); + int pin_level_cfg = FIELD_PREP(BMP580_INT_CONFIG_LEVEL, + data->trig_active_high); + int ret, int_pin_cfg = pin_drive_cfg | pin_level_cfg; + + ret = regmap_update_bits(data->regmap, BMP580_REG_INT_CONFIG, + BMP580_INT_CONFIG_MASK, int_pin_cfg); + if (ret) { + dev_err(data->dev, "Could not set interrupt settings.\n"); + return ret; + } + + ret = regmap_set_bits(data->regmap, BMP580_REG_INT_SOURCE, + BMP580_INT_SOURCE_DRDY); + if (ret) + dev_err(data->dev, "Could not set interrupt source.\n"); + + return ret; +} + +static irqreturn_t bmp580_irq_thread_handler(int irq, void *p) +{ + struct iio_dev *indio_dev = p; + struct bmp280_data *data = iio_priv(indio_dev); + unsigned int int_ctrl; + int ret; + + ret = regmap_read(data->regmap, BMP580_REG_INT_STATUS, &int_ctrl); + if (ret) + return IRQ_NONE; + + if (FIELD_GET(BMP580_INT_STATUS_DRDY_MASK, int_ctrl)) + iio_trigger_poll_nested(data->trig); + + return IRQ_HANDLED; +} + +static int bmp580_trigger_probe(struct iio_dev *indio_dev) +{ + return __bmp280_trigger_probe(indio_dev, &bmp580_trigger_ops, + bmp580_int_pin_config, + bmp580_irq_thread_handler); +} + static irqreturn_t bmp580_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmp280_data *data = iio_priv(indio_dev); - int ret; + int ret, offset; guard(mutex)(&data->lock); @@ -2202,13 +2619,17 @@ static irqreturn_t bmp580_trigger_handler(int irq, void *p) goto out; } - /* Temperature calculations */ - memcpy(&data->sensor_data[1], &data->buf[0], 3); + offset = 0; /* Pressure calculations */ - memcpy(&data->sensor_data[0], &data->buf[3], 3); + memcpy(&data->sensor_data[offset], &data->buf[3], 3); + + offset += sizeof(s32); - iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data, + /* Temperature calculations */ + memcpy(&data->sensor_data[offset], &data->buf[0], 3); + + iio_push_to_buffers_with_timestamp(indio_dev, data->sensor_data, iio_get_time_ns(indio_dev)); out: @@ -2257,11 +2678,14 @@ const struct bmp280_chip_info bmp580_chip_info = { .chip_config = bmp580_chip_config, .read_temp = bmp580_read_temp, .read_press = bmp580_read_press, + .set_mode = bmp580_set_mode, + .wait_conv = bmp580_wait_conv, .preinit = bmp580_preinit, + .trigger_probe = bmp580_trigger_probe, .trigger_handler = bmp580_trigger_handler, }; -EXPORT_SYMBOL_NS(bmp580_chip_info, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp580_chip_info, "IIO_BMP280"); static int bmp180_wait_for_eoc(struct bmp280_data *data, u8 ctrl_meas) { @@ -2504,6 +2928,19 @@ static int bmp180_read_press(struct bmp280_data *data, u32 *comp_press) return 0; } +/* Keep compatibility with newer generations of the sensor */ +static int bmp180_set_mode(struct bmp280_data *data, enum bmp280_op_mode mode) +{ + return 0; +} + +/* Keep compatibility with newer generations of the sensor */ +static int bmp180_wait_conv(struct bmp280_data *data) +{ + return 0; +} + +/* Keep compatibility with newer generations of the sensor */ static int bmp180_chip_config(struct bmp280_data *data) { return 0; @@ -2514,23 +2951,24 @@ static irqreturn_t bmp180_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmp280_data *data = iio_priv(indio_dev); - int ret, chan_value; + int ret, comp_temp, comp_press; + s32 *chans = (s32 *)data->sensor_data; guard(mutex)(&data->lock); - ret = bmp180_read_temp(data, &chan_value); + ret = bmp180_read_temp(data, &comp_temp); if (ret) goto out; - data->sensor_data[1] = chan_value; - ret = bmp180_read_press(data, &chan_value); + ret = bmp180_read_press(data, &comp_press); if (ret) goto out; - data->sensor_data[0] = chan_value; + chans[0] = comp_press; + chans[1] = comp_temp; - iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data, + iio_push_to_buffers_with_timestamp(indio_dev, data->sensor_data, iio_get_time_ns(indio_dev)); out: @@ -2574,10 +3012,12 @@ const struct bmp280_chip_info bmp180_chip_info = { .read_temp = bmp180_read_temp, .read_press = bmp180_read_press, .read_calib = bmp180_read_calib, + .set_mode = bmp180_set_mode, + .wait_conv = bmp180_wait_conv, .trigger_handler = bmp180_trigger_handler, }; -EXPORT_SYMBOL_NS(bmp180_chip_info, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp180_chip_info, "IIO_BMP280"); static irqreturn_t bmp085_eoc_irq(int irq, void *d) { @@ -2588,15 +3028,18 @@ static irqreturn_t bmp085_eoc_irq(int irq, void *d) return IRQ_HANDLED; } -static int bmp085_fetch_eoc_irq(struct device *dev, - const char *name, - int irq, - struct bmp280_data *data) +static int bmp085_trigger_probe(struct iio_dev *indio_dev) { + struct bmp280_data *data = iio_priv(indio_dev); + struct device *dev = data->dev; unsigned long irq_trig; - int ret; + int ret, irq; - irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq)); + irq = fwnode_irq_get(dev_fwnode(dev), 0); + if (irq < 0) + return dev_err_probe(dev, irq, "No interrupt found.\n"); + + irq_trig = irq_get_trigger_type(irq); if (irq_trig != IRQF_TRIGGER_RISING) { dev_err(dev, "non-rising trigger given for EOC interrupt, trying to enforce it\n"); irq_trig = IRQF_TRIGGER_RISING; @@ -2604,13 +3047,8 @@ static int bmp085_fetch_eoc_irq(struct device *dev, init_completion(&data->done); - ret = devm_request_threaded_irq(dev, - irq, - bmp085_eoc_irq, - NULL, - irq_trig, - name, - data); + ret = devm_request_irq(dev, irq, bmp085_eoc_irq, irq_trig, + indio_dev->name, data); if (ret) { /* Bail out without IRQ but keep the driver in place */ dev_err(dev, "unable to request DRDY IRQ\n"); @@ -2618,14 +3056,54 @@ static int bmp085_fetch_eoc_irq(struct device *dev, } data->use_eoc = true; + return 0; } +/* Identical to bmp180_chip_info + bmp085_trigger_probe */ +const struct bmp280_chip_info bmp085_chip_info = { + .id_reg = BMP280_REG_ID, + .chip_id = bmp180_chip_ids, + .num_chip_id = ARRAY_SIZE(bmp180_chip_ids), + .regmap_config = &bmp180_regmap_config, + .start_up_time = 2000, + .channels = bmp280_channels, + .num_channels = ARRAY_SIZE(bmp280_channels), + .avail_scan_masks = bmp280_avail_scan_masks, + + .oversampling_temp_avail = bmp180_oversampling_temp_avail, + .num_oversampling_temp_avail = + ARRAY_SIZE(bmp180_oversampling_temp_avail), + .oversampling_temp_default = 0, + + .oversampling_press_avail = bmp180_oversampling_press_avail, + .num_oversampling_press_avail = + ARRAY_SIZE(bmp180_oversampling_press_avail), + .oversampling_press_default = BMP180_MEAS_PRESS_8X, + + .temp_coeffs = bmp180_temp_coeffs, + .temp_coeffs_type = IIO_VAL_FRACTIONAL, + .press_coeffs = bmp180_press_coeffs, + .press_coeffs_type = IIO_VAL_FRACTIONAL, + + .chip_config = bmp180_chip_config, + .read_temp = bmp180_read_temp, + .read_press = bmp180_read_press, + .read_calib = bmp180_read_calib, + .set_mode = bmp180_set_mode, + .wait_conv = bmp180_wait_conv, + + .trigger_probe = bmp085_trigger_probe, + .trigger_handler = bmp180_trigger_handler, +}; +EXPORT_SYMBOL_NS(bmp085_chip_info, "IIO_BMP280"); + static int bmp280_buffer_preenable(struct iio_dev *indio_dev) { struct bmp280_data *data = iio_priv(indio_dev); pm_runtime_get_sync(data->dev); + data->chip_info->set_mode(data, BMP280_NORMAL); return 0; } @@ -2790,12 +3268,17 @@ int bmp280_common_probe(struct device *dev, * however as it happens, the BMP085 shares the chip ID of BMP180 * so we look for an IRQ if we have that. */ - if (irq > 0 && (chip_id == BMP180_CHIP_ID)) { - ret = bmp085_fetch_eoc_irq(dev, name, irq, data); + if (irq > 0) { + if (data->chip_info->trigger_probe) + ret = data->chip_info->trigger_probe(indio_dev); if (ret) return ret; } + ret = data->chip_info->set_mode(data, BMP280_SLEEP); + if (ret) + return dev_err_probe(dev, ret, "Failed to set sleep mode\n"); + /* Enable runtime PM */ pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); @@ -2814,13 +3297,16 @@ int bmp280_common_probe(struct device *dev, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS(bmp280_common_probe, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp280_common_probe, "IIO_BMP280"); static int bmp280_runtime_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct bmp280_data *data = iio_priv(indio_dev); + data->chip_info->set_mode(data, BMP280_SLEEP); + + fsleep(data->start_up_time); return regulator_bulk_disable(BMP280_NUM_SUPPLIES, data->supplies); } @@ -2835,7 +3321,12 @@ static int bmp280_runtime_resume(struct device *dev) return ret; usleep_range(data->start_up_time, data->start_up_time + 100); - return data->chip_info->chip_config(data); + + ret = data->chip_info->chip_config(data); + if (ret) + return ret; + + return data->chip_info->set_mode(data, data->op_mode); } EXPORT_RUNTIME_DEV_PM_OPS(bmp280_dev_pm_ops, bmp280_runtime_suspend, diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c index 5c3a63b4327c80faaad0043bb64007b9ef9f8526..868e1b2ec7112add5ec892f8be19e1b148985438 100644 --- a/drivers/iio/pressure/bmp280-i2c.c +++ b/drivers/iio/pressure/bmp280-i2c.c @@ -27,7 +27,7 @@ static int bmp280_i2c_probe(struct i2c_client *client) } static const struct of_device_id bmp280_of_i2c_match[] = { - { .compatible = "bosch,bmp085", .data = &bmp180_chip_info }, + { .compatible = "bosch,bmp085", .data = &bmp085_chip_info }, { .compatible = "bosch,bmp180", .data = &bmp180_chip_info }, { .compatible = "bosch,bmp280", .data = &bmp280_chip_info }, { .compatible = "bosch,bme280", .data = &bme280_chip_info }, @@ -38,7 +38,7 @@ static const struct of_device_id bmp280_of_i2c_match[] = { MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match); static const struct i2c_device_id bmp280_i2c_id[] = { - {"bmp085", (kernel_ulong_t)&bmp180_chip_info }, + {"bmp085", (kernel_ulong_t)&bmp085_chip_info }, {"bmp180", (kernel_ulong_t)&bmp180_chip_info }, {"bmp280", (kernel_ulong_t)&bmp280_chip_info }, {"bme280", (kernel_ulong_t)&bme280_chip_info }, @@ -62,4 +62,4 @@ module_i2c_driver(bmp280_i2c_driver); MODULE_AUTHOR("Vlad Dogaru "); MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_BMP280); +MODULE_IMPORT_NS("IIO_BMP280"); diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c index d27d68edd90656cbdce89a652a1700f82ededbfb..b6a7b417c8cf737535e8f36cd6d8df03eeb555fd 100644 --- a/drivers/iio/pressure/bmp280-regmap.c +++ b/drivers/iio/pressure/bmp280-regmap.c @@ -39,7 +39,7 @@ const struct regmap_config bmp180_regmap_config = { .writeable_reg = bmp180_is_writeable_reg, .volatile_reg = bmp180_is_volatile_reg, }; -EXPORT_SYMBOL_NS(bmp180_regmap_config, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp180_regmap_config, "IIO_BMP280"); static bool bme280_is_writeable_reg(struct device *dev, unsigned int reg) { @@ -200,7 +200,7 @@ const struct regmap_config bmp280_regmap_config = { .writeable_reg = bmp280_is_writeable_reg, .volatile_reg = bmp280_is_volatile_reg, }; -EXPORT_SYMBOL_NS(bmp280_regmap_config, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp280_regmap_config, "IIO_BMP280"); const struct regmap_config bme280_regmap_config = { .reg_bits = 8, @@ -212,7 +212,7 @@ const struct regmap_config bme280_regmap_config = { .writeable_reg = bme280_is_writeable_reg, .volatile_reg = bme280_is_volatile_reg, }; -EXPORT_SYMBOL_NS(bme280_regmap_config, IIO_BMP280); +EXPORT_SYMBOL_NS(bme280_regmap_config, "IIO_BMP280"); const struct regmap_config bmp380_regmap_config = { .reg_bits = 8, @@ -224,7 +224,7 @@ const struct regmap_config bmp380_regmap_config = { .writeable_reg = bmp380_is_writeable_reg, .volatile_reg = bmp380_is_volatile_reg, }; -EXPORT_SYMBOL_NS(bmp380_regmap_config, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp380_regmap_config, "IIO_BMP280"); const struct regmap_config bmp580_regmap_config = { .reg_bits = 8, @@ -236,4 +236,4 @@ const struct regmap_config bmp580_regmap_config = { .writeable_reg = bmp580_is_writeable_reg, .volatile_reg = bmp580_is_volatile_reg, }; -EXPORT_SYMBOL_NS(bmp580_regmap_config, IIO_BMP280); +EXPORT_SYMBOL_NS(bmp580_regmap_config, "IIO_BMP280"); diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c index d18549d9bb647dde8e0afb8d985957df24499592..0e6e27892f99a89380728a0f0f86b9b6b192b343 100644 --- a/drivers/iio/pressure/bmp280-spi.c +++ b/drivers/iio/pressure/bmp280-spi.c @@ -114,7 +114,7 @@ static int bmp280_spi_probe(struct spi_device *spi) } static const struct of_device_id bmp280_of_spi_match[] = { - { .compatible = "bosch,bmp085", .data = &bmp180_chip_info }, + { .compatible = "bosch,bmp085", .data = &bmp085_chip_info }, { .compatible = "bosch,bmp180", .data = &bmp180_chip_info }, { .compatible = "bosch,bmp181", .data = &bmp180_chip_info }, { .compatible = "bosch,bmp280", .data = &bmp280_chip_info }, @@ -126,7 +126,7 @@ static const struct of_device_id bmp280_of_spi_match[] = { MODULE_DEVICE_TABLE(of, bmp280_of_spi_match); static const struct spi_device_id bmp280_spi_id[] = { - { "bmp085", (kernel_ulong_t)&bmp180_chip_info }, + { "bmp085", (kernel_ulong_t)&bmp085_chip_info }, { "bmp180", (kernel_ulong_t)&bmp180_chip_info }, { "bmp181", (kernel_ulong_t)&bmp180_chip_info }, { "bmp280", (kernel_ulong_t)&bmp280_chip_info }, @@ -150,4 +150,4 @@ module_spi_driver(bmp280_spi_driver); MODULE_DESCRIPTION("BMP280 SPI bus driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_BMP280); +MODULE_IMPORT_NS("IIO_BMP280"); diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index ccacc67c1473115d4787d8850832960210d38117..2df1175b6b8539ad90a03c7da863dc16647e5b48 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -55,8 +55,17 @@ #define BMP580_CMD_NVM_WRITE_SEQ_1 0xA0 #define BMP580_CMD_SOFT_RESET 0xB6 +#define BMP580_INT_STATUS_DRDY_MASK BIT(0) #define BMP580_INT_STATUS_POR_MASK BIT(4) +#define BMP580_INT_SOURCE_DRDY BIT(0) + +#define BMP580_INT_CONFIG_MASK GENMASK(3, 0) +#define BMP580_INT_CONFIG_LATCH BIT(0) +#define BMP580_INT_CONFIG_LEVEL BIT(1) +#define BMP580_INT_CONFIG_OPEN_DRAIN BIT(2) +#define BMP580_INT_CONFIG_INT_EN BIT(3) + #define BMP580_STATUS_CORE_RDY_MASK BIT(0) #define BMP580_STATUS_NVM_RDY_MASK BIT(1) #define BMP580_STATUS_NVM_ERR_MASK BIT(2) @@ -170,6 +179,19 @@ #define BMP380_MODE_FORCED 1 #define BMP380_MODE_NORMAL 3 +#define BMP380_MEAS_OFFSET 234 +#define BMP380_MEAS_DUR 2020 +#define BMP380_TEMP_MEAS_OFFSET 163 +#define BMP380_PRESS_MEAS_OFFSET 392 + +#define BMP380_INT_STATUS_DRDY BIT(3) + +#define BMP380_INT_CTRL_SETTINGS_MASK GENMASK(2, 0) +#define BMP380_INT_CTRL_OPEN_DRAIN BIT(0) +#define BMP380_INT_CTRL_LEVEL BIT(1) +#define BMP380_INT_CTRL_LATCH BIT(2) +#define BMP380_INT_CTRL_DRDY_EN BIT(6) + #define BMP380_MIN_TEMP -4000 #define BMP380_MAX_TEMP 8500 #define BMP380_MIN_PRES 3000000 @@ -205,6 +227,10 @@ #define BMP280_REG_CONFIG 0xF5 #define BMP280_REG_CTRL_MEAS 0xF4 #define BMP280_REG_STATUS 0xF3 +#define BMP280_REG_STATUS_IM_UPDATE BIT(0) +#define BMP280_REG_STATUS_MEAS_BIT BIT(3) +#define BMP280_REG_RESET 0xE0 +#define BMP280_RST_SOFT_CMD 0xB6 #define BMP280_REG_COMP_TEMP_START 0x88 #define BMP280_COMP_TEMP_REG_COUNT 6 @@ -243,6 +269,10 @@ #define BMP280_MODE_FORCED 1 #define BMP280_MODE_NORMAL 3 +#define BMP280_MEAS_OFFSET 1250 +#define BMP280_MEAS_DUR 2300 +#define BMP280_PRESS_HUMID_MEAS_OFFSET 575 + /* BME280 specific registers */ #define BME280_REG_HUMIDITY_LSB 0xFE #define BME280_REG_HUMIDITY_MSB 0xFD @@ -257,8 +287,13 @@ #define BME280_REG_COMP_H5 0xE5 #define BME280_REG_COMP_H6 0xE7 +#define BME280_COMP_H4_GET_MASK_UP GENMASK(15, 8) +#define BME280_COMP_H4_PREP_MASK_UP GENMASK(11, 4) +#define BME280_COMP_H4_MASK_LOW GENMASK(3, 0) #define BME280_COMP_H5_MASK GENMASK(15, 4) +#define BME280_CONTIGUOUS_CALIB_REGS 7 + #define BME280_OSRS_HUMIDITY_MASK GENMASK(2, 0) #define BME280_OSRS_HUMIDITY_SKIP 0 #define BME280_OSRS_HUMIDITY_1X 1 @@ -314,6 +349,7 @@ BMP280_NUM_TEMP_BYTES + \ BME280_NUM_HUMIDITY_BYTES) +#define BME280_NUM_MAX_CHANNELS 3 /* Core exported structs */ static const char *const bmp280_supply_names[] = { @@ -376,12 +412,21 @@ struct bmp380_calib { s8 P11; }; +enum bmp280_op_mode { + BMP280_SLEEP, + BMP280_FORCED, + BMP280_NORMAL, +}; + struct bmp280_data { struct device *dev; struct mutex lock; struct regmap *regmap; struct completion done; bool use_eoc; + bool trig_open_drain; + bool trig_active_high; + struct iio_trigger *trig; const struct bmp280_chip_info *chip_info; union { struct bmp180_calib bmp180; @@ -411,7 +456,11 @@ struct bmp280_data { * Data to push to userspace triggered buffer. Up to 3 channels and * s64 timestamp, aligned. */ - s32 sensor_data[6] __aligned(8); + u8 sensor_data[ALIGN(sizeof(s32) * BME280_NUM_MAX_CHANNELS, sizeof(s64)) + + sizeof(s64)] __aligned(sizeof(s64)); + + /* Value to hold the current operation mode of the device */ + enum bmp280_op_mode op_mode; /* * DMA (thus cache coherency maintenance) may require the @@ -423,6 +472,7 @@ struct bmp280_data { /* Calibration data buffers */ __le16 bmp280_cal_buf[BMP280_CONTIGUOUS_CALIB_REGS / 2]; __be16 bmp180_cal_buf[BMP180_REG_CALIB_COUNT / 2]; + u8 bme280_humid_cal_buf[BME280_CONTIGUOUS_CALIB_REGS]; u8 bmp380_cal_buf[BMP380_CALIB_REG_COUNT]; /* Miscellaneous, endianness-aware data buffers */ __le16 le16; @@ -476,11 +526,15 @@ struct bmp280_chip_info { int (*read_humid)(struct bmp280_data *data, u32 *adc_humidity); int (*read_calib)(struct bmp280_data *data); int (*preinit)(struct bmp280_data *data); + int (*set_mode)(struct bmp280_data *data, enum bmp280_op_mode mode); + int (*wait_conv)(struct bmp280_data *data); + int (*trigger_probe)(struct iio_dev *indio_dev); irqreturn_t (*trigger_handler)(int irq, void *p); }; /* Chip infos for each variant */ +extern const struct bmp280_chip_info bmp085_chip_info; extern const struct bmp280_chip_info bmp180_chip_info; extern const struct bmp280_chip_info bmp280_chip_info; extern const struct bmp280_chip_info bme280_chip_info; diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c index 956045e2db293c541f0559d082f8e8a76c38ff9d..f7273d30c5f085dda08aaea521631a777dec860a 100644 --- a/drivers/iio/pressure/hid-sensor-press.c +++ b/drivers/iio/pressure/hid-sensor-press.c @@ -24,7 +24,7 @@ struct press_state { struct hid_sensor_hub_attribute_info press_attr; struct { u32 press_data; - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -241,11 +241,11 @@ static int press_parse_report(struct platform_device *pdev, /* Function to initialize the processing for usage id */ static int hid_press_probe(struct platform_device *pdev) { + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); int ret = 0; static const char *name = "press"; struct iio_dev *indio_dev; struct press_state *press_state; - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct press_state)); @@ -325,7 +325,7 @@ error_remove_trigger: /* Function to deinitialize the processing for usage id */ static void hid_press_remove(struct platform_device *pdev) { - struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct press_state *press_state = iio_priv(indio_dev); @@ -350,11 +350,11 @@ static struct platform_driver hid_press_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_press_probe, - .remove_new = hid_press_remove, + .remove = hid_press_remove, }; module_platform_driver(hid_press_platform_driver); MODULE_DESCRIPTION("HID Sensor Pressure"); MODULE_AUTHOR("Archana Patni "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/pressure/hsc030pa.c b/drivers/iio/pressure/hsc030pa.c index 4e6f10eeabc301c33764ec3aee64621e0c692996..168245818cfe364d71a9d67c3a3f250e658387b2 100644 --- a/drivers/iio/pressure/hsc030pa.c +++ b/drivers/iio/pressure/hsc030pa.c @@ -534,7 +534,7 @@ int hsc_common_probe(struct device *dev, hsc_recv_fn recv) return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS(hsc_common_probe, IIO_HONEYWELL_HSC030PA); +EXPORT_SYMBOL_NS(hsc_common_probe, "IIO_HONEYWELL_HSC030PA"); MODULE_AUTHOR("Petre Rodan "); MODULE_DESCRIPTION("Honeywell HSC and SSC pressure sensor core driver"); diff --git a/drivers/iio/pressure/hsc030pa_i2c.c b/drivers/iio/pressure/hsc030pa_i2c.c index b3fd230e71da12a34c3b26e1d3b01267faa6c3bf..7f2398aa815525951818b9f0bab3cc3f442c60ef 100644 --- a/drivers/iio/pressure/hsc030pa_i2c.c +++ b/drivers/iio/pressure/hsc030pa_i2c.c @@ -71,4 +71,4 @@ module_i2c_driver(hsc_i2c_driver); MODULE_AUTHOR("Petre Rodan "); MODULE_DESCRIPTION("Honeywell HSC and SSC pressure sensor i2c driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HONEYWELL_HSC030PA); +MODULE_IMPORT_NS("IIO_HONEYWELL_HSC030PA"); diff --git a/drivers/iio/pressure/hsc030pa_spi.c b/drivers/iio/pressure/hsc030pa_spi.c index 337eecc577d2a2c76191c9e86780cfa65da62802..60768726e9ad82aac86773a5433f5126a64f06c9 100644 --- a/drivers/iio/pressure/hsc030pa_spi.c +++ b/drivers/iio/pressure/hsc030pa_spi.c @@ -58,4 +58,4 @@ module_spi_driver(hsc_spi_driver); MODULE_AUTHOR("Petre Rodan "); MODULE_DESCRIPTION("Honeywell HSC and SSC pressure sensor spi driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HONEYWELL_HSC030PA); +MODULE_IMPORT_NS("IIO_HONEYWELL_HSC030PA"); diff --git a/drivers/iio/pressure/mpl115.c b/drivers/iio/pressure/mpl115.c index 02ea38c8a3e4312264ca3078d3c31b3c94158c96..71beb28b7f2ca060737ed3d82c08abebc5feee59 100644 --- a/drivers/iio/pressure/mpl115.c +++ b/drivers/iio/pressure/mpl115.c @@ -225,7 +225,7 @@ int mpl115_probe(struct device *dev, const char *name, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(mpl115_probe, IIO_MPL115); +EXPORT_SYMBOL_NS_GPL(mpl115_probe, "IIO_MPL115"); static int mpl115_runtime_suspend(struct device *dev) { diff --git a/drivers/iio/pressure/mpl115_i2c.c b/drivers/iio/pressure/mpl115_i2c.c index 0c51dc02478e21cc1aaf4e8c4826559c14e99811..3db9ef4e2770f15f08c761ae8b5fa2066b6f3ca0 100644 --- a/drivers/iio/pressure/mpl115_i2c.c +++ b/drivers/iio/pressure/mpl115_i2c.c @@ -63,4 +63,4 @@ module_i2c_driver(mpl115_i2c_driver); MODULE_AUTHOR("Peter Meerwald "); MODULE_DESCRIPTION("Freescale MPL115A2 pressure/temperature driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_MPL115); +MODULE_IMPORT_NS("IIO_MPL115"); diff --git a/drivers/iio/pressure/mpl115_spi.c b/drivers/iio/pressure/mpl115_spi.c index 58d218fd90dcb9666a530b9011ad7394983f7d19..888cfa6662381e5b8d59d628fb2158bb2504052b 100644 --- a/drivers/iio/pressure/mpl115_spi.c +++ b/drivers/iio/pressure/mpl115_spi.c @@ -102,4 +102,4 @@ module_spi_driver(mpl115_spi_driver); MODULE_AUTHOR("Akinobu Mita "); MODULE_DESCRIPTION("Freescale MPL115A1 pressure/temperature driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_MPL115); +MODULE_IMPORT_NS("IIO_MPL115"); diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index 3b6145348c2e3b46ae4d98450fe3944fcccdd1f8..2336f2760eaeb72903ab77128bb1cdcac045b56b 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -448,7 +448,7 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) return 0; } -EXPORT_SYMBOL_NS(mpr_common_probe, IIO_HONEYWELL_MPRLS0025PA); +EXPORT_SYMBOL_NS(mpr_common_probe, "IIO_HONEYWELL_MPRLS0025PA"); MODULE_AUTHOR("Andreas Klinger "); MODULE_DESCRIPTION("Honeywell MPR pressure sensor core driver"); diff --git a/drivers/iio/pressure/mprls0025pa_i2c.c b/drivers/iio/pressure/mprls0025pa_i2c.c index 7a5c5aa2b456b9af50637143b823b1bd4cbbb172..48b23a4256ced00f02d41853e6c0eb976124be8c 100644 --- a/drivers/iio/pressure/mprls0025pa_i2c.c +++ b/drivers/iio/pressure/mprls0025pa_i2c.c @@ -97,4 +97,4 @@ module_i2c_driver(mpr_i2c_driver); MODULE_AUTHOR("Andreas Klinger "); MODULE_DESCRIPTION("Honeywell MPR pressure sensor i2c driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HONEYWELL_MPRLS0025PA); +MODULE_IMPORT_NS("IIO_HONEYWELL_MPRLS0025PA"); diff --git a/drivers/iio/pressure/mprls0025pa_spi.c b/drivers/iio/pressure/mprls0025pa_spi.c index 3aed14cd95c5ab6f5126aab0dfc99862e1629428..09f724c76d706e3167e0e7e34333cafac6bbd978 100644 --- a/drivers/iio/pressure/mprls0025pa_spi.c +++ b/drivers/iio/pressure/mprls0025pa_spi.c @@ -89,4 +89,4 @@ module_spi_driver(mpr_spi_driver); MODULE_AUTHOR("Petre Rodan "); MODULE_DESCRIPTION("Honeywell MPR pressure sensor spi driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HONEYWELL_MPRLS0025PA); +MODULE_IMPORT_NS("IIO_HONEYWELL_MPRLS0025PA"); diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c index 2fc706f9d8ae7d1db059f9c60483b71946a16f4e..056c8271c49d937b4331e6e731a74317022ed126 100644 --- a/drivers/iio/pressure/ms5611_core.c +++ b/drivers/iio/pressure/ms5611_core.c @@ -449,7 +449,7 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, return 0; } -EXPORT_SYMBOL_NS(ms5611_probe, IIO_MS5611); +EXPORT_SYMBOL_NS(ms5611_probe, "IIO_MS5611"); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("MS5611 core driver"); diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index 7e2cb8b6afa223c65f0d6f5b172ab219e2eea3b1..1c041b9085fb019057fdfd5abac5881ff9e3c838 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -132,4 +132,4 @@ module_i2c_driver(ms5611_driver); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("MS5611 i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MS5611); +MODULE_IMPORT_NS("IIO_MS5611"); diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c index 87181963a3e3db36c8ecdceb1a9dc2742eacb297..b5a91e885793543bcd2e8f231a21ba91b8eac6c4 100644 --- a/drivers/iio/pressure/ms5611_spi.c +++ b/drivers/iio/pressure/ms5611_spi.c @@ -134,4 +134,4 @@ module_spi_driver(ms5611_driver); MODULE_AUTHOR("Tomasz Duszynski "); MODULE_DESCRIPTION("MS5611 spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MS5611); +MODULE_IMPORT_NS("IIO_MS5611"); diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c index ac30d76285d1c2d45598fcc02928b19ca41b71cd..a1767a17fdce9174878e21f07001098d676937ba 100644 --- a/drivers/iio/pressure/ms5637.c +++ b/drivers/iio/pressure/ms5637.c @@ -248,4 +248,4 @@ MODULE_DESCRIPTION("Measurement-Specialties ms5637 temperature & pressure driver MODULE_AUTHOR("William Markezana "); MODULE_AUTHOR("Ludovic Tancerel "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MEAS_SPEC_SENSORS); +MODULE_IMPORT_NS("IIO_MEAS_SPEC_SENSORS"); diff --git a/drivers/iio/pressure/rohm-bm1390.c b/drivers/iio/pressure/rohm-bm1390.c index ccaa07a569c9a8a07c6965ef0cf4ba4a734a42ee..f24d9f92768123fee772320fcecf906e69c23c40 100644 --- a/drivers/iio/pressure/rohm-bm1390.c +++ b/drivers/iio/pressure/rohm-bm1390.c @@ -417,9 +417,6 @@ static int __bm1390_fifo_flush(struct iio_dev *idev, unsigned int samples, return ret; } - if (ret) - return ret; - for (i = 0; i < smp_lvl; i++) { buffer[i].temp = temp; iio_push_to_buffers(idev, &buffer[i]); diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 597bf268ea5172e10d1fba4bbb92d8982816bf15..b70d1cee82f3248698f45a547e1c2efd5c8d4be1 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -738,7 +738,7 @@ const struct st_sensor_settings *st_press_get_settings(const char *name) return &st_press_sensors_settings[index]; } -EXPORT_SYMBOL_NS(st_press_get_settings, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_press_get_settings, "IIO_ST_SENSORS"); int st_press_common_probe(struct iio_dev *indio_dev) { @@ -790,9 +790,9 @@ int st_press_common_probe(struct iio_dev *indio_dev) return devm_iio_device_register(parent, indio_dev); } -EXPORT_SYMBOL_NS(st_press_common_probe, IIO_ST_SENSORS); +EXPORT_SYMBOL_NS(st_press_common_probe, "IIO_ST_SENSORS"); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics pressures driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 389523d6ae32106fcf396e2ae0290de4b9d759a7..b7b66ddc3a7307bda2ee35503c35592de63b29bb 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -121,4 +121,4 @@ module_i2c_driver(st_press_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics pressures i2c driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index 25cca5ad7c5599df8544eb10edcbe223e484aca0..1a4bd1a0f78745505cca1c12bf242d80c9770afa 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -123,4 +123,4 @@ module_spi_driver(st_press_driver); MODULE_AUTHOR("Denis Ciocca "); MODULE_DESCRIPTION("STMicroelectronics pressures spi driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ST_SENSORS); +MODULE_IMPORT_NS("IIO_ST_SENSORS"); diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index 950f8dee2b26b771e418733d433593259d9d9305..2adea84f5b4d08d56ed884ad1c80468cc5c1d1a9 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -162,7 +162,7 @@ bool zpa2326_isreg_writeable(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(zpa2326_isreg_writeable, IIO_ZPA2326); +EXPORT_SYMBOL_NS_GPL(zpa2326_isreg_writeable, "IIO_ZPA2326"); bool zpa2326_isreg_readable(struct device *dev, unsigned int reg) { @@ -191,7 +191,7 @@ bool zpa2326_isreg_readable(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(zpa2326_isreg_readable, IIO_ZPA2326); +EXPORT_SYMBOL_NS_GPL(zpa2326_isreg_readable, "IIO_ZPA2326"); bool zpa2326_isreg_precious(struct device *dev, unsigned int reg) { @@ -204,7 +204,7 @@ bool zpa2326_isreg_precious(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(zpa2326_isreg_precious, IIO_ZPA2326); +EXPORT_SYMBOL_NS_GPL(zpa2326_isreg_precious, "IIO_ZPA2326"); /** * zpa2326_enable_device() - Enable device, i.e. get out of low power mode. @@ -649,7 +649,7 @@ const struct dev_pm_ops zpa2326_pm_ops = { SET_RUNTIME_PM_OPS(zpa2326_runtime_suspend, zpa2326_runtime_resume, NULL) }; -EXPORT_SYMBOL_NS_GPL(zpa2326_pm_ops, IIO_ZPA2326); +EXPORT_SYMBOL_NS_GPL(zpa2326_pm_ops, "IIO_ZPA2326"); /** * zpa2326_resume() - Request the PM layer to power supply the device. @@ -1698,7 +1698,7 @@ poweroff: return err; } -EXPORT_SYMBOL_NS_GPL(zpa2326_probe, IIO_ZPA2326); +EXPORT_SYMBOL_NS_GPL(zpa2326_probe, "IIO_ZPA2326"); void zpa2326_remove(const struct device *parent) { @@ -1709,7 +1709,7 @@ void zpa2326_remove(const struct device *parent) zpa2326_sleep(indio_dev); zpa2326_power_off(indio_dev, iio_priv(indio_dev)); } -EXPORT_SYMBOL_NS_GPL(zpa2326_remove, IIO_ZPA2326); +EXPORT_SYMBOL_NS_GPL(zpa2326_remove, "IIO_ZPA2326"); MODULE_AUTHOR("Gregor Boirie "); MODULE_DESCRIPTION("Core driver for Murata ZPA2326 pressure sensor"); diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c index 4833e525c39357a4a15165937c99a85b4415b3a3..49a239ebdabff56dd81efbade18f82494d7e264f 100644 --- a/drivers/iio/pressure/zpa2326_i2c.c +++ b/drivers/iio/pressure/zpa2326_i2c.c @@ -85,4 +85,4 @@ module_i2c_driver(zpa2326_i2c_driver); MODULE_AUTHOR("Gregor Boirie "); MODULE_DESCRIPTION("I2C driver for Murata ZPA2326 pressure sensor"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ZPA2326); +MODULE_IMPORT_NS("IIO_ZPA2326"); diff --git a/drivers/iio/pressure/zpa2326_spi.c b/drivers/iio/pressure/zpa2326_spi.c index 9c1bcb82d3604e3139abf545a396f95fed22128c..317270fa1c435196db6386d7ecb37d1c29bb8ed1 100644 --- a/drivers/iio/pressure/zpa2326_spi.c +++ b/drivers/iio/pressure/zpa2326_spi.c @@ -89,4 +89,4 @@ module_spi_driver(zpa2326_spi_driver); MODULE_AUTHOR("Gregor Boirie "); MODULE_DESCRIPTION("SPI driver for Murata ZPA2326 pressure sensor"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_ZPA2326); +MODULE_IMPORT_NS("IIO_ZPA2326"); diff --git a/drivers/iio/proximity/aw96103.c b/drivers/iio/proximity/aw96103.c index 707ba0a510aa5f2a30d3fa70ae81fa58b8dfbc33..cdd254da9e5035e3c3e062fe27982b4108cc6a45 100644 --- a/drivers/iio/proximity/aw96103.c +++ b/drivers/iio/proximity/aw96103.c @@ -422,7 +422,7 @@ static int aw96103_read_event_config(struct iio_dev *indio_dev, static int aw96103_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct aw96103 *aw96103 = iio_priv(indio_dev); diff --git a/drivers/iio/proximity/cros_ec_mkbp_proximity.c b/drivers/iio/proximity/cros_ec_mkbp_proximity.c index c25472b14d4be0f2c2fdf34aae868d7bd5748057..667369be05553ea668bfcd79695645dbf1e56a25 100644 --- a/drivers/iio/proximity/cros_ec_mkbp_proximity.c +++ b/drivers/iio/proximity/cros_ec_mkbp_proximity.c @@ -167,7 +167,7 @@ static int cros_ec_mkbp_proximity_read_event_config(struct iio_dev *indio_dev, static int cros_ec_mkbp_proximity_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct cros_ec_mkbp_proximity_data *data = iio_priv(indio_dev); @@ -261,7 +261,7 @@ static struct platform_driver cros_ec_mkbp_proximity_driver = { .pm = pm_sleep_ptr(&cros_ec_mkbp_proximity_pm_ops), }, .probe = cros_ec_mkbp_proximity_probe, - .remove_new = cros_ec_mkbp_proximity_remove, + .remove = cros_ec_mkbp_proximity_remove, }; module_platform_driver(cros_ec_mkbp_proximity_driver); diff --git a/drivers/iio/proximity/hx9023s.c b/drivers/iio/proximity/hx9023s.c index d8fb34060d3db88a3ba5ecdc209b14be8e42e8b9..4021feb7a7ac70a135fb5fdcb832b9218b961fdc 100644 --- a/drivers/iio/proximity/hx9023s.c +++ b/drivers/iio/proximity/hx9023s.c @@ -874,12 +874,12 @@ static int hx9023s_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct hx9023s_data *data = iio_priv(indio_dev); if (test_bit(chan->channel, &data->chan_in_use)) { - hx9023s_ch_en(data, chan->channel, !!state); + hx9023s_ch_en(data, chan->channel, state); __assign_bit(chan->channel, &data->chan_event, data->ch_data[chan->channel].enable); } diff --git a/drivers/iio/proximity/irsd200.c b/drivers/iio/proximity/irsd200.c index 6e96b764fed8b577d71c3146210679b0b61d4c38..b09d15230111e6e5bbaae189adc26059a5a19f7a 100644 --- a/drivers/iio/proximity/irsd200.c +++ b/drivers/iio/proximity/irsd200.c @@ -648,7 +648,8 @@ static int irsd200_read_event_config(struct iio_dev *indio_dev, static int irsd200_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, + bool state) { struct irsd200_data *data = iio_priv(indio_dev); unsigned int tmp; @@ -662,7 +663,7 @@ static int irsd200_write_event_config(struct iio_dev *indio_dev, return ret; return regmap_field_write( - data->regfields[IRS_REGF_INTR_COUNT_THR_OR], !!state); + data->regfields[IRS_REGF_INTR_COUNT_THR_OR], state); default: return -EINVAL; } diff --git a/drivers/iio/proximity/srf04.c b/drivers/iio/proximity/srf04.c index 86c57672fc7e36f6f40babb5d58b076b31f59061..71ad29e441b23773afb18724df53769eea1d1733 100644 --- a/drivers/iio/proximity/srf04.c +++ b/drivers/iio/proximity/srf04.c @@ -389,7 +389,7 @@ static const struct dev_pm_ops srf04_pm_ops = { static struct platform_driver srf04_driver = { .probe = srf04_probe, - .remove_new = srf04_remove, + .remove = srf04_remove, .driver = { .name = "srf04-gpio", .of_match_table = of_srf04_match, diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c index 427c9343d6d163a20c2a19a3800254c5be5eb34f..0d7f0518d4fb952cc883d0f3959b6c777a616f01 100644 --- a/drivers/iio/proximity/sx9310.c +++ b/drivers/iio/proximity/sx9310.c @@ -1029,4 +1029,4 @@ MODULE_AUTHOR("Gwendal Grignou "); MODULE_AUTHOR("Daniel Campello "); MODULE_DESCRIPTION("Driver for Semtech SX9310/SX9311 proximity sensor"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SEMTECH_PROX); +MODULE_IMPORT_NS("SEMTECH_PROX"); diff --git a/drivers/iio/proximity/sx9324.c b/drivers/iio/proximity/sx9324.c index 629f83c37d595be28e403da4ff09648d0c8308cf..f7819dd2775cd0b5b531512fc7c70cdfa4267e46 100644 --- a/drivers/iio/proximity/sx9324.c +++ b/drivers/iio/proximity/sx9324.c @@ -868,6 +868,26 @@ static u8 sx9324_parse_phase_prop(struct device *dev, return raw; } +static void sx_common_get_raw_register_config(struct device *dev, + struct sx_common_reg_default *reg_def) +{ +#ifdef CONFIG_ACPI + struct acpi_device *adev = ACPI_COMPANION(dev); + u32 raw = 0, ret; + char prop[80]; + + if (!reg_def->property || !adev) + return; + + snprintf(prop, ARRAY_SIZE(prop), "%s,reg_%s", acpi_device_hid(adev), reg_def->property); + ret = device_property_read_u32(dev, prop, &raw); + if (ret) + return; + + reg_def->def = raw; +#endif +} + static const struct sx_common_reg_default * sx9324_get_default_reg(struct device *dev, int idx, struct sx_common_reg_default *reg_def) @@ -1135,4 +1155,4 @@ module_i2c_driver(sx9324_driver); MODULE_AUTHOR("Gwendal Grignou "); MODULE_DESCRIPTION("Driver for Semtech SX9324 proximity sensor"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SEMTECH_PROX); +MODULE_IMPORT_NS("SEMTECH_PROX"); diff --git a/drivers/iio/proximity/sx9360.c b/drivers/iio/proximity/sx9360.c index 2b90bf45a201212eaba8d1a0461c96452fbaaeca..a6ff16e33c1e205e661fc3504a11e7b060cf1e31 100644 --- a/drivers/iio/proximity/sx9360.c +++ b/drivers/iio/proximity/sx9360.c @@ -7,7 +7,6 @@ * https://edit.wpgdadawant.com/uploads/news_file/program/2019/30184/tech_files/program_30184_suggest_other_file.pdf */ -#include #include #include #include @@ -866,4 +865,4 @@ module_i2c_driver(sx9360_driver); MODULE_AUTHOR("Gwendal Grignou "); MODULE_DESCRIPTION("Driver for Semtech SX9360 proximity sensor"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SEMTECH_PROX); +MODULE_IMPORT_NS("SEMTECH_PROX"); diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index 3f4eace05cfc6a4679fe82854dc059aa4a710d6d..c4e94d0fb163740e5acb9bd1a3afd694023b04fa 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -540,7 +540,7 @@ static int sx9500_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct sx9500_data *data = iio_priv(indio_dev); int ret; @@ -551,7 +551,7 @@ static int sx9500_write_event_config(struct iio_dev *indio_dev, mutex_lock(&data->mutex); - if (state == 1) { + if (state) { ret = sx9500_inc_chan_users(data, chan->channel); if (ret < 0) goto out_unlock; @@ -571,7 +571,7 @@ static int sx9500_write_event_config(struct iio_dev *indio_dev, goto out_unlock; out_undo_chan: - if (state == 1) + if (state) sx9500_dec_chan_users(data, chan->channel); else sx9500_inc_chan_users(data, chan->channel); diff --git a/drivers/iio/proximity/sx_common.c b/drivers/iio/proximity/sx_common.c index 71aa6dced7d3422df8b057ebe347ee37783facfe..f70198a1f0d1452b5ff210e35d5703beabd08799 100644 --- a/drivers/iio/proximity/sx_common.c +++ b/drivers/iio/proximity/sx_common.c @@ -53,7 +53,7 @@ const struct iio_event_spec sx_common_events[3] = { BIT(IIO_EV_INFO_VALUE), }, }; -EXPORT_SYMBOL_NS_GPL(sx_common_events, SEMTECH_PROX); +EXPORT_SYMBOL_NS_GPL(sx_common_events, "SEMTECH_PROX"); static irqreturn_t sx_common_irq_handler(int irq, void *private) { @@ -233,7 +233,7 @@ out: return ret; } -EXPORT_SYMBOL_NS_GPL(sx_common_read_proximity, SEMTECH_PROX); +EXPORT_SYMBOL_NS_GPL(sx_common_read_proximity, "SEMTECH_PROX"); /** * sx_common_read_event_config() - Configure event setting. @@ -253,7 +253,7 @@ int sx_common_read_event_config(struct iio_dev *indio_dev, return !!(data->chan_event & BIT(chan->channel)); } -EXPORT_SYMBOL_NS_GPL(sx_common_read_event_config, SEMTECH_PROX); +EXPORT_SYMBOL_NS_GPL(sx_common_read_event_config, "SEMTECH_PROX"); /** * sx_common_write_event_config() - Configure event setting. @@ -268,7 +268,7 @@ EXPORT_SYMBOL_NS_GPL(sx_common_read_event_config, SEMTECH_PROX); int sx_common_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct sx_common_data *data = iio_priv(indio_dev); unsigned int eventirq = SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ; @@ -303,7 +303,7 @@ out_unlock: mutex_unlock(&data->mutex); return ret; } -EXPORT_SYMBOL_NS_GPL(sx_common_write_event_config, SEMTECH_PROX); +EXPORT_SYMBOL_NS_GPL(sx_common_write_event_config, "SEMTECH_PROX"); static int sx_common_set_trigger_state(struct iio_trigger *trig, bool state) { @@ -421,27 +421,6 @@ static const struct iio_buffer_setup_ops sx_common_buffer_setup_ops = { .postdisable = sx_common_buffer_postdisable, }; -void sx_common_get_raw_register_config(struct device *dev, - struct sx_common_reg_default *reg_def) -{ -#ifdef CONFIG_ACPI - struct acpi_device *adev = ACPI_COMPANION(dev); - u32 raw = 0, ret; - char prop[80]; - - if (!reg_def->property || !adev) - return; - - snprintf(prop, ARRAY_SIZE(prop), "%s,reg_%s", acpi_device_hid(adev), reg_def->property); - ret = device_property_read_u32(dev, prop, &raw); - if (ret) - return; - - reg_def->def = raw; -#endif -} -EXPORT_SYMBOL_NS_GPL(sx_common_get_raw_register_config, SEMTECH_PROX); - #define SX_COMMON_SOFT_RESET 0xde static int sx_common_init_device(struct device *dev, struct iio_dev *indio_dev) @@ -563,7 +542,7 @@ int sx_common_probe(struct i2c_client *client, return devm_iio_device_register(dev, indio_dev); } -EXPORT_SYMBOL_NS_GPL(sx_common_probe, SEMTECH_PROX); +EXPORT_SYMBOL_NS_GPL(sx_common_probe, "SEMTECH_PROX"); MODULE_AUTHOR("Gwendal Grignou "); MODULE_DESCRIPTION("Common functions and structures for Semtech sensor"); diff --git a/drivers/iio/proximity/sx_common.h b/drivers/iio/proximity/sx_common.h index 101b90e52ff268983383836ae099e696376718f1..fb14e6f06a6de3485e0b817e4a069d5300ddfb6c 100644 --- a/drivers/iio/proximity/sx_common.h +++ b/drivers/iio/proximity/sx_common.h @@ -8,7 +8,6 @@ #ifndef IIO_SX_COMMON_H #define IIO_SX_COMMON_H -#include #include #include #include @@ -144,15 +143,12 @@ int sx_common_read_event_config(struct iio_dev *indio_dev, int sx_common_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state); + enum iio_event_direction dir, bool state); int sx_common_probe(struct i2c_client *client, const struct sx_common_chip_info *chip_info, const struct regmap_config *regmap_config); -void sx_common_get_raw_register_config(struct device *dev, - struct sx_common_reg_default *reg_def); - /* 3 is the number of events defined by a single phase. */ extern const struct iio_event_spec sx_common_events[3]; diff --git a/drivers/iio/proximity/vcnl3020.c b/drivers/iio/proximity/vcnl3020.c index d1ddf85f53836ec34464d382426b187804964a57..bb6c9cc88b358de098543df8a0da7d22914c5e47 100644 --- a/drivers/iio/proximity/vcnl3020.c +++ b/drivers/iio/proximity/vcnl3020.c @@ -449,7 +449,7 @@ static int vcnl3020_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { switch (chan->type) { case IIO_PROXIMITY: diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c index 8d4f3f849fe246370f34d6c4b0a4dbaf90204d6a..87d10faaff9b11eb37d22a9372187425072976a7 100644 --- a/drivers/iio/proximity/vl53l0x-i2c.c +++ b/drivers/iio/proximity/vl53l0x-i2c.c @@ -20,8 +20,13 @@ #include #include #include +#include #include +#include +#include +#include +#include #define VL_REG_SYSRANGE_START 0x00 @@ -39,21 +44,74 @@ #define VL_REG_RESULT_INT_STATUS 0x13 #define VL_REG_RESULT_RANGE_STATUS 0x14 +#define VL_REG_IDENTIFICATION_MODEL_ID 0xC0 #define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0) +#define VL53L0X_MODEL_ID_VAL 0xEE +#define VL53L0X_CONTINUOUS_MODE 0x02 +#define VL53L0X_SINGLE_MODE 0x01 + struct vl53l0x_data { struct i2c_client *client; struct completion completion; struct regulator *vdd_supply; struct gpio_desc *reset_gpio; + struct iio_trigger *trig; + + struct { + u16 chan; + aligned_s64 timestamp; + } scan; }; -static irqreturn_t vl53l0x_handle_irq(int irq, void *priv) +static int vl53l0x_clear_irq(struct vl53l0x_data *data) +{ int ret; + + ret = i2c_smbus_write_byte_data(data->client, + VL_REG_SYSTEM_INTERRUPT_CLEAR, 1); + if (ret < 0) { + dev_err(&data->client->dev, "failed to clear irq: %d\n", ret); + return -EINVAL; + } + + return 0; +} + +static irqreturn_t vl53l0x_trigger_handler(int irq, void *priv) +{ + struct iio_poll_func *pf = priv; + struct iio_dev *indio_dev = pf->indio_dev; + struct vl53l0x_data *data = iio_priv(indio_dev); + u8 buffer[12]; + int ret; + + ret = i2c_smbus_read_i2c_block_data(data->client, + VL_REG_RESULT_RANGE_STATUS, + sizeof(buffer), buffer); + if (ret < 0) + return ret; + else if (ret != 12) + return -EREMOTEIO; + + data->scan.chan = get_unaligned_be16(&buffer[10]); + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + iio_get_time_ns(indio_dev)); + + iio_trigger_notify_done(indio_dev->trig); + vl53l0x_clear_irq(data); + + return IRQ_HANDLED; +} + +static irqreturn_t vl53l0x_threaded_irq(int irq, void *priv) { struct iio_dev *indio_dev = priv; struct vl53l0x_data *data = iio_priv(indio_dev); - complete(&data->completion); + if (iio_buffer_enabled(indio_dev)) + iio_trigger_poll_nested(indio_dev->trig); + else + complete(&data->completion); return IRQ_HANDLED; } @@ -68,8 +126,9 @@ static int vl53l0x_configure_irq(struct i2c_client *client, if (!irq_flags) irq_flags = IRQF_TRIGGER_FALLING; - ret = devm_request_irq(&client->dev, client->irq, vl53l0x_handle_irq, - irq_flags, indio_dev->name, indio_dev); + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, vl53l0x_threaded_irq, + irq_flags | IRQF_ONESHOT, indio_dev->name, indio_dev); if (ret) { dev_err(&client->dev, "devm_request_irq error: %d\n", ret); return ret; @@ -84,26 +143,6 @@ static int vl53l0x_configure_irq(struct i2c_client *client, return ret; } -static void vl53l0x_clear_irq(struct vl53l0x_data *data) -{ - struct device *dev = &data->client->dev; - int ret; - - ret = i2c_smbus_write_byte_data(data->client, - VL_REG_SYSTEM_INTERRUPT_CLEAR, 1); - if (ret < 0) - dev_err(dev, "failed to clear error irq: %d\n", ret); - - ret = i2c_smbus_write_byte_data(data->client, - VL_REG_SYSTEM_INTERRUPT_CLEAR, 0); - if (ret < 0) - dev_err(dev, "failed to clear range irq: %d\n", ret); - - ret = i2c_smbus_read_byte_data(data->client, VL_REG_RESULT_INT_STATUS); - if (ret < 0 || ret & 0x07) - dev_err(dev, "failed to clear irq: %d\n", ret); -} - static int vl53l0x_read_proximity(struct vl53l0x_data *data, const struct iio_chan_spec *chan, int *val) @@ -125,7 +164,9 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data, if (time_left == 0) return -ETIMEDOUT; - vl53l0x_clear_irq(data); + ret = vl53l0x_clear_irq(data); + if (ret < 0) + return ret; } else { do { ret = i2c_smbus_read_byte_data(client, @@ -150,7 +191,7 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data, return -EREMOTEIO; /* Values should be between 30~1200 in millimeters. */ - *val = (buffer[10] << 8) + buffer[11]; + *val = get_unaligned_be16(&buffer[10]); return 0; } @@ -160,7 +201,14 @@ static const struct iio_chan_spec vl53l0x_channels[] = { .type = IIO_DISTANCE, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, }, + IIO_CHAN_SOFT_TIMESTAMP(1), }; static int vl53l0x_read_raw(struct iio_dev *indio_dev, @@ -190,8 +238,16 @@ static int vl53l0x_read_raw(struct iio_dev *indio_dev, } } +static int vl53l0x_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig) +{ + struct vl53l0x_data *data = iio_priv(indio_dev); + + return data->trig == trig ? 0 : -EINVAL; +} + static const struct iio_info vl53l0x_info = { .read_raw = vl53l0x_read_raw, + .validate_trigger = vl53l0x_validate_trigger, }; static void vl53l0x_power_off(void *_data) @@ -218,11 +274,46 @@ static int vl53l0x_power_on(struct vl53l0x_data *data) return 0; } +static int vl53l0x_buffer_postenable(struct iio_dev *indio_dev) +{ + struct vl53l0x_data *data = iio_priv(indio_dev); + + return i2c_smbus_write_byte_data(data->client, VL_REG_SYSRANGE_START, + VL53L0X_CONTINUOUS_MODE); +} + +static int vl53l0x_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct vl53l0x_data *data = iio_priv(indio_dev); + int ret; + + ret = i2c_smbus_write_byte_data(data->client, VL_REG_SYSRANGE_START, + VL53L0X_SINGLE_MODE); + if (ret < 0) + return ret; + + /* Let the ongoing reading finish */ + reinit_completion(&data->completion); + wait_for_completion_timeout(&data->completion, HZ / 10); + + return vl53l0x_clear_irq(data); +} + +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { + .postenable = &vl53l0x_buffer_postenable, + .postdisable = &vl53l0x_buffer_postdisable, +}; + +static const struct iio_trigger_ops vl53l0x_trigger_ops = { + .validate_device = iio_trigger_validate_own_device, +}; + static int vl53l0x_probe(struct i2c_client *client) { struct vl53l0x_data *data; struct iio_dev *indio_dev; int error; + int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) @@ -237,6 +328,13 @@ static int vl53l0x_probe(struct i2c_client *client) I2C_FUNC_SMBUS_BYTE_DATA)) return -EOPNOTSUPP; + ret = i2c_smbus_read_byte_data(data->client, VL_REG_IDENTIFICATION_MODEL_ID); + if (ret < 0) + return -EINVAL; + + if (ret != VL53L0X_MODEL_ID_VAL) + dev_info(&client->dev, "Unknown model id: 0x%x", ret); + data->vdd_supply = devm_regulator_get(&client->dev, "vdd"); if (IS_ERR(data->vdd_supply)) return dev_err_probe(&client->dev, PTR_ERR(data->vdd_supply), @@ -265,13 +363,33 @@ static int vl53l0x_probe(struct i2c_client *client) /* usage of interrupt is optional */ if (client->irq) { - int ret; - init_completion(&data->completion); + data->trig = devm_iio_trigger_alloc(&client->dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops = &vl53l0x_trigger_ops; + iio_trigger_set_drvdata(data->trig, indio_dev); + ret = devm_iio_trigger_register(&client->dev, data->trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(data->trig); + ret = vl53l0x_configure_irq(client, indio_dev); if (ret) return ret; + + ret = devm_iio_triggered_buffer_setup(&client->dev, + indio_dev, + NULL, + &vl53l0x_trigger_handler, + &iio_triggered_buffer_setup_ops); + if (ret) + return ret; } return devm_iio_device_register(&client->dev, indio_dev); diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig index ed0e4963362f96a0d79e001efd490e03b5a6bd5c..1244d8e17d504ab23425f0c33f5f2d06dadba663 100644 --- a/drivers/iio/temperature/Kconfig +++ b/drivers/iio/temperature/Kconfig @@ -91,6 +91,8 @@ config MLX90635 config TMP006 tristate "TMP006 infrared thermopile sensor" depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help If you say yes here you get support for the Texas Instruments TMP006 infrared thermopile sensor. diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c index 0143fd478933cc6ceea383bb9b2095c95d096b95..692520e1c497bbeda538e217b6a09f43ee26aadc 100644 --- a/drivers/iio/temperature/hid-sensor-temperature.c +++ b/drivers/iio/temperature/hid-sensor-temperature.c @@ -18,7 +18,7 @@ struct temperature_state { struct hid_sensor_hub_attribute_info temperature_attr; struct { s32 temperature_data; - u64 timestamp __aligned(8); + aligned_s64 timestamp; } scan; int scale_pre_decml; int scale_post_decml; @@ -283,11 +283,11 @@ static struct platform_driver hid_temperature_platform_driver = { .pm = &hid_sensor_pm_ops, }, .probe = hid_temperature_probe, - .remove_new = hid_temperature_remove, + .remove = hid_temperature_remove, }; module_platform_driver(hid_temperature_platform_driver); MODULE_DESCRIPTION("HID Environmental temperature sensor"); MODULE_AUTHOR("Song Hongyan "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/iio/temperature/mcp9600.c b/drivers/iio/temperature/mcp9600.c index f1bb0976273d37fd662ed4e7e3f43c9ae82e2aaf..c2447860adfd6f4b1a9f4d61e3de301271fe05d9 100644 --- a/drivers/iio/temperature/mcp9600.c +++ b/drivers/iio/temperature/mcp9600.c @@ -200,7 +200,7 @@ static int mcp9600_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state) + bool state) { struct mcp9600_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index 6d8d661f0c82aa7e610ae28bc7823143a2381cfa..0c844137d7aa907429a125687f1c91f697d1b878 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c @@ -7,8 +7,6 @@ * Driver for the Texas Instruments I2C 16-bit IR thermopile sensor * * (7-bit I2C slave address 0x40, changeable via ADR pins) - * - * TODO: data ready irq */ #include @@ -21,6 +19,9 @@ #include #include +#include +#include +#include #define TMP006_VOBJECT 0x00 #define TMP006_TAMBIENT 0x01 @@ -45,6 +46,7 @@ struct tmp006_data { struct i2c_client *client; u16 config; + struct iio_trigger *drdy_trig; }; static int tmp006_read_measurement(struct tmp006_data *data, u8 reg) @@ -83,15 +85,19 @@ static int tmp006_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: if (channel->type == IIO_VOLTAGE) { /* LSB is 156.25 nV */ - ret = tmp006_read_measurement(data, TMP006_VOBJECT); - if (ret < 0) - return ret; + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret = tmp006_read_measurement(data, TMP006_VOBJECT); + if (ret < 0) + return ret; + } *val = sign_extend32(ret, 15); } else if (channel->type == IIO_TEMP) { /* LSB is 0.03125 degrees Celsius */ - ret = tmp006_read_measurement(data, TMP006_TAMBIENT); - if (ret < 0) - return ret; + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret = tmp006_read_measurement(data, TMP006_TAMBIENT); + if (ret < 0) + return ret; + } *val = sign_extend32(ret, 15) >> TMP006_TAMBIENT_SHIFT; } else { break; @@ -128,7 +134,7 @@ static int tmp006_write_raw(struct iio_dev *indio_dev, long mask) { struct tmp006_data *data = iio_priv(indio_dev); - int i; + int ret, i; if (mask != IIO_CHAN_INFO_SAMP_FREQ) return -EINVAL; @@ -136,13 +142,19 @@ static int tmp006_write_raw(struct iio_dev *indio_dev, for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++) if ((val == tmp006_freqs[i][0]) && (val2 == tmp006_freqs[i][1])) { + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + data->config &= ~TMP006_CONFIG_CR_MASK; data->config |= i << TMP006_CONFIG_CR_SHIFT; - return i2c_smbus_write_word_swapped(data->client, - TMP006_CONFIG, - data->config); + ret = i2c_smbus_write_word_swapped(data->client, + TMP006_CONFIG, + data->config); + iio_device_release_direct_mode(indio_dev); + return ret; } return -EINVAL; } @@ -164,13 +176,29 @@ static const struct iio_chan_spec tmp006_channels[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_BE, + } }, { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - } + .scan_index = 1, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + .shift = TMP006_TAMBIENT_SHIFT, + .endianness = IIO_BE, + } + }, + IIO_CHAN_SOFT_TIMESTAMP(2), }; static const struct iio_info tmp006_info = { @@ -213,6 +241,54 @@ static void tmp006_powerdown_cleanup(void *dev) tmp006_power(dev, false); } +static irqreturn_t tmp006_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct tmp006_data *data = iio_priv(indio_dev); + struct { + s16 channels[2]; + s64 ts __aligned(8); + } scan; + s32 ret; + + ret = i2c_smbus_read_word_data(data->client, TMP006_VOBJECT); + if (ret < 0) + goto err; + scan.channels[0] = ret; + + ret = i2c_smbus_read_word_data(data->client, TMP006_TAMBIENT); + if (ret < 0) + goto err; + scan.channels[1] = ret; + + iio_push_to_buffers_with_timestamp(indio_dev, &scan, + iio_get_time_ns(indio_dev)); +err: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static int tmp006_set_trigger_state(struct iio_trigger *trig, bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct tmp006_data *data = iio_priv(indio_dev); + + if (state) + data->config |= TMP006_CONFIG_DRDY_EN; + else + data->config &= ~TMP006_CONFIG_DRDY_EN; + + return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG, + data->config); +} + +static const struct iio_trigger_ops tmp006_trigger_ops = { + .set_trigger_state = tmp006_set_trigger_state, +}; + +static const unsigned long tmp006_scan_masks[] = { 0x3, 0 }; + static int tmp006_probe(struct i2c_client *client) { struct iio_dev *indio_dev; @@ -241,6 +317,7 @@ static int tmp006_probe(struct i2c_client *client) indio_dev->channels = tmp006_channels; indio_dev->num_channels = ARRAY_SIZE(tmp006_channels); + indio_dev->available_scan_masks = tmp006_scan_masks; ret = i2c_smbus_read_word_swapped(data->client, TMP006_CONFIG); if (ret < 0) @@ -258,6 +335,37 @@ static int tmp006_probe(struct i2c_client *client) if (ret < 0) return ret; + if (client->irq > 0) { + data->drdy_trig = devm_iio_trigger_alloc(&client->dev, + "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!data->drdy_trig) + return -ENOMEM; + + data->drdy_trig->ops = &tmp006_trigger_ops; + iio_trigger_set_drvdata(data->drdy_trig, indio_dev); + ret = iio_trigger_register(data->drdy_trig); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(data->drdy_trig); + + ret = devm_request_threaded_irq(&client->dev, client->irq, + iio_trigger_generic_data_rdy_poll, + NULL, + IRQF_ONESHOT, + "tmp006_irq", + data->drdy_trig); + if (ret < 0) + return ret; + } + + ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL, + tmp006_trigger_handler, NULL); + if (ret < 0) + return ret; + return devm_iio_device_register(&client->dev, indio_dev); } diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c index 9bdfa94234929c35f3e4871bc291be21bbfba82e..fd4d389ce1dfec031652d4f7881ec0b72a015998 100644 --- a/drivers/iio/temperature/tmp007.c +++ b/drivers/iio/temperature/tmp007.c @@ -216,7 +216,7 @@ static irqreturn_t tmp007_interrupt_handler(int irq, void *private) static int tmp007_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct tmp007_data *data = iio_priv(indio_dev); unsigned int status_mask; diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index 9213761c5d18a42cbb1ad2f7a3bbadc20dc1c7ed..cfaa16f46a3fde699f5d635c691702656eb7ebfa 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -232,4 +232,4 @@ MODULE_DESCRIPTION("Measurement-Specialties tsys01 temperature driver"); MODULE_AUTHOR("William Markezana "); MODULE_AUTHOR("Ludovic Tancerel "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MEAS_SPEC_SENSORS); +MODULE_IMPORT_NS("IIO_MEAS_SPEC_SENSORS"); diff --git a/drivers/iio/temperature/tsys02d.c b/drivers/iio/temperature/tsys02d.c index 2b4959d6e46761737e9474f30ab3fdc99b1e46b9..ef34b3c58f262b0c41a1f9642a846d14f99d55a1 100644 --- a/drivers/iio/temperature/tsys02d.c +++ b/drivers/iio/temperature/tsys02d.c @@ -187,4 +187,4 @@ MODULE_DESCRIPTION("Measurement-Specialties tsys02d temperature driver"); MODULE_AUTHOR("William Markezana "); MODULE_AUTHOR("Ludovic Tancerel "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_MEAS_SPEC_SENSORS); +MODULE_IMPORT_NS("IIO_MEAS_SPEC_SENSORS"); diff --git a/drivers/iio/test/iio-test-gts.c b/drivers/iio/test/iio-test-gts.c index 5f16a7b5e6d4116a1a7dfc8c04d2870ce24e21ba..1eceec9d477f4c54925e6a14a28a99b882fa32fe 100644 --- a/drivers/iio/test/iio-test-gts.c +++ b/drivers/iio/test/iio-test-gts.c @@ -512,4 +512,4 @@ kunit_test_suite(iio_gts_test_suite); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Matti Vaittinen "); MODULE_DESCRIPTION("Test IIO light sensor gain-time-scale helpers"); -MODULE_IMPORT_NS(IIO_GTS_HELPER); +MODULE_IMPORT_NS("IIO_GTS_HELPER"); diff --git a/drivers/iio/test/iio-test-rescale.c b/drivers/iio/test/iio-test-rescale.c index 31ee55a6faed92a1316d20fe34c0c78910042f0c..cbf13337ed1ff48f02c75c733a1e2aca913faf89 100644 --- a/drivers/iio/test/iio-test-rescale.c +++ b/drivers/iio/test/iio-test-rescale.c @@ -712,4 +712,4 @@ kunit_test_suite(iio_rescale_test_suite); MODULE_AUTHOR("Liam Beguin "); MODULE_DESCRIPTION("Test IIO rescale conversion functions"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(IIO_RESCALE); +MODULE_IMPORT_NS("IIO_RESCALE"); diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c index dec256bfbd73e1e636e50cae514a57361a0a2ae7..21c6b6292a721a49032204b7f30aa5c02b76dd26 100644 --- a/drivers/iio/trigger/iio-trig-interrupt.c +++ b/drivers/iio/trigger/iio-trig-interrupt.c @@ -96,7 +96,7 @@ static void iio_interrupt_trigger_remove(struct platform_device *pdev) static struct platform_driver iio_interrupt_trigger_driver = { .probe = iio_interrupt_trigger_probe, - .remove_new = iio_interrupt_trigger_remove, + .remove = iio_interrupt_trigger_remove, .driver = { .name = "iio_interrupt_trigger", }, diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index 0684329956d9562341314b15090ab99ee5056ab5..bb60b2d7b2eca54ca1a9eff82b9b177c618905f4 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c @@ -900,7 +900,7 @@ MODULE_DEVICE_TABLE(of, stm32_trig_of_match); static struct platform_driver stm32_timer_trigger_driver = { .probe = stm32_timer_trigger_probe, - .remove_new = stm32_timer_trigger_remove, + .remove = stm32_timer_trigger_remove, .driver = { .name = "stm32-timer-trigger", .of_match_table = stm32_trig_of_match, diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c index 9fcd37761264a4a2ae48c0e1a0d7b7f152131cbb..0ec2e4120cc94bb0ba74cad6cd5e56a010f26b7f 100644 --- a/drivers/infiniband/core/umem_dmabuf.c +++ b/drivers/infiniband/core/umem_dmabuf.c @@ -10,7 +10,7 @@ #include "uverbs.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf) { diff --git a/drivers/infiniband/hw/mana/device.c b/drivers/infiniband/hw/mana/device.c index 7ac01918ef7c0db1ccf64d5615a1435714843fcd..3416a85f87382563a46e3239a6e464642e0ed42a 100644 --- a/drivers/infiniband/hw/mana/device.c +++ b/drivers/infiniband/hw/mana/device.c @@ -9,7 +9,7 @@ MODULE_DESCRIPTION("Microsoft Azure Network Adapter IB driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(NET_MANA); +MODULE_IMPORT_NS("NET_MANA"); static const struct ib_device_ops mana_ib_dev_ops = { .owner = THIS_MODULE, diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c b/drivers/infiniband/hw/qib/qib_sysfs.c index 53ec7510e4ebfb144e79884ca7dd7d0c873bd8a7..ba2cd68b53e6c240f1afc65c64012c75ccf488e0 100644 --- a/drivers/infiniband/hw/qib/qib_sysfs.c +++ b/drivers/infiniband/hw/qib/qib_sysfs.c @@ -283,7 +283,7 @@ static struct bin_attribute *port_ccmgta_attributes[] = { }; static umode_t qib_ccmgta_is_bin_visible(struct kobject *kobj, - struct bin_attribute *attr, int n) + const struct bin_attribute *attr, int n) { struct qib_pportdata *ppd = qib_get_pportdata_kobj(kobj); diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index 7e9b996b47c833c59873520d28c723f7ca97d07a..9d5404a07e8aa56fb5a85665ce9f043b125415f5 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -808,7 +808,7 @@ void icc_put(struct icc_path *path) mutex_unlock(&icc_bw_lock); mutex_unlock(&icc_lock); - kfree_const(path->name); + kfree(path->name); kfree(path); } EXPORT_SYMBOL_GPL(icc_put); @@ -1081,7 +1081,7 @@ static int of_count_icc_providers(struct device_node *np) int count = 0; for_each_available_child_of_node(np, child) { - if (of_property_read_bool(child, "#interconnect-cells") && + if (of_property_present(child, "#interconnect-cells") && likely(!of_match_node(ignore_list, child))) count++; count += of_count_icc_providers(child); diff --git a/drivers/interconnect/imx/imx8mm.c b/drivers/interconnect/imx/imx8mm.c index a36aaaf106aeed8f7b16405319b73a7188d13f48..efed12d635c1d88ece6875eca3c66c8b331f5789 100644 --- a/drivers/interconnect/imx/imx8mm.c +++ b/drivers/interconnect/imx/imx8mm.c @@ -88,7 +88,7 @@ static int imx8mm_icc_probe(struct platform_device *pdev) static struct platform_driver imx8mm_icc_driver = { .probe = imx8mm_icc_probe, - .remove_new = imx_icc_unregister, + .remove = imx_icc_unregister, .driver = { .name = "imx8mm-interconnect", }, diff --git a/drivers/interconnect/imx/imx8mn.c b/drivers/interconnect/imx/imx8mn.c index 2a97c74e875b968aefe7c2494222ae3b3e777575..535fae791f2e90f7779f85949d5f19c6d43d6a6e 100644 --- a/drivers/interconnect/imx/imx8mn.c +++ b/drivers/interconnect/imx/imx8mn.c @@ -77,7 +77,7 @@ static int imx8mn_icc_probe(struct platform_device *pdev) static struct platform_driver imx8mn_icc_driver = { .probe = imx8mn_icc_probe, - .remove_new = imx_icc_unregister, + .remove = imx_icc_unregister, .driver = { .name = "imx8mn-interconnect", }, diff --git a/drivers/interconnect/imx/imx8mp.c b/drivers/interconnect/imx/imx8mp.c index 86d4c1517b263f7910e7816c85b15dd7599729f6..c5751ed18d51938a790f93aee5ddb48660762ffa 100644 --- a/drivers/interconnect/imx/imx8mp.c +++ b/drivers/interconnect/imx/imx8mp.c @@ -241,7 +241,7 @@ static int imx8mp_icc_probe(struct platform_device *pdev) static struct platform_driver imx8mp_icc_driver = { .probe = imx8mp_icc_probe, - .remove_new = imx_icc_unregister, + .remove = imx_icc_unregister, .driver = { .name = "imx8mp-interconnect", }, diff --git a/drivers/interconnect/imx/imx8mq.c b/drivers/interconnect/imx/imx8mq.c index f817d24aeefb676c78ae729052a02295282027ca..6aa4f06b467645c059decef3ed7df00c0c666f49 100644 --- a/drivers/interconnect/imx/imx8mq.c +++ b/drivers/interconnect/imx/imx8mq.c @@ -87,7 +87,7 @@ static int imx8mq_icc_probe(struct platform_device *pdev) static struct platform_driver imx8mq_icc_driver = { .probe = imx8mq_icc_probe, - .remove_new = imx_icc_unregister, + .remove = imx_icc_unregister, .driver = { .name = "imx8mq-interconnect", .sync_state = icc_sync_state, diff --git a/drivers/interconnect/mediatek/mt8183.c b/drivers/interconnect/mediatek/mt8183.c index 24245085c7a94447f7cdf67700fa6cfed08f1573..c212e79334cf5b2fac1493d1aeb8979b1ec1187b 100644 --- a/drivers/interconnect/mediatek/mt8183.c +++ b/drivers/interconnect/mediatek/mt8183.c @@ -133,7 +133,7 @@ static struct platform_driver mtk_emi_icc_mt8183_driver = { .sync_state = icc_sync_state, }, .probe = mtk_emi_icc_probe, - .remove_new = mtk_emi_icc_remove, + .remove = mtk_emi_icc_remove, }; module_platform_driver(mtk_emi_icc_mt8183_driver); diff --git a/drivers/interconnect/mediatek/mt8195.c b/drivers/interconnect/mediatek/mt8195.c index 710e14c5447ccf8fc851f72bad0a5bae8325cc40..3ca23469ab18d159371a26566c05ded3ad575fca 100644 --- a/drivers/interconnect/mediatek/mt8195.c +++ b/drivers/interconnect/mediatek/mt8195.c @@ -329,7 +329,7 @@ static struct platform_driver mtk_emi_icc_mt8195_driver = { .sync_state = icc_sync_state, }, .probe = mtk_emi_icc_probe, - .remove_new = mtk_emi_icc_remove, + .remove = mtk_emi_icc_remove, }; module_platform_driver(mtk_emi_icc_mt8195_driver); diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index de96d466134066d785a49c6b71942e38359f98f4..362fb9b0a198a98a4ffe1ea4d20cddac998c30d4 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -105,6 +105,26 @@ config INTERCONNECT_QCOM_QCS404 This is a driver for the Qualcomm Network-on-Chip on qcs404-based platforms. +config INTERCONNECT_QCOM_QCS615 + tristate "Qualcomm QCS615 interconnect driver" + depends on INTERCONNECT_QCOM_RPMH_POSSIBLE + select INTERCONNECT_QCOM_RPMH + select INTERCONNECT_QCOM_BCM_VOTER + help + This is a driver for the Qualcomm Network-on-Chip on qcs615-based + platforms. + +config INTERCONNECT_QCOM_QCS8300 + tristate "Qualcomm QCS8300 interconnect driver" + depends on INTERCONNECT_QCOM_RPMH_POSSIBLE + select INTERCONNECT_QCOM_RPMH + select INTERCONNECT_QCOM_BCM_VOTER + help + This is a driver for the Qualcomm Technologies, Inc. Network-on-Chip + on QCS8300-based platforms. The interconnect provider collects and + aggreagates the cosumer bandwidth requests to satisfy constraints + placed on Network-on-Chip performance states. + config INTERCONNECT_QCOM_QDU1000 tristate "Qualcomm QDU1000/QRU1000 interconnect driver" depends on INTERCONNECT_QCOM_RPMH_POSSIBLE @@ -137,6 +157,15 @@ config INTERCONNECT_QCOM_SA8775P This is a driver for the Qualcomm Network-on-Chip on sa8775p-based platforms. +config INTERCONNECT_QCOM_SAR2130P + tristate "Qualcomm SAR2130P interconnect driver" + depends on INTERCONNECT_QCOM_RPMH_POSSIBLE + select INTERCONNECT_QCOM_RPMH + select INTERCONNECT_QCOM_BCM_VOTER + help + This is a driver for the Qualcomm Network-on-Chip on SAR2130P-based + platforms. + config INTERCONNECT_QCOM_SC7180 tristate "Qualcomm SC7180 interconnect driver" depends on INTERCONNECT_QCOM_RPMH_POSSIBLE diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index bfeea8416fcf9ea2b518f40cee26c1ae784b5924..9997728c02bf19c77f13f5243a0d87fec8629eef 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -15,9 +15,12 @@ qnoc-msm8996-objs := msm8996.o icc-osm-l3-objs := osm-l3.o qnoc-qcm2290-objs := qcm2290.o qnoc-qcs404-objs := qcs404.o +qnoc-qcs615-objs := qcs615.o +qnoc-qcs8300-objs := qcs8300.o qnoc-qdu1000-objs := qdu1000.o icc-rpmh-obj := icc-rpmh.o qnoc-sa8775p-objs := sa8775p.o +qnoc-sar2130p-objs := sar2130p.o qnoc-sc7180-objs := sc7180.o qnoc-sc7280-objs := sc7280.o qnoc-sc8180x-objs := sc8180x.o @@ -52,9 +55,12 @@ obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o obj-$(CONFIG_INTERCONNECT_QCOM_QCM2290) += qnoc-qcm2290.o obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o +obj-$(CONFIG_INTERCONNECT_QCOM_QCS615) += qnoc-qcs615.o +obj-$(CONFIG_INTERCONNECT_QCOM_QCS8300) += qnoc-qcs8300.o obj-$(CONFIG_INTERCONNECT_QCOM_QDU1000) += qnoc-qdu1000.o obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o obj-$(CONFIG_INTERCONNECT_QCOM_SA8775P) += qnoc-sa8775p.o +obj-$(CONFIG_INTERCONNECT_QCOM_SAR2130P) += qnoc-sar2130p.o obj-$(CONFIG_INTERCONNECT_QCOM_SC7180) += qnoc-sc7180.o obj-$(CONFIG_INTERCONNECT_QCOM_SC7280) += qnoc-sc7280.o obj-$(CONFIG_INTERCONNECT_QCOM_SC8180X) += qnoc-sc8180x.o diff --git a/drivers/interconnect/qcom/icc-rpmh.c b/drivers/interconnect/qcom/icc-rpmh.c index f49a8e0cb03c06b162e649ac513470f3fc709004..f2d63745be54c489061e29803ac64d22de88a848 100644 --- a/drivers/interconnect/qcom/icc-rpmh.c +++ b/drivers/interconnect/qcom/icc-rpmh.c @@ -311,7 +311,10 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev) } qp->num_clks = devm_clk_bulk_get_all(qp->dev, &qp->clks); - if (qp->num_clks < 0 || (!qp->num_clks && desc->qos_clks_required)) { + if (qp->num_clks == -EPROBE_DEFER) + return dev_err_probe(dev, qp->num_clks, "Failed to get QoS clocks\n"); + + if (qp->num_clks < 0 || (!qp->num_clks && desc->qos_requires_clocks)) { dev_info(dev, "Skipping QoS, failed to get clk: %d\n", qp->num_clks); goto skip_qos_config; } diff --git a/drivers/interconnect/qcom/icc-rpmh.h b/drivers/interconnect/qcom/icc-rpmh.h index 14db89850fb3d957390d5f0e237390374cc69ed5..82344c734091eae78350c00ef8f05f8998739cce 100644 --- a/drivers/interconnect/qcom/icc-rpmh.h +++ b/drivers/interconnect/qcom/icc-rpmh.h @@ -153,7 +153,7 @@ struct qcom_icc_desc { size_t num_nodes; struct qcom_icc_bcm * const *bcms; size_t num_bcms; - bool qos_clks_required; + bool qos_requires_clocks; }; int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, diff --git a/drivers/interconnect/qcom/msm8909.c b/drivers/interconnect/qcom/msm8909.c index 0d0cd7282f5b70b0298fb1aa6706c9ef7daa721f..dd656ce7b64d1ae6691383e68ebe0a94647368dd 100644 --- a/drivers/interconnect/qcom/msm8909.c +++ b/drivers/interconnect/qcom/msm8909.c @@ -1316,7 +1316,7 @@ MODULE_DEVICE_TABLE(of, msm8909_noc_of_match); static struct platform_driver msm8909_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-msm8909", .of_match_table = msm8909_noc_of_match, diff --git a/drivers/interconnect/qcom/msm8916.c b/drivers/interconnect/qcom/msm8916.c index 499b1a9ac413bf52a587e81969e4f2e72e745049..35148880b3e87de86e78977390a7bd988f52e1c3 100644 --- a/drivers/interconnect/qcom/msm8916.c +++ b/drivers/interconnect/qcom/msm8916.c @@ -1344,7 +1344,7 @@ MODULE_DEVICE_TABLE(of, msm8916_noc_of_match); static struct platform_driver msm8916_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-msm8916", .of_match_table = msm8916_noc_of_match, diff --git a/drivers/interconnect/qcom/msm8937.c b/drivers/interconnect/qcom/msm8937.c index 052b14c28ef8bcd2b3b83a192519293ee8e269a1..58533d00266b4a241e46c60b660be11486c7cafd 100644 --- a/drivers/interconnect/qcom/msm8937.c +++ b/drivers/interconnect/qcom/msm8937.c @@ -1175,7 +1175,7 @@ static struct qcom_icc_node slv_lpass = { .qos.qos_mode = NOC_QOS_MODE_INVALID, }; -static struct qcom_icc_node *msm8937_bimc_nodes[] = { +static struct qcom_icc_node * const msm8937_bimc_nodes[] = { [MAS_APPS_PROC] = &mas_apps_proc, [MAS_OXILI] = &mas_oxili, [MAS_SNOC_BIMC_0] = &mas_snoc_bimc_0, @@ -1204,7 +1204,7 @@ static const struct qcom_icc_desc msm8937_bimc = { .ab_coeff = 154, }; -static struct qcom_icc_node *msm8937_pcnoc_nodes[] = { +static struct qcom_icc_node * const msm8937_pcnoc_nodes[] = { [MAS_SPDM] = &mas_spdm, [MAS_BLSP_1] = &mas_blsp_1, [MAS_BLSP_2] = &mas_blsp_2, @@ -1268,7 +1268,7 @@ static const struct qcom_icc_desc msm8937_pcnoc = { .regmap_cfg = &msm8937_pcnoc_regmap_config, }; -static struct qcom_icc_node *msm8937_snoc_nodes[] = { +static struct qcom_icc_node * const msm8937_snoc_nodes[] = { [MAS_QDSS_BAM] = &mas_qdss_bam, [MAS_BIMC_SNOC] = &mas_bimc_snoc, [MAS_PCNOC_SNOC] = &mas_pcnoc_snoc, @@ -1304,7 +1304,7 @@ static const struct qcom_icc_desc msm8937_snoc = { .qos_offset = 0x7000, }; -static struct qcom_icc_node *msm8937_snoc_mm_nodes[] = { +static struct qcom_icc_node * const msm8937_snoc_mm_nodes[] = { [MAS_JPEG] = &mas_jpeg, [MAS_MDP] = &mas_mdp, [MAS_VENUS] = &mas_venus, @@ -1337,7 +1337,7 @@ MODULE_DEVICE_TABLE(of, msm8937_noc_of_match); static struct platform_driver msm8937_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-msm8937", .of_match_table = msm8937_noc_of_match, diff --git a/drivers/interconnect/qcom/msm8939.c b/drivers/interconnect/qcom/msm8939.c index 8ff2c23b1ca0dd8759290190931f7e294a4e2d3d..b52c5ac1175c3fa458007b13906bba92219368db 100644 --- a/drivers/interconnect/qcom/msm8939.c +++ b/drivers/interconnect/qcom/msm8939.c @@ -1421,7 +1421,7 @@ MODULE_DEVICE_TABLE(of, msm8939_noc_of_match); static struct platform_driver msm8939_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-msm8939", .of_match_table = msm8939_noc_of_match, diff --git a/drivers/interconnect/qcom/msm8953.c b/drivers/interconnect/qcom/msm8953.c index 62f8c0774b3ecc104f8e3a2297f52c747e2cce5e..be2b1a606612cc6c43ab63c4d5b74eabc281d325 100644 --- a/drivers/interconnect/qcom/msm8953.c +++ b/drivers/interconnect/qcom/msm8953.c @@ -1310,7 +1310,7 @@ static const struct of_device_id msm8953_noc_of_match[] = { static struct platform_driver msm8953_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-msm8953", .of_match_table = msm8953_noc_of_match, diff --git a/drivers/interconnect/qcom/msm8974.c b/drivers/interconnect/qcom/msm8974.c index 241076b5f36b460b4c1035cbf0c3422d35dc5735..469fc48ebfe94d9ebb723132564583f4790d4850 100644 --- a/drivers/interconnect/qcom/msm8974.c +++ b/drivers/interconnect/qcom/msm8974.c @@ -762,7 +762,7 @@ MODULE_DEVICE_TABLE(of, msm8974_noc_of_match); static struct platform_driver msm8974_noc_driver = { .probe = msm8974_icc_probe, - .remove_new = msm8974_icc_remove, + .remove = msm8974_icc_remove, .driver = { .name = "qnoc-msm8974", .of_match_table = msm8974_noc_of_match, diff --git a/drivers/interconnect/qcom/msm8976.c b/drivers/interconnect/qcom/msm8976.c index ab963def77c3ae82daa483365d8dc2b0a5367389..4e2ac7ebe7429fe764540be194023c004f8fbca0 100644 --- a/drivers/interconnect/qcom/msm8976.c +++ b/drivers/interconnect/qcom/msm8976.c @@ -1427,7 +1427,7 @@ MODULE_DEVICE_TABLE(of, msm8976_noc_of_match); static struct platform_driver msm8976_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-msm8976", .of_match_table = msm8976_noc_of_match, diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c index 788131400cd132a4d963503db24efaf05ce7a46b..b73566c9b21f9dd275878419e030ab07163ef8dd 100644 --- a/drivers/interconnect/qcom/msm8996.c +++ b/drivers/interconnect/qcom/msm8996.c @@ -2108,7 +2108,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-msm8996", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c index 61a8695a9adc73b0bf0dc47f1232c03da7a1a52d..6a656ed44d49ba2985d106ee28fff5af159e6444 100644 --- a/drivers/interconnect/qcom/osm-l3.c +++ b/drivers/interconnect/qcom/osm-l3.c @@ -290,7 +290,7 @@ MODULE_DEVICE_TABLE(of, osm_l3_of_match); static struct platform_driver osm_l3_driver = { .probe = qcom_osm_l3_probe, - .remove_new = qcom_osm_l3_remove, + .remove = qcom_osm_l3_remove, .driver = { .name = "osm-l3", .of_match_table = osm_l3_of_match, diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c index ccbdc6202c07a69877b0a831dbe397b01b77980a..e120bc1395f35c021809424a3fb0d54b504c7bc5 100644 --- a/drivers/interconnect/qcom/qcm2290.c +++ b/drivers/interconnect/qcom/qcm2290.c @@ -1367,7 +1367,7 @@ MODULE_DEVICE_TABLE(of, qcm2290_noc_of_match); static struct platform_driver qcm2290_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-qcm2290", .of_match_table = qcm2290_noc_of_match, diff --git a/drivers/interconnect/qcom/qcs404.c b/drivers/interconnect/qcom/qcs404.c index 63e9ff223ac49153f0407fa9f9a698993ba70d59..ceac7a69876951f2c04321fde8f2450cf90ac1a5 100644 --- a/drivers/interconnect/qcom/qcs404.c +++ b/drivers/interconnect/qcom/qcs404.c @@ -1204,7 +1204,7 @@ MODULE_DEVICE_TABLE(of, qcs404_noc_of_match); static struct platform_driver qcs404_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-qcs404", .of_match_table = qcs404_noc_of_match, diff --git a/drivers/interconnect/qcom/qcs615.c b/drivers/interconnect/qcom/qcs615.c new file mode 100644 index 0000000000000000000000000000000000000000..7e59e91ce886d641599a780b0f0d56a9e64b7de4 --- /dev/null +++ b/drivers/interconnect/qcom/qcs615.c @@ -0,0 +1,1563 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "bcm-voter.h" +#include "icc-rpmh.h" +#include "qcs615.h" + +static struct qcom_icc_node qhm_a1noc_cfg = { + .name = "qhm_a1noc_cfg", + .id = QCS615_MASTER_A1NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_SERVICE_A2NOC }, +}; + +static struct qcom_icc_node qhm_qdss_bam = { + .name = "qhm_qdss_bam", + .id = QCS615_MASTER_QDSS_BAM, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qhm_qspi = { + .name = "qhm_qspi", + .id = QCS615_MASTER_QSPI, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qhm_qup0 = { + .name = "qhm_qup0", + .id = QCS615_MASTER_QUP_0, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qhm_qup1 = { + .name = "qhm_qup1", + .id = QCS615_MASTER_BLSP_1, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qnm_cnoc = { + .name = "qnm_cnoc", + .id = QCS615_MASTER_CNOC_A2NOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qxm_crypto = { + .name = "qxm_crypto", + .id = QCS615_MASTER_CRYPTO, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qxm_ipa = { + .name = "qxm_ipa", + .id = QCS615_MASTER_IPA, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_LPASS_SNOC }, +}; + +static struct qcom_icc_node xm_emac_avb = { + .name = "xm_emac_avb", + .id = QCS615_MASTER_EMAC_EVB, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_pcie = { + .name = "xm_pcie", + .id = QCS615_MASTER_PCIE, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_ANOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node xm_qdss_etr = { + .name = "xm_qdss_etr", + .id = QCS615_MASTER_QDSS_ETR, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_sdc1 = { + .name = "xm_sdc1", + .id = QCS615_MASTER_SDCC_1, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_sdc2 = { + .name = "xm_sdc2", + .id = QCS615_MASTER_SDCC_2, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_ufs_mem = { + .name = "xm_ufs_mem", + .id = QCS615_MASTER_UFS_MEM, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_usb2 = { + .name = "xm_usb2", + .id = QCS615_MASTER_USB2, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_usb3_0 = { + .name = "xm_usb3_0", + .id = QCS615_MASTER_USB3_0, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qxm_camnoc_hf0_uncomp = { + .name = "qxm_camnoc_hf0_uncomp", + .id = QCS615_MASTER_CAMNOC_HF0_UNCOMP, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_CAMNOC_UNCOMP }, +}; + +static struct qcom_icc_node qxm_camnoc_hf1_uncomp = { + .name = "qxm_camnoc_hf1_uncomp", + .id = QCS615_MASTER_CAMNOC_HF1_UNCOMP, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_CAMNOC_UNCOMP }, +}; + +static struct qcom_icc_node qxm_camnoc_sf_uncomp = { + .name = "qxm_camnoc_sf_uncomp", + .id = QCS615_MASTER_CAMNOC_SF_UNCOMP, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_CAMNOC_UNCOMP }, +}; + +static struct qcom_icc_node qhm_spdm = { + .name = "qhm_spdm", + .id = QCS615_MASTER_SPDM, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_CNOC_A2NOC }, +}; + +static struct qcom_icc_node qnm_snoc = { + .name = "qnm_snoc", + .id = QCS615_MASTER_SNOC_CNOC, + .channels = 1, + .buswidth = 8, + .num_links = 39, + .links = { QCS615_SLAVE_A1NOC_CFG, QCS615_SLAVE_AHB2PHY_EAST, + QCS615_SLAVE_AHB2PHY_WEST, QCS615_SLAVE_AOP, + QCS615_SLAVE_AOSS, QCS615_SLAVE_CAMERA_CFG, + QCS615_SLAVE_CLK_CTL, QCS615_SLAVE_RBCPR_CX_CFG, + QCS615_SLAVE_RBCPR_MX_CFG, QCS615_SLAVE_CRYPTO_0_CFG, + QCS615_SLAVE_CNOC_DDRSS, QCS615_SLAVE_DISPLAY_CFG, + QCS615_SLAVE_EMAC_AVB_CFG, QCS615_SLAVE_GLM, + QCS615_SLAVE_GFX3D_CFG, QCS615_SLAVE_IMEM_CFG, + QCS615_SLAVE_IPA_CFG, QCS615_SLAVE_CNOC_MNOC_CFG, + QCS615_SLAVE_PCIE_CFG, QCS615_SLAVE_PIMEM_CFG, + QCS615_SLAVE_PRNG, QCS615_SLAVE_QDSS_CFG, + QCS615_SLAVE_QSPI, QCS615_SLAVE_QUP_0, + QCS615_SLAVE_QUP_1, QCS615_SLAVE_SDCC_1, + QCS615_SLAVE_SDCC_2, QCS615_SLAVE_SNOC_CFG, + QCS615_SLAVE_SPDM_WRAPPER, QCS615_SLAVE_TCSR, + QCS615_SLAVE_TLMM_EAST, QCS615_SLAVE_TLMM_SOUTH, + QCS615_SLAVE_TLMM_WEST, QCS615_SLAVE_UFS_MEM_CFG, + QCS615_SLAVE_USB2, QCS615_SLAVE_USB3, + QCS615_SLAVE_VENUS_CFG, QCS615_SLAVE_VSENSE_CTRL_CFG, + QCS615_SLAVE_SERVICE_CNOC }, +}; + +static struct qcom_icc_node xm_qdss_dap = { + .name = "xm_qdss_dap", + .id = QCS615_MASTER_QDSS_DAP, + .channels = 1, + .buswidth = 8, + .num_links = 40, + .links = { QCS615_SLAVE_A1NOC_CFG, QCS615_SLAVE_AHB2PHY_EAST, + QCS615_SLAVE_AHB2PHY_WEST, QCS615_SLAVE_AOP, + QCS615_SLAVE_AOSS, QCS615_SLAVE_CAMERA_CFG, + QCS615_SLAVE_CLK_CTL, QCS615_SLAVE_RBCPR_CX_CFG, + QCS615_SLAVE_RBCPR_MX_CFG, QCS615_SLAVE_CRYPTO_0_CFG, + QCS615_SLAVE_CNOC_DDRSS, QCS615_SLAVE_DISPLAY_CFG, + QCS615_SLAVE_EMAC_AVB_CFG, QCS615_SLAVE_GLM, + QCS615_SLAVE_GFX3D_CFG, QCS615_SLAVE_IMEM_CFG, + QCS615_SLAVE_IPA_CFG, QCS615_SLAVE_CNOC_MNOC_CFG, + QCS615_SLAVE_PCIE_CFG, QCS615_SLAVE_PIMEM_CFG, + QCS615_SLAVE_PRNG, QCS615_SLAVE_QDSS_CFG, + QCS615_SLAVE_QSPI, QCS615_SLAVE_QUP_0, + QCS615_SLAVE_QUP_1, QCS615_SLAVE_SDCC_1, + QCS615_SLAVE_SDCC_2, QCS615_SLAVE_SNOC_CFG, + QCS615_SLAVE_SPDM_WRAPPER, QCS615_SLAVE_TCSR, + QCS615_SLAVE_TLMM_EAST, QCS615_SLAVE_TLMM_SOUTH, + QCS615_SLAVE_TLMM_WEST, QCS615_SLAVE_UFS_MEM_CFG, + QCS615_SLAVE_USB2, QCS615_SLAVE_USB3, + QCS615_SLAVE_VENUS_CFG, QCS615_SLAVE_VSENSE_CTRL_CFG, + QCS615_SLAVE_CNOC_A2NOC, QCS615_SLAVE_SERVICE_CNOC }, +}; + +static struct qcom_icc_node qhm_cnoc = { + .name = "qhm_cnoc", + .id = QCS615_MASTER_CNOC_DC_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 2, + .links = { QCS615_SLAVE_DC_NOC_GEMNOC, QCS615_SLAVE_LLCC_CFG }, +}; + +static struct qcom_icc_node acm_apps = { + .name = "acm_apps", + .id = QCS615_MASTER_APPSS_PROC, + .channels = 1, + .buswidth = 16, + .num_links = 3, + .links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC, + QCS615_SLAVE_MEM_NOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node acm_gpu_tcu = { + .name = "acm_gpu_tcu", + .id = QCS615_MASTER_GPU_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC }, +}; + +static struct qcom_icc_node acm_sys_tcu = { + .name = "acm_sys_tcu", + .id = QCS615_MASTER_SYS_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qhm_gemnoc_cfg = { + .name = "qhm_gemnoc_cfg", + .id = QCS615_MASTER_GEM_NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 2, + .links = { QCS615_SLAVE_MSS_PROC_MS_MPU_CFG, QCS615_SLAVE_SERVICE_GEM_NOC }, +}; + +static struct qcom_icc_node qnm_gpu = { + .name = "qnm_gpu", + .id = QCS615_MASTER_GFX3D, + .channels = 2, + .buswidth = 32, + .num_links = 2, + .links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_mnoc_hf = { + .name = "qnm_mnoc_hf", + .id = QCS615_MASTER_MNOC_HF_MEM_NOC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_mnoc_sf = { + .name = "qnm_mnoc_sf", + .id = QCS615_MASTER_MNOC_SF_MEM_NOC, + .channels = 1, + .buswidth = 32, + .num_links = 2, + .links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_snoc_gc = { + .name = "qnm_snoc_gc", + .id = QCS615_MASTER_SNOC_GC_MEM_NOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_snoc_sf = { + .name = "qnm_snoc_sf", + .id = QCS615_MASTER_SNOC_SF_MEM_NOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS615_SLAVE_LLCC }, +}; + +static struct qcom_icc_node ipa_core_master = { + .name = "ipa_core_master", + .id = QCS615_MASTER_IPA_CORE, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_IPA_CORE }, +}; + +static struct qcom_icc_node llcc_mc = { + .name = "llcc_mc", + .id = QCS615_MASTER_LLCC, + .channels = 2, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_EBI1 }, +}; + +static struct qcom_icc_node qhm_mnoc_cfg = { + .name = "qhm_mnoc_cfg", + .id = QCS615_MASTER_CNOC_MNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_SERVICE_MNOC }, +}; + +static struct qcom_icc_node qxm_camnoc_hf0 = { + .name = "qxm_camnoc_hf0", + .id = QCS615_MASTER_CAMNOC_HF0, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qxm_camnoc_hf1 = { + .name = "qxm_camnoc_hf1", + .id = QCS615_MASTER_CAMNOC_HF1, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qxm_camnoc_sf = { + .name = "qxm_camnoc_sf", + .id = QCS615_MASTER_CAMNOC_SF, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qxm_mdp0 = { + .name = "qxm_mdp0", + .id = QCS615_MASTER_MDP0, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qxm_rot = { + .name = "qxm_rot", + .id = QCS615_MASTER_ROTATOR, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qxm_venus0 = { + .name = "qxm_venus0", + .id = QCS615_MASTER_VIDEO_P0, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qxm_venus_arm9 = { + .name = "qxm_venus_arm9", + .id = QCS615_MASTER_VIDEO_PROC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qhm_snoc_cfg = { + .name = "qhm_snoc_cfg", + .id = QCS615_MASTER_SNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_SLAVE_SERVICE_SNOC }, +}; + +static struct qcom_icc_node qnm_aggre1_noc = { + .name = "qnm_aggre1_noc", + .id = QCS615_MASTER_A1NOC_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 8, + .links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC, + QCS615_SLAVE_SNOC_GEM_NOC_SF, QCS615_SLAVE_IMEM, + QCS615_SLAVE_PIMEM, QCS615_SLAVE_PCIE_0, + QCS615_SLAVE_QDSS_STM, QCS615_SLAVE_TCU }, +}; + +static struct qcom_icc_node qnm_gemnoc = { + .name = "qnm_gemnoc", + .id = QCS615_MASTER_GEM_NOC_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 6, + .links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC, + QCS615_SLAVE_IMEM, QCS615_SLAVE_PIMEM, + QCS615_SLAVE_QDSS_STM, QCS615_SLAVE_TCU }, +}; + +static struct qcom_icc_node qnm_gemnoc_pcie = { + .name = "qnm_gemnoc_pcie", + .id = QCS615_MASTER_GEM_NOC_PCIE_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_SLAVE_PCIE_0 }, +}; + +static struct qcom_icc_node qnm_lpass_anoc = { + .name = "qnm_lpass_anoc", + .id = QCS615_MASTER_LPASS_ANOC, + .channels = 1, + .buswidth = 8, + .num_links = 7, + .links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC, + QCS615_SLAVE_SNOC_GEM_NOC_SF, QCS615_SLAVE_IMEM, + QCS615_SLAVE_PIMEM, QCS615_SLAVE_PCIE_0, + QCS615_SLAVE_QDSS_STM }, +}; + +static struct qcom_icc_node qnm_pcie_anoc = { + .name = "qnm_pcie_anoc", + .id = QCS615_MASTER_ANOC_PCIE_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 5, + .links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC, + QCS615_SLAVE_SNOC_GEM_NOC_SF, QCS615_SLAVE_IMEM, + QCS615_SLAVE_QDSS_STM }, +}; + +static struct qcom_icc_node qxm_pimem = { + .name = "qxm_pimem", + .id = QCS615_MASTER_PIMEM, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { QCS615_SLAVE_SNOC_MEM_NOC_GC, QCS615_SLAVE_IMEM }, +}; + +static struct qcom_icc_node xm_gic = { + .name = "xm_gic", + .id = QCS615_MASTER_GIC, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { QCS615_SLAVE_SNOC_MEM_NOC_GC, QCS615_SLAVE_IMEM }, +}; + +static struct qcom_icc_node qns_a1noc_snoc = { + .name = "qns_a1noc_snoc", + .id = QCS615_SLAVE_A1NOC_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS615_MASTER_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qns_lpass_snoc = { + .name = "qns_lpass_snoc", + .id = QCS615_SLAVE_LPASS_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_MASTER_LPASS_ANOC }, +}; + +static struct qcom_icc_node qns_pcie_snoc = { + .name = "qns_pcie_snoc", + .id = QCS615_SLAVE_ANOC_PCIE_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_MASTER_ANOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node srvc_aggre2_noc = { + .name = "srvc_aggre2_noc", + .id = QCS615_SLAVE_SERVICE_A2NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_camnoc_uncomp = { + .name = "qns_camnoc_uncomp", + .id = QCS615_SLAVE_CAMNOC_UNCOMP, + .channels = 1, + .buswidth = 32, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_a1_noc_cfg = { + .name = "qhs_a1_noc_cfg", + .id = QCS615_SLAVE_A1NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_MASTER_A1NOC_CFG }, +}; + +static struct qcom_icc_node qhs_ahb2phy_east = { + .name = "qhs_ahb2phy_east", + .id = QCS615_SLAVE_AHB2PHY_EAST, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ahb2phy_west = { + .name = "qhs_ahb2phy_west", + .id = QCS615_SLAVE_AHB2PHY_WEST, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_aop = { + .name = "qhs_aop", + .id = QCS615_SLAVE_AOP, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_aoss = { + .name = "qhs_aoss", + .id = QCS615_SLAVE_AOSS, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_camera_cfg = { + .name = "qhs_camera_cfg", + .id = QCS615_SLAVE_CAMERA_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_clk_ctl = { + .name = "qhs_clk_ctl", + .id = QCS615_SLAVE_CLK_CTL, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_cx = { + .name = "qhs_cpr_cx", + .id = QCS615_SLAVE_RBCPR_CX_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_mx = { + .name = "qhs_cpr_mx", + .id = QCS615_SLAVE_RBCPR_MX_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_crypto0_cfg = { + .name = "qhs_crypto0_cfg", + .id = QCS615_SLAVE_CRYPTO_0_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ddrss_cfg = { + .name = "qhs_ddrss_cfg", + .id = QCS615_SLAVE_CNOC_DDRSS, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_MASTER_CNOC_DC_NOC }, +}; + +static struct qcom_icc_node qhs_display_cfg = { + .name = "qhs_display_cfg", + .id = QCS615_SLAVE_DISPLAY_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_emac_avb_cfg = { + .name = "qhs_emac_avb_cfg", + .id = QCS615_SLAVE_EMAC_AVB_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_glm = { + .name = "qhs_glm", + .id = QCS615_SLAVE_GLM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_gpuss_cfg = { + .name = "qhs_gpuss_cfg", + .id = QCS615_SLAVE_GFX3D_CFG, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_imem_cfg = { + .name = "qhs_imem_cfg", + .id = QCS615_SLAVE_IMEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ipa = { + .name = "qhs_ipa", + .id = QCS615_SLAVE_IPA_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_mnoc_cfg = { + .name = "qhs_mnoc_cfg", + .id = QCS615_SLAVE_CNOC_MNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_MASTER_CNOC_MNOC_CFG }, +}; + +static struct qcom_icc_node qhs_pcie_config = { + .name = "qhs_pcie_config", + .id = QCS615_SLAVE_PCIE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pimem_cfg = { + .name = "qhs_pimem_cfg", + .id = QCS615_SLAVE_PIMEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_prng = { + .name = "qhs_prng", + .id = QCS615_SLAVE_PRNG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qdss_cfg = { + .name = "qhs_qdss_cfg", + .id = QCS615_SLAVE_QDSS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qspi = { + .name = "qhs_qspi", + .id = QCS615_SLAVE_QSPI, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qup0 = { + .name = "qhs_qup0", + .id = QCS615_SLAVE_QUP_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qup1 = { + .name = "qhs_qup1", + .id = QCS615_SLAVE_QUP_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_sdc1 = { + .name = "qhs_sdc1", + .id = QCS615_SLAVE_SDCC_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_sdc2 = { + .name = "qhs_sdc2", + .id = QCS615_SLAVE_SDCC_2, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_snoc_cfg = { + .name = "qhs_snoc_cfg", + .id = QCS615_SLAVE_SNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_MASTER_SNOC_CFG }, +}; + +static struct qcom_icc_node qhs_spdm = { + .name = "qhs_spdm", + .id = QCS615_SLAVE_SPDM_WRAPPER, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tcsr = { + .name = "qhs_tcsr", + .id = QCS615_SLAVE_TCSR, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tlmm_east = { + .name = "qhs_tlmm_east", + .id = QCS615_SLAVE_TLMM_EAST, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tlmm_south = { + .name = "qhs_tlmm_south", + .id = QCS615_SLAVE_TLMM_SOUTH, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tlmm_west = { + .name = "qhs_tlmm_west", + .id = QCS615_SLAVE_TLMM_WEST, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ufs_mem_cfg = { + .name = "qhs_ufs_mem_cfg", + .id = QCS615_SLAVE_UFS_MEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_usb2 = { + .name = "qhs_usb2", + .id = QCS615_SLAVE_USB2, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_usb3 = { + .name = "qhs_usb3", + .id = QCS615_SLAVE_USB3, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_venus_cfg = { + .name = "qhs_venus_cfg", + .id = QCS615_SLAVE_VENUS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_vsense_ctrl_cfg = { + .name = "qhs_vsense_ctrl_cfg", + .id = QCS615_SLAVE_VSENSE_CTRL_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_cnoc_a2noc = { + .name = "qns_cnoc_a2noc", + .id = QCS615_SLAVE_CNOC_A2NOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_MASTER_CNOC_A2NOC }, +}; + +static struct qcom_icc_node srvc_cnoc = { + .name = "srvc_cnoc", + .id = QCS615_SLAVE_SERVICE_CNOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_dc_noc_gemnoc = { + .name = "qhs_dc_noc_gemnoc", + .id = QCS615_SLAVE_DC_NOC_GEMNOC, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS615_MASTER_GEM_NOC_CFG }, +}; + +static struct qcom_icc_node qhs_llcc = { + .name = "qhs_llcc", + .id = QCS615_SLAVE_LLCC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_mdsp_ms_mpu_cfg = { + .name = "qhs_mdsp_ms_mpu_cfg", + .id = QCS615_SLAVE_MSS_PROC_MS_MPU_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_gem_noc_snoc = { + .name = "qns_gem_noc_snoc", + .id = QCS615_SLAVE_GEM_NOC_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_MASTER_GEM_NOC_SNOC }, +}; + +static struct qcom_icc_node qns_llcc = { + .name = "qns_llcc", + .id = QCS615_SLAVE_LLCC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS615_MASTER_LLCC }, +}; + +static struct qcom_icc_node qns_sys_pcie = { + .name = "qns_sys_pcie", + .id = QCS615_SLAVE_MEM_NOC_PCIE_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_MASTER_GEM_NOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node srvc_gemnoc = { + .name = "srvc_gemnoc", + .id = QCS615_SLAVE_SERVICE_GEM_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node ipa_core_slave = { + .name = "ipa_core_slave", + .id = QCS615_SLAVE_IPA_CORE, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node ebi = { + .name = "ebi", + .id = QCS615_SLAVE_EBI1, + .channels = 2, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns2_mem_noc = { + .name = "qns2_mem_noc", + .id = QCS615_SLAVE_MNOC_SF_MEM_NOC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_MASTER_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qns_mem_noc_hf = { + .name = "qns_mem_noc_hf", + .id = QCS615_SLAVE_MNOC_HF_MEM_NOC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS615_MASTER_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node srvc_mnoc = { + .name = "srvc_mnoc", + .id = QCS615_SLAVE_SERVICE_MNOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_apss = { + .name = "qhs_apss", + .id = QCS615_SLAVE_APPSS, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qns_cnoc = { + .name = "qns_cnoc", + .id = QCS615_SLAVE_SNOC_CNOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_MASTER_SNOC_CNOC }, +}; + +static struct qcom_icc_node qns_gemnoc_sf = { + .name = "qns_gemnoc_sf", + .id = QCS615_SLAVE_SNOC_GEM_NOC_SF, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS615_MASTER_SNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qns_memnoc_gc = { + .name = "qns_memnoc_gc", + .id = QCS615_SLAVE_SNOC_MEM_NOC_GC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS615_MASTER_SNOC_GC_MEM_NOC }, +}; + +static struct qcom_icc_node qxs_imem = { + .name = "qxs_imem", + .id = QCS615_SLAVE_IMEM, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qxs_pimem = { + .name = "qxs_pimem", + .id = QCS615_SLAVE_PIMEM, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_snoc = { + .name = "srvc_snoc", + .id = QCS615_SLAVE_SERVICE_SNOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node xs_pcie = { + .name = "xs_pcie", + .id = QCS615_SLAVE_PCIE_0, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node xs_qdss_stm = { + .name = "xs_qdss_stm", + .id = QCS615_SLAVE_QDSS_STM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node xs_sys_tcu_cfg = { + .name = "xs_sys_tcu_cfg", + .id = QCS615_SLAVE_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", + .num_nodes = 1, + .nodes = { &ebi }, +}; + +static struct qcom_icc_bcm bcm_ce0 = { + .name = "CE0", + .num_nodes = 1, + .nodes = { &qxm_crypto }, +}; + +static struct qcom_icc_bcm bcm_cn0 = { + .name = "CN0", + .keepalive = true, + .num_nodes = 37, + .nodes = { &qhm_spdm, &qnm_snoc, + &qhs_a1_noc_cfg, &qhs_aop, + &qhs_aoss, &qhs_camera_cfg, + &qhs_clk_ctl, &qhs_cpr_cx, + &qhs_cpr_mx, &qhs_crypto0_cfg, + &qhs_ddrss_cfg, &qhs_display_cfg, + &qhs_emac_avb_cfg, &qhs_glm, + &qhs_gpuss_cfg, &qhs_imem_cfg, + &qhs_ipa, &qhs_mnoc_cfg, + &qhs_pcie_config, &qhs_pimem_cfg, + &qhs_prng, &qhs_qdss_cfg, + &qhs_qup0, &qhs_qup1, + &qhs_snoc_cfg, &qhs_spdm, + &qhs_tcsr, &qhs_tlmm_east, + &qhs_tlmm_south, &qhs_tlmm_west, + &qhs_ufs_mem_cfg, &qhs_usb2, + &qhs_usb3, &qhs_venus_cfg, + &qhs_vsense_ctrl_cfg, &qns_cnoc_a2noc, + &srvc_cnoc }, +}; + +static struct qcom_icc_bcm bcm_cn1 = { + .name = "CN1", + .num_nodes = 8, + .nodes = { &qhm_qspi, &xm_sdc1, + &xm_sdc2, &qhs_ahb2phy_east, + &qhs_ahb2phy_west, &qhs_qspi, + &qhs_sdc1, &qhs_sdc2 }, +}; + +static struct qcom_icc_bcm bcm_ip0 = { + .name = "IP0", + .num_nodes = 1, + .nodes = { &ipa_core_slave }, +}; + +static struct qcom_icc_bcm bcm_mc0 = { + .name = "MC0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &ebi }, +}; + +static struct qcom_icc_bcm bcm_mm0 = { + .name = "MM0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_mem_noc_hf }, +}; + +static struct qcom_icc_bcm bcm_mm1 = { + .name = "MM1", + .num_nodes = 7, + .nodes = { &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, + &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0, + &qxm_camnoc_hf1, &qxm_mdp0, + &qxm_rot }, +}; + +static struct qcom_icc_bcm bcm_mm2 = { + .name = "MM2", + .num_nodes = 2, + .nodes = { &qxm_camnoc_sf, &qns2_mem_noc }, +}; + +static struct qcom_icc_bcm bcm_mm3 = { + .name = "MM3", + .num_nodes = 2, + .nodes = { &qxm_venus0, &qxm_venus_arm9 }, +}; + +static struct qcom_icc_bcm bcm_qup0 = { + .name = "QUP0", + .keepalive = true, + .vote_scale = 1, + .num_nodes = 2, + .nodes = { &qhm_qup0, &qhm_qup1 }, +}; + +static struct qcom_icc_bcm bcm_sh0 = { + .name = "SH0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_llcc }, +}; + +static struct qcom_icc_bcm bcm_sh2 = { + .name = "SH2", + .num_nodes = 1, + .nodes = { &acm_apps }, +}; + +static struct qcom_icc_bcm bcm_sh3 = { + .name = "SH3", + .num_nodes = 1, + .nodes = { &qns_gem_noc_snoc }, +}; + +static struct qcom_icc_bcm bcm_sn0 = { + .name = "SN0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_gemnoc_sf }, +}; + +static struct qcom_icc_bcm bcm_sn1 = { + .name = "SN1", + .num_nodes = 1, + .nodes = { &qxs_imem }, +}; + +static struct qcom_icc_bcm bcm_sn2 = { + .name = "SN2", + .num_nodes = 1, + .nodes = { &qns_memnoc_gc }, +}; + +static struct qcom_icc_bcm bcm_sn3 = { + .name = "SN3", + .num_nodes = 2, + .nodes = { &srvc_aggre2_noc, &qns_cnoc }, +}; + +static struct qcom_icc_bcm bcm_sn4 = { + .name = "SN4", + .num_nodes = 1, + .nodes = { &qxs_pimem }, +}; + +static struct qcom_icc_bcm bcm_sn5 = { + .name = "SN5", + .num_nodes = 1, + .nodes = { &xs_qdss_stm }, +}; + +static struct qcom_icc_bcm bcm_sn8 = { + .name = "SN8", + .num_nodes = 2, + .nodes = { &qnm_gemnoc_pcie, &xs_pcie }, +}; + +static struct qcom_icc_bcm bcm_sn9 = { + .name = "SN9", + .num_nodes = 1, + .nodes = { &qnm_aggre1_noc }, +}; + +static struct qcom_icc_bcm bcm_sn12 = { + .name = "SN12", + .num_nodes = 2, + .nodes = { &qxm_pimem, &xm_gic }, +}; + +static struct qcom_icc_bcm bcm_sn13 = { + .name = "SN13", + .num_nodes = 1, + .nodes = { &qnm_lpass_anoc }, +}; + +static struct qcom_icc_bcm bcm_sn14 = { + .name = "SN14", + .num_nodes = 1, + .nodes = { &qns_pcie_snoc }, +}; + +static struct qcom_icc_bcm bcm_sn15 = { + .name = "SN15", + .num_nodes = 1, + .nodes = { &qnm_gemnoc }, +}; + +static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { + &bcm_ce0, + &bcm_cn1, + &bcm_qup0, + &bcm_sn3, + &bcm_sn14, + &bcm_ip0, +}; + +static struct qcom_icc_node * const aggre1_noc_nodes[] = { + [MASTER_A1NOC_CFG] = &qhm_a1noc_cfg, + [MASTER_QDSS_BAM] = &qhm_qdss_bam, + [MASTER_QSPI] = &qhm_qspi, + [MASTER_QUP_0] = &qhm_qup0, + [MASTER_BLSP_1] = &qhm_qup1, + [MASTER_CNOC_A2NOC] = &qnm_cnoc, + [MASTER_CRYPTO] = &qxm_crypto, + [MASTER_IPA] = &qxm_ipa, + [MASTER_EMAC_EVB] = &xm_emac_avb, + [MASTER_PCIE] = &xm_pcie, + [MASTER_QDSS_ETR] = &xm_qdss_etr, + [MASTER_SDCC_1] = &xm_sdc1, + [MASTER_SDCC_2] = &xm_sdc2, + [MASTER_UFS_MEM] = &xm_ufs_mem, + [MASTER_USB2] = &xm_usb2, + [MASTER_USB3_0] = &xm_usb3_0, + [SLAVE_A1NOC_SNOC] = &qns_a1noc_snoc, + [SLAVE_LPASS_SNOC] = &qns_lpass_snoc, + [SLAVE_ANOC_PCIE_SNOC] = &qns_pcie_snoc, + [SLAVE_SERVICE_A2NOC] = &srvc_aggre2_noc, +}; + +static const struct qcom_icc_desc qcs615_aggre1_noc = { + .nodes = aggre1_noc_nodes, + .num_nodes = ARRAY_SIZE(aggre1_noc_nodes), + .bcms = aggre1_noc_bcms, + .num_bcms = ARRAY_SIZE(aggre1_noc_bcms), +}; + +static struct qcom_icc_bcm * const camnoc_virt_bcms[] = { + &bcm_mm1, +}; + +static struct qcom_icc_node * const camnoc_virt_nodes[] = { + [MASTER_CAMNOC_HF0_UNCOMP] = &qxm_camnoc_hf0_uncomp, + [MASTER_CAMNOC_HF1_UNCOMP] = &qxm_camnoc_hf1_uncomp, + [MASTER_CAMNOC_SF_UNCOMP] = &qxm_camnoc_sf_uncomp, + [SLAVE_CAMNOC_UNCOMP] = &qns_camnoc_uncomp, +}; + +static const struct qcom_icc_desc qcs615_camnoc_virt = { + .nodes = camnoc_virt_nodes, + .num_nodes = ARRAY_SIZE(camnoc_virt_nodes), + .bcms = camnoc_virt_bcms, + .num_bcms = ARRAY_SIZE(camnoc_virt_bcms), +}; + +static struct qcom_icc_bcm * const config_noc_bcms[] = { + &bcm_cn0, + &bcm_cn1, +}; + +static struct qcom_icc_node * const config_noc_nodes[] = { + [MASTER_SPDM] = &qhm_spdm, + [MASTER_SNOC_CNOC] = &qnm_snoc, + [MASTER_QDSS_DAP] = &xm_qdss_dap, + [SLAVE_A1NOC_CFG] = &qhs_a1_noc_cfg, + [SLAVE_AHB2PHY_EAST] = &qhs_ahb2phy_east, + [SLAVE_AHB2PHY_WEST] = &qhs_ahb2phy_west, + [SLAVE_AOP] = &qhs_aop, + [SLAVE_AOSS] = &qhs_aoss, + [SLAVE_CAMERA_CFG] = &qhs_camera_cfg, + [SLAVE_CLK_CTL] = &qhs_clk_ctl, + [SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx, + [SLAVE_RBCPR_MX_CFG] = &qhs_cpr_mx, + [SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg, + [SLAVE_CNOC_DDRSS] = &qhs_ddrss_cfg, + [SLAVE_DISPLAY_CFG] = &qhs_display_cfg, + [SLAVE_EMAC_AVB_CFG] = &qhs_emac_avb_cfg, + [SLAVE_GLM] = &qhs_glm, + [SLAVE_GFX3D_CFG] = &qhs_gpuss_cfg, + [SLAVE_IMEM_CFG] = &qhs_imem_cfg, + [SLAVE_IPA_CFG] = &qhs_ipa, + [SLAVE_CNOC_MNOC_CFG] = &qhs_mnoc_cfg, + [SLAVE_PCIE_CFG] = &qhs_pcie_config, + [SLAVE_PIMEM_CFG] = &qhs_pimem_cfg, + [SLAVE_PRNG] = &qhs_prng, + [SLAVE_QDSS_CFG] = &qhs_qdss_cfg, + [SLAVE_QSPI] = &qhs_qspi, + [SLAVE_QUP_0] = &qhs_qup0, + [SLAVE_QUP_1] = &qhs_qup1, + [SLAVE_SDCC_1] = &qhs_sdc1, + [SLAVE_SDCC_2] = &qhs_sdc2, + [SLAVE_SNOC_CFG] = &qhs_snoc_cfg, + [SLAVE_SPDM_WRAPPER] = &qhs_spdm, + [SLAVE_TCSR] = &qhs_tcsr, + [SLAVE_TLMM_EAST] = &qhs_tlmm_east, + [SLAVE_TLMM_SOUTH] = &qhs_tlmm_south, + [SLAVE_TLMM_WEST] = &qhs_tlmm_west, + [SLAVE_UFS_MEM_CFG] = &qhs_ufs_mem_cfg, + [SLAVE_USB2] = &qhs_usb2, + [SLAVE_USB3] = &qhs_usb3, + [SLAVE_VENUS_CFG] = &qhs_venus_cfg, + [SLAVE_VSENSE_CTRL_CFG] = &qhs_vsense_ctrl_cfg, + [SLAVE_CNOC_A2NOC] = &qns_cnoc_a2noc, + [SLAVE_SERVICE_CNOC] = &srvc_cnoc, +}; + +static const struct qcom_icc_desc qcs615_config_noc = { + .nodes = config_noc_nodes, + .num_nodes = ARRAY_SIZE(config_noc_nodes), + .bcms = config_noc_bcms, + .num_bcms = ARRAY_SIZE(config_noc_bcms), +}; + +static struct qcom_icc_node * const dc_noc_nodes[] = { + [MASTER_CNOC_DC_NOC] = &qhm_cnoc, + [SLAVE_DC_NOC_GEMNOC] = &qhs_dc_noc_gemnoc, + [SLAVE_LLCC_CFG] = &qhs_llcc, +}; + +static const struct qcom_icc_desc qcs615_dc_noc = { + .nodes = dc_noc_nodes, + .num_nodes = ARRAY_SIZE(dc_noc_nodes), +}; + +static struct qcom_icc_bcm * const gem_noc_bcms[] = { + &bcm_sh0, + &bcm_sh2, + &bcm_sh3, + &bcm_mm1, +}; + +static struct qcom_icc_node * const gem_noc_nodes[] = { + [MASTER_APPSS_PROC] = &acm_apps, + [MASTER_GPU_TCU] = &acm_gpu_tcu, + [MASTER_SYS_TCU] = &acm_sys_tcu, + [MASTER_GEM_NOC_CFG] = &qhm_gemnoc_cfg, + [MASTER_GFX3D] = &qnm_gpu, + [MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf, + [MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf, + [MASTER_SNOC_GC_MEM_NOC] = &qnm_snoc_gc, + [MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf, + [SLAVE_MSS_PROC_MS_MPU_CFG] = &qhs_mdsp_ms_mpu_cfg, + [SLAVE_GEM_NOC_SNOC] = &qns_gem_noc_snoc, + [SLAVE_LLCC] = &qns_llcc, + [SLAVE_MEM_NOC_PCIE_SNOC] = &qns_sys_pcie, + [SLAVE_SERVICE_GEM_NOC] = &srvc_gemnoc, +}; + +static const struct qcom_icc_desc qcs615_gem_noc = { + .nodes = gem_noc_nodes, + .num_nodes = ARRAY_SIZE(gem_noc_nodes), + .bcms = gem_noc_bcms, + .num_bcms = ARRAY_SIZE(gem_noc_bcms), +}; + +static struct qcom_icc_bcm * const ipa_virt_bcms[] = { + &bcm_ip0, +}; + +static struct qcom_icc_node * const ipa_virt_nodes[] = { + [MASTER_IPA_CORE] = &ipa_core_master, + [SLAVE_IPA_CORE] = &ipa_core_slave, +}; + +static const struct qcom_icc_desc qcs615_ipa_virt = { + .nodes = ipa_virt_nodes, + .num_nodes = ARRAY_SIZE(ipa_virt_nodes), + .bcms = ipa_virt_bcms, + .num_bcms = ARRAY_SIZE(ipa_virt_bcms), +}; + +static struct qcom_icc_bcm * const mc_virt_bcms[] = { + &bcm_acv, + &bcm_mc0, +}; + +static struct qcom_icc_node * const mc_virt_nodes[] = { + [MASTER_LLCC] = &llcc_mc, + [SLAVE_EBI1] = &ebi, +}; + +static const struct qcom_icc_desc qcs615_mc_virt = { + .nodes = mc_virt_nodes, + .num_nodes = ARRAY_SIZE(mc_virt_nodes), + .bcms = mc_virt_bcms, + .num_bcms = ARRAY_SIZE(mc_virt_bcms), +}; + +static struct qcom_icc_bcm * const mmss_noc_bcms[] = { + &bcm_mm0, + &bcm_mm1, + &bcm_mm2, + &bcm_mm3, +}; + +static struct qcom_icc_node * const mmss_noc_nodes[] = { + [MASTER_CNOC_MNOC_CFG] = &qhm_mnoc_cfg, + [MASTER_CAMNOC_HF0] = &qxm_camnoc_hf0, + [MASTER_CAMNOC_HF1] = &qxm_camnoc_hf1, + [MASTER_CAMNOC_SF] = &qxm_camnoc_sf, + [MASTER_MDP0] = &qxm_mdp0, + [MASTER_ROTATOR] = &qxm_rot, + [MASTER_VIDEO_P0] = &qxm_venus0, + [MASTER_VIDEO_PROC] = &qxm_venus_arm9, + [SLAVE_MNOC_SF_MEM_NOC] = &qns2_mem_noc, + [SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf, + [SLAVE_SERVICE_MNOC] = &srvc_mnoc, +}; + +static const struct qcom_icc_desc qcs615_mmss_noc = { + .nodes = mmss_noc_nodes, + .num_nodes = ARRAY_SIZE(mmss_noc_nodes), + .bcms = mmss_noc_bcms, + .num_bcms = ARRAY_SIZE(mmss_noc_bcms), +}; + +static struct qcom_icc_bcm * const system_noc_bcms[] = { + &bcm_sn0, + &bcm_sn1, + &bcm_sn2, + &bcm_sn3, + &bcm_sn4, + &bcm_sn5, + &bcm_sn8, + &bcm_sn9, + &bcm_sn12, + &bcm_sn13, + &bcm_sn15, +}; + +static struct qcom_icc_node * const system_noc_nodes[] = { + [MASTER_SNOC_CFG] = &qhm_snoc_cfg, + [MASTER_A1NOC_SNOC] = &qnm_aggre1_noc, + [MASTER_GEM_NOC_SNOC] = &qnm_gemnoc, + [MASTER_GEM_NOC_PCIE_SNOC] = &qnm_gemnoc_pcie, + [MASTER_LPASS_ANOC] = &qnm_lpass_anoc, + [MASTER_ANOC_PCIE_SNOC] = &qnm_pcie_anoc, + [MASTER_PIMEM] = &qxm_pimem, + [MASTER_GIC] = &xm_gic, + [SLAVE_APPSS] = &qhs_apss, + [SLAVE_SNOC_CNOC] = &qns_cnoc, + [SLAVE_SNOC_GEM_NOC_SF] = &qns_gemnoc_sf, + [SLAVE_SNOC_MEM_NOC_GC] = &qns_memnoc_gc, + [SLAVE_IMEM] = &qxs_imem, + [SLAVE_PIMEM] = &qxs_pimem, + [SLAVE_SERVICE_SNOC] = &srvc_snoc, + [SLAVE_PCIE_0] = &xs_pcie, + [SLAVE_QDSS_STM] = &xs_qdss_stm, + [SLAVE_TCU] = &xs_sys_tcu_cfg, +}; + +static const struct qcom_icc_desc qcs615_system_noc = { + .nodes = system_noc_nodes, + .num_nodes = ARRAY_SIZE(system_noc_nodes), + .bcms = system_noc_bcms, + .num_bcms = ARRAY_SIZE(system_noc_bcms), +}; + +static const struct of_device_id qnoc_of_match[] = { + { .compatible = "qcom,qcs615-aggre1-noc", + .data = &qcs615_aggre1_noc}, + { .compatible = "qcom,qcs615-camnoc-virt", + .data = &qcs615_camnoc_virt}, + { .compatible = "qcom,qcs615-config-noc", + .data = &qcs615_config_noc}, + { .compatible = "qcom,qcs615-dc-noc", + .data = &qcs615_dc_noc}, + { .compatible = "qcom,qcs615-gem-noc", + .data = &qcs615_gem_noc}, + { .compatible = "qcom,qcs615-ipa-virt", + .data = &qcs615_ipa_virt}, + { .compatible = "qcom,qcs615-mc-virt", + .data = &qcs615_mc_virt}, + { .compatible = "qcom,qcs615-mmss-noc", + .data = &qcs615_mmss_noc}, + { .compatible = "qcom,qcs615-system-noc", + .data = &qcs615_system_noc}, + { } +}; +MODULE_DEVICE_TABLE(of, qnoc_of_match); + +static struct platform_driver qnoc_driver = { + .probe = qcom_icc_rpmh_probe, + .remove = qcom_icc_rpmh_remove, + .driver = { + .name = "qnoc-qcs615", + .of_match_table = qnoc_of_match, + .sync_state = icc_sync_state, + }, +}; + +static int __init qnoc_driver_init(void) +{ + return platform_driver_register(&qnoc_driver); +} +core_initcall(qnoc_driver_init); + +static void __exit qnoc_driver_exit(void) +{ + platform_driver_unregister(&qnoc_driver); +} +module_exit(qnoc_driver_exit); + +MODULE_DESCRIPTION("qcs615 NoC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/interconnect/qcom/qcs615.h b/drivers/interconnect/qcom/qcs615.h new file mode 100644 index 0000000000000000000000000000000000000000..66e66c7e23d4ecaf92c2697e695980c3f8663664 --- /dev/null +++ b/drivers/interconnect/qcom/qcs615.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __DRIVERS_INTERCONNECT_QCOM_QCS615_H +#define __DRIVERS_INTERCONNECT_QCOM_QCS615_H + +#define QCS615_MASTER_A1NOC_CFG 1 +#define QCS615_MASTER_A1NOC_SNOC 2 +#define QCS615_MASTER_ANOC_PCIE_SNOC 3 +#define QCS615_MASTER_APPSS_PROC 4 +#define QCS615_MASTER_BLSP_1 5 +#define QCS615_MASTER_CAMNOC_HF0 6 +#define QCS615_MASTER_CAMNOC_HF0_UNCOMP 7 +#define QCS615_MASTER_CAMNOC_HF1 8 +#define QCS615_MASTER_CAMNOC_HF1_UNCOMP 9 +#define QCS615_MASTER_CAMNOC_SF 10 +#define QCS615_MASTER_CAMNOC_SF_UNCOMP 11 +#define QCS615_MASTER_CNOC_A2NOC 12 +#define QCS615_MASTER_CNOC_DC_NOC 13 +#define QCS615_MASTER_CNOC_MNOC_CFG 14 +#define QCS615_MASTER_CRYPTO 15 +#define QCS615_MASTER_EMAC_EVB 16 +#define QCS615_MASTER_GEM_NOC_CFG 17 +#define QCS615_MASTER_GEM_NOC_PCIE_SNOC 18 +#define QCS615_MASTER_GEM_NOC_SNOC 19 +#define QCS615_MASTER_GFX3D 20 +#define QCS615_MASTER_GIC 21 +#define QCS615_MASTER_GPU_TCU 22 +#define QCS615_MASTER_IPA 23 +#define QCS615_MASTER_IPA_CORE 24 +#define QCS615_MASTER_LLCC 25 +#define QCS615_MASTER_LPASS_ANOC 26 +#define QCS615_MASTER_MDP0 27 +#define QCS615_MASTER_MNOC_HF_MEM_NOC 28 +#define QCS615_MASTER_MNOC_SF_MEM_NOC 29 +#define QCS615_MASTER_PCIE 30 +#define QCS615_MASTER_PIMEM 31 +#define QCS615_MASTER_QDSS_BAM 32 +#define QCS615_MASTER_QDSS_DAP 33 +#define QCS615_MASTER_QDSS_ETR 34 +#define QCS615_MASTER_QSPI 35 +#define QCS615_MASTER_QUP_0 36 +#define QCS615_MASTER_ROTATOR 37 +#define QCS615_MASTER_SDCC_1 38 +#define QCS615_MASTER_SDCC_2 39 +#define QCS615_MASTER_SNOC_CFG 40 +#define QCS615_MASTER_SNOC_CNOC 41 +#define QCS615_MASTER_SNOC_GC_MEM_NOC 42 +#define QCS615_MASTER_SNOC_SF_MEM_NOC 43 +#define QCS615_MASTER_SPDM 44 +#define QCS615_MASTER_SYS_TCU 45 +#define QCS615_MASTER_UFS_MEM 46 +#define QCS615_MASTER_USB2 47 +#define QCS615_MASTER_USB3_0 48 +#define QCS615_MASTER_VIDEO_P0 49 +#define QCS615_MASTER_VIDEO_PROC 50 +#define QCS615_SLAVE_A1NOC_CFG 51 +#define QCS615_SLAVE_A1NOC_SNOC 52 +#define QCS615_SLAVE_AHB2PHY_EAST 53 +#define QCS615_SLAVE_AHB2PHY_WEST 54 +#define QCS615_SLAVE_ANOC_PCIE_SNOC 55 +#define QCS615_SLAVE_AOP 56 +#define QCS615_SLAVE_AOSS 57 +#define QCS615_SLAVE_APPSS 58 +#define QCS615_SLAVE_CAMERA_CFG 59 +#define QCS615_SLAVE_CAMNOC_UNCOMP 60 +#define QCS615_SLAVE_CLK_CTL 61 +#define QCS615_SLAVE_CNOC_A2NOC 62 +#define QCS615_SLAVE_CNOC_DDRSS 63 +#define QCS615_SLAVE_CNOC_MNOC_CFG 64 +#define QCS615_SLAVE_CRYPTO_0_CFG 65 +#define QCS615_SLAVE_DC_NOC_GEMNOC 66 +#define QCS615_SLAVE_DISPLAY_CFG 67 +#define QCS615_SLAVE_EBI1 68 +#define QCS615_SLAVE_EMAC_AVB_CFG 69 +#define QCS615_SLAVE_GEM_NOC_SNOC 70 +#define QCS615_SLAVE_GFX3D_CFG 71 +#define QCS615_SLAVE_GLM 72 +#define QCS615_SLAVE_IMEM 73 +#define QCS615_SLAVE_IMEM_CFG 74 +#define QCS615_SLAVE_IPA_CFG 75 +#define QCS615_SLAVE_IPA_CORE 76 +#define QCS615_SLAVE_LLCC 77 +#define QCS615_SLAVE_LLCC_CFG 78 +#define QCS615_SLAVE_LPASS_SNOC 79 +#define QCS615_SLAVE_MEM_NOC_PCIE_SNOC 80 +#define QCS615_SLAVE_MNOC_HF_MEM_NOC 81 +#define QCS615_SLAVE_MNOC_SF_MEM_NOC 82 +#define QCS615_SLAVE_MSS_PROC_MS_MPU_CFG 83 +#define QCS615_SLAVE_PCIE_0 84 +#define QCS615_SLAVE_PCIE_CFG 85 +#define QCS615_SLAVE_PIMEM 86 +#define QCS615_SLAVE_PIMEM_CFG 87 +#define QCS615_SLAVE_PRNG 88 +#define QCS615_SLAVE_QDSS_CFG 89 +#define QCS615_SLAVE_QDSS_STM 90 +#define QCS615_SLAVE_QSPI 91 +#define QCS615_SLAVE_QUP_0 92 +#define QCS615_SLAVE_QUP_1 93 +#define QCS615_SLAVE_RBCPR_CX_CFG 94 +#define QCS615_SLAVE_RBCPR_MX_CFG 95 +#define QCS615_SLAVE_SDCC_1 96 +#define QCS615_SLAVE_SDCC_2 97 +#define QCS615_SLAVE_SERVICE_A2NOC 98 +#define QCS615_SLAVE_SERVICE_CNOC 99 +#define QCS615_SLAVE_SERVICE_GEM_NOC 100 +#define QCS615_SLAVE_SERVICE_MNOC 101 +#define QCS615_SLAVE_SERVICE_SNOC 102 +#define QCS615_SLAVE_SNOC_CFG 103 +#define QCS615_SLAVE_SNOC_CNOC 104 +#define QCS615_SLAVE_SNOC_GEM_NOC_SF 105 +#define QCS615_SLAVE_SNOC_MEM_NOC_GC 106 +#define QCS615_SLAVE_SPDM_WRAPPER 107 +#define QCS615_SLAVE_TCSR 108 +#define QCS615_SLAVE_TCU 109 +#define QCS615_SLAVE_TLMM_EAST 110 +#define QCS615_SLAVE_TLMM_SOUTH 111 +#define QCS615_SLAVE_TLMM_WEST 112 +#define QCS615_SLAVE_UFS_MEM_CFG 113 +#define QCS615_SLAVE_USB2 114 +#define QCS615_SLAVE_USB3 115 +#define QCS615_SLAVE_VENUS_CFG 116 +#define QCS615_SLAVE_VSENSE_CTRL_CFG 117 + +#endif + diff --git a/drivers/interconnect/qcom/qcs8300.c b/drivers/interconnect/qcom/qcs8300.c new file mode 100644 index 0000000000000000000000000000000000000000..e7a1b2fc69babe15b914da8d3a3769bfed110179 --- /dev/null +++ b/drivers/interconnect/qcom/qcs8300.c @@ -0,0 +1,2088 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "bcm-voter.h" +#include "icc-rpmh.h" +#include "qcs8300.h" + +static struct qcom_icc_node qxm_qup3 = { + .name = "qxm_qup3", + .id = QCS8300_MASTER_QUP_3, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_emac_0 = { + .name = "xm_emac_0", + .id = QCS8300_MASTER_EMAC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_sdc1 = { + .name = "xm_sdc1", + .id = QCS8300_MASTER_SDC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_ufs_mem = { + .name = "xm_ufs_mem", + .id = QCS8300_MASTER_UFS_MEM, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_usb2_2 = { + .name = "xm_usb2_2", + .id = QCS8300_MASTER_USB2, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node xm_usb3_0 = { + .name = "xm_usb3_0", + .id = QCS8300_MASTER_USB3_0, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qhm_qdss_bam = { + .name = "qhm_qdss_bam", + .id = QCS8300_MASTER_QDSS_BAM, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qhm_qup0 = { + .name = "qhm_qup0", + .id = QCS8300_MASTER_QUP_0, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qhm_qup1 = { + .name = "qhm_qup1", + .id = QCS8300_MASTER_QUP_1, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qnm_cnoc_datapath = { + .name = "qnm_cnoc_datapath", + .id = QCS8300_MASTER_CNOC_A2NOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qxm_crypto_0 = { + .name = "qxm_crypto_0", + .id = QCS8300_MASTER_CRYPTO_CORE0, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qxm_crypto_1 = { + .name = "qxm_crypto_1", + .id = QCS8300_MASTER_CRYPTO_CORE1, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qxm_ipa = { + .name = "qxm_ipa", + .id = QCS8300_MASTER_IPA, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node xm_qdss_etr_0 = { + .name = "xm_qdss_etr_0", + .id = QCS8300_MASTER_QDSS_ETR_0, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node xm_qdss_etr_1 = { + .name = "xm_qdss_etr_1", + .id = QCS8300_MASTER_QDSS_ETR_1, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qup0_core_master = { + .name = "qup0_core_master", + .id = QCS8300_MASTER_QUP_CORE_0, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_QUP_CORE_0 }, +}; + +static struct qcom_icc_node qup1_core_master = { + .name = "qup1_core_master", + .id = QCS8300_MASTER_QUP_CORE_1, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_QUP_CORE_1 }, +}; + +static struct qcom_icc_node qup3_core_master = { + .name = "qup3_core_master", + .id = QCS8300_MASTER_QUP_CORE_3, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_QUP_CORE_3 }, +}; + +static struct qcom_icc_node qnm_gemnoc_cnoc = { + .name = "qnm_gemnoc_cnoc", + .id = QCS8300_MASTER_GEM_NOC_CNOC, + .channels = 1, + .buswidth = 16, + .num_links = 71, + .links = { QCS8300_SLAVE_AHB2PHY_2, QCS8300_SLAVE_AHB2PHY_3, + QCS8300_SLAVE_ANOC_THROTTLE_CFG, QCS8300_SLAVE_AOSS, + QCS8300_SLAVE_APPSS, QCS8300_SLAVE_BOOT_ROM, + QCS8300_SLAVE_CAMERA_CFG, QCS8300_SLAVE_CAMERA_NRT_THROTTLE_CFG, + QCS8300_SLAVE_CAMERA_RT_THROTTLE_CFG, QCS8300_SLAVE_CLK_CTL, + QCS8300_SLAVE_CDSP_CFG, QCS8300_SLAVE_RBCPR_CX_CFG, + QCS8300_SLAVE_RBCPR_MMCX_CFG, QCS8300_SLAVE_RBCPR_MX_CFG, + QCS8300_SLAVE_CPR_NSPCX, QCS8300_SLAVE_CPR_NSPHMX, + QCS8300_SLAVE_CRYPTO_0_CFG, QCS8300_SLAVE_CX_RDPM, + QCS8300_SLAVE_DISPLAY_CFG, QCS8300_SLAVE_DISPLAY_RT_THROTTLE_CFG, + QCS8300_SLAVE_EMAC_CFG, QCS8300_SLAVE_GP_DSP0_CFG, + QCS8300_SLAVE_GPDSP0_THROTTLE_CFG, QCS8300_SLAVE_GPU_TCU_THROTTLE_CFG, + QCS8300_SLAVE_GFX3D_CFG, QCS8300_SLAVE_HWKM, + QCS8300_SLAVE_IMEM_CFG, QCS8300_SLAVE_IPA_CFG, + QCS8300_SLAVE_IPC_ROUTER_CFG, QCS8300_SLAVE_LPASS, + QCS8300_SLAVE_LPASS_THROTTLE_CFG, QCS8300_SLAVE_MX_RDPM, + QCS8300_SLAVE_MXC_RDPM, QCS8300_SLAVE_PCIE_0_CFG, + QCS8300_SLAVE_PCIE_1_CFG, QCS8300_SLAVE_PCIE_TCU_THROTTLE_CFG, + QCS8300_SLAVE_PCIE_THROTTLE_CFG, QCS8300_SLAVE_PDM, + QCS8300_SLAVE_PIMEM_CFG, QCS8300_SLAVE_PKA_WRAPPER_CFG, + QCS8300_SLAVE_QDSS_CFG, QCS8300_SLAVE_QM_CFG, + QCS8300_SLAVE_QM_MPU_CFG, QCS8300_SLAVE_QUP_0, + QCS8300_SLAVE_QUP_1, QCS8300_SLAVE_QUP_3, + QCS8300_SLAVE_SAIL_THROTTLE_CFG, QCS8300_SLAVE_SDC1, + QCS8300_SLAVE_SECURITY, QCS8300_SLAVE_SNOC_THROTTLE_CFG, + QCS8300_SLAVE_TCSR, QCS8300_SLAVE_TLMM, + QCS8300_SLAVE_TSC_CFG, QCS8300_SLAVE_UFS_MEM_CFG, + QCS8300_SLAVE_USB2, QCS8300_SLAVE_USB3_0, + QCS8300_SLAVE_VENUS_CFG, QCS8300_SLAVE_VENUS_CVP_THROTTLE_CFG, + QCS8300_SLAVE_VENUS_V_CPU_THROTTLE_CFG, + QCS8300_SLAVE_VENUS_VCODEC_THROTTLE_CFG, + QCS8300_SLAVE_DDRSS_CFG, QCS8300_SLAVE_GPDSP_NOC_CFG, + QCS8300_SLAVE_CNOC_MNOC_HF_CFG, QCS8300_SLAVE_CNOC_MNOC_SF_CFG, + QCS8300_SLAVE_PCIE_ANOC_CFG, QCS8300_SLAVE_SNOC_CFG, + QCS8300_SLAVE_BOOT_IMEM, QCS8300_SLAVE_IMEM, + QCS8300_SLAVE_PIMEM, QCS8300_SLAVE_QDSS_STM, + QCS8300_SLAVE_TCU }, +}; + +static struct qcom_icc_node qnm_gemnoc_pcie = { + .name = "qnm_gemnoc_pcie", + .id = QCS8300_MASTER_GEM_NOC_PCIE_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 2, + .links = { QCS8300_SLAVE_PCIE_0, QCS8300_SLAVE_PCIE_1 }, +}; + +static struct qcom_icc_node qnm_cnoc_dc_noc = { + .name = "qnm_cnoc_dc_noc", + .id = QCS8300_MASTER_CNOC_DC_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 2, + .links = { QCS8300_SLAVE_LLCC_CFG, QCS8300_SLAVE_GEM_NOC_CFG }, +}; + +static struct qcom_icc_node alm_gpu_tcu = { + .name = "alm_gpu_tcu", + .id = QCS8300_MASTER_GPU_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node alm_pcie_tcu = { + .name = "alm_pcie_tcu", + .id = QCS8300_MASTER_PCIE_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node alm_sys_tcu = { + .name = "alm_sys_tcu", + .id = QCS8300_MASTER_SYS_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node chm_apps = { + .name = "chm_apps", + .id = QCS8300_MASTER_APPSS_PROC, + .channels = 4, + .buswidth = 32, + .num_links = 3, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC, + QCS8300_SLAVE_GEM_NOC_PCIE_CNOC }, +}; + +static struct qcom_icc_node qnm_cmpnoc0 = { + .name = "qnm_cmpnoc0", + .id = QCS8300_MASTER_COMPUTE_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 2, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_gemnoc_cfg = { + .name = "qnm_gemnoc_cfg", + .id = QCS8300_MASTER_GEM_NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 4, + .links = { QCS8300_SLAVE_SERVICE_GEM_NOC_1, QCS8300_SLAVE_SERVICE_GEM_NOC_2, + QCS8300_SLAVE_SERVICE_GEM_NOC, QCS8300_SLAVE_SERVICE_GEM_NOC2 }, +}; + +static struct qcom_icc_node qnm_gpdsp_sail = { + .name = "qnm_gpdsp_sail", + .id = QCS8300_MASTER_GPDSP_SAIL, + .channels = 1, + .buswidth = 16, + .num_links = 2, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_gpu = { + .name = "qnm_gpu", + .id = QCS8300_MASTER_GFX3D, + .channels = 2, + .buswidth = 32, + .num_links = 2, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_mnoc_hf = { + .name = "qnm_mnoc_hf", + .id = QCS8300_MASTER_MNOC_HF_MEM_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 2, + .links = { QCS8300_SLAVE_LLCC, QCS8300_SLAVE_GEM_NOC_PCIE_CNOC }, +}; + +static struct qcom_icc_node qnm_mnoc_sf = { + .name = "qnm_mnoc_sf", + .id = QCS8300_MASTER_MNOC_SF_MEM_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 3, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC, + QCS8300_SLAVE_GEM_NOC_PCIE_CNOC }, +}; + +static struct qcom_icc_node qnm_pcie = { + .name = "qnm_pcie", + .id = QCS8300_MASTER_ANOC_PCIE_GEM_NOC, + .channels = 1, + .buswidth = 32, + .num_links = 2, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_snoc_gc = { + .name = "qnm_snoc_gc", + .id = QCS8300_MASTER_SNOC_GC_MEM_NOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_LLCC }, +}; + +static struct qcom_icc_node qnm_snoc_sf = { + .name = "qnm_snoc_sf", + .id = QCS8300_MASTER_SNOC_SF_MEM_NOC, + .channels = 1, + .buswidth = 16, + .num_links = 3, + .links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC, + QCS8300_SLAVE_GEM_NOC_PCIE_CNOC }, +}; + +static struct qcom_icc_node qnm_sailss_md0 = { + .name = "qnm_sailss_md0", + .id = QCS8300_MASTER_SAILSS_MD0, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_SLAVE_GP_DSP_SAIL_NOC }, +}; + +static struct qcom_icc_node qxm_dsp0 = { + .name = "qxm_dsp0", + .id = QCS8300_MASTER_DSP0, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_SLAVE_GP_DSP_SAIL_NOC }, +}; + +static struct qcom_icc_node qhm_config_noc = { + .name = "qhm_config_noc", + .id = QCS8300_MASTER_CNOC_LPASS_AG_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 6, + .links = { QCS8300_SLAVE_LPASS_CORE_CFG, QCS8300_SLAVE_LPASS_LPI_CFG, + QCS8300_SLAVE_LPASS_MPU_CFG, QCS8300_SLAVE_LPASS_TOP_CFG, + QCS8300_SLAVE_SERVICES_LPASS_AML_NOC, QCS8300_SLAVE_SERVICE_LPASS_AG_NOC }, +}; + +static struct qcom_icc_node qxm_lpass_dsp = { + .name = "qxm_lpass_dsp", + .id = QCS8300_MASTER_LPASS_PROC, + .channels = 1, + .buswidth = 8, + .num_links = 4, + .links = { QCS8300_SLAVE_LPASS_TOP_CFG, QCS8300_SLAVE_LPASS_SNOC, + QCS8300_SLAVE_SERVICES_LPASS_AML_NOC, QCS8300_SLAVE_SERVICE_LPASS_AG_NOC }, +}; + +static struct qcom_icc_node llcc_mc = { + .name = "llcc_mc", + .id = QCS8300_MASTER_LLCC, + .channels = 8, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_EBI1 }, +}; + +static struct qcom_icc_node qnm_camnoc_hf = { + .name = "qnm_camnoc_hf", + .id = QCS8300_MASTER_CAMNOC_HF, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_camnoc_icp = { + .name = "qnm_camnoc_icp", + .id = QCS8300_MASTER_CAMNOC_ICP, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_camnoc_sf = { + .name = "qnm_camnoc_sf", + .id = QCS8300_MASTER_CAMNOC_SF, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_mdp0_0 = { + .name = "qnm_mdp0_0", + .id = QCS8300_MASTER_MDP0, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_mdp0_1 = { + .name = "qnm_mdp0_1", + .id = QCS8300_MASTER_MDP1, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_mnoc_hf_cfg = { + .name = "qnm_mnoc_hf_cfg", + .id = QCS8300_MASTER_CNOC_MNOC_HF_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_SERVICE_MNOC_HF }, +}; + +static struct qcom_icc_node qnm_mnoc_sf_cfg = { + .name = "qnm_mnoc_sf_cfg", + .id = QCS8300_MASTER_CNOC_MNOC_SF_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_SERVICE_MNOC_SF }, +}; + +static struct qcom_icc_node qnm_video0 = { + .name = "qnm_video0", + .id = QCS8300_MASTER_VIDEO_P0, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_video_cvp = { + .name = "qnm_video_cvp", + .id = QCS8300_MASTER_VIDEO_PROC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_video_v_cpu = { + .name = "qnm_video_v_cpu", + .id = QCS8300_MASTER_VIDEO_V_PROC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qhm_nsp_noc_config = { + .name = "qhm_nsp_noc_config", + .id = QCS8300_MASTER_CDSP_NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_SERVICE_NSP_NOC }, +}; + +static struct qcom_icc_node qxm_nsp = { + .name = "qxm_nsp", + .id = QCS8300_MASTER_CDSP_PROC, + .channels = 2, + .buswidth = 32, + .num_links = 2, + .links = { QCS8300_SLAVE_HCP_A, QCS8300_SLAVE_CDSP_MEM_NOC }, +}; + +static struct qcom_icc_node xm_pcie3_0 = { + .name = "xm_pcie3_0", + .id = QCS8300_MASTER_PCIE_0, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_SLAVE_ANOC_PCIE_GEM_NOC }, +}; + +static struct qcom_icc_node xm_pcie3_1 = { + .name = "xm_pcie3_1", + .id = QCS8300_MASTER_PCIE_1, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_ANOC_PCIE_GEM_NOC }, +}; + +static struct qcom_icc_node qhm_gic = { + .name = "qhm_gic", + .id = QCS8300_MASTER_GIC_AHB, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF }, +}; + +static struct qcom_icc_node qnm_aggre1_noc = { + .name = "qnm_aggre1_noc", + .id = QCS8300_MASTER_A1NOC_SNOC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF }, +}; + +static struct qcom_icc_node qnm_aggre2_noc = { + .name = "qnm_aggre2_noc", + .id = QCS8300_MASTER_A2NOC_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF }, +}; + +static struct qcom_icc_node qnm_lpass_noc = { + .name = "qnm_lpass_noc", + .id = QCS8300_MASTER_LPASS_ANOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF }, +}; + +static struct qcom_icc_node qnm_snoc_cfg = { + .name = "qnm_snoc_cfg", + .id = QCS8300_MASTER_SNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_SLAVE_SERVICE_SNOC }, +}; + +static struct qcom_icc_node qxm_pimem = { + .name = "qxm_pimem", + .id = QCS8300_MASTER_PIMEM, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_SNOC_GEM_NOC_GC }, +}; + +static struct qcom_icc_node xm_gic = { + .name = "xm_gic", + .id = QCS8300_MASTER_GIC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_SLAVE_SNOC_GEM_NOC_GC }, +}; + +static struct qcom_icc_node qns_a1noc_snoc = { + .name = "qns_a1noc_snoc", + .id = QCS8300_SLAVE_A1NOC_SNOC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_MASTER_A1NOC_SNOC }, +}; + +static struct qcom_icc_node qns_a2noc_snoc = { + .name = "qns_a2noc_snoc", + .id = QCS8300_SLAVE_A2NOC_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_MASTER_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qup0_core_slave = { + .name = "qup0_core_slave", + .id = QCS8300_SLAVE_QUP_CORE_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qup1_core_slave = { + .name = "qup1_core_slave", + .id = QCS8300_SLAVE_QUP_CORE_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qup3_core_slave = { + .name = "qup3_core_slave", + .id = QCS8300_SLAVE_QUP_CORE_3, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ahb2phy2 = { + .name = "qhs_ahb2phy2", + .id = QCS8300_SLAVE_AHB2PHY_2, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ahb2phy3 = { + .name = "qhs_ahb2phy3", + .id = QCS8300_SLAVE_AHB2PHY_3, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_anoc_throttle_cfg = { + .name = "qhs_anoc_throttle_cfg", + .id = QCS8300_SLAVE_ANOC_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_aoss = { + .name = "qhs_aoss", + .id = QCS8300_SLAVE_AOSS, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_apss = { + .name = "qhs_apss", + .id = QCS8300_SLAVE_APPSS, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_boot_rom = { + .name = "qhs_boot_rom", + .id = QCS8300_SLAVE_BOOT_ROM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_camera_cfg = { + .name = "qhs_camera_cfg", + .id = QCS8300_SLAVE_CAMERA_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_camera_nrt_throttle_cfg = { + .name = "qhs_camera_nrt_throttle_cfg", + .id = QCS8300_SLAVE_CAMERA_NRT_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_camera_rt_throttle_cfg = { + .name = "qhs_camera_rt_throttle_cfg", + .id = QCS8300_SLAVE_CAMERA_RT_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_clk_ctl = { + .name = "qhs_clk_ctl", + .id = QCS8300_SLAVE_CLK_CTL, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_compute0_cfg = { + .name = "qhs_compute0_cfg", + .id = QCS8300_SLAVE_CDSP_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_MASTER_CDSP_NOC_CFG }, +}; + +static struct qcom_icc_node qhs_cpr_cx = { + .name = "qhs_cpr_cx", + .id = QCS8300_SLAVE_RBCPR_CX_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_mmcx = { + .name = "qhs_cpr_mmcx", + .id = QCS8300_SLAVE_RBCPR_MMCX_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_mx = { + .name = "qhs_cpr_mx", + .id = QCS8300_SLAVE_RBCPR_MX_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_nspcx = { + .name = "qhs_cpr_nspcx", + .id = QCS8300_SLAVE_CPR_NSPCX, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_nsphmx = { + .name = "qhs_cpr_nsphmx", + .id = QCS8300_SLAVE_CPR_NSPHMX, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_crypto0_cfg = { + .name = "qhs_crypto0_cfg", + .id = QCS8300_SLAVE_CRYPTO_0_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cx_rdpm = { + .name = "qhs_cx_rdpm", + .id = QCS8300_SLAVE_CX_RDPM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_display0_cfg = { + .name = "qhs_display0_cfg", + .id = QCS8300_SLAVE_DISPLAY_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_display0_rt_throttle_cfg = { + .name = "qhs_display0_rt_throttle_cfg", + .id = QCS8300_SLAVE_DISPLAY_RT_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_emac0_cfg = { + .name = "qhs_emac0_cfg", + .id = QCS8300_SLAVE_EMAC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_gp_dsp0_cfg = { + .name = "qhs_gp_dsp0_cfg", + .id = QCS8300_SLAVE_GP_DSP0_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_gpdsp0_throttle_cfg = { + .name = "qhs_gpdsp0_throttle_cfg", + .id = QCS8300_SLAVE_GPDSP0_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_gpu_tcu_throttle_cfg = { + .name = "qhs_gpu_tcu_throttle_cfg", + .id = QCS8300_SLAVE_GPU_TCU_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_gpuss_cfg = { + .name = "qhs_gpuss_cfg", + .id = QCS8300_SLAVE_GFX3D_CFG, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_hwkm = { + .name = "qhs_hwkm", + .id = QCS8300_SLAVE_HWKM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_imem_cfg = { + .name = "qhs_imem_cfg", + .id = QCS8300_SLAVE_IMEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ipa = { + .name = "qhs_ipa", + .id = QCS8300_SLAVE_IPA_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ipc_router = { + .name = "qhs_ipc_router", + .id = QCS8300_SLAVE_IPC_ROUTER_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_cfg = { + .name = "qhs_lpass_cfg", + .id = QCS8300_SLAVE_LPASS, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_MASTER_CNOC_LPASS_AG_NOC }, +}; + +static struct qcom_icc_node qhs_lpass_throttle_cfg = { + .name = "qhs_lpass_throttle_cfg", + .id = QCS8300_SLAVE_LPASS_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_mx_rdpm = { + .name = "qhs_mx_rdpm", + .id = QCS8300_SLAVE_MX_RDPM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_mxc_rdpm = { + .name = "qhs_mxc_rdpm", + .id = QCS8300_SLAVE_MXC_RDPM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pcie0_cfg = { + .name = "qhs_pcie0_cfg", + .id = QCS8300_SLAVE_PCIE_0_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pcie1_cfg = { + .name = "qhs_pcie1_cfg", + .id = QCS8300_SLAVE_PCIE_1_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pcie_tcu_throttle_cfg = { + .name = "qhs_pcie_tcu_throttle_cfg", + .id = QCS8300_SLAVE_PCIE_TCU_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pcie_throttle_cfg = { + .name = "qhs_pcie_throttle_cfg", + .id = QCS8300_SLAVE_PCIE_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pdm = { + .name = "qhs_pdm", + .id = QCS8300_SLAVE_PDM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pimem_cfg = { + .name = "qhs_pimem_cfg", + .id = QCS8300_SLAVE_PIMEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pke_wrapper_cfg = { + .name = "qhs_pke_wrapper_cfg", + .id = QCS8300_SLAVE_PKA_WRAPPER_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qdss_cfg = { + .name = "qhs_qdss_cfg", + .id = QCS8300_SLAVE_QDSS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qm_cfg = { + .name = "qhs_qm_cfg", + .id = QCS8300_SLAVE_QM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qm_mpu_cfg = { + .name = "qhs_qm_mpu_cfg", + .id = QCS8300_SLAVE_QM_MPU_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qup0 = { + .name = "qhs_qup0", + .id = QCS8300_SLAVE_QUP_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qup1 = { + .name = "qhs_qup1", + .id = QCS8300_SLAVE_QUP_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qup3 = { + .name = "qhs_qup3", + .id = QCS8300_SLAVE_QUP_3, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_sail_throttle_cfg = { + .name = "qhs_sail_throttle_cfg", + .id = QCS8300_SLAVE_SAIL_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_sdc1 = { + .name = "qhs_sdc1", + .id = QCS8300_SLAVE_SDC1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_security = { + .name = "qhs_security", + .id = QCS8300_SLAVE_SECURITY, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_snoc_throttle_cfg = { + .name = "qhs_snoc_throttle_cfg", + .id = QCS8300_SLAVE_SNOC_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tcsr = { + .name = "qhs_tcsr", + .id = QCS8300_SLAVE_TCSR, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tlmm = { + .name = "qhs_tlmm", + .id = QCS8300_SLAVE_TLMM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tsc_cfg = { + .name = "qhs_tsc_cfg", + .id = QCS8300_SLAVE_TSC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ufs_mem_cfg = { + .name = "qhs_ufs_mem_cfg", + .id = QCS8300_SLAVE_UFS_MEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_usb2_0 = { + .name = "qhs_usb2_0", + .id = QCS8300_SLAVE_USB2, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_usb3_0 = { + .name = "qhs_usb3_0", + .id = QCS8300_SLAVE_USB3_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_venus_cfg = { + .name = "qhs_venus_cfg", + .id = QCS8300_SLAVE_VENUS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_venus_cvp_throttle_cfg = { + .name = "qhs_venus_cvp_throttle_cfg", + .id = QCS8300_SLAVE_VENUS_CVP_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_venus_v_cpu_throttle_cfg = { + .name = "qhs_venus_v_cpu_throttle_cfg", + .id = QCS8300_SLAVE_VENUS_V_CPU_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_venus_vcodec_throttle_cfg = { + .name = "qhs_venus_vcodec_throttle_cfg", + .id = QCS8300_SLAVE_VENUS_VCODEC_THROTTLE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_ddrss_cfg = { + .name = "qns_ddrss_cfg", + .id = QCS8300_SLAVE_DDRSS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_MASTER_CNOC_DC_NOC }, +}; + +static struct qcom_icc_node qns_gpdsp_noc_cfg = { + .name = "qns_gpdsp_noc_cfg", + .id = QCS8300_SLAVE_GPDSP_NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_mnoc_hf_cfg = { + .name = "qns_mnoc_hf_cfg", + .id = QCS8300_SLAVE_CNOC_MNOC_HF_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_MASTER_CNOC_MNOC_HF_CFG }, +}; + +static struct qcom_icc_node qns_mnoc_sf_cfg = { + .name = "qns_mnoc_sf_cfg", + .id = QCS8300_SLAVE_CNOC_MNOC_SF_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_MASTER_CNOC_MNOC_SF_CFG }, +}; + +static struct qcom_icc_node qns_pcie_anoc_cfg = { + .name = "qns_pcie_anoc_cfg", + .id = QCS8300_SLAVE_PCIE_ANOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_snoc_cfg = { + .name = "qns_snoc_cfg", + .id = QCS8300_SLAVE_SNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_MASTER_SNOC_CFG }, +}; + +static struct qcom_icc_node qxs_boot_imem = { + .name = "qxs_boot_imem", + .id = QCS8300_SLAVE_BOOT_IMEM, + .channels = 1, + .buswidth = 16, + .num_links = 0, +}; + +static struct qcom_icc_node qxs_imem = { + .name = "qxs_imem", + .id = QCS8300_SLAVE_IMEM, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qxs_pimem = { + .name = "qxs_pimem", + .id = QCS8300_SLAVE_PIMEM, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node xs_pcie_0 = { + .name = "xs_pcie_0", + .id = QCS8300_SLAVE_PCIE_0, + .channels = 1, + .buswidth = 16, + .num_links = 0, +}; + +static struct qcom_icc_node xs_pcie_1 = { + .name = "xs_pcie_1", + .id = QCS8300_SLAVE_PCIE_1, + .channels = 1, + .buswidth = 32, + .num_links = 0, +}; + +static struct qcom_icc_node xs_qdss_stm = { + .name = "xs_qdss_stm", + .id = QCS8300_SLAVE_QDSS_STM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node xs_sys_tcu_cfg = { + .name = "xs_sys_tcu_cfg", + .id = QCS8300_SLAVE_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_llcc = { + .name = "qhs_llcc", + .id = QCS8300_SLAVE_LLCC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_gemnoc = { + .name = "qns_gemnoc", + .id = QCS8300_SLAVE_GEM_NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { QCS8300_MASTER_GEM_NOC_CFG }, +}; + +static struct qcom_icc_node qns_gem_noc_cnoc = { + .name = "qns_gem_noc_cnoc", + .id = QCS8300_SLAVE_GEM_NOC_CNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_MASTER_GEM_NOC_CNOC }, +}; + +static struct qcom_icc_node qns_llcc = { + .name = "qns_llcc", + .id = QCS8300_SLAVE_LLCC, + .channels = 4, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_MASTER_LLCC }, +}; + +static struct qcom_icc_node qns_pcie = { + .name = "qns_pcie", + .id = QCS8300_SLAVE_GEM_NOC_PCIE_CNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_MASTER_GEM_NOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node srvc_even_gemnoc = { + .name = "srvc_even_gemnoc", + .id = QCS8300_SLAVE_SERVICE_GEM_NOC_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_odd_gemnoc = { + .name = "srvc_odd_gemnoc", + .id = QCS8300_SLAVE_SERVICE_GEM_NOC_2, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_sys_gemnoc = { + .name = "srvc_sys_gemnoc", + .id = QCS8300_SLAVE_SERVICE_GEM_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_sys_gemnoc_2 = { + .name = "srvc_sys_gemnoc_2", + .id = QCS8300_SLAVE_SERVICE_GEM_NOC2, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_gp_dsp_sail_noc = { + .name = "qns_gp_dsp_sail_noc", + .id = QCS8300_SLAVE_GP_DSP_SAIL_NOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_MASTER_GPDSP_SAIL }, +}; + +static struct qcom_icc_node qhs_lpass_core = { + .name = "qhs_lpass_core", + .id = QCS8300_SLAVE_LPASS_CORE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_lpi = { + .name = "qhs_lpass_lpi", + .id = QCS8300_SLAVE_LPASS_LPI_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_mpu = { + .name = "qhs_lpass_mpu", + .id = QCS8300_SLAVE_LPASS_MPU_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_top = { + .name = "qhs_lpass_top", + .id = QCS8300_SLAVE_LPASS_TOP_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_sysnoc = { + .name = "qns_sysnoc", + .id = QCS8300_SLAVE_LPASS_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_MASTER_LPASS_ANOC }, +}; + +static struct qcom_icc_node srvc_niu_aml_noc = { + .name = "srvc_niu_aml_noc", + .id = QCS8300_SLAVE_SERVICES_LPASS_AML_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_niu_lpass_agnoc = { + .name = "srvc_niu_lpass_agnoc", + .id = QCS8300_SLAVE_SERVICE_LPASS_AG_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node ebi = { + .name = "ebi", + .id = QCS8300_SLAVE_EBI1, + .channels = 8, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_mem_noc_hf = { + .name = "qns_mem_noc_hf", + .id = QCS8300_SLAVE_MNOC_HF_MEM_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_MASTER_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qns_mem_noc_sf = { + .name = "qns_mem_noc_sf", + .id = QCS8300_SLAVE_MNOC_SF_MEM_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_MASTER_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node srvc_mnoc_hf = { + .name = "srvc_mnoc_hf", + .id = QCS8300_SLAVE_SERVICE_MNOC_HF, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_mnoc_sf = { + .name = "srvc_mnoc_sf", + .id = QCS8300_SLAVE_SERVICE_MNOC_SF, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_hcp = { + .name = "qns_hcp", + .id = QCS8300_SLAVE_HCP_A, + .channels = 2, + .buswidth = 32, + .num_links = 0, +}; + +static struct qcom_icc_node qns_nsp_gemnoc = { + .name = "qns_nsp_gemnoc", + .id = QCS8300_SLAVE_CDSP_MEM_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_MASTER_COMPUTE_NOC }, +}; + +static struct qcom_icc_node service_nsp_noc = { + .name = "service_nsp_noc", + .id = QCS8300_SLAVE_SERVICE_NSP_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_pcie_mem_noc = { + .name = "qns_pcie_mem_noc", + .id = QCS8300_SLAVE_ANOC_PCIE_GEM_NOC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { QCS8300_MASTER_ANOC_PCIE_GEM_NOC }, +}; + +static struct qcom_icc_node qns_gemnoc_gc = { + .name = "qns_gemnoc_gc", + .id = QCS8300_SLAVE_SNOC_GEM_NOC_GC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { QCS8300_MASTER_SNOC_GC_MEM_NOC }, +}; + +static struct qcom_icc_node qns_gemnoc_sf = { + .name = "qns_gemnoc_sf", + .id = QCS8300_SLAVE_SNOC_GEM_NOC_SF, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { QCS8300_MASTER_SNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node srvc_snoc = { + .name = "srvc_snoc", + .id = QCS8300_SLAVE_SERVICE_SNOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", + .enable_mask = BIT(3), + .num_nodes = 1, + .nodes = { &ebi }, +}; + +static struct qcom_icc_bcm bcm_ce0 = { + .name = "CE0", + .num_nodes = 2, + .nodes = { &qxm_crypto_0, &qxm_crypto_1 }, +}; + +static struct qcom_icc_bcm bcm_cn0 = { + .name = "CN0", + .keepalive = true, + .num_nodes = 2, + .nodes = { &qnm_gemnoc_cnoc, &qnm_gemnoc_pcie }, +}; + +static struct qcom_icc_bcm bcm_cn1 = { + .name = "CN1", + .num_nodes = 66, + .nodes = { &qhs_ahb2phy2, &qhs_ahb2phy3, + &qhs_anoc_throttle_cfg, &qhs_aoss, + &qhs_apss, &qhs_boot_rom, + &qhs_camera_cfg, &qhs_camera_nrt_throttle_cfg, + &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl, + &qhs_compute0_cfg, &qhs_cpr_cx, + &qhs_cpr_mmcx, &qhs_cpr_mx, + &qhs_cpr_nspcx, &qhs_cpr_nsphmx, + &qhs_crypto0_cfg, &qhs_cx_rdpm, + &qhs_display0_cfg, &qhs_display0_rt_throttle_cfg, + &qhs_emac0_cfg, &qhs_gp_dsp0_cfg, + &qhs_gpdsp0_throttle_cfg, &qhs_gpu_tcu_throttle_cfg, + &qhs_gpuss_cfg, &qhs_hwkm, + &qhs_imem_cfg, &qhs_ipa, + &qhs_ipc_router, &qhs_lpass_cfg, + &qhs_lpass_throttle_cfg, &qhs_mx_rdpm, + &qhs_mxc_rdpm, &qhs_pcie0_cfg, + &qhs_pcie1_cfg, &qhs_pcie_tcu_throttle_cfg, + &qhs_pcie_throttle_cfg, &qhs_pdm, + &qhs_pimem_cfg, &qhs_pke_wrapper_cfg, + &qhs_qdss_cfg, &qhs_qm_cfg, + &qhs_qm_mpu_cfg, &qhs_sail_throttle_cfg, + &qhs_sdc1, &qhs_security, + &qhs_snoc_throttle_cfg, &qhs_tcsr, + &qhs_tlmm, &qhs_tsc_cfg, + &qhs_ufs_mem_cfg, &qhs_usb2_0, + &qhs_usb3_0, &qhs_venus_cfg, + &qhs_venus_cvp_throttle_cfg, &qhs_venus_v_cpu_throttle_cfg, + &qhs_venus_vcodec_throttle_cfg, &qns_ddrss_cfg, + &qns_gpdsp_noc_cfg, &qns_mnoc_hf_cfg, + &qns_mnoc_sf_cfg, &qns_pcie_anoc_cfg, + &qns_snoc_cfg, &qxs_boot_imem, + &qxs_imem, &xs_sys_tcu_cfg }, +}; + +static struct qcom_icc_bcm bcm_cn2 = { + .name = "CN2", + .num_nodes = 3, + .nodes = { &qhs_qup0, &qhs_qup1, + &qhs_qup3 }, +}; + +static struct qcom_icc_bcm bcm_cn3 = { + .name = "CN3", + .num_nodes = 2, + .nodes = { &xs_pcie_0, &xs_pcie_1 }, +}; + +static struct qcom_icc_bcm bcm_gna0 = { + .name = "GNA0", + .num_nodes = 1, + .nodes = { &qxm_dsp0 }, +}; + +static struct qcom_icc_bcm bcm_mc0 = { + .name = "MC0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &ebi }, +}; + +static struct qcom_icc_bcm bcm_mm0 = { + .name = "MM0", + .keepalive = true, + .num_nodes = 4, + .nodes = { &qnm_camnoc_hf, &qnm_mdp0_0, + &qnm_mdp0_1, &qns_mem_noc_hf }, +}; + +static struct qcom_icc_bcm bcm_mm1 = { + .name = "MM1", + .num_nodes = 6, + .nodes = { &qnm_camnoc_icp, &qnm_camnoc_sf, + &qnm_video0, &qnm_video_cvp, + &qnm_video_v_cpu, &qns_mem_noc_sf }, +}; + +static struct qcom_icc_bcm bcm_nsa0 = { + .name = "NSA0", + .num_nodes = 2, + .nodes = { &qns_hcp, &qns_nsp_gemnoc }, +}; + +static struct qcom_icc_bcm bcm_nsa1 = { + .name = "NSA1", + .num_nodes = 1, + .nodes = { &qxm_nsp }, +}; + +static struct qcom_icc_bcm bcm_pci0 = { + .name = "PCI0", + .num_nodes = 1, + .nodes = { &qns_pcie_mem_noc }, +}; + +static struct qcom_icc_bcm bcm_qup0 = { + .name = "QUP0", + .vote_scale = 1, + .keepalive = true, + .num_nodes = 1, + .nodes = { &qup0_core_slave }, +}; + +static struct qcom_icc_bcm bcm_qup1 = { + .name = "QUP1", + .vote_scale = 1, + .keepalive = true, + .num_nodes = 1, + .nodes = { &qup1_core_slave }, +}; + +static struct qcom_icc_bcm bcm_qup2 = { + .name = "QUP2", + .vote_scale = 1, + .keepalive = true, + .num_nodes = 1, + .nodes = { &qup3_core_slave }, +}; + +static struct qcom_icc_bcm bcm_sh0 = { + .name = "SH0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_llcc }, +}; + +static struct qcom_icc_bcm bcm_sh2 = { + .name = "SH2", + .num_nodes = 1, + .nodes = { &chm_apps }, +}; + +static struct qcom_icc_bcm bcm_sn0 = { + .name = "SN0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_gemnoc_sf }, +}; + +static struct qcom_icc_bcm bcm_sn1 = { + .name = "SN1", + .num_nodes = 1, + .nodes = { &qns_gemnoc_gc }, +}; + +static struct qcom_icc_bcm bcm_sn2 = { + .name = "SN2", + .num_nodes = 1, + .nodes = { &qxs_pimem }, +}; + +static struct qcom_icc_bcm bcm_sn3 = { + .name = "SN3", + .num_nodes = 2, + .nodes = { &qns_a1noc_snoc, &qnm_aggre1_noc }, +}; + +static struct qcom_icc_bcm bcm_sn4 = { + .name = "SN4", + .num_nodes = 2, + .nodes = { &qns_a2noc_snoc, &qnm_aggre2_noc }, +}; + +static struct qcom_icc_bcm bcm_sn9 = { + .name = "SN9", + .num_nodes = 2, + .nodes = { &qns_sysnoc, &qnm_lpass_noc }, +}; + +static struct qcom_icc_bcm bcm_sn10 = { + .name = "SN10", + .num_nodes = 1, + .nodes = { &xs_qdss_stm }, +}; + +static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { + &bcm_sn3, +}; + +static struct qcom_icc_node * const aggre1_noc_nodes[] = { + [MASTER_QUP_3] = &qxm_qup3, + [MASTER_EMAC] = &xm_emac_0, + [MASTER_SDC] = &xm_sdc1, + [MASTER_UFS_MEM] = &xm_ufs_mem, + [MASTER_USB2] = &xm_usb2_2, + [MASTER_USB3_0] = &xm_usb3_0, + [SLAVE_A1NOC_SNOC] = &qns_a1noc_snoc, +}; + +static const struct qcom_icc_desc qcs8300_aggre1_noc = { + .nodes = aggre1_noc_nodes, + .num_nodes = ARRAY_SIZE(aggre1_noc_nodes), + .bcms = aggre1_noc_bcms, + .num_bcms = ARRAY_SIZE(aggre1_noc_bcms), +}; + +static struct qcom_icc_bcm * const aggre2_noc_bcms[] = { + &bcm_ce0, + &bcm_sn4, +}; + +static struct qcom_icc_node * const aggre2_noc_nodes[] = { + [MASTER_QDSS_BAM] = &qhm_qdss_bam, + [MASTER_QUP_0] = &qhm_qup0, + [MASTER_QUP_1] = &qhm_qup1, + [MASTER_CNOC_A2NOC] = &qnm_cnoc_datapath, + [MASTER_CRYPTO_CORE0] = &qxm_crypto_0, + [MASTER_CRYPTO_CORE1] = &qxm_crypto_1, + [MASTER_IPA] = &qxm_ipa, + [MASTER_QDSS_ETR_0] = &xm_qdss_etr_0, + [MASTER_QDSS_ETR_1] = &xm_qdss_etr_1, + [SLAVE_A2NOC_SNOC] = &qns_a2noc_snoc, +}; + +static const struct qcom_icc_desc qcs8300_aggre2_noc = { + .nodes = aggre2_noc_nodes, + .num_nodes = ARRAY_SIZE(aggre2_noc_nodes), + .bcms = aggre2_noc_bcms, + .num_bcms = ARRAY_SIZE(aggre2_noc_bcms), +}; + +static struct qcom_icc_bcm * const clk_virt_bcms[] = { + &bcm_qup0, + &bcm_qup1, + &bcm_qup2, +}; + +static struct qcom_icc_node * const clk_virt_nodes[] = { + [MASTER_QUP_CORE_0] = &qup0_core_master, + [MASTER_QUP_CORE_1] = &qup1_core_master, + [MASTER_QUP_CORE_3] = &qup3_core_master, + [SLAVE_QUP_CORE_0] = &qup0_core_slave, + [SLAVE_QUP_CORE_1] = &qup1_core_slave, + [SLAVE_QUP_CORE_3] = &qup3_core_slave, +}; + +static const struct qcom_icc_desc qcs8300_clk_virt = { + .nodes = clk_virt_nodes, + .num_nodes = ARRAY_SIZE(clk_virt_nodes), + .bcms = clk_virt_bcms, + .num_bcms = ARRAY_SIZE(clk_virt_bcms), +}; + +static struct qcom_icc_bcm * const config_noc_bcms[] = { + &bcm_cn0, + &bcm_cn1, + &bcm_cn2, + &bcm_cn3, + &bcm_sn2, + &bcm_sn10, +}; + +static struct qcom_icc_node * const config_noc_nodes[] = { + [MASTER_GEM_NOC_CNOC] = &qnm_gemnoc_cnoc, + [MASTER_GEM_NOC_PCIE_SNOC] = &qnm_gemnoc_pcie, + [SLAVE_AHB2PHY_2] = &qhs_ahb2phy2, + [SLAVE_AHB2PHY_3] = &qhs_ahb2phy3, + [SLAVE_ANOC_THROTTLE_CFG] = &qhs_anoc_throttle_cfg, + [SLAVE_AOSS] = &qhs_aoss, + [SLAVE_APPSS] = &qhs_apss, + [SLAVE_BOOT_ROM] = &qhs_boot_rom, + [SLAVE_CAMERA_CFG] = &qhs_camera_cfg, + [SLAVE_CAMERA_NRT_THROTTLE_CFG] = &qhs_camera_nrt_throttle_cfg, + [SLAVE_CAMERA_RT_THROTTLE_CFG] = &qhs_camera_rt_throttle_cfg, + [SLAVE_CLK_CTL] = &qhs_clk_ctl, + [SLAVE_CDSP_CFG] = &qhs_compute0_cfg, + [SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx, + [SLAVE_RBCPR_MMCX_CFG] = &qhs_cpr_mmcx, + [SLAVE_RBCPR_MX_CFG] = &qhs_cpr_mx, + [SLAVE_CPR_NSPCX] = &qhs_cpr_nspcx, + [SLAVE_CPR_NSPHMX] = &qhs_cpr_nsphmx, + [SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg, + [SLAVE_CX_RDPM] = &qhs_cx_rdpm, + [SLAVE_DISPLAY_CFG] = &qhs_display0_cfg, + [SLAVE_DISPLAY_RT_THROTTLE_CFG] = &qhs_display0_rt_throttle_cfg, + [SLAVE_EMAC_CFG] = &qhs_emac0_cfg, + [SLAVE_GP_DSP0_CFG] = &qhs_gp_dsp0_cfg, + [SLAVE_GPDSP0_THROTTLE_CFG] = &qhs_gpdsp0_throttle_cfg, + [SLAVE_GPU_TCU_THROTTLE_CFG] = &qhs_gpu_tcu_throttle_cfg, + [SLAVE_GFX3D_CFG] = &qhs_gpuss_cfg, + [SLAVE_HWKM] = &qhs_hwkm, + [SLAVE_IMEM_CFG] = &qhs_imem_cfg, + [SLAVE_IPA_CFG] = &qhs_ipa, + [SLAVE_IPC_ROUTER_CFG] = &qhs_ipc_router, + [SLAVE_LPASS] = &qhs_lpass_cfg, + [SLAVE_LPASS_THROTTLE_CFG] = &qhs_lpass_throttle_cfg, + [SLAVE_MX_RDPM] = &qhs_mx_rdpm, + [SLAVE_MXC_RDPM] = &qhs_mxc_rdpm, + [SLAVE_PCIE_0_CFG] = &qhs_pcie0_cfg, + [SLAVE_PCIE_1_CFG] = &qhs_pcie1_cfg, + [SLAVE_PCIE_TCU_THROTTLE_CFG] = &qhs_pcie_tcu_throttle_cfg, + [SLAVE_PCIE_THROTTLE_CFG] = &qhs_pcie_throttle_cfg, + [SLAVE_PDM] = &qhs_pdm, + [SLAVE_PIMEM_CFG] = &qhs_pimem_cfg, + [SLAVE_PKA_WRAPPER_CFG] = &qhs_pke_wrapper_cfg, + [SLAVE_QDSS_CFG] = &qhs_qdss_cfg, + [SLAVE_QM_CFG] = &qhs_qm_cfg, + [SLAVE_QM_MPU_CFG] = &qhs_qm_mpu_cfg, + [SLAVE_QUP_0] = &qhs_qup0, + [SLAVE_QUP_1] = &qhs_qup1, + [SLAVE_QUP_3] = &qhs_qup3, + [SLAVE_SAIL_THROTTLE_CFG] = &qhs_sail_throttle_cfg, + [SLAVE_SDC1] = &qhs_sdc1, + [SLAVE_SECURITY] = &qhs_security, + [SLAVE_SNOC_THROTTLE_CFG] = &qhs_snoc_throttle_cfg, + [SLAVE_TCSR] = &qhs_tcsr, + [SLAVE_TLMM] = &qhs_tlmm, + [SLAVE_TSC_CFG] = &qhs_tsc_cfg, + [SLAVE_UFS_MEM_CFG] = &qhs_ufs_mem_cfg, + [SLAVE_USB2] = &qhs_usb2_0, + [SLAVE_USB3_0] = &qhs_usb3_0, + [SLAVE_VENUS_CFG] = &qhs_venus_cfg, + [SLAVE_VENUS_CVP_THROTTLE_CFG] = &qhs_venus_cvp_throttle_cfg, + [SLAVE_VENUS_V_CPU_THROTTLE_CFG] = &qhs_venus_v_cpu_throttle_cfg, + [SLAVE_VENUS_VCODEC_THROTTLE_CFG] = &qhs_venus_vcodec_throttle_cfg, + [SLAVE_DDRSS_CFG] = &qns_ddrss_cfg, + [SLAVE_GPDSP_NOC_CFG] = &qns_gpdsp_noc_cfg, + [SLAVE_CNOC_MNOC_HF_CFG] = &qns_mnoc_hf_cfg, + [SLAVE_CNOC_MNOC_SF_CFG] = &qns_mnoc_sf_cfg, + [SLAVE_PCIE_ANOC_CFG] = &qns_pcie_anoc_cfg, + [SLAVE_SNOC_CFG] = &qns_snoc_cfg, + [SLAVE_BOOT_IMEM] = &qxs_boot_imem, + [SLAVE_IMEM] = &qxs_imem, + [SLAVE_PIMEM] = &qxs_pimem, + [SLAVE_PCIE_0] = &xs_pcie_0, + [SLAVE_PCIE_1] = &xs_pcie_1, + [SLAVE_QDSS_STM] = &xs_qdss_stm, + [SLAVE_TCU] = &xs_sys_tcu_cfg, +}; + +static const struct qcom_icc_desc qcs8300_config_noc = { + .nodes = config_noc_nodes, + .num_nodes = ARRAY_SIZE(config_noc_nodes), + .bcms = config_noc_bcms, + .num_bcms = ARRAY_SIZE(config_noc_bcms), +}; + +static struct qcom_icc_node * const dc_noc_nodes[] = { + [MASTER_CNOC_DC_NOC] = &qnm_cnoc_dc_noc, + [SLAVE_LLCC_CFG] = &qhs_llcc, + [SLAVE_GEM_NOC_CFG] = &qns_gemnoc, +}; + +static const struct qcom_icc_desc qcs8300_dc_noc = { + .nodes = dc_noc_nodes, + .num_nodes = ARRAY_SIZE(dc_noc_nodes), +}; + +static struct qcom_icc_bcm * const gem_noc_bcms[] = { + &bcm_sh0, + &bcm_sh2, +}; + +static struct qcom_icc_node * const gem_noc_nodes[] = { + [MASTER_GPU_TCU] = &alm_gpu_tcu, + [MASTER_PCIE_TCU] = &alm_pcie_tcu, + [MASTER_SYS_TCU] = &alm_sys_tcu, + [MASTER_APPSS_PROC] = &chm_apps, + [MASTER_COMPUTE_NOC] = &qnm_cmpnoc0, + [MASTER_GEM_NOC_CFG] = &qnm_gemnoc_cfg, + [MASTER_GPDSP_SAIL] = &qnm_gpdsp_sail, + [MASTER_GFX3D] = &qnm_gpu, + [MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf, + [MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf, + [MASTER_ANOC_PCIE_GEM_NOC] = &qnm_pcie, + [MASTER_SNOC_GC_MEM_NOC] = &qnm_snoc_gc, + [MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf, + [SLAVE_GEM_NOC_CNOC] = &qns_gem_noc_cnoc, + [SLAVE_LLCC] = &qns_llcc, + [SLAVE_GEM_NOC_PCIE_CNOC] = &qns_pcie, + [SLAVE_SERVICE_GEM_NOC_1] = &srvc_even_gemnoc, + [SLAVE_SERVICE_GEM_NOC_2] = &srvc_odd_gemnoc, + [SLAVE_SERVICE_GEM_NOC] = &srvc_sys_gemnoc, + [SLAVE_SERVICE_GEM_NOC2] = &srvc_sys_gemnoc_2, +}; + +static const struct qcom_icc_desc qcs8300_gem_noc = { + .nodes = gem_noc_nodes, + .num_nodes = ARRAY_SIZE(gem_noc_nodes), + .bcms = gem_noc_bcms, + .num_bcms = ARRAY_SIZE(gem_noc_bcms), +}; + +static struct qcom_icc_bcm * const gpdsp_anoc_bcms[] = { + &bcm_gna0, +}; + +static struct qcom_icc_node * const gpdsp_anoc_nodes[] = { + [MASTER_SAILSS_MD0] = &qnm_sailss_md0, + [MASTER_DSP0] = &qxm_dsp0, + [SLAVE_GP_DSP_SAIL_NOC] = &qns_gp_dsp_sail_noc, +}; + +static const struct qcom_icc_desc qcs8300_gpdsp_anoc = { + .nodes = gpdsp_anoc_nodes, + .num_nodes = ARRAY_SIZE(gpdsp_anoc_nodes), + .bcms = gpdsp_anoc_bcms, + .num_bcms = ARRAY_SIZE(gpdsp_anoc_bcms), +}; + +static struct qcom_icc_bcm * const lpass_ag_noc_bcms[] = { + &bcm_sn9, +}; + +static struct qcom_icc_node * const lpass_ag_noc_nodes[] = { + [MASTER_CNOC_LPASS_AG_NOC] = &qhm_config_noc, + [MASTER_LPASS_PROC] = &qxm_lpass_dsp, + [SLAVE_LPASS_CORE_CFG] = &qhs_lpass_core, + [SLAVE_LPASS_LPI_CFG] = &qhs_lpass_lpi, + [SLAVE_LPASS_MPU_CFG] = &qhs_lpass_mpu, + [SLAVE_LPASS_TOP_CFG] = &qhs_lpass_top, + [SLAVE_LPASS_SNOC] = &qns_sysnoc, + [SLAVE_SERVICES_LPASS_AML_NOC] = &srvc_niu_aml_noc, + [SLAVE_SERVICE_LPASS_AG_NOC] = &srvc_niu_lpass_agnoc, +}; + +static const struct qcom_icc_desc qcs8300_lpass_ag_noc = { + .nodes = lpass_ag_noc_nodes, + .num_nodes = ARRAY_SIZE(lpass_ag_noc_nodes), + .bcms = lpass_ag_noc_bcms, + .num_bcms = ARRAY_SIZE(lpass_ag_noc_bcms), +}; + +static struct qcom_icc_bcm * const mc_virt_bcms[] = { + &bcm_acv, + &bcm_mc0, +}; + +static struct qcom_icc_node * const mc_virt_nodes[] = { + [MASTER_LLCC] = &llcc_mc, + [SLAVE_EBI1] = &ebi, +}; + +static const struct qcom_icc_desc qcs8300_mc_virt = { + .nodes = mc_virt_nodes, + .num_nodes = ARRAY_SIZE(mc_virt_nodes), + .bcms = mc_virt_bcms, + .num_bcms = ARRAY_SIZE(mc_virt_bcms), +}; + +static struct qcom_icc_bcm * const mmss_noc_bcms[] = { + &bcm_mm0, + &bcm_mm1, +}; + +static struct qcom_icc_node * const mmss_noc_nodes[] = { + [MASTER_CAMNOC_HF] = &qnm_camnoc_hf, + [MASTER_CAMNOC_ICP] = &qnm_camnoc_icp, + [MASTER_CAMNOC_SF] = &qnm_camnoc_sf, + [MASTER_MDP0] = &qnm_mdp0_0, + [MASTER_MDP1] = &qnm_mdp0_1, + [MASTER_CNOC_MNOC_HF_CFG] = &qnm_mnoc_hf_cfg, + [MASTER_CNOC_MNOC_SF_CFG] = &qnm_mnoc_sf_cfg, + [MASTER_VIDEO_P0] = &qnm_video0, + [MASTER_VIDEO_PROC] = &qnm_video_cvp, + [MASTER_VIDEO_V_PROC] = &qnm_video_v_cpu, + [SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf, + [SLAVE_MNOC_SF_MEM_NOC] = &qns_mem_noc_sf, + [SLAVE_SERVICE_MNOC_HF] = &srvc_mnoc_hf, + [SLAVE_SERVICE_MNOC_SF] = &srvc_mnoc_sf, +}; + +static const struct qcom_icc_desc qcs8300_mmss_noc = { + .nodes = mmss_noc_nodes, + .num_nodes = ARRAY_SIZE(mmss_noc_nodes), + .bcms = mmss_noc_bcms, + .num_bcms = ARRAY_SIZE(mmss_noc_bcms), +}; + +static struct qcom_icc_bcm * const nspa_noc_bcms[] = { + &bcm_nsa0, + &bcm_nsa1, +}; + +static struct qcom_icc_node * const nspa_noc_nodes[] = { + [MASTER_CDSP_NOC_CFG] = &qhm_nsp_noc_config, + [MASTER_CDSP_PROC] = &qxm_nsp, + [SLAVE_HCP_A] = &qns_hcp, + [SLAVE_CDSP_MEM_NOC] = &qns_nsp_gemnoc, + [SLAVE_SERVICE_NSP_NOC] = &service_nsp_noc, +}; + +static const struct qcom_icc_desc qcs8300_nspa_noc = { + .nodes = nspa_noc_nodes, + .num_nodes = ARRAY_SIZE(nspa_noc_nodes), + .bcms = nspa_noc_bcms, + .num_bcms = ARRAY_SIZE(nspa_noc_bcms), +}; + +static struct qcom_icc_bcm * const pcie_anoc_bcms[] = { + &bcm_pci0, +}; + +static struct qcom_icc_node * const pcie_anoc_nodes[] = { + [MASTER_PCIE_0] = &xm_pcie3_0, + [MASTER_PCIE_1] = &xm_pcie3_1, + [SLAVE_ANOC_PCIE_GEM_NOC] = &qns_pcie_mem_noc, +}; + +static const struct qcom_icc_desc qcs8300_pcie_anoc = { + .nodes = pcie_anoc_nodes, + .num_nodes = ARRAY_SIZE(pcie_anoc_nodes), + .bcms = pcie_anoc_bcms, + .num_bcms = ARRAY_SIZE(pcie_anoc_bcms), +}; + +static struct qcom_icc_bcm * const system_noc_bcms[] = { + &bcm_sn0, + &bcm_sn1, + &bcm_sn3, + &bcm_sn4, + &bcm_sn9, +}; + +static struct qcom_icc_node * const system_noc_nodes[] = { + [MASTER_GIC_AHB] = &qhm_gic, + [MASTER_A1NOC_SNOC] = &qnm_aggre1_noc, + [MASTER_A2NOC_SNOC] = &qnm_aggre2_noc, + [MASTER_LPASS_ANOC] = &qnm_lpass_noc, + [MASTER_SNOC_CFG] = &qnm_snoc_cfg, + [MASTER_PIMEM] = &qxm_pimem, + [MASTER_GIC] = &xm_gic, + [SLAVE_SNOC_GEM_NOC_GC] = &qns_gemnoc_gc, + [SLAVE_SNOC_GEM_NOC_SF] = &qns_gemnoc_sf, + [SLAVE_SERVICE_SNOC] = &srvc_snoc, +}; + +static const struct qcom_icc_desc qcs8300_system_noc = { + .nodes = system_noc_nodes, + .num_nodes = ARRAY_SIZE(system_noc_nodes), + .bcms = system_noc_bcms, + .num_bcms = ARRAY_SIZE(system_noc_bcms), +}; + +static const struct of_device_id qnoc_of_match[] = { + { .compatible = "qcom,qcs8300-aggre1-noc", + .data = &qcs8300_aggre1_noc}, + { .compatible = "qcom,qcs8300-aggre2-noc", + .data = &qcs8300_aggre2_noc}, + { .compatible = "qcom,qcs8300-clk-virt", + .data = &qcs8300_clk_virt}, + { .compatible = "qcom,qcs8300-config-noc", + .data = &qcs8300_config_noc}, + { .compatible = "qcom,qcs8300-dc-noc", + .data = &qcs8300_dc_noc}, + { .compatible = "qcom,qcs8300-gem-noc", + .data = &qcs8300_gem_noc}, + { .compatible = "qcom,qcs8300-gpdsp-anoc", + .data = &qcs8300_gpdsp_anoc}, + { .compatible = "qcom,qcs8300-lpass-ag-noc", + .data = &qcs8300_lpass_ag_noc}, + { .compatible = "qcom,qcs8300-mc-virt", + .data = &qcs8300_mc_virt}, + { .compatible = "qcom,qcs8300-mmss-noc", + .data = &qcs8300_mmss_noc}, + { .compatible = "qcom,qcs8300-nspa-noc", + .data = &qcs8300_nspa_noc}, + { .compatible = "qcom,qcs8300-pcie-anoc", + .data = &qcs8300_pcie_anoc}, + { .compatible = "qcom,qcs8300-system-noc", + .data = &qcs8300_system_noc}, + { } +}; +MODULE_DEVICE_TABLE(of, qnoc_of_match); + +static struct platform_driver qnoc_driver = { + .probe = qcom_icc_rpmh_probe, + .remove = qcom_icc_rpmh_remove, + .driver = { + .name = "qnoc-qcs8300", + .of_match_table = qnoc_of_match, + .sync_state = icc_sync_state, + }, +}; + +static int __init qnoc_driver_init(void) +{ + return platform_driver_register(&qnoc_driver); +} +core_initcall(qnoc_driver_init); + +static void __exit qnoc_driver_exit(void) +{ + platform_driver_unregister(&qnoc_driver); +} +module_exit(qnoc_driver_exit); + +MODULE_DESCRIPTION("QCS8300 NoC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/interconnect/qcom/qcs8300.h b/drivers/interconnect/qcom/qcs8300.h new file mode 100644 index 0000000000000000000000000000000000000000..6b9e2b424c2ad0401f72d5fb8cfb7e0f48a1db85 --- /dev/null +++ b/drivers/interconnect/qcom/qcs8300.h @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __DRIVERS_INTERCONNECT_QCOM_QCS8300_H +#define __DRIVERS_INTERCONNECT_QCOM_QCS8300_H + +#define QCS8300_MASTER_GPU_TCU 0 +#define QCS8300_MASTER_PCIE_TCU 1 +#define QCS8300_MASTER_SYS_TCU 2 +#define QCS8300_MASTER_APPSS_PROC 3 +#define QCS8300_MASTER_LLCC 4 +#define QCS8300_MASTER_CNOC_LPASS_AG_NOC 5 +#define QCS8300_MASTER_GIC_AHB 6 +#define QCS8300_MASTER_CDSP_NOC_CFG 7 +#define QCS8300_MASTER_QDSS_BAM 8 +#define QCS8300_MASTER_QUP_0 9 +#define QCS8300_MASTER_QUP_1 10 +#define QCS8300_MASTER_A1NOC_SNOC 11 +#define QCS8300_MASTER_A2NOC_SNOC 12 +#define QCS8300_MASTER_CAMNOC_HF 13 +#define QCS8300_MASTER_CAMNOC_ICP 14 +#define QCS8300_MASTER_CAMNOC_SF 15 +#define QCS8300_MASTER_COMPUTE_NOC 16 +#define QCS8300_MASTER_CNOC_A2NOC 17 +#define QCS8300_MASTER_CNOC_DC_NOC 18 +#define QCS8300_MASTER_GEM_NOC_CFG 19 +#define QCS8300_MASTER_GEM_NOC_CNOC 20 +#define QCS8300_MASTER_GEM_NOC_PCIE_SNOC 21 +#define QCS8300_MASTER_GPDSP_SAIL 22 +#define QCS8300_MASTER_GFX3D 23 +#define QCS8300_MASTER_LPASS_ANOC 24 +#define QCS8300_MASTER_MDP0 25 +#define QCS8300_MASTER_MDP1 26 +#define QCS8300_MASTER_MNOC_HF_MEM_NOC 27 +#define QCS8300_MASTER_CNOC_MNOC_HF_CFG 28 +#define QCS8300_MASTER_MNOC_SF_MEM_NOC 29 +#define QCS8300_MASTER_CNOC_MNOC_SF_CFG 30 +#define QCS8300_MASTER_ANOC_PCIE_GEM_NOC 31 +#define QCS8300_MASTER_SAILSS_MD0 32 +#define QCS8300_MASTER_SNOC_CFG 33 +#define QCS8300_MASTER_SNOC_GC_MEM_NOC 34 +#define QCS8300_MASTER_SNOC_SF_MEM_NOC 35 +#define QCS8300_MASTER_VIDEO_P0 36 +#define QCS8300_MASTER_VIDEO_PROC 37 +#define QCS8300_MASTER_VIDEO_V_PROC 38 +#define QCS8300_MASTER_QUP_CORE_0 39 +#define QCS8300_MASTER_QUP_CORE_1 40 +#define QCS8300_MASTER_QUP_CORE_3 41 +#define QCS8300_MASTER_CRYPTO_CORE0 42 +#define QCS8300_MASTER_CRYPTO_CORE1 43 +#define QCS8300_MASTER_DSP0 44 +#define QCS8300_MASTER_IPA 45 +#define QCS8300_MASTER_LPASS_PROC 46 +#define QCS8300_MASTER_CDSP_PROC 47 +#define QCS8300_MASTER_PIMEM 48 +#define QCS8300_MASTER_QUP_3 49 +#define QCS8300_MASTER_EMAC 50 +#define QCS8300_MASTER_GIC 51 +#define QCS8300_MASTER_PCIE_0 52 +#define QCS8300_MASTER_PCIE_1 53 +#define QCS8300_MASTER_QDSS_ETR_0 54 +#define QCS8300_MASTER_QDSS_ETR_1 55 +#define QCS8300_MASTER_SDC 56 +#define QCS8300_MASTER_UFS_MEM 57 +#define QCS8300_MASTER_USB2 58 +#define QCS8300_MASTER_USB3_0 59 +#define QCS8300_SLAVE_EBI1 60 +#define QCS8300_SLAVE_AHB2PHY_2 61 +#define QCS8300_SLAVE_AHB2PHY_3 62 +#define QCS8300_SLAVE_ANOC_THROTTLE_CFG 63 +#define QCS8300_SLAVE_AOSS 64 +#define QCS8300_SLAVE_APPSS 65 +#define QCS8300_SLAVE_BOOT_ROM 66 +#define QCS8300_SLAVE_CAMERA_CFG 67 +#define QCS8300_SLAVE_CAMERA_NRT_THROTTLE_CFG 68 +#define QCS8300_SLAVE_CAMERA_RT_THROTTLE_CFG 69 +#define QCS8300_SLAVE_CLK_CTL 70 +#define QCS8300_SLAVE_CDSP_CFG 71 +#define QCS8300_SLAVE_RBCPR_CX_CFG 72 +#define QCS8300_SLAVE_RBCPR_MMCX_CFG 73 +#define QCS8300_SLAVE_RBCPR_MX_CFG 74 +#define QCS8300_SLAVE_CPR_NSPCX 75 +#define QCS8300_SLAVE_CPR_NSPHMX 76 +#define QCS8300_SLAVE_CRYPTO_0_CFG 77 +#define QCS8300_SLAVE_CX_RDPM 78 +#define QCS8300_SLAVE_DISPLAY_CFG 79 +#define QCS8300_SLAVE_DISPLAY_RT_THROTTLE_CFG 80 +#define QCS8300_SLAVE_EMAC_CFG 81 +#define QCS8300_SLAVE_GP_DSP0_CFG 82 +#define QCS8300_SLAVE_GPDSP0_THROTTLE_CFG 83 +#define QCS8300_SLAVE_GPU_TCU_THROTTLE_CFG 84 +#define QCS8300_SLAVE_GFX3D_CFG 85 +#define QCS8300_SLAVE_HWKM 86 +#define QCS8300_SLAVE_IMEM_CFG 87 +#define QCS8300_SLAVE_IPA_CFG 88 +#define QCS8300_SLAVE_IPC_ROUTER_CFG 89 +#define QCS8300_SLAVE_LLCC_CFG 90 +#define QCS8300_SLAVE_LPASS 91 +#define QCS8300_SLAVE_LPASS_CORE_CFG 92 +#define QCS8300_SLAVE_LPASS_LPI_CFG 93 +#define QCS8300_SLAVE_LPASS_MPU_CFG 94 +#define QCS8300_SLAVE_LPASS_THROTTLE_CFG 95 +#define QCS8300_SLAVE_LPASS_TOP_CFG 96 +#define QCS8300_SLAVE_MX_RDPM 97 +#define QCS8300_SLAVE_MXC_RDPM 98 +#define QCS8300_SLAVE_PCIE_0_CFG 99 +#define QCS8300_SLAVE_PCIE_1_CFG 100 +#define QCS8300_SLAVE_PCIE_TCU_THROTTLE_CFG 101 +#define QCS8300_SLAVE_PCIE_THROTTLE_CFG 102 +#define QCS8300_SLAVE_PDM 103 +#define QCS8300_SLAVE_PIMEM_CFG 104 +#define QCS8300_SLAVE_PKA_WRAPPER_CFG 105 +#define QCS8300_SLAVE_QDSS_CFG 106 +#define QCS8300_SLAVE_QM_CFG 107 +#define QCS8300_SLAVE_QM_MPU_CFG 108 +#define QCS8300_SLAVE_QUP_0 109 +#define QCS8300_SLAVE_QUP_1 110 +#define QCS8300_SLAVE_QUP_3 111 +#define QCS8300_SLAVE_SAIL_THROTTLE_CFG 112 +#define QCS8300_SLAVE_SDC1 113 +#define QCS8300_SLAVE_SECURITY 114 +#define QCS8300_SLAVE_SNOC_THROTTLE_CFG 115 +#define QCS8300_SLAVE_TCSR 116 +#define QCS8300_SLAVE_TLMM 117 +#define QCS8300_SLAVE_TSC_CFG 118 +#define QCS8300_SLAVE_UFS_MEM_CFG 119 +#define QCS8300_SLAVE_USB2 120 +#define QCS8300_SLAVE_USB3_0 121 +#define QCS8300_SLAVE_VENUS_CFG 122 +#define QCS8300_SLAVE_VENUS_CVP_THROTTLE_CFG 123 +#define QCS8300_SLAVE_VENUS_V_CPU_THROTTLE_CFG 124 +#define QCS8300_SLAVE_VENUS_VCODEC_THROTTLE_CFG 125 +#define QCS8300_SLAVE_A1NOC_SNOC 126 +#define QCS8300_SLAVE_A2NOC_SNOC 127 +#define QCS8300_SLAVE_DDRSS_CFG 128 +#define QCS8300_SLAVE_GEM_NOC_CNOC 129 +#define QCS8300_SLAVE_GEM_NOC_CFG 130 +#define QCS8300_SLAVE_SNOC_GEM_NOC_GC 131 +#define QCS8300_SLAVE_SNOC_GEM_NOC_SF 132 +#define QCS8300_SLAVE_GP_DSP_SAIL_NOC 133 +#define QCS8300_SLAVE_GPDSP_NOC_CFG 134 +#define QCS8300_SLAVE_HCP_A 135 +#define QCS8300_SLAVE_LLCC 136 +#define QCS8300_SLAVE_MNOC_HF_MEM_NOC 137 +#define QCS8300_SLAVE_MNOC_SF_MEM_NOC 138 +#define QCS8300_SLAVE_CNOC_MNOC_HF_CFG 139 +#define QCS8300_SLAVE_CNOC_MNOC_SF_CFG 140 +#define QCS8300_SLAVE_CDSP_MEM_NOC 141 +#define QCS8300_SLAVE_GEM_NOC_PCIE_CNOC 142 +#define QCS8300_SLAVE_PCIE_ANOC_CFG 143 +#define QCS8300_SLAVE_ANOC_PCIE_GEM_NOC 144 +#define QCS8300_SLAVE_SNOC_CFG 145 +#define QCS8300_SLAVE_LPASS_SNOC 146 +#define QCS8300_SLAVE_QUP_CORE_0 147 +#define QCS8300_SLAVE_QUP_CORE_1 148 +#define QCS8300_SLAVE_QUP_CORE_3 149 +#define QCS8300_SLAVE_BOOT_IMEM 150 +#define QCS8300_SLAVE_IMEM 151 +#define QCS8300_SLAVE_PIMEM 152 +#define QCS8300_SLAVE_SERVICE_NSP_NOC 153 +#define QCS8300_SLAVE_SERVICE_GEM_NOC_1 154 +#define QCS8300_SLAVE_SERVICE_MNOC_HF 155 +#define QCS8300_SLAVE_SERVICE_MNOC_SF 156 +#define QCS8300_SLAVE_SERVICES_LPASS_AML_NOC 157 +#define QCS8300_SLAVE_SERVICE_LPASS_AG_NOC 158 +#define QCS8300_SLAVE_SERVICE_GEM_NOC_2 159 +#define QCS8300_SLAVE_SERVICE_SNOC 160 +#define QCS8300_SLAVE_SERVICE_GEM_NOC 161 +#define QCS8300_SLAVE_SERVICE_GEM_NOC2 162 +#define QCS8300_SLAVE_PCIE_0 163 +#define QCS8300_SLAVE_PCIE_1 164 +#define QCS8300_SLAVE_QDSS_STM 165 +#define QCS8300_SLAVE_TCU 166 + +#endif diff --git a/drivers/interconnect/qcom/qdu1000.c b/drivers/interconnect/qcom/qdu1000.c index 9cb477d2bdfe2b5d7c6cbb9d50e2732a3f421355..a7392eb73d4a990ec65e9d55f3d0429d05270802 100644 --- a/drivers/interconnect/qcom/qdu1000.c +++ b/drivers/interconnect/qcom/qdu1000.c @@ -1046,7 +1046,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qnoc_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-qdu1000", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sa8775p.c b/drivers/interconnect/qcom/sa8775p.c index a729775c2aa45e52dc27aaf4cedefc88297d551b..e2826af3ea2e1e34eaedc2c56715809938926553 100644 --- a/drivers/interconnect/qcom/sa8775p.c +++ b/drivers/interconnect/qcom/sa8775p.c @@ -2519,7 +2519,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sa8775p", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sar2130p.c b/drivers/interconnect/qcom/sar2130p.c new file mode 100644 index 0000000000000000000000000000000000000000..9eac0ac7681273d6f4350f4431b81ce94dbada3f --- /dev/null +++ b/drivers/interconnect/qcom/sar2130p.c @@ -0,0 +1,1930 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bcm-voter.h" +#include "icc-common.h" +#include "icc-rpmh.h" + +enum { + SAR2130P_MASTER_QUP_CORE_0, + SAR2130P_MASTER_QUP_CORE_1, + SAR2130P_MASTER_GEM_NOC_CNOC, + SAR2130P_MASTER_GEM_NOC_PCIE_SNOC, + SAR2130P_MASTER_QDSS_DAP, + SAR2130P_MASTER_GPU_TCU, + SAR2130P_MASTER_SYS_TCU, + SAR2130P_MASTER_APPSS_PROC, + SAR2130P_MASTER_GFX3D, + SAR2130P_MASTER_MNOC_HF_MEM_NOC, + SAR2130P_MASTER_MNOC_SF_MEM_NOC, + SAR2130P_MASTER_COMPUTE_NOC, + SAR2130P_MASTER_ANOC_PCIE_GEM_NOC, + SAR2130P_MASTER_SNOC_GC_MEM_NOC, + SAR2130P_MASTER_SNOC_SF_MEM_NOC, + SAR2130P_MASTER_WLAN_Q6, + SAR2130P_MASTER_CNOC_LPASS_AG_NOC, + SAR2130P_MASTER_LPASS_PROC, + SAR2130P_MASTER_LLCC, + SAR2130P_MASTER_CAMNOC_HF, + SAR2130P_MASTER_CAMNOC_ICP, + SAR2130P_MASTER_CAMNOC_SF, + SAR2130P_MASTER_LSR, + SAR2130P_MASTER_MDP, + SAR2130P_MASTER_CNOC_MNOC_CFG, + SAR2130P_MASTER_VIDEO, + SAR2130P_MASTER_VIDEO_CV_PROC, + SAR2130P_MASTER_VIDEO_PROC, + SAR2130P_MASTER_VIDEO_V_PROC, + SAR2130P_MASTER_CDSP_NOC_CFG, + SAR2130P_MASTER_CDSP_PROC, + SAR2130P_MASTER_PCIE_0, + SAR2130P_MASTER_PCIE_1, + SAR2130P_MASTER_GIC_AHB, + SAR2130P_MASTER_QDSS_BAM, + SAR2130P_MASTER_QSPI_0, + SAR2130P_MASTER_QUP_0, + SAR2130P_MASTER_QUP_1, + SAR2130P_MASTER_A2NOC_SNOC, + SAR2130P_MASTER_CNOC_DATAPATH, + SAR2130P_MASTER_LPASS_ANOC, + SAR2130P_MASTER_SNOC_CFG, + SAR2130P_MASTER_CRYPTO, + SAR2130P_MASTER_PIMEM, + SAR2130P_MASTER_GIC, + SAR2130P_MASTER_QDSS_ETR, + SAR2130P_MASTER_QDSS_ETR_1, + SAR2130P_MASTER_SDCC_1, + SAR2130P_MASTER_USB3_0, + SAR2130P_SLAVE_QUP_CORE_0, + SAR2130P_SLAVE_QUP_CORE_1, + SAR2130P_SLAVE_AHB2PHY_SOUTH, + SAR2130P_SLAVE_AOSS, + SAR2130P_SLAVE_CAMERA_CFG, + SAR2130P_SLAVE_CLK_CTL, + SAR2130P_SLAVE_CDSP_CFG, + SAR2130P_SLAVE_RBCPR_CX_CFG, + SAR2130P_SLAVE_RBCPR_MMCX_CFG, + SAR2130P_SLAVE_RBCPR_MXA_CFG, + SAR2130P_SLAVE_RBCPR_MXC_CFG, + SAR2130P_SLAVE_CPR_NSPCX, + SAR2130P_SLAVE_CRYPTO_0_CFG, + SAR2130P_SLAVE_CX_RDPM, + SAR2130P_SLAVE_DISPLAY_CFG, + SAR2130P_SLAVE_GFX3D_CFG, + SAR2130P_SLAVE_IMEM_CFG, + SAR2130P_SLAVE_IPC_ROUTER_CFG, + SAR2130P_SLAVE_LPASS, + SAR2130P_SLAVE_MX_RDPM, + SAR2130P_SLAVE_PCIE_0_CFG, + SAR2130P_SLAVE_PCIE_1_CFG, + SAR2130P_SLAVE_PDM, + SAR2130P_SLAVE_PIMEM_CFG, + SAR2130P_SLAVE_PRNG, + SAR2130P_SLAVE_QDSS_CFG, + SAR2130P_SLAVE_QSPI_0, + SAR2130P_SLAVE_QUP_0, + SAR2130P_SLAVE_QUP_1, + SAR2130P_SLAVE_SDCC_1, + SAR2130P_SLAVE_TCSR, + SAR2130P_SLAVE_TLMM, + SAR2130P_SLAVE_TME_CFG, + SAR2130P_SLAVE_USB3_0, + SAR2130P_SLAVE_VENUS_CFG, + SAR2130P_SLAVE_VSENSE_CTRL_CFG, + SAR2130P_SLAVE_WLAN_Q6_CFG, + SAR2130P_SLAVE_DDRSS_CFG, + SAR2130P_SLAVE_CNOC_MNOC_CFG, + SAR2130P_SLAVE_SNOC_CFG, + SAR2130P_SLAVE_IMEM, + SAR2130P_SLAVE_PIMEM, + SAR2130P_SLAVE_SERVICE_CNOC, + SAR2130P_SLAVE_PCIE_0, + SAR2130P_SLAVE_PCIE_1, + SAR2130P_SLAVE_QDSS_STM, + SAR2130P_SLAVE_TCU, + SAR2130P_SLAVE_GEM_NOC_CNOC, + SAR2130P_SLAVE_LLCC, + SAR2130P_SLAVE_MEM_NOC_PCIE_SNOC, + SAR2130P_SLAVE_LPASS_CORE_CFG, + SAR2130P_SLAVE_LPASS_LPI_CFG, + SAR2130P_SLAVE_LPASS_MPU_CFG, + SAR2130P_SLAVE_LPASS_TOP_CFG, + SAR2130P_SLAVE_LPASS_SNOC, + SAR2130P_SLAVE_SERVICES_LPASS_AML_NOC, + SAR2130P_SLAVE_SERVICE_LPASS_AG_NOC, + SAR2130P_SLAVE_EBI1, + SAR2130P_SLAVE_MNOC_HF_MEM_NOC, + SAR2130P_SLAVE_MNOC_SF_MEM_NOC, + SAR2130P_SLAVE_SERVICE_MNOC, + SAR2130P_SLAVE_CDSP_MEM_NOC, + SAR2130P_SLAVE_SERVICE_NSP_NOC, + SAR2130P_SLAVE_ANOC_PCIE_GEM_NOC, + SAR2130P_SLAVE_A2NOC_SNOC, + SAR2130P_SLAVE_SNOC_GEM_NOC_GC, + SAR2130P_SLAVE_SNOC_GEM_NOC_SF, + SAR2130P_SLAVE_SERVICE_SNOC, +}; + +static const struct regmap_config icc_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +static struct qcom_icc_node qup0_core_master = { + .name = "qup0_core_master", + .id = SAR2130P_MASTER_QUP_CORE_0, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_SLAVE_QUP_CORE_0 }, +}; + +static struct qcom_icc_node qup1_core_master = { + .name = "qup1_core_master", + .id = SAR2130P_MASTER_QUP_CORE_1, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_SLAVE_QUP_CORE_1 }, +}; + +static struct qcom_icc_node qnm_gemnoc_cnoc = { + .name = "qnm_gemnoc_cnoc", + .id = SAR2130P_MASTER_GEM_NOC_CNOC, + .channels = 1, + .buswidth = 16, + .num_links = 43, + .links = { SAR2130P_SLAVE_AHB2PHY_SOUTH, SAR2130P_SLAVE_AOSS, + SAR2130P_SLAVE_CAMERA_CFG, SAR2130P_SLAVE_CLK_CTL, + SAR2130P_SLAVE_CDSP_CFG, SAR2130P_SLAVE_RBCPR_CX_CFG, + SAR2130P_SLAVE_RBCPR_MMCX_CFG, SAR2130P_SLAVE_RBCPR_MXA_CFG, + SAR2130P_SLAVE_RBCPR_MXC_CFG, SAR2130P_SLAVE_CPR_NSPCX, + SAR2130P_SLAVE_CRYPTO_0_CFG, SAR2130P_SLAVE_CX_RDPM, + SAR2130P_SLAVE_DISPLAY_CFG, SAR2130P_SLAVE_GFX3D_CFG, + SAR2130P_SLAVE_IMEM_CFG, SAR2130P_SLAVE_IPC_ROUTER_CFG, + SAR2130P_SLAVE_LPASS, SAR2130P_SLAVE_MX_RDPM, + SAR2130P_SLAVE_PCIE_0_CFG, SAR2130P_SLAVE_PCIE_1_CFG, + SAR2130P_SLAVE_PDM, SAR2130P_SLAVE_PIMEM_CFG, + SAR2130P_SLAVE_PRNG, SAR2130P_SLAVE_QDSS_CFG, + SAR2130P_SLAVE_QSPI_0, SAR2130P_SLAVE_QUP_0, + SAR2130P_SLAVE_QUP_1, SAR2130P_SLAVE_SDCC_1, + SAR2130P_SLAVE_TCSR, SAR2130P_SLAVE_TLMM, + SAR2130P_SLAVE_TME_CFG, SAR2130P_SLAVE_USB3_0, + SAR2130P_SLAVE_VENUS_CFG, SAR2130P_SLAVE_VSENSE_CTRL_CFG, + SAR2130P_SLAVE_WLAN_Q6_CFG, SAR2130P_SLAVE_DDRSS_CFG, + SAR2130P_SLAVE_CNOC_MNOC_CFG, SAR2130P_SLAVE_SNOC_CFG, + SAR2130P_SLAVE_IMEM, SAR2130P_SLAVE_PIMEM, + SAR2130P_SLAVE_SERVICE_CNOC, SAR2130P_SLAVE_QDSS_STM, + SAR2130P_SLAVE_TCU }, +}; + +static struct qcom_icc_node qnm_gemnoc_pcie = { + .name = "qnm_gemnoc_pcie", + .id = SAR2130P_MASTER_GEM_NOC_PCIE_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 2, + .links = { SAR2130P_SLAVE_PCIE_0, SAR2130P_SLAVE_PCIE_1 }, +}; + +static struct qcom_icc_node xm_qdss_dap = { + .name = "xm_qdss_dap", + .id = SAR2130P_MASTER_QDSS_DAP, + .channels = 1, + .buswidth = 8, + .num_links = 43, + .links = { SAR2130P_SLAVE_AHB2PHY_SOUTH, SAR2130P_SLAVE_AOSS, + SAR2130P_SLAVE_CAMERA_CFG, SAR2130P_SLAVE_CLK_CTL, + SAR2130P_SLAVE_CDSP_CFG, SAR2130P_SLAVE_RBCPR_CX_CFG, + SAR2130P_SLAVE_RBCPR_MMCX_CFG, SAR2130P_SLAVE_RBCPR_MXA_CFG, + SAR2130P_SLAVE_RBCPR_MXC_CFG, SAR2130P_SLAVE_CPR_NSPCX, + SAR2130P_SLAVE_CRYPTO_0_CFG, SAR2130P_SLAVE_CX_RDPM, + SAR2130P_SLAVE_DISPLAY_CFG, SAR2130P_SLAVE_GFX3D_CFG, + SAR2130P_SLAVE_IMEM_CFG, SAR2130P_SLAVE_IPC_ROUTER_CFG, + SAR2130P_SLAVE_LPASS, SAR2130P_SLAVE_MX_RDPM, + SAR2130P_SLAVE_PCIE_0_CFG, SAR2130P_SLAVE_PCIE_1_CFG, + SAR2130P_SLAVE_PDM, SAR2130P_SLAVE_PIMEM_CFG, + SAR2130P_SLAVE_PRNG, SAR2130P_SLAVE_QDSS_CFG, + SAR2130P_SLAVE_QSPI_0, SAR2130P_SLAVE_QUP_0, + SAR2130P_SLAVE_QUP_1, SAR2130P_SLAVE_SDCC_1, + SAR2130P_SLAVE_TCSR, SAR2130P_SLAVE_TLMM, + SAR2130P_SLAVE_TME_CFG, SAR2130P_SLAVE_USB3_0, + SAR2130P_SLAVE_VENUS_CFG, SAR2130P_SLAVE_VSENSE_CTRL_CFG, + SAR2130P_SLAVE_WLAN_Q6_CFG, SAR2130P_SLAVE_DDRSS_CFG, + SAR2130P_SLAVE_CNOC_MNOC_CFG, SAR2130P_SLAVE_SNOC_CFG, + SAR2130P_SLAVE_IMEM, SAR2130P_SLAVE_PIMEM, + SAR2130P_SLAVE_SERVICE_CNOC, SAR2130P_SLAVE_QDSS_STM, + SAR2130P_SLAVE_TCU }, +}; + +static const struct qcom_icc_qosbox alm_gpu_tcu_qos = { + .num_ports = 1, + .port_offsets = { 0x9e000 }, + .prio = 1, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node alm_gpu_tcu = { + .name = "alm_gpu_tcu", + .id = SAR2130P_MASTER_GPU_TCU, + .channels = 1, + .buswidth = 8, + .qosbox = &alm_gpu_tcu_qos, + .num_links = 2, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC }, +}; + +static const struct qcom_icc_qosbox alm_sys_tcu_qos = { + .num_ports = 1, + .port_offsets = { 0x9f000 }, + .prio = 6, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node alm_sys_tcu = { + .name = "alm_sys_tcu", + .id = SAR2130P_MASTER_SYS_TCU, + .channels = 1, + .buswidth = 8, + .qosbox = &alm_sys_tcu_qos, + .num_links = 2, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC }, +}; + +static struct qcom_icc_node chm_apps = { + .name = "chm_apps", + .id = SAR2130P_MASTER_APPSS_PROC, + .channels = 1, + .buswidth = 32, + .num_links = 3, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC, + SAR2130P_SLAVE_MEM_NOC_PCIE_SNOC }, +}; + +static const struct qcom_icc_qosbox qnm_gpu_qos = { + .num_ports = 2, + .port_offsets = { 0xe000, 0x4e000 }, + .prio = 0, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qnm_gpu = { + .name = "qnm_gpu", + .id = SAR2130P_MASTER_GFX3D, + .channels = 2, + .buswidth = 32, + .qosbox = &qnm_gpu_qos, + .num_links = 2, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC }, +}; + +static const struct qcom_icc_qosbox qnm_mnoc_hf_qos = { + .num_ports = 2, + .port_offsets = { 0xf000, 0x4f000 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_mnoc_hf = { + .name = "qnm_mnoc_hf", + .id = SAR2130P_MASTER_MNOC_HF_MEM_NOC, + .channels = 2, + .buswidth = 32, + .qosbox = &qnm_mnoc_hf_qos, + .num_links = 2, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC }, +}; + +static const struct qcom_icc_qosbox qnm_mnoc_sf_qos = { + .num_ports = 1, + .port_offsets = { 0x9d000 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_mnoc_sf = { + .name = "qnm_mnoc_sf", + .id = SAR2130P_MASTER_MNOC_SF_MEM_NOC, + .channels = 1, + .buswidth = 32, + .qosbox = &qnm_mnoc_sf_qos, + .num_links = 2, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC }, +}; + +static const struct qcom_icc_qosbox qnm_nsp_gemnoc_qos = { + .num_ports = 2, + .port_offsets = { 0x10000, 0x50000 }, + .prio = 0, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qnm_nsp_gemnoc = { + .name = "qnm_nsp_gemnoc", + .id = SAR2130P_MASTER_COMPUTE_NOC, + .channels = 2, + .buswidth = 32, + .qosbox = &qnm_nsp_gemnoc_qos, + .num_links = 2, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC }, +}; + +static const struct qcom_icc_qosbox qnm_pcie_qos = { + .num_ports = 1, + .port_offsets = { 0xa2000 }, + .prio = 2, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_pcie = { + .name = "qnm_pcie", + .id = SAR2130P_MASTER_ANOC_PCIE_GEM_NOC, + .channels = 1, + .buswidth = 16, + .qosbox = &qnm_pcie_qos, + .num_links = 2, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC }, +}; + +static const struct qcom_icc_qosbox qnm_snoc_gc_qos = { + .num_ports = 1, + .port_offsets = { 0xa0000 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_snoc_gc = { + .name = "qnm_snoc_gc", + .id = SAR2130P_MASTER_SNOC_GC_MEM_NOC, + .channels = 1, + .buswidth = 8, + .qosbox = &qnm_snoc_gc_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_LLCC }, +}; + +static const struct qcom_icc_qosbox qnm_snoc_sf_qos = { + .num_ports = 1, + .port_offsets = { 0xa1000 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_snoc_sf = { + .name = "qnm_snoc_sf", + .id = SAR2130P_MASTER_SNOC_SF_MEM_NOC, + .channels = 1, + .buswidth = 16, + .qosbox = &qnm_snoc_sf_qos, + .num_links = 3, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC, + SAR2130P_SLAVE_MEM_NOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node qxm_wlan_q6 = { + .name = "qxm_wlan_q6", + .id = SAR2130P_MASTER_WLAN_Q6, + .channels = 1, + .buswidth = 8, + .num_links = 3, + .links = { SAR2130P_SLAVE_GEM_NOC_CNOC, SAR2130P_SLAVE_LLCC, + SAR2130P_SLAVE_MEM_NOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node qhm_config_noc = { + .name = "qhm_config_noc", + .id = SAR2130P_MASTER_CNOC_LPASS_AG_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 6, + .links = { SAR2130P_SLAVE_LPASS_CORE_CFG, SAR2130P_SLAVE_LPASS_LPI_CFG, + SAR2130P_SLAVE_LPASS_MPU_CFG, SAR2130P_SLAVE_LPASS_TOP_CFG, + SAR2130P_SLAVE_SERVICES_LPASS_AML_NOC, SAR2130P_SLAVE_SERVICE_LPASS_AG_NOC }, +}; + +static struct qcom_icc_node qxm_lpass_dsp = { + .name = "qxm_lpass_dsp", + .id = SAR2130P_MASTER_LPASS_PROC, + .channels = 1, + .buswidth = 8, + .num_links = 4, + .links = { SAR2130P_SLAVE_LPASS_TOP_CFG, SAR2130P_SLAVE_LPASS_SNOC, + SAR2130P_SLAVE_SERVICES_LPASS_AML_NOC, SAR2130P_SLAVE_SERVICE_LPASS_AG_NOC }, +}; + +static struct qcom_icc_node llcc_mc = { + .name = "llcc_mc", + .id = SAR2130P_MASTER_LLCC, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_SLAVE_EBI1 }, +}; + +static const struct qcom_icc_qosbox qnm_camnoc_hf_qos = { + .num_ports = 1, + .port_offsets = { 0x1c000 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_camnoc_hf = { + .name = "qnm_camnoc_hf", + .id = SAR2130P_MASTER_CAMNOC_HF, + .channels = 1, + .buswidth = 32, + .qosbox = &qnm_camnoc_hf_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox qnm_camnoc_icp_qos = { + .num_ports = 1, + .port_offsets = { 0x1c080 }, + .prio = 4, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_camnoc_icp = { + .name = "qnm_camnoc_icp", + .id = SAR2130P_MASTER_CAMNOC_ICP, + .channels = 1, + .buswidth = 8, + .qosbox = &qnm_camnoc_icp_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox qnm_camnoc_sf_qos = { + .num_ports = 1, + .port_offsets = { 0x1c100 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_camnoc_sf = { + .name = "qnm_camnoc_sf", + .id = SAR2130P_MASTER_CAMNOC_SF, + .channels = 1, + .buswidth = 32, + .qosbox = &qnm_camnoc_sf_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox qnm_lsr_qos = { + .num_ports = 2, + .port_offsets = { 0x1f000, 0x1f080 }, + .prio = 3, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_lsr = { + .name = "qnm_lsr", + .id = SAR2130P_MASTER_LSR, + .channels = 2, + .buswidth = 32, + .qosbox = &qnm_lsr_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox qnm_mdp_qos = { + .num_ports = 2, + .port_offsets = { 0x1d000, 0x1d080 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_mdp = { + .name = "qnm_mdp", + .id = SAR2130P_MASTER_MDP, + .channels = 2, + .buswidth = 32, + .qosbox = &qnm_mdp_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qnm_mnoc_cfg = { + .name = "qnm_mnoc_cfg", + .id = SAR2130P_MASTER_CNOC_MNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_SLAVE_SERVICE_MNOC }, +}; + +static const struct qcom_icc_qosbox qnm_video_qos = { + .num_ports = 2, + .port_offsets = { 0x1e000, 0x1e080 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_video = { + .name = "qnm_video", + .id = SAR2130P_MASTER_VIDEO, + .channels = 2, + .buswidth = 32, + .qosbox = &qnm_video_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox qnm_video_cv_cpu_qos = { + .num_ports = 1, + .port_offsets = { 0x1e100 }, + .prio = 4, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_video_cv_cpu = { + .name = "qnm_video_cv_cpu", + .id = SAR2130P_MASTER_VIDEO_CV_PROC, + .channels = 1, + .buswidth = 8, + .qosbox = &qnm_video_cv_cpu_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox qnm_video_cvp_qos = { + .num_ports = 1, + .port_offsets = { 0x1e180 }, + .prio = 0, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_video_cvp = { + .name = "qnm_video_cvp", + .id = SAR2130P_MASTER_VIDEO_PROC, + .channels = 1, + .buswidth = 32, + .qosbox = &qnm_video_cvp_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox qnm_video_v_cpu_qos = { + .num_ports = 1, + .port_offsets = { 0x1e200 }, + .prio = 4, + .urg_fwd = 1, +}; + +static struct qcom_icc_node qnm_video_v_cpu = { + .name = "qnm_video_v_cpu", + .id = SAR2130P_MASTER_VIDEO_V_PROC, + .channels = 1, + .buswidth = 8, + .qosbox = &qnm_video_v_cpu_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node qhm_nsp_noc_config = { + .name = "qhm_nsp_noc_config", + .id = SAR2130P_MASTER_CDSP_NOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_SLAVE_SERVICE_NSP_NOC }, +}; + +static struct qcom_icc_node qxm_nsp = { + .name = "qxm_nsp", + .id = SAR2130P_MASTER_CDSP_PROC, + .channels = 2, + .buswidth = 32, + .num_links = 1, + .links = { SAR2130P_SLAVE_CDSP_MEM_NOC }, +}; + +static const struct qcom_icc_qosbox xm_pcie3_0_qos = { + .num_ports = 1, + .port_offsets = { 0x9000 }, + .prio = 3, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node xm_pcie3_0 = { + .name = "xm_pcie3_0", + .id = SAR2130P_MASTER_PCIE_0, + .channels = 1, + .buswidth = 8, + .qosbox = &xm_pcie3_0_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_ANOC_PCIE_GEM_NOC }, +}; + +static const struct qcom_icc_qosbox xm_pcie3_1_qos = { + .num_ports = 1, + .port_offsets = { 0xa000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node xm_pcie3_1 = { + .name = "xm_pcie3_1", + .id = SAR2130P_MASTER_PCIE_1, + .channels = 1, + .buswidth = 8, + .qosbox = &xm_pcie3_1_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_ANOC_PCIE_GEM_NOC }, +}; + +static const struct qcom_icc_qosbox qhm_gic_qos = { + .num_ports = 1, + .port_offsets = { 0x1d000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qhm_gic = { + .name = "qhm_gic", + .id = SAR2130P_MASTER_GIC_AHB, + .channels = 1, + .buswidth = 4, + .qosbox = &qhm_gic_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_SNOC_GEM_NOC_SF }, +}; + +static const struct qcom_icc_qosbox qhm_qdss_bam_qos = { + .num_ports = 1, + .port_offsets = { 0x22000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qhm_qdss_bam = { + .name = "qhm_qdss_bam", + .id = SAR2130P_MASTER_QDSS_BAM, + .channels = 1, + .buswidth = 4, + .qosbox = &qhm_qdss_bam_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox qhm_qspi_qos = { + .num_ports = 1, + .port_offsets = { 0x23000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qhm_qspi = { + .name = "qhm_qspi", + .id = SAR2130P_MASTER_QSPI_0, + .channels = 1, + .buswidth = 4, + .qosbox = &qhm_qspi_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox qhm_qup0_qos = { + .num_ports = 1, + .port_offsets = { 0x24000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qhm_qup0 = { + .name = "qhm_qup0", + .id = SAR2130P_MASTER_QUP_0, + .channels = 1, + .buswidth = 4, + .qosbox = &qhm_qup0_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox qhm_qup1_qos = { + .num_ports = 1, + .port_offsets = { 0x25000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qhm_qup1 = { + .name = "qhm_qup1", + .id = SAR2130P_MASTER_QUP_1, + .channels = 1, + .buswidth = 4, + .qosbox = &qhm_qup1_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qnm_aggre2_noc = { + .name = "qnm_aggre2_noc", + .id = SAR2130P_MASTER_A2NOC_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { SAR2130P_SLAVE_SNOC_GEM_NOC_SF }, +}; + +static const struct qcom_icc_qosbox qnm_cnoc_datapath_qos = { + .num_ports = 1, + .port_offsets = { 0x26000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qnm_cnoc_datapath = { + .name = "qnm_cnoc_datapath", + .id = SAR2130P_MASTER_CNOC_DATAPATH, + .channels = 1, + .buswidth = 8, + .qosbox = &qnm_cnoc_datapath_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox qnm_lpass_noc_qos = { + .num_ports = 1, + .port_offsets = { 0x1e000 }, + .prio = 0, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qnm_lpass_noc = { + .name = "qnm_lpass_noc", + .id = SAR2130P_MASTER_LPASS_ANOC, + .channels = 1, + .buswidth = 16, + .qosbox = &qnm_lpass_noc_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_SNOC_GEM_NOC_SF }, +}; + +static struct qcom_icc_node qnm_snoc_cfg = { + .name = "qnm_snoc_cfg", + .id = SAR2130P_MASTER_SNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_SLAVE_SERVICE_SNOC }, +}; + +static const struct qcom_icc_qosbox qxm_crypto_qos = { + .num_ports = 1, + .port_offsets = { 0x27000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qxm_crypto = { + .name = "qxm_crypto", + .id = SAR2130P_MASTER_CRYPTO, + .channels = 1, + .buswidth = 8, + .qosbox = &qxm_crypto_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox qxm_pimem_qos = { + .num_ports = 1, + .port_offsets = { 0x1f000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node qxm_pimem = { + .name = "qxm_pimem", + .id = SAR2130P_MASTER_PIMEM, + .channels = 1, + .buswidth = 8, + .qosbox = &qxm_pimem_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_SNOC_GEM_NOC_GC }, +}; + +static const struct qcom_icc_qosbox xm_gic_qos = { + .num_ports = 1, + .port_offsets = { 0x21000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node xm_gic = { + .name = "xm_gic", + .id = SAR2130P_MASTER_GIC, + .channels = 1, + .buswidth = 8, + .qosbox = &xm_gic_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_SNOC_GEM_NOC_GC }, +}; + +static const struct qcom_icc_qosbox xm_qdss_etr_0_qos = { + .num_ports = 1, + .port_offsets = { 0x1b000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node xm_qdss_etr_0 = { + .name = "xm_qdss_etr_0", + .id = SAR2130P_MASTER_QDSS_ETR, + .channels = 1, + .buswidth = 8, + .qosbox = &xm_qdss_etr_0_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox xm_qdss_etr_1_qos = { + .num_ports = 1, + .port_offsets = { 0x1c000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node xm_qdss_etr_1 = { + .name = "xm_qdss_etr_1", + .id = SAR2130P_MASTER_QDSS_ETR_1, + .channels = 1, + .buswidth = 8, + .qosbox = &xm_qdss_etr_1_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox xm_sdc1_qos = { + .num_ports = 1, + .port_offsets = { 0x29000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node xm_sdc1 = { + .name = "xm_sdc1", + .id = SAR2130P_MASTER_SDCC_1, + .channels = 1, + .buswidth = 8, + .qosbox = &xm_sdc1_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static const struct qcom_icc_qosbox xm_usb3_0_qos = { + .num_ports = 1, + .port_offsets = { 0x28000 }, + .prio = 2, + .urg_fwd = 0, + .prio_fwd_disable = 1, +}; + +static struct qcom_icc_node xm_usb3_0 = { + .name = "xm_usb3_0", + .id = SAR2130P_MASTER_USB3_0, + .channels = 1, + .buswidth = 8, + .qosbox = &xm_usb3_0_qos, + .num_links = 1, + .links = { SAR2130P_SLAVE_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qup0_core_slave = { + .name = "qup0_core_slave", + .id = SAR2130P_SLAVE_QUP_CORE_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qup1_core_slave = { + .name = "qup1_core_slave", + .id = SAR2130P_SLAVE_QUP_CORE_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ahb2phy0 = { + .name = "qhs_ahb2phy0", + .id = SAR2130P_SLAVE_AHB2PHY_SOUTH, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_aoss = { + .name = "qhs_aoss", + .id = SAR2130P_SLAVE_AOSS, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_camera_cfg = { + .name = "qhs_camera_cfg", + .id = SAR2130P_SLAVE_CAMERA_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_clk_ctl = { + .name = "qhs_clk_ctl", + .id = SAR2130P_SLAVE_CLK_CTL, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_compute_cfg = { + .name = "qhs_compute_cfg", + .id = SAR2130P_SLAVE_CDSP_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_MASTER_CDSP_NOC_CFG }, +}; + +static struct qcom_icc_node qhs_cpr_cx = { + .name = "qhs_cpr_cx", + .id = SAR2130P_SLAVE_RBCPR_CX_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_mmcx = { + .name = "qhs_cpr_mmcx", + .id = SAR2130P_SLAVE_RBCPR_MMCX_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_mxa = { + .name = "qhs_cpr_mxa", + .id = SAR2130P_SLAVE_RBCPR_MXA_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_mxc = { + .name = "qhs_cpr_mxc", + .id = SAR2130P_SLAVE_RBCPR_MXC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cpr_nspcx = { + .name = "qhs_cpr_nspcx", + .id = SAR2130P_SLAVE_CPR_NSPCX, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_crypto0_cfg = { + .name = "qhs_crypto0_cfg", + .id = SAR2130P_SLAVE_CRYPTO_0_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_cx_rdpm = { + .name = "qhs_cx_rdpm", + .id = SAR2130P_SLAVE_CX_RDPM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_display_cfg = { + .name = "qhs_display_cfg", + .id = SAR2130P_SLAVE_DISPLAY_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_gpuss_cfg = { + .name = "qhs_gpuss_cfg", + .id = SAR2130P_SLAVE_GFX3D_CFG, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_imem_cfg = { + .name = "qhs_imem_cfg", + .id = SAR2130P_SLAVE_IMEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_ipc_router = { + .name = "qhs_ipc_router", + .id = SAR2130P_SLAVE_IPC_ROUTER_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_cfg = { + .name = "qhs_lpass_cfg", + .id = SAR2130P_SLAVE_LPASS, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_MASTER_CNOC_LPASS_AG_NOC }, +}; + +static struct qcom_icc_node qhs_mx_rdpm = { + .name = "qhs_mx_rdpm", + .id = SAR2130P_SLAVE_MX_RDPM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pcie0_cfg = { + .name = "qhs_pcie0_cfg", + .id = SAR2130P_SLAVE_PCIE_0_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pcie1_cfg = { + .name = "qhs_pcie1_cfg", + .id = SAR2130P_SLAVE_PCIE_1_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pdm = { + .name = "qhs_pdm", + .id = SAR2130P_SLAVE_PDM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_pimem_cfg = { + .name = "qhs_pimem_cfg", + .id = SAR2130P_SLAVE_PIMEM_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_prng = { + .name = "qhs_prng", + .id = SAR2130P_SLAVE_PRNG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qdss_cfg = { + .name = "qhs_qdss_cfg", + .id = SAR2130P_SLAVE_QDSS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qspi = { + .name = "qhs_qspi", + .id = SAR2130P_SLAVE_QSPI_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qup0 = { + .name = "qhs_qup0", + .id = SAR2130P_SLAVE_QUP_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_qup1 = { + .name = "qhs_qup1", + .id = SAR2130P_SLAVE_QUP_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_sdc1 = { + .name = "qhs_sdc1", + .id = SAR2130P_SLAVE_SDCC_1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tcsr = { + .name = "qhs_tcsr", + .id = SAR2130P_SLAVE_TCSR, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tlmm = { + .name = "qhs_tlmm", + .id = SAR2130P_SLAVE_TLMM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_tme_cfg = { + .name = "qhs_tme_cfg", + .id = SAR2130P_SLAVE_TME_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_usb3_0 = { + .name = "qhs_usb3_0", + .id = SAR2130P_SLAVE_USB3_0, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_venus_cfg = { + .name = "qhs_venus_cfg", + .id = SAR2130P_SLAVE_VENUS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_vsense_ctrl_cfg = { + .name = "qhs_vsense_ctrl_cfg", + .id = SAR2130P_SLAVE_VSENSE_CTRL_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_wlan_q6 = { + .name = "qhs_wlan_q6", + .id = SAR2130P_SLAVE_WLAN_Q6_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_ddrss_cfg = { + .name = "qns_ddrss_cfg", + .id = SAR2130P_SLAVE_DDRSS_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_mnoc_cfg = { + .name = "qns_mnoc_cfg", + .id = SAR2130P_SLAVE_CNOC_MNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_MASTER_CNOC_MNOC_CFG }, +}; + +static struct qcom_icc_node qns_snoc_cfg = { + .name = "qns_snoc_cfg", + .id = SAR2130P_SLAVE_SNOC_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 1, + .links = { SAR2130P_MASTER_SNOC_CFG }, +}; + +static struct qcom_icc_node qxs_imem = { + .name = "qxs_imem", + .id = SAR2130P_SLAVE_IMEM, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qxs_pimem = { + .name = "qxs_pimem", + .id = SAR2130P_SLAVE_PIMEM, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_cnoc = { + .name = "srvc_cnoc", + .id = SAR2130P_SLAVE_SERVICE_CNOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node xs_pcie_0 = { + .name = "xs_pcie_0", + .id = SAR2130P_SLAVE_PCIE_0, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node xs_pcie_1 = { + .name = "xs_pcie_1", + .id = SAR2130P_SLAVE_PCIE_1, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node xs_qdss_stm = { + .name = "xs_qdss_stm", + .id = SAR2130P_SLAVE_QDSS_STM, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node xs_sys_tcu_cfg = { + .name = "xs_sys_tcu_cfg", + .id = SAR2130P_SLAVE_TCU, + .channels = 1, + .buswidth = 8, + .num_links = 0, +}; + +static struct qcom_icc_node qns_gem_noc_cnoc = { + .name = "qns_gem_noc_cnoc", + .id = SAR2130P_SLAVE_GEM_NOC_CNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { SAR2130P_MASTER_GEM_NOC_CNOC }, +}; + +static struct qcom_icc_node qns_llcc = { + .name = "qns_llcc", + .id = SAR2130P_SLAVE_LLCC, + .channels = 2, + .buswidth = 16, + .num_links = 1, + .links = { SAR2130P_MASTER_LLCC }, +}; + +static struct qcom_icc_node qns_pcie = { + .name = "qns_pcie", + .id = SAR2130P_SLAVE_MEM_NOC_PCIE_SNOC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { SAR2130P_MASTER_GEM_NOC_PCIE_SNOC }, +}; + +static struct qcom_icc_node qhs_lpass_core = { + .name = "qhs_lpass_core", + .id = SAR2130P_SLAVE_LPASS_CORE_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_lpi = { + .name = "qhs_lpass_lpi", + .id = SAR2130P_SLAVE_LPASS_LPI_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_mpu = { + .name = "qhs_lpass_mpu", + .id = SAR2130P_SLAVE_LPASS_MPU_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qhs_lpass_top = { + .name = "qhs_lpass_top", + .id = SAR2130P_SLAVE_LPASS_TOP_CFG, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_sysnoc = { + .name = "qns_sysnoc", + .id = SAR2130P_SLAVE_LPASS_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { SAR2130P_MASTER_LPASS_ANOC }, +}; + +static struct qcom_icc_node srvc_niu_aml_noc = { + .name = "srvc_niu_aml_noc", + .id = SAR2130P_SLAVE_SERVICES_LPASS_AML_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node srvc_niu_lpass_agnoc = { + .name = "srvc_niu_lpass_agnoc", + .id = SAR2130P_SLAVE_SERVICE_LPASS_AG_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node ebi = { + .name = "ebi", + .id = SAR2130P_SLAVE_EBI1, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_mem_noc_hf = { + .name = "qns_mem_noc_hf", + .id = SAR2130P_SLAVE_MNOC_HF_MEM_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 1, + .links = { SAR2130P_MASTER_MNOC_HF_MEM_NOC }, +}; + +static struct qcom_icc_node qns_mem_noc_sf = { + .name = "qns_mem_noc_sf", + .id = SAR2130P_SLAVE_MNOC_SF_MEM_NOC, + .channels = 1, + .buswidth = 32, + .num_links = 1, + .links = { SAR2130P_MASTER_MNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node srvc_mnoc = { + .name = "srvc_mnoc", + .id = SAR2130P_SLAVE_SERVICE_MNOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_nsp_gemnoc = { + .name = "qns_nsp_gemnoc", + .id = SAR2130P_SLAVE_CDSP_MEM_NOC, + .channels = 2, + .buswidth = 32, + .num_links = 1, + .links = { SAR2130P_MASTER_COMPUTE_NOC }, +}; + +static struct qcom_icc_node service_nsp_noc = { + .name = "service_nsp_noc", + .id = SAR2130P_SLAVE_SERVICE_NSP_NOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_node qns_pcie_mem_noc = { + .name = "qns_pcie_mem_noc", + .id = SAR2130P_SLAVE_ANOC_PCIE_GEM_NOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { SAR2130P_MASTER_ANOC_PCIE_GEM_NOC }, +}; + +static struct qcom_icc_node qns_a2noc_snoc = { + .name = "qns_a2noc_snoc", + .id = SAR2130P_SLAVE_A2NOC_SNOC, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { SAR2130P_MASTER_A2NOC_SNOC }, +}; + +static struct qcom_icc_node qns_gemnoc_gc = { + .name = "qns_gemnoc_gc", + .id = SAR2130P_SLAVE_SNOC_GEM_NOC_GC, + .channels = 1, + .buswidth = 8, + .num_links = 1, + .links = { SAR2130P_MASTER_SNOC_GC_MEM_NOC }, +}; + +static struct qcom_icc_node qns_gemnoc_sf = { + .name = "qns_gemnoc_sf", + .id = SAR2130P_SLAVE_SNOC_GEM_NOC_SF, + .channels = 1, + .buswidth = 16, + .num_links = 1, + .links = { SAR2130P_MASTER_SNOC_SF_MEM_NOC }, +}; + +static struct qcom_icc_node srvc_snoc = { + .name = "srvc_snoc", + .id = SAR2130P_SLAVE_SERVICE_SNOC, + .channels = 1, + .buswidth = 4, + .num_links = 0, +}; + +static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", + .enable_mask = BIT(3), + .num_nodes = 1, + .nodes = { &ebi }, +}; + +static struct qcom_icc_bcm bcm_ce0 = { + .name = "CE0", + .num_nodes = 1, + .nodes = { &qxm_crypto }, +}; + +static struct qcom_icc_bcm bcm_cn0 = { + .name = "CN0", + .enable_mask = BIT(0), + .keepalive = true, + .num_nodes = 48, + .nodes = { &qnm_gemnoc_cnoc, &qnm_gemnoc_pcie, + &xm_qdss_dap, &qhs_ahb2phy0, + &qhs_aoss, &qhs_camera_cfg, + &qhs_clk_ctl, &qhs_compute_cfg, + &qhs_cpr_cx, &qhs_cpr_mmcx, + &qhs_cpr_mxa, &qhs_cpr_mxc, + &qhs_cpr_nspcx, &qhs_crypto0_cfg, + &qhs_cx_rdpm, &qhs_display_cfg, + &qhs_gpuss_cfg, &qhs_imem_cfg, + &qhs_ipc_router, &qhs_lpass_cfg, + &qhs_mx_rdpm, &qhs_pcie0_cfg, + &qhs_pcie1_cfg, &qhs_pdm, + &qhs_pimem_cfg, &qhs_prng, + &qhs_qdss_cfg, &qhs_qspi, + &qhs_qup0, &qhs_qup1, + &qhs_sdc1, &qhs_tcsr, + &qhs_tlmm, &qhs_tme_cfg, + &qhs_usb3_0, &qhs_venus_cfg, + &qhs_vsense_ctrl_cfg, &qhs_wlan_q6, + &qns_ddrss_cfg, &qns_mnoc_cfg, + &qns_snoc_cfg, &qxs_imem, + &qxs_pimem, &srvc_cnoc, + &xs_pcie_0, &xs_pcie_1, + &xs_qdss_stm, &xs_sys_tcu_cfg }, +}; + +static struct qcom_icc_bcm bcm_co0 = { + .name = "CO0", + .enable_mask = BIT(0), + .num_nodes = 2, + .nodes = { &qxm_nsp, &qns_nsp_gemnoc }, +}; + +static struct qcom_icc_bcm bcm_mc0 = { + .name = "MC0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &ebi }, +}; + +static struct qcom_icc_bcm bcm_mm0 = { + .name = "MM0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_mem_noc_hf }, +}; + +static struct qcom_icc_bcm bcm_mm1 = { + .name = "MM1", + .enable_mask = BIT(0), + .num_nodes = 11, + .nodes = { &qnm_camnoc_hf, &qnm_camnoc_icp, + &qnm_camnoc_sf, &qnm_lsr, + &qnm_mdp, &qnm_mnoc_cfg, + &qnm_video, &qnm_video_cv_cpu, + &qnm_video_cvp, &qnm_video_v_cpu, + &qns_mem_noc_sf }, +}; + +static struct qcom_icc_bcm bcm_qup0 = { + .name = "QUP0", + .keepalive = true, + .vote_scale = 1, + .num_nodes = 1, + .nodes = { &qup0_core_slave }, +}; + +static struct qcom_icc_bcm bcm_qup1 = { + .name = "QUP1", + .keepalive = true, + .vote_scale = 1, + .num_nodes = 1, + .nodes = { &qup1_core_slave }, +}; + +static struct qcom_icc_bcm bcm_sh0 = { + .name = "SH0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_llcc }, +}; + +static struct qcom_icc_bcm bcm_sh1 = { + .name = "SH1", + .enable_mask = BIT(0), + .num_nodes = 13, + .nodes = { &alm_gpu_tcu, &alm_sys_tcu, + &chm_apps, &qnm_gpu, + &qnm_mnoc_hf, &qnm_mnoc_sf, + &qnm_nsp_gemnoc, &qnm_pcie, + &qnm_snoc_gc, &qnm_snoc_sf, + &qxm_wlan_q6, &qns_gem_noc_cnoc, + &qns_pcie }, +}; + +static struct qcom_icc_bcm bcm_sn0 = { + .name = "SN0", + .keepalive = true, + .num_nodes = 1, + .nodes = { &qns_gemnoc_sf }, +}; + +static struct qcom_icc_bcm bcm_sn1 = { + .name = "SN1", + .enable_mask = BIT(0), + .num_nodes = 4, + .nodes = { &qhm_gic, &qxm_pimem, + &xm_gic, &qns_gemnoc_gc }, +}; + +static struct qcom_icc_bcm bcm_sn3 = { + .name = "SN3", + .num_nodes = 1, + .nodes = { &qnm_aggre2_noc }, +}; + +static struct qcom_icc_bcm bcm_sn4 = { + .name = "SN4", + .num_nodes = 1, + .nodes = { &qnm_lpass_noc }, +}; + +static struct qcom_icc_bcm bcm_sn7 = { + .name = "SN7", + .num_nodes = 1, + .nodes = { &qns_pcie_mem_noc }, +}; + +static struct qcom_icc_bcm * const clk_virt_bcms[] = { + &bcm_qup0, + &bcm_qup1, +}; + +static struct qcom_icc_node * const clk_virt_nodes[] = { + [MASTER_QUP_CORE_0] = &qup0_core_master, + [MASTER_QUP_CORE_1] = &qup1_core_master, + [SLAVE_QUP_CORE_0] = &qup0_core_slave, + [SLAVE_QUP_CORE_1] = &qup1_core_slave, +}; + +static const struct qcom_icc_desc sar2130p_clk_virt = { + .nodes = clk_virt_nodes, + .num_nodes = ARRAY_SIZE(clk_virt_nodes), + .bcms = clk_virt_bcms, + .num_bcms = ARRAY_SIZE(clk_virt_bcms), +}; + +static struct qcom_icc_bcm * const config_noc_bcms[] = { + &bcm_cn0, +}; + +static struct qcom_icc_node * const config_noc_nodes[] = { + [MASTER_GEM_NOC_CNOC] = &qnm_gemnoc_cnoc, + [MASTER_GEM_NOC_PCIE_SNOC] = &qnm_gemnoc_pcie, + [MASTER_QDSS_DAP] = &xm_qdss_dap, + [SLAVE_AHB2PHY_SOUTH] = &qhs_ahb2phy0, + [SLAVE_AOSS] = &qhs_aoss, + [SLAVE_CAMERA_CFG] = &qhs_camera_cfg, + [SLAVE_CLK_CTL] = &qhs_clk_ctl, + [SLAVE_CDSP_CFG] = &qhs_compute_cfg, + [SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx, + [SLAVE_RBCPR_MMCX_CFG] = &qhs_cpr_mmcx, + [SLAVE_RBCPR_MXA_CFG] = &qhs_cpr_mxa, + [SLAVE_RBCPR_MXC_CFG] = &qhs_cpr_mxc, + [SLAVE_CPR_NSPCX] = &qhs_cpr_nspcx, + [SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg, + [SLAVE_CX_RDPM] = &qhs_cx_rdpm, + [SLAVE_DISPLAY_CFG] = &qhs_display_cfg, + [SLAVE_GFX3D_CFG] = &qhs_gpuss_cfg, + [SLAVE_IMEM_CFG] = &qhs_imem_cfg, + [SLAVE_IPC_ROUTER_CFG] = &qhs_ipc_router, + [SLAVE_LPASS] = &qhs_lpass_cfg, + [SLAVE_MX_RDPM] = &qhs_mx_rdpm, + [SLAVE_PCIE_0_CFG] = &qhs_pcie0_cfg, + [SLAVE_PCIE_1_CFG] = &qhs_pcie1_cfg, + [SLAVE_PDM] = &qhs_pdm, + [SLAVE_PIMEM_CFG] = &qhs_pimem_cfg, + [SLAVE_PRNG] = &qhs_prng, + [SLAVE_QDSS_CFG] = &qhs_qdss_cfg, + [SLAVE_QSPI_0] = &qhs_qspi, + [SLAVE_QUP_0] = &qhs_qup0, + [SLAVE_QUP_1] = &qhs_qup1, + [SLAVE_SDCC_1] = &qhs_sdc1, + [SLAVE_TCSR] = &qhs_tcsr, + [SLAVE_TLMM] = &qhs_tlmm, + [SLAVE_TME_CFG] = &qhs_tme_cfg, + [SLAVE_USB3_0] = &qhs_usb3_0, + [SLAVE_VENUS_CFG] = &qhs_venus_cfg, + [SLAVE_VSENSE_CTRL_CFG] = &qhs_vsense_ctrl_cfg, + [SLAVE_WLAN_Q6_CFG] = &qhs_wlan_q6, + [SLAVE_DDRSS_CFG] = &qns_ddrss_cfg, + [SLAVE_CNOC_MNOC_CFG] = &qns_mnoc_cfg, + [SLAVE_SNOC_CFG] = &qns_snoc_cfg, + [SLAVE_IMEM] = &qxs_imem, + [SLAVE_PIMEM] = &qxs_pimem, + [SLAVE_SERVICE_CNOC] = &srvc_cnoc, + [SLAVE_PCIE_0] = &xs_pcie_0, + [SLAVE_PCIE_1] = &xs_pcie_1, + [SLAVE_QDSS_STM] = &xs_qdss_stm, + [SLAVE_TCU] = &xs_sys_tcu_cfg, +}; + +static const struct qcom_icc_desc sar2130p_config_noc = { + .config = &icc_regmap_config, + .nodes = config_noc_nodes, + .num_nodes = ARRAY_SIZE(config_noc_nodes), + .bcms = config_noc_bcms, + .num_bcms = ARRAY_SIZE(config_noc_bcms), +}; + +static struct qcom_icc_bcm * const gem_noc_bcms[] = { + &bcm_sh0, + &bcm_sh1, +}; + +static struct qcom_icc_node * const gem_noc_nodes[] = { + [MASTER_GPU_TCU] = &alm_gpu_tcu, + [MASTER_SYS_TCU] = &alm_sys_tcu, + [MASTER_APPSS_PROC] = &chm_apps, + [MASTER_GFX3D] = &qnm_gpu, + [MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf, + [MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf, + [MASTER_COMPUTE_NOC] = &qnm_nsp_gemnoc, + [MASTER_ANOC_PCIE_GEM_NOC] = &qnm_pcie, + [MASTER_SNOC_GC_MEM_NOC] = &qnm_snoc_gc, + [MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf, + [MASTER_WLAN_Q6] = &qxm_wlan_q6, + [SLAVE_GEM_NOC_CNOC] = &qns_gem_noc_cnoc, + [SLAVE_LLCC] = &qns_llcc, + [SLAVE_MEM_NOC_PCIE_SNOC] = &qns_pcie, +}; + +static const struct qcom_icc_desc sar2130p_gem_noc = { + .config = &icc_regmap_config, + .nodes = gem_noc_nodes, + .num_nodes = ARRAY_SIZE(gem_noc_nodes), + .bcms = gem_noc_bcms, + .num_bcms = ARRAY_SIZE(gem_noc_bcms), +}; + +static struct qcom_icc_bcm * const lpass_ag_noc_bcms[] = { +}; + +static struct qcom_icc_node * const lpass_ag_noc_nodes[] = { + [MASTER_CNOC_LPASS_AG_NOC] = &qhm_config_noc, + [MASTER_LPASS_PROC] = &qxm_lpass_dsp, + [SLAVE_LPASS_CORE_CFG] = &qhs_lpass_core, + [SLAVE_LPASS_LPI_CFG] = &qhs_lpass_lpi, + [SLAVE_LPASS_MPU_CFG] = &qhs_lpass_mpu, + [SLAVE_LPASS_TOP_CFG] = &qhs_lpass_top, + [SLAVE_LPASS_SNOC] = &qns_sysnoc, + [SLAVE_SERVICES_LPASS_AML_NOC] = &srvc_niu_aml_noc, + [SLAVE_SERVICE_LPASS_AG_NOC] = &srvc_niu_lpass_agnoc, +}; + +static const struct qcom_icc_desc sar2130p_lpass_ag_noc = { + .config = &icc_regmap_config, + .nodes = lpass_ag_noc_nodes, + .num_nodes = ARRAY_SIZE(lpass_ag_noc_nodes), + .bcms = lpass_ag_noc_bcms, + .num_bcms = ARRAY_SIZE(lpass_ag_noc_bcms), +}; + +static struct qcom_icc_bcm * const mc_virt_bcms[] = { + &bcm_acv, + &bcm_mc0, +}; + +static struct qcom_icc_node * const mc_virt_nodes[] = { + [MASTER_LLCC] = &llcc_mc, + [SLAVE_EBI1] = &ebi, +}; + +static const struct qcom_icc_desc sar2130p_mc_virt = { + .nodes = mc_virt_nodes, + .num_nodes = ARRAY_SIZE(mc_virt_nodes), + .bcms = mc_virt_bcms, + .num_bcms = ARRAY_SIZE(mc_virt_bcms), +}; + +static struct qcom_icc_bcm * const mmss_noc_bcms[] = { + &bcm_mm0, + &bcm_mm1, +}; + +static struct qcom_icc_node * const mmss_noc_nodes[] = { + [MASTER_CAMNOC_HF] = &qnm_camnoc_hf, + [MASTER_CAMNOC_ICP] = &qnm_camnoc_icp, + [MASTER_CAMNOC_SF] = &qnm_camnoc_sf, + [MASTER_LSR] = &qnm_lsr, + [MASTER_MDP] = &qnm_mdp, + [MASTER_CNOC_MNOC_CFG] = &qnm_mnoc_cfg, + [MASTER_VIDEO] = &qnm_video, + [MASTER_VIDEO_CV_PROC] = &qnm_video_cv_cpu, + [MASTER_VIDEO_PROC] = &qnm_video_cvp, + [MASTER_VIDEO_V_PROC] = &qnm_video_v_cpu, + [SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf, + [SLAVE_MNOC_SF_MEM_NOC] = &qns_mem_noc_sf, + [SLAVE_SERVICE_MNOC] = &srvc_mnoc, +}; + +static const struct qcom_icc_desc sar2130p_mmss_noc = { + .config = &icc_regmap_config, + .nodes = mmss_noc_nodes, + .num_nodes = ARRAY_SIZE(mmss_noc_nodes), + .bcms = mmss_noc_bcms, + .num_bcms = ARRAY_SIZE(mmss_noc_bcms), +}; + +static struct qcom_icc_bcm * const nsp_noc_bcms[] = { + &bcm_co0, +}; + +static struct qcom_icc_node * const nsp_noc_nodes[] = { + [MASTER_CDSP_NOC_CFG] = &qhm_nsp_noc_config, + [MASTER_CDSP_PROC] = &qxm_nsp, + [SLAVE_CDSP_MEM_NOC] = &qns_nsp_gemnoc, + [SLAVE_SERVICE_NSP_NOC] = &service_nsp_noc, +}; + +static const struct qcom_icc_desc sar2130p_nsp_noc = { + .config = &icc_regmap_config, + .nodes = nsp_noc_nodes, + .num_nodes = ARRAY_SIZE(nsp_noc_nodes), + .bcms = nsp_noc_bcms, + .num_bcms = ARRAY_SIZE(nsp_noc_bcms), +}; + +static struct qcom_icc_bcm * const pcie_anoc_bcms[] = { + &bcm_sn7, +}; + +static struct qcom_icc_node * const pcie_anoc_nodes[] = { + [MASTER_PCIE_0] = &xm_pcie3_0, + [MASTER_PCIE_1] = &xm_pcie3_1, + [SLAVE_ANOC_PCIE_GEM_NOC] = &qns_pcie_mem_noc, +}; + +static const struct qcom_icc_desc sar2130p_pcie_anoc = { + .config = &icc_regmap_config, + .nodes = pcie_anoc_nodes, + .num_nodes = ARRAY_SIZE(pcie_anoc_nodes), + .bcms = pcie_anoc_bcms, + .num_bcms = ARRAY_SIZE(pcie_anoc_bcms), +}; + +static struct qcom_icc_bcm * const system_noc_bcms[] = { + &bcm_ce0, + &bcm_sn0, + &bcm_sn1, + &bcm_sn3, + &bcm_sn4, +}; + +static struct qcom_icc_node * const system_noc_nodes[] = { + [MASTER_GIC_AHB] = &qhm_gic, + [MASTER_QDSS_BAM] = &qhm_qdss_bam, + [MASTER_QSPI_0] = &qhm_qspi, + [MASTER_QUP_0] = &qhm_qup0, + [MASTER_QUP_1] = &qhm_qup1, + [MASTER_A2NOC_SNOC] = &qnm_aggre2_noc, + [MASTER_CNOC_DATAPATH] = &qnm_cnoc_datapath, + [MASTER_LPASS_ANOC] = &qnm_lpass_noc, + [MASTER_SNOC_CFG] = &qnm_snoc_cfg, + [MASTER_CRYPTO] = &qxm_crypto, + [MASTER_PIMEM] = &qxm_pimem, + [MASTER_GIC] = &xm_gic, + [MASTER_QDSS_ETR] = &xm_qdss_etr_0, + [MASTER_QDSS_ETR_1] = &xm_qdss_etr_1, + [MASTER_SDCC_1] = &xm_sdc1, + [MASTER_USB3_0] = &xm_usb3_0, + [SLAVE_A2NOC_SNOC] = &qns_a2noc_snoc, + [SLAVE_SNOC_GEM_NOC_GC] = &qns_gemnoc_gc, + [SLAVE_SNOC_GEM_NOC_SF] = &qns_gemnoc_sf, + [SLAVE_SERVICE_SNOC] = &srvc_snoc, +}; + +static const struct qcom_icc_desc sar2130p_system_noc = { + .config = &icc_regmap_config, + .nodes = system_noc_nodes, + .num_nodes = ARRAY_SIZE(system_noc_nodes), + .bcms = system_noc_bcms, + .num_bcms = ARRAY_SIZE(system_noc_bcms), +}; + +static const struct of_device_id qnoc_of_match[] = { + { .compatible = "qcom,sar2130p-clk-virt", .data = &sar2130p_clk_virt}, + { .compatible = "qcom,sar2130p-config-noc", .data = &sar2130p_config_noc}, + { .compatible = "qcom,sar2130p-gem-noc", .data = &sar2130p_gem_noc}, + { .compatible = "qcom,sar2130p-lpass-ag-noc", .data = &sar2130p_lpass_ag_noc}, + { .compatible = "qcom,sar2130p-mc-virt", .data = &sar2130p_mc_virt}, + { .compatible = "qcom,sar2130p-mmss-noc", .data = &sar2130p_mmss_noc}, + { .compatible = "qcom,sar2130p-nsp-noc", .data = &sar2130p_nsp_noc}, + { .compatible = "qcom,sar2130p-pcie-anoc", .data = &sar2130p_pcie_anoc}, + { .compatible = "qcom,sar2130p-system-noc", .data = &sar2130p_system_noc}, + { } +}; +MODULE_DEVICE_TABLE(of, qnoc_of_match); + +static struct platform_driver qnoc_driver = { + .probe = qcom_icc_rpmh_probe, + .remove = qcom_icc_rpmh_remove, + .driver = { + .name = "qnoc-sar2130p", + .of_match_table = qnoc_of_match, + .sync_state = icc_sync_state, + }, +}; + +static int __init qnoc_driver_init(void) +{ + return platform_driver_register(&qnoc_driver); +} +core_initcall(qnoc_driver_init); + +static void __exit qnoc_driver_exit(void) +{ + platform_driver_unregister(&qnoc_driver); +} + +module_exit(qnoc_driver_exit); +MODULE_DESCRIPTION("Qualcomm SAR2130P NoC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c index 34a1d163d6e164f278e27b4ed3178ab0014a15ac..af2be15438403e4b46fca464b84abd1e0ebebe76 100644 --- a/drivers/interconnect/qcom/sc7180.c +++ b/drivers/interconnect/qcom/sc7180.c @@ -1807,7 +1807,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sc7180", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sc7280.c b/drivers/interconnect/qcom/sc7280.c index 167971f8e8bec3f6bab7f9c70450b208c7fa778b..346f18d70e9e5e95821437ca716ef8f151a42574 100644 --- a/drivers/interconnect/qcom/sc7280.c +++ b/drivers/interconnect/qcom/sc7280.c @@ -1691,7 +1691,7 @@ static const struct qcom_icc_desc sc7280_aggre1_noc = { .num_nodes = ARRAY_SIZE(aggre1_noc_nodes), .bcms = aggre1_noc_bcms, .num_bcms = ARRAY_SIZE(aggre1_noc_bcms), - .qos_clks_required = true, + .qos_requires_clocks = true, }; static struct qcom_icc_bcm * const aggre2_noc_bcms[] = { @@ -1723,7 +1723,7 @@ static const struct qcom_icc_desc sc7280_aggre2_noc = { .num_nodes = ARRAY_SIZE(aggre2_noc_nodes), .bcms = aggre2_noc_bcms, .num_bcms = ARRAY_SIZE(aggre2_noc_bcms), - .qos_clks_required = true, + .qos_requires_clocks = true, }; static struct qcom_icc_bcm * const clk_virt_bcms[] = { @@ -2111,7 +2111,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sc7280", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sc8180x.c b/drivers/interconnect/qcom/sc8180x.c index 03d626776ba17a3ff18c91c1e685a0230e8fcbbb..a741badaa966e0b1d0e0117f73f5d37c6ef9f19d 100644 --- a/drivers/interconnect/qcom/sc8180x.c +++ b/drivers/interconnect/qcom/sc8180x.c @@ -1889,7 +1889,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sc8180x", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sc8280xp.c b/drivers/interconnect/qcom/sc8280xp.c index 7acd152bf0dd8d1c2b2b713a4d6d5d805282f8c2..0270f6c64481a92149cb19556acdc6e2fead39c9 100644 --- a/drivers/interconnect/qcom/sc8280xp.c +++ b/drivers/interconnect/qcom/sc8280xp.c @@ -2391,7 +2391,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sc8280xp", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sdm660.c b/drivers/interconnect/qcom/sdm660.c index ab91de446da8818e31b6b8ddd30064f2592521f1..7392bebba3344fbf65e0dc36378e8c3fe5f3ae18 100644 --- a/drivers/interconnect/qcom/sdm660.c +++ b/drivers/interconnect/qcom/sdm660.c @@ -1714,7 +1714,7 @@ MODULE_DEVICE_TABLE(of, sdm660_noc_of_match); static struct platform_driver sdm660_noc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-sdm660", .of_match_table = sdm660_noc_of_match, diff --git a/drivers/interconnect/qcom/sdm670.c b/drivers/interconnect/qcom/sdm670.c index e5ee7fbaa641c9132f6187c53a024495c0599e96..907e1ff4ff81796ec9459ccc72a3f8c5d110ec57 100644 --- a/drivers/interconnect/qcom/sdm670.c +++ b/drivers/interconnect/qcom/sdm670.c @@ -1533,7 +1533,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sdm670", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index 584800ac871a8d1ce582acef1cb3a108f87e20da..855802be93fea1d999bc8a885f36c3c318e1d86d 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -1802,7 +1802,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sdm845", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sdx55.c b/drivers/interconnect/qcom/sdx55.c index e97f28b8d2b25d0b95de0008c59306fe4f1d5dc7..4117db046fa00c634a43d9287711589315f60210 100644 --- a/drivers/interconnect/qcom/sdx55.c +++ b/drivers/interconnect/qcom/sdx55.c @@ -913,7 +913,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sdx55", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sdx65.c b/drivers/interconnect/qcom/sdx65.c index 2f3f5479d8a51350be37263ce9e357ec31895fce..d3a6c6c148e5dedc95dbac3ad9b20538ce56a16d 100644 --- a/drivers/interconnect/qcom/sdx65.c +++ b/drivers/interconnect/qcom/sdx65.c @@ -897,7 +897,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sdx65", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sdx75.c b/drivers/interconnect/qcom/sdx75.c index 7f422c27488d3321532fcdd70ea3af99cc943df2..7ef1f17f3292e15959cb06e3d8d8c5f3c6ecd060 100644 --- a/drivers/interconnect/qcom/sdx75.c +++ b/drivers/interconnect/qcom/sdx75.c @@ -1083,7 +1083,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sdx75", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm6115.c b/drivers/interconnect/qcom/sm6115.c index 271b07c74862d2f76ad1fd9015082ecb4f2a436c..3ee12c8a4d56b36d1d2dcec10e5e916b3e766742 100644 --- a/drivers/interconnect/qcom/sm6115.c +++ b/drivers/interconnect/qcom/sm6115.c @@ -1402,7 +1402,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qnoc_probe, - .remove_new = qnoc_remove, + .remove = qnoc_remove, .driver = { .name = "qnoc-sm6115", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm6350.c b/drivers/interconnect/qcom/sm6350.c index 20923e8e611020c63c59620aae05efe158316692..f41d7e19ba269cba7cc07b0136a6d1fcccd8af4d 100644 --- a/drivers/interconnect/qcom/sm6350.c +++ b/drivers/interconnect/qcom/sm6350.c @@ -1702,7 +1702,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm6350", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm7150.c b/drivers/interconnect/qcom/sm7150.c index dc0d1343f5100b8c6b3c7946e1bfd9229d49c0da..c8c77407cd508dfede2821b7d52bf9da54283bad 100644 --- a/drivers/interconnect/qcom/sm7150.c +++ b/drivers/interconnect/qcom/sm7150.c @@ -1730,7 +1730,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm7150", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm8150.c b/drivers/interconnect/qcom/sm8150.c index f29b77556a7998a94d0b1ed7f13379a8d22c2666..edfe824cad3533cfc6263c2031838f96e1986fa5 100644 --- a/drivers/interconnect/qcom/sm8150.c +++ b/drivers/interconnect/qcom/sm8150.c @@ -1864,7 +1864,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm8150", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm8250.c b/drivers/interconnect/qcom/sm8250.c index 1879fa15761f5e73ad45852130da72750b5713b6..cc1b14c1352910fd450c334fa90f2a0b390bb9bc 100644 --- a/drivers/interconnect/qcom/sm8250.c +++ b/drivers/interconnect/qcom/sm8250.c @@ -1991,7 +1991,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm8250", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm8350.c b/drivers/interconnect/qcom/sm8350.c index 4236a43dc256f926ee53ea44a50e3c6722b72839..38105ead4f29548ab32c60aeba224fbf3909667c 100644 --- a/drivers/interconnect/qcom/sm8350.c +++ b/drivers/interconnect/qcom/sm8350.c @@ -1807,7 +1807,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm8350", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm8450.c b/drivers/interconnect/qcom/sm8450.c index b3cd0087377ca7ca4b0492e5e049af4561ed8d43..eb7e17df32ba656cf1934e0fc112189966b22ac2 100644 --- a/drivers/interconnect/qcom/sm8450.c +++ b/drivers/interconnect/qcom/sm8450.c @@ -1884,7 +1884,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm8450", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm8550.c b/drivers/interconnect/qcom/sm8550.c index 4d0e6fa9e003bde70eecbe154863743aeb33632a..fdb97d1f1d074d17b55f10a5852ce80388b611b7 100644 --- a/drivers/interconnect/qcom/sm8550.c +++ b/drivers/interconnect/qcom/sm8550.c @@ -1645,7 +1645,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm8550", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/sm8650.c b/drivers/interconnect/qcom/sm8650.c index b962e6c233ef78ed3ed44cf0b0777bb62fbd50a6..20ac5bc5e1fbafe74800ad6f22839bac006ca7db 100644 --- a/drivers/interconnect/qcom/sm8650.c +++ b/drivers/interconnect/qcom/sm8650.c @@ -1650,7 +1650,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-sm8650", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/qcom/smd-rpm.c b/drivers/interconnect/qcom/smd-rpm.c index 3816bfb4e2f39eaa31a5322146d28ba4fd604f1f..8316c87a2c60f5f99edece3443cc60e9e75fa11f 100644 --- a/drivers/interconnect/qcom/smd-rpm.c +++ b/drivers/interconnect/qcom/smd-rpm.c @@ -85,7 +85,7 @@ static struct platform_driver qcom_interconnect_rpm_smd_driver = { .name = "icc_smd_rpm", }, .probe = qcom_icc_rpm_smd_probe, - .remove_new = qcom_icc_rpm_smd_remove, + .remove = qcom_icc_rpm_smd_remove, }; module_platform_driver(qcom_interconnect_rpm_smd_driver); MODULE_AUTHOR("Georgi Djakov "); diff --git a/drivers/interconnect/qcom/x1e80100.c b/drivers/interconnect/qcom/x1e80100.c index 654abb9ce08eedaa06dbe12945cc42d45e0844b0..2c46fdb4a0543f8345e03dbfe83d3a7ab95bd17c 100644 --- a/drivers/interconnect/qcom/x1e80100.c +++ b/drivers/interconnect/qcom/x1e80100.c @@ -1964,7 +1964,7 @@ MODULE_DEVICE_TABLE(of, qnoc_of_match); static struct platform_driver qnoc_driver = { .probe = qcom_icc_rpmh_probe, - .remove_new = qcom_icc_rpmh_remove, + .remove = qcom_icc_rpmh_remove, .driver = { .name = "qnoc-x1e80100", .of_match_table = qnoc_of_match, diff --git a/drivers/interconnect/samsung/exynos.c b/drivers/interconnect/samsung/exynos.c index c9e5361e17c5b03c2c250e601d6ee6a63c88064e..9e041365d9091be35f2bed1c7557ca60d7dba5ca 100644 --- a/drivers/interconnect/samsung/exynos.c +++ b/drivers/interconnect/samsung/exynos.c @@ -180,7 +180,7 @@ static struct platform_driver exynos_generic_icc_driver = { .sync_state = icc_sync_state, }, .probe = exynos_generic_icc_probe, - .remove_new = exynos_generic_icc_remove, + .remove = exynos_generic_icc_remove, }; module_platform_driver(exynos_generic_icc_driver); diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index eb1e62cd499a580d5ef0ea494e9d986d48e1ed3b..95ba3caeb40177901086076416874b9905a1f40a 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -1352,7 +1352,7 @@ static struct platform_driver apple_dart_driver = { .pm = pm_sleep_ptr(&apple_dart_pm_ops), }, .probe = apple_dart_probe, - .remove_new = apple_dart_remove, + .remove = apple_dart_remove, }; module_platform_driver(apple_dart_driver); diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c index 6cc14d82399fa2666bd5374bb7d565171f6ce7ac..c7cc613050d933d76ebced5d556466da165571c2 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c @@ -398,4 +398,4 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev, return &vsmmu->core; } -MODULE_IMPORT_NS(IOMMUFD); +MODULE_IMPORT_NS("IOMMUFD"); diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c index 84baa021370a86efb5f7b3e496b1be02e8ddcb2c..d2671bfd37981b363bafd50a2ddc811b7f7d6187 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c @@ -607,6 +607,6 @@ static struct kunit_suite arm_smmu_v3_test_module = { }; kunit_test_suites(&arm_smmu_v3_test_module); -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); MODULE_DESCRIPTION("KUnit tests for arm-smmu-v3 driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index e4ebd9e12ad468f132ed3646128c6b9ba2c98561..a5c7002ff75bb0ce377e60faa29ae1c6d01fb18e 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -4729,7 +4729,7 @@ static struct platform_driver arm_smmu_driver = { .suppress_bind_attrs = true, }, .probe = arm_smmu_device_probe, - .remove_new = arm_smmu_device_remove, + .remove = arm_smmu_device_remove, .shutdown = arm_smmu_device_shutdown, }; module_driver(arm_smmu_driver, platform_driver_register, diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index ade4684c14c9b2724a71e2457288dbfaf7562c83..650664e0f6e3ff4cf8a2bf212af8cff14470367a 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -2367,7 +2367,7 @@ static struct platform_driver arm_smmu_driver = { .suppress_bind_attrs = true, }, .probe = arm_smmu_device_probe, - .remove_new = arm_smmu_device_remove, + .remove = arm_smmu_device_remove, .shutdown = arm_smmu_device_shutdown, }; module_platform_driver(arm_smmu_driver); diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index b98a7a598b89739daedaa218b0f63e0ff707ec77..3907924646a20cf983ad7804a190123c74453376 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -759,7 +759,7 @@ static struct platform_driver qcom_iommu_ctx_driver = { .of_match_table = ctx_of_match, }, .probe = qcom_iommu_ctx_probe, - .remove_new = qcom_iommu_ctx_remove, + .remove = qcom_iommu_ctx_remove, }; static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu) @@ -931,7 +931,7 @@ static struct platform_driver qcom_iommu_driver = { .pm = &qcom_iommu_pm_ops, }, .probe = qcom_iommu_device_probe, - .remove_new = qcom_iommu_device_remove, + .remove = qcom_iommu_device_remove, }; static int __init qcom_iommu_init(void) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 9bc0c74cca3c7e8f93b8ab2a27f164384e104a77..599030e1e890ba6f0fa273ddd24fd3c9b2d1de44 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2211,7 +2211,7 @@ int iommu_group_replace_domain(struct iommu_group *group, mutex_unlock(&group->mutex); return ret; } -EXPORT_SYMBOL_NS_GPL(iommu_group_replace_domain, IOMMUFD_INTERNAL); +EXPORT_SYMBOL_NS_GPL(iommu_group_replace_domain, "IOMMUFD_INTERNAL"); static int __iommu_device_set_domain(struct iommu_group *group, struct device *dev, @@ -3482,7 +3482,7 @@ iommu_attach_handle_get(struct iommu_group *group, ioasid_t pasid, unsigned int return handle; } -EXPORT_SYMBOL_NS_GPL(iommu_attach_handle_get, IOMMUFD_INTERNAL); +EXPORT_SYMBOL_NS_GPL(iommu_attach_handle_get, "IOMMUFD_INTERNAL"); /** * iommu_attach_group_handle - Attach an IOMMU domain to an IOMMU group @@ -3522,7 +3522,7 @@ err_unlock: mutex_unlock(&group->mutex); return ret; } -EXPORT_SYMBOL_NS_GPL(iommu_attach_group_handle, IOMMUFD_INTERNAL); +EXPORT_SYMBOL_NS_GPL(iommu_attach_group_handle, "IOMMUFD_INTERNAL"); /** * iommu_detach_group_handle - Detach an IOMMU domain from an IOMMU group @@ -3540,7 +3540,7 @@ void iommu_detach_group_handle(struct iommu_domain *domain, xa_erase(&group->pasid_array, IOMMU_NO_PASID); mutex_unlock(&group->mutex); } -EXPORT_SYMBOL_NS_GPL(iommu_detach_group_handle, IOMMUFD_INTERNAL); +EXPORT_SYMBOL_NS_GPL(iommu_detach_group_handle, "IOMMUFD_INTERNAL"); /** * iommu_replace_group_handle - replace the domain that a group is attached to @@ -3586,4 +3586,4 @@ err_unlock: mutex_unlock(&group->mutex); return ret; } -EXPORT_SYMBOL_NS_GPL(iommu_replace_group_handle, IOMMUFD_INTERNAL); +EXPORT_SYMBOL_NS_GPL(iommu_replace_group_handle, "IOMMUFD_INTERNAL"); diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 5fd3dd42029015ffd158b9f82971eb2cb870b7e0..dfd0898fb6c157312c0406c883c60b8dae7ba117 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -233,7 +233,7 @@ out_group_put: iommufd_put_group(igroup); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(iommufd_device_bind, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_device_bind, "IOMMUFD"); /** * iommufd_ctx_has_group - True if any device within the group is bound @@ -264,7 +264,7 @@ bool iommufd_ctx_has_group(struct iommufd_ctx *ictx, struct iommu_group *group) xa_unlock(&ictx->objects); return false; } -EXPORT_SYMBOL_NS_GPL(iommufd_ctx_has_group, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_ctx_has_group, "IOMMUFD"); /** * iommufd_device_unbind - Undo iommufd_device_bind() @@ -279,19 +279,19 @@ void iommufd_device_unbind(struct iommufd_device *idev) { iommufd_object_destroy_user(idev->ictx, &idev->obj); } -EXPORT_SYMBOL_NS_GPL(iommufd_device_unbind, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_device_unbind, "IOMMUFD"); struct iommufd_ctx *iommufd_device_to_ictx(struct iommufd_device *idev) { return idev->ictx; } -EXPORT_SYMBOL_NS_GPL(iommufd_device_to_ictx, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_device_to_ictx, "IOMMUFD"); u32 iommufd_device_to_id(struct iommufd_device *idev) { return idev->obj.id; } -EXPORT_SYMBOL_NS_GPL(iommufd_device_to_id, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_device_to_id, "IOMMUFD"); static int iommufd_group_setup_msi(struct iommufd_group *igroup, struct iommufd_hwpt_paging *hwpt_paging) @@ -692,7 +692,7 @@ int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id) refcount_inc(&idev->obj.users); return 0; } -EXPORT_SYMBOL_NS_GPL(iommufd_device_attach, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_device_attach, "IOMMUFD"); /** * iommufd_device_replace - Change the device's iommu_domain @@ -714,7 +714,7 @@ int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id) return iommufd_device_change_pt(idev, pt_id, &iommufd_device_do_replace); } -EXPORT_SYMBOL_NS_GPL(iommufd_device_replace, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_device_replace, "IOMMUFD"); /** * iommufd_device_detach - Disconnect a device to an iommu_domain @@ -731,7 +731,7 @@ void iommufd_device_detach(struct iommufd_device *idev) iommufd_hw_pagetable_put(idev->ictx, hwpt); refcount_dec(&idev->obj.users); } -EXPORT_SYMBOL_NS_GPL(iommufd_device_detach, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_device_detach, "IOMMUFD"); /* * On success, it will refcount_inc() at a valid new_ioas and refcount_dec() at @@ -853,7 +853,7 @@ iommufd_access_create(struct iommufd_ctx *ictx, mutex_init(&access->ioas_lock); return access; } -EXPORT_SYMBOL_NS_GPL(iommufd_access_create, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_create, "IOMMUFD"); /** * iommufd_access_destroy - Destroy an iommufd_access @@ -865,7 +865,7 @@ void iommufd_access_destroy(struct iommufd_access *access) { iommufd_object_destroy_user(access->ictx, &access->obj); } -EXPORT_SYMBOL_NS_GPL(iommufd_access_destroy, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_destroy, "IOMMUFD"); void iommufd_access_detach(struct iommufd_access *access) { @@ -877,7 +877,7 @@ void iommufd_access_detach(struct iommufd_access *access) WARN_ON(iommufd_access_change_ioas(access, NULL)); mutex_unlock(&access->ioas_lock); } -EXPORT_SYMBOL_NS_GPL(iommufd_access_detach, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_detach, "IOMMUFD"); int iommufd_access_attach(struct iommufd_access *access, u32 ioas_id) { @@ -893,7 +893,7 @@ int iommufd_access_attach(struct iommufd_access *access, u32 ioas_id) mutex_unlock(&access->ioas_lock); return rc; } -EXPORT_SYMBOL_NS_GPL(iommufd_access_attach, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_attach, "IOMMUFD"); int iommufd_access_replace(struct iommufd_access *access, u32 ioas_id) { @@ -908,7 +908,7 @@ int iommufd_access_replace(struct iommufd_access *access, u32 ioas_id) mutex_unlock(&access->ioas_lock); return rc; } -EXPORT_SYMBOL_NS_GPL(iommufd_access_replace, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_replace, "IOMMUFD"); /** * iommufd_access_notify_unmap - Notify users of an iopt to stop using it @@ -991,7 +991,7 @@ void iommufd_access_unpin_pages(struct iommufd_access *access, up_read(&iopt->iova_rwsem); mutex_unlock(&access->ioas_lock); } -EXPORT_SYMBOL_NS_GPL(iommufd_access_unpin_pages, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_unpin_pages, "IOMMUFD"); static bool iopt_area_contig_is_aligned(struct iopt_area_contig_iter *iter) { @@ -1106,7 +1106,7 @@ err_remove: mutex_unlock(&access->ioas_lock); return rc; } -EXPORT_SYMBOL_NS_GPL(iommufd_access_pin_pages, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_pin_pages, "IOMMUFD"); /** * iommufd_access_rw - Read or write data under the iova @@ -1170,7 +1170,7 @@ err_out: mutex_unlock(&access->ioas_lock); return rc; } -EXPORT_SYMBOL_NS_GPL(iommufd_access_rw, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_access_rw, "IOMMUFD"); int iommufd_get_hw_info(struct iommufd_ucmd *ucmd) { diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c index 7b67fdf44134c51461ab025317b0545a9128133d..2d98b04ff1cb7edd382064f1bcedd10afe0a5b77 100644 --- a/drivers/iommu/iommufd/driver.c +++ b/drivers/iommu/iommufd/driver.c @@ -34,7 +34,7 @@ out_free: kfree(obj); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(_iommufd_object_alloc, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(_iommufd_object_alloc, "IOMMUFD"); /* Caller should xa_lock(&viommu->vdevs) to protect the return value */ struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu, @@ -47,7 +47,7 @@ struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu, vdev = xa_load(&viommu->vdevs, vdev_id); return vdev ? vdev->dev : NULL; } -EXPORT_SYMBOL_NS_GPL(iommufd_viommu_find_dev, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_viommu_find_dev, "IOMMUFD"); MODULE_DESCRIPTION("iommufd code shared with builtin modules"); MODULE_LICENSE("GPL"); diff --git a/drivers/iommu/iommufd/iova_bitmap.c b/drivers/iommu/iommufd/iova_bitmap.c index d90b9e253412ff84c24f42bf4ae3761a814aa3de..ab665cf38ef4a9b8af98acaf51d16e99e3d63607 100644 --- a/drivers/iommu/iommufd/iova_bitmap.c +++ b/drivers/iommu/iommufd/iova_bitmap.c @@ -272,7 +272,7 @@ err: iova_bitmap_free(bitmap); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(iova_bitmap_alloc, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iova_bitmap_alloc, "IOMMUFD"); /** * iova_bitmap_free() - Frees an IOVA bitmap object @@ -294,7 +294,7 @@ void iova_bitmap_free(struct iova_bitmap *bitmap) kfree(bitmap); } -EXPORT_SYMBOL_NS_GPL(iova_bitmap_free, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iova_bitmap_free, "IOMMUFD"); /* * Returns the remaining bitmap indexes from mapped_total_index to process for @@ -387,7 +387,7 @@ int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque, { return fn(bitmap, bitmap->iova, bitmap->length, opaque); } -EXPORT_SYMBOL_NS_GPL(iova_bitmap_for_each, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iova_bitmap_for_each, "IOMMUFD"); /** * iova_bitmap_set() - Records an IOVA range in bitmap @@ -445,4 +445,4 @@ update_indexes: cur_bit += nbits; } while (cur_bit <= last_bit); } -EXPORT_SYMBOL_NS_GPL(iova_bitmap_set, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iova_bitmap_set, "IOMMUFD"); diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 0a96cc8f27dacd6a76f0ad7f0565c37c53e64029..97c5e3567d33e453dea87f85ba42da7f3ad41cf5 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -427,7 +427,7 @@ void iommufd_ctx_get(struct iommufd_ctx *ictx) { get_file(ictx->file); } -EXPORT_SYMBOL_NS_GPL(iommufd_ctx_get, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_ctx_get, "IOMMUFD"); /** * iommufd_ctx_from_file - Acquires a reference to the iommufd context @@ -447,7 +447,7 @@ struct iommufd_ctx *iommufd_ctx_from_file(struct file *file) iommufd_ctx_get(ictx); return ictx; } -EXPORT_SYMBOL_NS_GPL(iommufd_ctx_from_file, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_ctx_from_file, "IOMMUFD"); /** * iommufd_ctx_from_fd - Acquires a reference to the iommufd context @@ -471,7 +471,7 @@ struct iommufd_ctx *iommufd_ctx_from_fd(int fd) /* fget is the same as iommufd_ctx_get() */ return file->private_data; } -EXPORT_SYMBOL_NS_GPL(iommufd_ctx_from_fd, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_ctx_from_fd, "IOMMUFD"); /** * iommufd_ctx_put - Put back a reference @@ -481,7 +481,7 @@ void iommufd_ctx_put(struct iommufd_ctx *ictx) { fput(ictx->file); } -EXPORT_SYMBOL_NS_GPL(iommufd_ctx_put, IOMMUFD); +EXPORT_SYMBOL_NS_GPL(iommufd_ctx_put, "IOMMUFD"); static const struct iommufd_object_ops iommufd_object_ops[] = { [IOMMUFD_OBJ_ACCESS] = { @@ -575,7 +575,7 @@ module_exit(iommufd_exit); MODULE_ALIAS_MISCDEV(VFIO_MINOR); MODULE_ALIAS("devname:vfio/vfio"); #endif -MODULE_IMPORT_NS(IOMMUFD_INTERNAL); -MODULE_IMPORT_NS(IOMMUFD); +MODULE_IMPORT_NS("IOMMUFD_INTERNAL"); +MODULE_IMPORT_NS("IOMMUFD"); MODULE_DESCRIPTION("I/O Address Space Management for passthrough devices"); MODULE_LICENSE("GPL"); diff --git a/drivers/iommu/iommufd/vfio_compat.c b/drivers/iommu/iommufd/vfio_compat.c index 514aacd6400949d673236c11f5c425415df69675..a258ee2f4579f523a816af298a565e4f819746f3 100644 --- a/drivers/iommu/iommufd/vfio_compat.c +++ b/drivers/iommu/iommufd/vfio_compat.c @@ -44,7 +44,7 @@ int iommufd_vfio_compat_ioas_get_id(struct iommufd_ctx *ictx, u32 *out_ioas_id) iommufd_put_object(ictx, &ioas->obj); return 0; } -EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_ioas_get_id, IOMMUFD_VFIO); +EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_ioas_get_id, "IOMMUFD_VFIO"); /** * iommufd_vfio_compat_set_no_iommu - Called when a no-iommu device is attached @@ -66,7 +66,7 @@ int iommufd_vfio_compat_set_no_iommu(struct iommufd_ctx *ictx) xa_unlock(&ictx->objects); return ret; } -EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_set_no_iommu, IOMMUFD_VFIO); +EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_set_no_iommu, "IOMMUFD_VFIO"); /** * iommufd_vfio_compat_ioas_create - Ensure the compat IOAS is created @@ -118,7 +118,7 @@ out_abort: iommufd_object_abort(ictx, &ioas->obj); return ret; } -EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_ioas_create, IOMMUFD_VFIO); +EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_ioas_create, "IOMMUFD_VFIO"); int iommufd_vfio_ioas(struct iommufd_ucmd *ucmd) { diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index ff55b8c307126945d5583241d20ed2ba4597842a..074daf1aac4e4c0c0f7df8e9c59b64b4f63d03c6 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -1159,6 +1159,6 @@ static struct platform_driver ipmmu_driver = { .pm = pm_sleep_ptr(&ipmmu_pm), }, .probe = ipmmu_probe, - .remove_new = ipmmu_remove, + .remove = ipmmu_remove, }; builtin_platform_driver(ipmmu_driver); diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 989e0869d80554ba9b462fac95bcf39b600a1b7a..ce40f0a419ea093ee9b8ae6ff421656f96f6d49b 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -838,6 +838,6 @@ static struct platform_driver msm_iommu_driver = { .of_match_table = msm_iommu_dt_match, }, .probe = msm_iommu_probe, - .remove_new = msm_iommu_remove, + .remove = msm_iommu_remove, }; builtin_platform_driver(msm_iommu_driver); diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index c45313c43b9ec9454506985ed4c423ee7f3cec2f..ab60901f8f92881974352174bc5d4e452219ed2e 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -1794,7 +1794,7 @@ MODULE_DEVICE_TABLE(of, mtk_iommu_of_ids); static struct platform_driver mtk_iommu_driver = { .probe = mtk_iommu_probe, - .remove_new = mtk_iommu_remove, + .remove = mtk_iommu_remove, .driver = { .name = "mtk-iommu", .of_match_table = mtk_iommu_of_ids, diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index ee4e55b6b1900308bd06961d71269953e36e1e51..b6de1ca00cefa3eaf77b968b4c86d398bc890689 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -745,7 +745,7 @@ static const struct dev_pm_ops mtk_iommu_v1_pm_ops = { static struct platform_driver mtk_iommu_v1_driver = { .probe = mtk_iommu_v1_probe, - .remove_new = mtk_iommu_v1_remove, + .remove = mtk_iommu_v1_remove, .driver = { .name = "mtk-iommu-v1", .of_match_table = mtk_iommu_v1_of_ids, diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 3f72aef8bd5bc9690f86327128d0f934685acf84..3c62337f43c67720a15b67e8b610da7886f6f39c 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1285,7 +1285,7 @@ static const struct of_device_id omap_iommu_of_match[] = { static struct platform_driver omap_iommu_driver = { .probe = omap_iommu_probe, - .remove_new = omap_iommu_remove, + .remove = omap_iommu_remove, .driver = { .name = "omap-iommu", .pm = &omap_iommu_pm_ops, diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c index da336863f152f7383bda6f2e155edbb8bb8c25ee..382ba28418498eb048180f790e2fe9c548f6fdec 100644 --- a/drivers/iommu/riscv/iommu-platform.c +++ b/drivers/iommu/riscv/iommu-platform.c @@ -81,7 +81,7 @@ static const struct of_device_id riscv_iommu_of_match[] = { static struct platform_driver riscv_iommu_platform_driver = { .probe = riscv_iommu_platform_probe, - .remove_new = riscv_iommu_platform_remove, + .remove = riscv_iommu_platform_remove, .driver = { .name = "riscv,iommu", .of_match_table = riscv_iommu_of_match, diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c index a2f4ffe6d9491c1e495439cd031592dacbdaef1b..941d1f361c8cda5a9175f073d77cbacdd60f4146 100644 --- a/drivers/iommu/sprd-iommu.c +++ b/drivers/iommu/sprd-iommu.c @@ -531,7 +531,7 @@ static struct platform_driver sprd_iommu_driver = { .suppress_bind_attrs = true, }, .probe = sprd_iommu_probe, - .remove_new = sprd_iommu_remove, + .remove = sprd_iommu_remove, }; module_platform_driver(sprd_iommu_driver); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 16acce0f102d49015272e1abeb0fa831d9e8e465..92244cfa04647b48ea4521cc6cb9304b1a7e27b4 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -47,6 +47,7 @@ #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) #define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3) +#define ITS_FLAGS_WORKAROUND_HISILICON_162100801 (1ULL << 4) #define RD_LOCAL_LPI_ENABLED BIT(0) #define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1) @@ -64,6 +65,7 @@ static u32 lpi_id_bits; #define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K) static u8 __ro_after_init lpi_prop_prio; +static struct its_node *find_4_1_its(void); /* * Collection structure - just an ID, and a redistributor address to @@ -3883,6 +3885,20 @@ static void its_vpe_db_proxy_move(struct its_vpe *vpe, int from, int to) raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags); } +static void its_vpe_4_1_invall_locked(int cpu, struct its_vpe *vpe) +{ + void __iomem *rdbase; + u64 val; + + val = GICR_INVALLR_V; + val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id); + + guard(raw_spinlock)(&gic_data_rdist_cpu(cpu)->rd_lock); + rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; + gic_write_lpir(val, rdbase + GICR_INVALLR); + wait_for_syncr(rdbase); +} + static int its_vpe_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) @@ -3890,6 +3906,7 @@ static int its_vpe_set_affinity(struct irq_data *d, struct its_vpe *vpe = irq_data_get_irq_chip_data(d); unsigned int from, cpu = nr_cpu_ids; struct cpumask *table_mask; + struct its_node *its; unsigned long flags; /* @@ -3952,6 +3969,11 @@ static int its_vpe_set_affinity(struct irq_data *d, vpe->col_idx = cpu; its_send_vmovp(vpe); + + its = find_4_1_its(); + if (its && its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100801) + its_vpe_4_1_invall_locked(cpu, vpe); + its_vpe_db_proxy_move(vpe, from, cpu); out: @@ -4259,22 +4281,12 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe, static void its_vpe_4_1_invall(struct its_vpe *vpe) { - void __iomem *rdbase; unsigned long flags; - u64 val; int cpu; - val = GICR_INVALLR_V; - val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id); - /* Target the redistributor this vPE is currently known on */ cpu = vpe_to_cpuid_lock(vpe, &flags); - raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); - rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; - gic_write_lpir(val, rdbase + GICR_INVALLR); - - wait_for_syncr(rdbase); - raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); + its_vpe_4_1_invall_locked(cpu, vpe); vpe_to_cpuid_unlock(vpe, flags); } @@ -4867,6 +4879,14 @@ static bool its_set_non_coherent(void *data) return true; } +static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data) +{ + struct its_node *its = data; + + its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801; + return true; +} + static const struct gic_quirk its_quirks[] = { #ifdef CONFIG_CAVIUM_ERRATUM_22375 { @@ -4913,6 +4933,14 @@ static const struct gic_quirk its_quirks[] = { .init = its_enable_quirk_hip07_161600802, }, #endif +#ifdef CONFIG_HISILICON_ERRATUM_162100801 + { + .desc = "ITS: Hip09 erratum 162100801", + .iidr = 0x00051736, + .mask = 0xffffffff, + .init = its_enable_quirk_hip09_162100801, + }, +#endif #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001 { .desc = "ITS: Rockchip erratum RK3588001", diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 3be7bd8cd8cdeb6d03a0f03bd99235375c1dadf0..8fae6dc010241e10b9eef9bec40b1661e4e9e698 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -400,7 +400,7 @@ static void gic_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gic_chip_data *gic = irq_data_get_irq_chip_data(d); if (gic->domain->pm_dev) - seq_printf(p, gic->domain->pm_dev->of_node->name); + seq_puts(p, gic->domain->pm_dev->of_node->name); else seq_printf(p, "GIC-%d", (int)(gic - &gic_data[0])); } diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c index b42ed68acfa66767e73b063705e031dfd6883fdb..85f80bac096159c8de66db9776dab79b740c8745 100644 --- a/drivers/irqchip/irq-imgpdc.c +++ b/drivers/irqchip/irq-imgpdc.c @@ -479,7 +479,7 @@ static struct platform_driver pdc_intc_driver = { .of_match_table = pdc_intc_match, }, .probe = pdc_intc_probe, - .remove_new = pdc_intc_remove, + .remove = pdc_intc_remove, }; static int __init pdc_intc_init(void) diff --git a/drivers/irqchip/irq-imx-intmux.c b/drivers/irqchip/irq-imx-intmux.c index 511adfaeec8227f018a07c1d8fb472c86323bf3c..787543d07565be3a97c22aeedbe0557ce470ad6c 100644 --- a/drivers/irqchip/irq-imx-intmux.c +++ b/drivers/irqchip/irq-imx-intmux.c @@ -361,6 +361,6 @@ static struct platform_driver imx_intmux_driver = { .pm = &imx_intmux_pm_ops, }, .probe = imx_intmux_probe, - .remove_new = imx_intmux_remove, + .remove = imx_intmux_remove, }; builtin_platform_driver(imx_intmux_driver); diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c index 75a0e980ff352493e6b638b3073149374f7b5c34..b0e9788c0045488842b4239f73bc24e786eb1982 100644 --- a/drivers/irqchip/irq-imx-irqsteer.c +++ b/drivers/irqchip/irq-imx-irqsteer.c @@ -328,6 +328,6 @@ static struct platform_driver imx_irqsteer_driver = { .pm = &imx_irqsteer_pm_ops, }, .probe = imx_irqsteer_probe, - .remove_new = imx_irqsteer_remove, + .remove = imx_irqsteer_remove, }; builtin_platform_driver(imx_irqsteer_driver); diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c index 30f1979fa1240a3d8d7642fb60e34025d10bf138..808c781e254835161813eb09a4ac3498ee6f334c 100644 --- a/drivers/irqchip/irq-keystone.c +++ b/drivers/irqchip/irq-keystone.c @@ -211,7 +211,7 @@ MODULE_DEVICE_TABLE(of, keystone_irq_dt_ids); static struct platform_driver keystone_irq_device_driver = { .probe = keystone_irq_probe, - .remove_new = keystone_irq_remove, + .remove = keystone_irq_remove, .driver = { .name = "keystone_irq", .of_match_table = of_match_ptr(keystone_irq_dt_ids), diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c index 1aef5c4d27c63130648093e24bdb8f89cda75aef..c0e1aafe468c321f30b680f6556e1597f49077fc 100644 --- a/drivers/irqchip/irq-ls-scfg-msi.c +++ b/drivers/irqchip/irq-ls-scfg-msi.c @@ -418,7 +418,7 @@ static struct platform_driver ls_scfg_msi_driver = { .of_match_table = ls_scfg_msi_id, }, .probe = ls_scfg_msi_probe, - .remove_new = ls_scfg_msi_remove, + .remove = ls_scfg_msi_remove, }; module_platform_driver(ls_scfg_msi_driver); diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c index acceb6e7fa95f5af6e1c76065a43701e225f7922..b32982c11515ff4b02c489e56fe6addaf357a01b 100644 --- a/drivers/irqchip/irq-madera.c +++ b/drivers/irqchip/irq-madera.c @@ -236,7 +236,7 @@ static void madera_irq_remove(struct platform_device *pdev) static struct platform_driver madera_irq_driver = { .probe = madera_irq_probe, - .remove_new = madera_irq_remove, + .remove = madera_irq_remove, .driver = { .name = "madera-irq", .pm = &madera_irq_pm_ops, diff --git a/drivers/irqchip/irq-mvebu-pic.c b/drivers/irqchip/irq-mvebu-pic.c index 08b0cc862adf03eccab646ac62bf26d4e3ec941b..3888b7585981466ca4059c5ceb5d7e269b08ad28 100644 --- a/drivers/irqchip/irq-mvebu-pic.c +++ b/drivers/irqchip/irq-mvebu-pic.c @@ -71,7 +71,7 @@ static void mvebu_pic_print_chip(struct irq_data *d, struct seq_file *p) { struct mvebu_pic *pic = irq_data_get_irq_chip_data(d); - seq_printf(p, dev_name(&pic->pdev->dev)); + seq_puts(p, dev_name(&pic->pdev->dev)); } static const struct irq_chip mvebu_pic_chip = { @@ -183,7 +183,7 @@ MODULE_DEVICE_TABLE(of, mvebu_pic_of_match); static struct platform_driver mvebu_pic_driver = { .probe = mvebu_pic_probe, - .remove_new = mvebu_pic_remove, + .remove = mvebu_pic_remove, .driver = { .name = "mvebu-pic", .of_match_table = mvebu_pic_of_match, diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c index f8c70f2d100a110cff3a6e2bc5cea3646747eb1c..065166ab5dbc044bb2f61248b069b0b0c183a886 100644 --- a/drivers/irqchip/irq-mvebu-sei.c +++ b/drivers/irqchip/irq-mvebu-sei.c @@ -192,7 +192,6 @@ static void mvebu_sei_domain_free(struct irq_domain *domain, unsigned int virq, } static const struct irq_domain_ops mvebu_sei_domain_ops = { - .select = msi_lib_irq_domain_select, .alloc = mvebu_sei_domain_alloc, .free = mvebu_sei_domain_free, }; @@ -306,6 +305,7 @@ static void mvebu_sei_cp_domain_free(struct irq_domain *domain, } static const struct irq_domain_ops mvebu_sei_cp_domain_ops = { + .select = msi_lib_irq_domain_select, .alloc = mvebu_sei_cp_domain_alloc, .free = mvebu_sei_cp_domain_free, }; diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 060eb000e9d359ec54d59f4a31ad6b7be44dd8c3..bee01980b4630c2c4ac03be4c65f91fe084fd4af 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -648,7 +648,7 @@ static struct platform_driver pruss_intc_driver = { .suppress_bind_attrs = true, }, .probe = pruss_intc_probe, - .remove_new = pruss_intc_remove, + .remove = pruss_intc_remove, }; module_platform_driver(pruss_intc_driver); diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 9ad37237ba9547d235a41bfd5ed2201a2b34c5e8..954419f2460d1180b2484a337539d9c53e4aeaba 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -584,7 +584,7 @@ static SIMPLE_DEV_PM_OPS(intc_irqpin_pm_ops, intc_irqpin_suspend, NULL); static struct platform_driver intc_irqpin_device_driver = { .probe = intc_irqpin_probe, - .remove_new = intc_irqpin_remove, + .remove = intc_irqpin_remove, .driver = { .name = "renesas_intc_irqpin", .of_match_table = intc_irqpin_dt_ids, diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 76026e0b8e2010649889b0285463d0219dbf8b01..cbce8ffc7de4aae0721bc9cea18766d072a8ddb4 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c @@ -247,7 +247,7 @@ MODULE_DEVICE_TABLE(of, irqc_dt_ids); static struct platform_driver irqc_device_driver = { .probe = irqc_probe, - .remove_new = irqc_remove, + .remove = irqc_remove, .driver = { .name = "renesas_irqc", .of_match_table = irqc_dt_ids, diff --git a/drivers/irqchip/irq-renesas-rza1.c b/drivers/irqchip/irq-renesas-rza1.c index f05afe82db4d1ddd1a4ec0f2de251fd5878b0651..d4e6a68889ec1c02d3d6729f499064b4fba51d29 100644 --- a/drivers/irqchip/irq-renesas-rza1.c +++ b/drivers/irqchip/irq-renesas-rza1.c @@ -259,7 +259,7 @@ MODULE_DEVICE_TABLE(of, rza1_irqc_dt_ids); static struct platform_driver rza1_irqc_device_driver = { .probe = rza1_irqc_probe, - .remove_new = rza1_irqc_remove, + .remove = rza1_irqc_remove, .driver = { .name = "renesas_rza1_irqc", .of_match_table = rza1_irqc_dt_ids, diff --git a/drivers/irqchip/irq-ts4800.c b/drivers/irqchip/irq-ts4800.c index b5dddb3c1568ea6c9f2da61ed4069c00c7f27249..cc219f28d317fed141d882fea637d6490c0ecc23 100644 --- a/drivers/irqchip/irq-ts4800.c +++ b/drivers/irqchip/irq-ts4800.c @@ -154,7 +154,7 @@ MODULE_DEVICE_TABLE(of, ts4800_ic_of_match); static struct platform_driver ts4800_ic_driver = { .probe = ts4800_ic_probe, - .remove_new = ts4800_ic_remove, + .remove = ts4800_ic_remove, .driver = { .name = "ts4800-irqc", .of_match_table = ts4800_ic_of_match, diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index ca471c6fee998b239f0ab32378b5bbfababf1b31..0abc8934c2ee00e4077c1dddb867141d4a008ea5 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -69,7 +69,7 @@ static void fpga_irq_print_chip(struct irq_data *d, struct seq_file *p) { struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); - seq_printf(p, irq_domain_get_of_node(f->domain)->name); + seq_puts(p, irq_domain_get_of_node(f->domain)->name); } static const struct irq_chip fpga_chip = { diff --git a/drivers/leds/flash/leds-ktd2692.c b/drivers/leds/flash/leds-ktd2692.c index 743830a10f99baceea139a9401f9d6264a533de2..0f16eefcfe4cd336cc3e7df6f7ae6a13694e0b5e 100644 --- a/drivers/leds/flash/leds-ktd2692.c +++ b/drivers/leds/flash/leds-ktd2692.c @@ -349,7 +349,7 @@ static struct platform_driver ktd2692_driver = { module_platform_driver(ktd2692_driver); -MODULE_IMPORT_NS(EXPRESSWIRE); +MODULE_IMPORT_NS("EXPRESSWIRE"); MODULE_AUTHOR("Ingi Kim "); MODULE_DESCRIPTION("Kinetic KTD2692 LED driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/leds/leds-expresswire.c b/drivers/leds/leds-expresswire.c index e4937a8e0f44174b6c6882e2e406dc2583d98765..bb69be228a6d3c7a8f2abc7fa75bd473d4c7c79c 100644 --- a/drivers/leds/leds-expresswire.c +++ b/drivers/leds/leds-expresswire.c @@ -18,7 +18,7 @@ void expresswire_power_off(struct expresswire_common_props *props) gpiod_set_value_cansleep(props->ctrl_gpio, 0); usleep_range(props->timing.poweroff_us, props->timing.poweroff_us * 2); } -EXPORT_SYMBOL_NS_GPL(expresswire_power_off, EXPRESSWIRE); +EXPORT_SYMBOL_NS_GPL(expresswire_power_off, "EXPRESSWIRE"); void expresswire_enable(struct expresswire_common_props *props) { @@ -28,14 +28,14 @@ void expresswire_enable(struct expresswire_common_props *props) udelay(props->timing.detect_us); gpiod_set_value(props->ctrl_gpio, 1); } -EXPORT_SYMBOL_NS_GPL(expresswire_enable, EXPRESSWIRE); +EXPORT_SYMBOL_NS_GPL(expresswire_enable, "EXPRESSWIRE"); void expresswire_start(struct expresswire_common_props *props) { gpiod_set_value(props->ctrl_gpio, 1); udelay(props->timing.data_start_us); } -EXPORT_SYMBOL_NS_GPL(expresswire_start, EXPRESSWIRE); +EXPORT_SYMBOL_NS_GPL(expresswire_start, "EXPRESSWIRE"); void expresswire_end(struct expresswire_common_props *props) { @@ -44,7 +44,7 @@ void expresswire_end(struct expresswire_common_props *props) gpiod_set_value(props->ctrl_gpio, 1); udelay(props->timing.end_of_data_high_us); } -EXPORT_SYMBOL_NS_GPL(expresswire_end, EXPRESSWIRE); +EXPORT_SYMBOL_NS_GPL(expresswire_end, "EXPRESSWIRE"); void expresswire_set_bit(struct expresswire_common_props *props, bool bit) { @@ -60,7 +60,7 @@ void expresswire_set_bit(struct expresswire_common_props *props, bool bit) udelay(props->timing.short_bitset_us); } } -EXPORT_SYMBOL_NS_GPL(expresswire_set_bit, EXPRESSWIRE); +EXPORT_SYMBOL_NS_GPL(expresswire_set_bit, "EXPRESSWIRE"); void expresswire_write_u8(struct expresswire_common_props *props, u8 val) { @@ -69,4 +69,4 @@ void expresswire_write_u8(struct expresswire_common_props *props, u8 val) expresswire_set_bit(props, val & BIT(i)); expresswire_end(props); } -EXPORT_SYMBOL_NS_GPL(expresswire_write_u8, EXPRESSWIRE); +EXPORT_SYMBOL_NS_GPL(expresswire_write_u8, "EXPRESSWIRE"); diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 2576a53f247eaa549b4bd212c27bc8a8f9ce1470..0b2e08a1bee0763468837db3997ff01f70a4faae 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -499,7 +499,7 @@ static struct platform_driver therm_of_driver = { .of_match_table = therm_of_match, }, .probe = therm_of_probe, - .remove_new = therm_of_remove, + .remove = therm_of_remove, }; struct apple_thermal_info { diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index 876b4d8cbe378ad609f3b64bc75eb70449bd9f19..5bd6d1ccf2460d434ab9414bbf5e0c008a7f0759 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -669,7 +669,7 @@ static void wf_pm112_remove(struct platform_device *dev) static struct platform_driver wf_pm112_driver = { .probe = wf_pm112_probe, - .remove_new = wf_pm112_remove, + .remove = wf_pm112_remove, .driver = { .name = "windfarm", }, diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c index cd45fbc4fe1cec25dd5c288ee58001fcccac56db..660180c843a3d76dc900181b2a963e50adddd669 100644 --- a/drivers/macintosh/windfarm_pm121.c +++ b/drivers/macintosh/windfarm_pm121.c @@ -999,7 +999,7 @@ static void pm121_remove(struct platform_device *ddev) static struct platform_driver pm121_driver = { .probe = pm121_probe, - .remove_new = pm121_remove, + .remove = pm121_remove, .driver = { .name = "windfarm", .bus = &platform_bus_type, diff --git a/drivers/macintosh/windfarm_pm72.c b/drivers/macintosh/windfarm_pm72.c index 14fa1e9ac3e00489ce2340f5f72405d50c1f1c94..10aa14074c3937a785934ea64a412296e1b8abcc 100644 --- a/drivers/macintosh/windfarm_pm72.c +++ b/drivers/macintosh/windfarm_pm72.c @@ -782,7 +782,7 @@ static void wf_pm72_remove(struct platform_device *dev) static struct platform_driver wf_pm72_driver = { .probe = wf_pm72_probe, - .remove_new = wf_pm72_remove, + .remove = wf_pm72_remove, .driver = { .name = "windfarm", }, diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index 404d2454e33de622c1926442aa9733d3d451bfca..ada97377e19ed417419ec03201e74f9ee19ef2a4 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -765,7 +765,7 @@ static void wf_smu_remove(struct platform_device *ddev) static struct platform_driver wf_smu_driver = { .probe = wf_smu_probe, - .remove_new = wf_smu_remove, + .remove = wf_smu_remove, .driver = { .name = "windfarm", }, diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index fba02a375435e40956fa6f6565f616dc0b20ff06..108d7938e714b293185ead03fd799a9028adc188 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -695,7 +695,7 @@ static void wf_smu_remove(struct platform_device *ddev) static struct platform_driver wf_smu_driver = { .probe = wf_smu_probe, - .remove_new = wf_smu_remove, + .remove = wf_smu_remove, .driver = { .name = "windfarm", }, diff --git a/drivers/macintosh/windfarm_rm31.c b/drivers/macintosh/windfarm_rm31.c index dc8f2c7ef10315edf556b1a461a0acfed463d884..44d86a4102380d1a8c27f6412f15012bce1bb5ab 100644 --- a/drivers/macintosh/windfarm_rm31.c +++ b/drivers/macintosh/windfarm_rm31.c @@ -675,7 +675,7 @@ static void wf_rm31_remove(struct platform_device *dev) static struct platform_driver wf_rm31_driver = { .probe = wf_rm31_probe, - .remove_new = wf_rm31_remove, + .remove = wf_rm31_remove, .driver = { .name = "windfarm", }, diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c index 6797770474a55d7dfe3ece61c3b97014a6e5b64f..680243751d625ff49cd16928a201d081332c9be4 100644 --- a/drivers/mailbox/omap-mailbox.c +++ b/drivers/mailbox/omap-mailbox.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c index 91bbd948ee93180b139f25e931a00bf9735c7a01..9b8c40a6459a7045c31431057c22da9da1e329e4 100644 --- a/drivers/mcb/mcb-core.c +++ b/drivers/mcb/mcb-core.c @@ -191,7 +191,7 @@ int __mcb_register_driver(struct mcb_driver *drv, struct module *owner, return driver_register(&drv->driver); } -EXPORT_SYMBOL_NS_GPL(__mcb_register_driver, MCB); +EXPORT_SYMBOL_NS_GPL(__mcb_register_driver, "MCB"); /** * mcb_unregister_driver() - Unregister a @mcb_driver from the system @@ -203,7 +203,7 @@ void mcb_unregister_driver(struct mcb_driver *drv) { driver_unregister(&drv->driver); } -EXPORT_SYMBOL_NS_GPL(mcb_unregister_driver, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_unregister_driver, "MCB"); static void mcb_release_dev(struct device *dev) { @@ -250,7 +250,7 @@ out: return ret; } -EXPORT_SYMBOL_NS_GPL(mcb_device_register, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_device_register, "MCB"); static void mcb_free_bus(struct device *dev) { @@ -303,7 +303,7 @@ err_put: put_device(&bus->dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(mcb_alloc_bus, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_alloc_bus, "MCB"); static int __mcb_devices_unregister(struct device *dev, void *data) { @@ -325,7 +325,7 @@ void mcb_release_bus(struct mcb_bus *bus) { mcb_devices_unregister(bus); } -EXPORT_SYMBOL_NS_GPL(mcb_release_bus, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_release_bus, "MCB"); /** * mcb_bus_get() - Increment refcnt @@ -340,7 +340,7 @@ struct mcb_bus *mcb_bus_get(struct mcb_bus *bus) return bus; } -EXPORT_SYMBOL_NS_GPL(mcb_bus_get, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_bus_get, "MCB"); /** * mcb_bus_put() - Decrement refcnt @@ -353,7 +353,7 @@ void mcb_bus_put(struct mcb_bus *bus) if (bus) put_device(&bus->dev); } -EXPORT_SYMBOL_NS_GPL(mcb_bus_put, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_bus_put, "MCB"); /** * mcb_alloc_dev() - Allocate a device @@ -373,7 +373,7 @@ struct mcb_device *mcb_alloc_dev(struct mcb_bus *bus) return dev; } -EXPORT_SYMBOL_NS_GPL(mcb_alloc_dev, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_alloc_dev, "MCB"); /** * mcb_free_dev() - Free @mcb_device @@ -385,7 +385,7 @@ void mcb_free_dev(struct mcb_device *dev) { kfree(dev); } -EXPORT_SYMBOL_NS_GPL(mcb_free_dev, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_free_dev, "MCB"); static int __mcb_bus_add_devices(struct device *dev, void *data) { @@ -410,7 +410,7 @@ void mcb_bus_add_devices(const struct mcb_bus *bus) { bus_for_each_dev(bus->dev.bus, NULL, NULL, __mcb_bus_add_devices); } -EXPORT_SYMBOL_NS_GPL(mcb_bus_add_devices, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_bus_add_devices, "MCB"); /** * mcb_get_resource() - get a resource for a mcb device @@ -426,7 +426,7 @@ struct resource *mcb_get_resource(struct mcb_device *dev, unsigned int type) else return NULL; } -EXPORT_SYMBOL_NS_GPL(mcb_get_resource, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_get_resource, "MCB"); /** * mcb_request_mem() - Request memory @@ -452,7 +452,7 @@ struct resource *mcb_request_mem(struct mcb_device *dev, const char *name) return mem; } -EXPORT_SYMBOL_NS_GPL(mcb_request_mem, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_request_mem, "MCB"); /** * mcb_release_mem() - Release memory requested by device @@ -467,7 +467,7 @@ void mcb_release_mem(struct resource *mem) size = resource_size(mem); release_mem_region(mem->start, size); } -EXPORT_SYMBOL_NS_GPL(mcb_release_mem, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_release_mem, "MCB"); static int __mcb_get_irq(struct mcb_device *dev) { @@ -493,7 +493,7 @@ int mcb_get_irq(struct mcb_device *dev) return __mcb_get_irq(dev); } -EXPORT_SYMBOL_NS_GPL(mcb_get_irq, MCB); +EXPORT_SYMBOL_NS_GPL(mcb_get_irq, "MCB"); static int mcb_init(void) { diff --git a/drivers/mcb/mcb-lpc.c b/drivers/mcb/mcb-lpc.c index 2bec2086ee1719c33b7563a408604e83e329a1f8..070aa787abc606c24a1f7c203c9866becb401f4b 100644 --- a/drivers/mcb/mcb-lpc.c +++ b/drivers/mcb/mcb-lpc.c @@ -138,7 +138,7 @@ static struct platform_driver mcb_lpc_driver = { .name = "mcb-lpc", }, .probe = mcb_lpc_probe, - .remove_new = mcb_lpc_remove, + .remove = mcb_lpc_remove, }; static const struct dmi_system_id mcb_lpc_dmi_table[] = { @@ -184,4 +184,4 @@ module_exit(mcb_lpc_exit); MODULE_AUTHOR("Andreas Werner "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MCB over LPC support"); -MODULE_IMPORT_NS(MCB); +MODULE_IMPORT_NS("MCB"); diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c index a5f8ab9a09103d128dec38b5a513ca437f9a275c..02a680c73979b933e6321823cd6666d7f0aff7d0 100644 --- a/drivers/mcb/mcb-parse.c +++ b/drivers/mcb/mcb-parse.c @@ -251,4 +251,4 @@ free_header: return ret; } -EXPORT_SYMBOL_NS_GPL(chameleon_parse_cells, MCB); +EXPORT_SYMBOL_NS_GPL(chameleon_parse_cells, "MCB"); diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c index 3b634ea318c741f92edd9b7313f7934e75e1a197..f1353da6ef4fc4dbd0b5ef53d28442a2c859207d 100644 --- a/drivers/mcb/mcb-pci.c +++ b/drivers/mcb/mcb-pci.c @@ -154,4 +154,4 @@ module_pci_driver(mcb_pci_driver); MODULE_AUTHOR("Johannes Thumshirn "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MCB over PCI support"); -MODULE_IMPORT_NS(MCB); +MODULE_IMPORT_NS("MCB"); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index baaf5f8b80ae1c10fc3b80f448f5f40240238b8e..7049ec7fb8eb4449b9e62db6410bf5e97fc6ec57 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -384,6 +384,7 @@ static int raid0_set_limits(struct mddev *mddev) lim.max_write_zeroes_sectors = mddev->chunk_sectors; lim.io_min = mddev->chunk_sectors << 9; lim.io_opt = lim.io_min * mddev->raid_disks; + lim.features |= BLK_FEAT_ATOMIC_WRITES_STACKED; err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY); if (err) { queue_limits_cancel_update(mddev->gendisk->queue); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a5adf08ee174199531575b9deb9f34577bbb72bc..519c56f0ee3d40e97cfd4343e43e81610bfeeb3c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1571,7 +1571,21 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, continue; } if (is_bad) { - int good_sectors = first_bad - r1_bio->sector; + int good_sectors; + + /* + * We cannot atomically write this, so just + * error in that case. It could be possible to + * atomically write other mirrors, but the + * complexity of supporting that is not worth + * the benefit. + */ + if (bio->bi_opf & REQ_ATOMIC) { + error = -EIO; + goto err_handle; + } + + good_sectors = first_bad - r1_bio->sector; if (good_sectors < max_sectors) max_sectors = good_sectors; } @@ -1657,7 +1671,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, mbio->bi_iter.bi_sector = (r1_bio->sector + rdev->data_offset); mbio->bi_end_io = raid1_end_write_request; - mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA)); + mbio->bi_opf = bio_op(bio) | + (bio->bi_opf & (REQ_SYNC | REQ_FUA | REQ_ATOMIC)); if (test_bit(FailFast, &rdev->flags) && !test_bit(WriteMostly, &rdev->flags) && conf->raid_disks - mddev->degraded > 1) @@ -3224,6 +3239,7 @@ static int raid1_set_limits(struct mddev *mddev) md_init_stacking_limits(&lim); lim.max_write_zeroes_sectors = 0; + lim.features |= BLK_FEAT_ATOMIC_WRITES_STACKED; err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY); if (err) { queue_limits_cancel_update(mddev->gendisk->queue); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 18989231791a0a68cb0e5eb7009104ac83190fa0..7d7a8a2524dcab91c7d84bb9af49d827fd370122 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1255,6 +1255,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio, const enum req_op op = bio_op(bio); const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC; const blk_opf_t do_fua = bio->bi_opf & REQ_FUA; + const blk_opf_t do_atomic = bio->bi_opf & REQ_ATOMIC; unsigned long flags; struct r10conf *conf = mddev->private; struct md_rdev *rdev; @@ -1273,7 +1274,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio, mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr + choose_data_offset(r10_bio, rdev)); mbio->bi_end_io = raid10_end_write_request; - mbio->bi_opf = op | do_sync | do_fua; + mbio->bi_opf = op | do_sync | do_fua | do_atomic; if (!replacement && test_bit(FailFast, &conf->mirrors[devnum].rdev->flags) && enough(conf, devnum)) @@ -1468,7 +1469,21 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, continue; } if (is_bad) { - int good_sectors = first_bad - dev_sector; + int good_sectors; + + /* + * We cannot atomically write this, so just + * error in that case. It could be possible to + * atomically write other mirrors, but the + * complexity of supporting that is not worth + * the benefit. + */ + if (bio->bi_opf & REQ_ATOMIC) { + error = -EIO; + goto err_handle; + } + + good_sectors = first_bad - dev_sector; if (good_sectors < max_sectors) max_sectors = good_sectors; } @@ -4025,6 +4040,7 @@ static int raid10_set_queue_limits(struct mddev *mddev) lim.max_write_zeroes_sectors = 0; lim.io_min = mddev->chunk_sectors << 9; lim.io_opt = lim.io_min * raid10_nr_stripes(conf); + lim.features |= BLK_FEAT_ATOMIC_WRITES_STACKED; err = mddev_stack_rdev_limits(mddev, &lim, MDDEV_STACK_INTEGRITY); if (err) { queue_limits_cancel_update(mddev->gendisk->queue); diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index c0cc441b51644ef4e4aa2263a22a649ed41b9805..2df566f409b65eb99fa7fbe308b8e3afe1bdcbca 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -3334,4 +3334,4 @@ EXPORT_SYMBOL_GPL(vb2_thread_stop); MODULE_DESCRIPTION("Media buffer core framework"); MODULE_AUTHOR("Pawel Osciak , Marek Szyprowski"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index bb0b7fa67b539aa73ad5ccf3c3bc318e26f8a4cb..a13ec569c82f6da2d977222b94af32e74c6c6c82 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -862,4 +862,4 @@ EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size); MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2"); MODULE_AUTHOR("Pawel Osciak "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index 6975a71d740f6d70c139eca739ae665d51007af2..c6ddf2357c58c12df336a35206bed242d10b9a30 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -676,4 +676,4 @@ EXPORT_SYMBOL_GPL(vb2_dma_sg_memops); MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2"); MODULE_AUTHOR("Andrzej Pietrasiewicz"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index 7d953706f3f8002f7463273aaf5a145e17339b96..3f777068cd34b74c13b8df7e251f581ef3c3e19c 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c @@ -442,4 +442,4 @@ EXPORT_SYMBOL_GPL(vb2_vmalloc_memops); MODULE_DESCRIPTION("vmalloc memory handling routines for videobuf2"); MODULE_AUTHOR("Pawel Osciak "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index 8eed4a200fd89b5af1fc4578cb865bf1408acd76..79bddfee2e2ec7e389478a5fc63ea9f19d09a30d 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -904,4 +904,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Texas Instruments DS90UB913 FPD-Link III Serializer Driver"); MODULE_AUTHOR("Luca Ceresoli "); MODULE_AUTHOR("Tomi Valkeinen "); -MODULE_IMPORT_NS(I2C_ATR); +MODULE_IMPORT_NS("I2C_ATR"); diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 8b028a84f5bc7fd2af5c95115dcb6a7c1dadc821..725589b3e1c58af72bb59dbfc06fc5041b7d7f11 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -1425,4 +1425,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Texas Instruments FPD-Link III/IV CSI-2 Serializers Driver"); MODULE_AUTHOR("Luca Ceresoli "); MODULE_AUTHOR("Tomi Valkeinen "); -MODULE_IMPORT_NS(I2C_ATR); +MODULE_IMPORT_NS("I2C_ATR"); diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 33f362a008757578e4c96e6ea7bed2e590776d8d..1b1ff7f7505b00949c2e8bd848888d4c29909a16 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -4052,4 +4052,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Texas Instruments FPD-Link III/IV Deserializers Driver"); MODULE_AUTHOR("Luca Ceresoli "); MODULE_AUTHOR("Tomi Valkeinen "); -MODULE_IMPORT_NS(I2C_ATR); +MODULE_IMPORT_NS("I2C_ATR"); diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c index a0e9a71580b5dcd681cae4d3fd033853b8c3f892..1bf249f446a988769e7976ccdb0e179beadac30a 100644 --- a/drivers/media/pci/intel/ipu-bridge.c +++ b/drivers/media/pci/intel/ipu-bridge.c @@ -323,7 +323,7 @@ int ipu_bridge_parse_ssdb(struct acpi_device *adev, struct ipu_sensor *sensor) return 0; } -EXPORT_SYMBOL_NS_GPL(ipu_bridge_parse_ssdb, INTEL_IPU_BRIDGE); +EXPORT_SYMBOL_NS_GPL(ipu_bridge_parse_ssdb, "INTEL_IPU_BRIDGE"); static void ipu_bridge_create_fwnode_properties( struct ipu_sensor *sensor, @@ -631,7 +631,7 @@ int ipu_bridge_instantiate_vcm(struct device *sensor) return 0; } -EXPORT_SYMBOL_NS_GPL(ipu_bridge_instantiate_vcm, INTEL_IPU_BRIDGE); +EXPORT_SYMBOL_NS_GPL(ipu_bridge_instantiate_vcm, "INTEL_IPU_BRIDGE"); static int ipu_bridge_instantiate_ivsc(struct ipu_sensor *sensor) { @@ -882,7 +882,7 @@ err_free_bridge: return ret; } -EXPORT_SYMBOL_NS_GPL(ipu_bridge_init, INTEL_IPU_BRIDGE); +EXPORT_SYMBOL_NS_GPL(ipu_bridge_init, "INTEL_IPU_BRIDGE"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Intel IPU Sensors Bridge driver"); diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 4e98f432ed557393c83dbbe404b6d5e6d87fd106..dd73d534ac490b2d88f709d4c34801fb04728ee3 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -2000,4 +2000,4 @@ MODULE_AUTHOR("Yuning Pu"); MODULE_AUTHOR("Yong Zhi "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("IPU3 CIO2 driver"); -MODULE_IMPORT_NS(INTEL_IPU_BRIDGE); +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c index 277e101da137ec1fefa1ec58c77bb3b8d71b151e..e898902e83f3719b228479638c4352e99a40bc29 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c @@ -506,7 +506,7 @@ bool ipu6_buttress_auth_done(struct ipu6_device *isp) return val == BUTTRESS_SECURITY_CTL_AUTH_DONE; } -EXPORT_SYMBOL_NS_GPL(ipu6_buttress_auth_done, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_buttress_auth_done, "INTEL_IPU6"); int ipu6_buttress_reset_authentication(struct ipu6_device *isp) { @@ -598,7 +598,7 @@ out: return ret; } -EXPORT_SYMBOL_NS_GPL(ipu6_buttress_map_fw_image, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_buttress_map_fw_image, "INTEL_IPU6"); void ipu6_buttress_unmap_fw_image(struct ipu6_bus_device *sys, struct sg_table *sgt) @@ -609,7 +609,7 @@ void ipu6_buttress_unmap_fw_image(struct ipu6_bus_device *sys, dma_unmap_sgtable(&pdev->dev, sgt, DMA_TO_DEVICE, 0); sg_free_table(sgt); } -EXPORT_SYMBOL_NS_GPL(ipu6_buttress_unmap_fw_image, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_buttress_unmap_fw_image, "INTEL_IPU6"); int ipu6_buttress_authenticate(struct ipu6_device *isp) { @@ -774,7 +774,7 @@ int ipu6_buttress_start_tsc_sync(struct ipu6_device *isp) return -ETIMEDOUT; } -EXPORT_SYMBOL_NS_GPL(ipu6_buttress_start_tsc_sync, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_buttress_start_tsc_sync, "INTEL_IPU6"); void ipu6_buttress_tsc_read(struct ipu6_device *isp, u64 *val) { @@ -796,7 +796,7 @@ void ipu6_buttress_tsc_read(struct ipu6_device *isp, u64 *val) } local_irq_restore(flags); } -EXPORT_SYMBOL_NS_GPL(ipu6_buttress_tsc_read, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_buttress_tsc_read, "INTEL_IPU6"); u64 ipu6_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu6_device *isp) { @@ -811,7 +811,7 @@ u64 ipu6_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu6_device *isp) */ return div_u64(ns, isp->buttress.ref_clk); } -EXPORT_SYMBOL_NS_GPL(ipu6_buttress_tsc_ticks_to_ns, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_buttress_tsc_ticks_to_ns, "INTEL_IPU6"); void ipu6_buttress_restore(struct ipu6_device *isp) { diff --git a/drivers/media/pci/intel/ipu6/ipu6-cpd.c b/drivers/media/pci/intel/ipu6/ipu6-cpd.c index 55ffd988ae4f1c1ab5b431ddb3593792971ce18d..8b8142bcb2d50a6f59971e7913ea8b4eec68fd50 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-cpd.c +++ b/drivers/media/pci/intel/ipu6/ipu6-cpd.c @@ -216,14 +216,14 @@ int ipu6_cpd_create_pkg_dir(struct ipu6_bus_device *adev, const void *src) return 0; } -EXPORT_SYMBOL_NS_GPL(ipu6_cpd_create_pkg_dir, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_cpd_create_pkg_dir, "INTEL_IPU6"); void ipu6_cpd_free_pkg_dir(struct ipu6_bus_device *adev) { ipu6_dma_free(adev, adev->pkg_dir_size, adev->pkg_dir, adev->pkg_dir_dma_addr, 0); } -EXPORT_SYMBOL_NS_GPL(ipu6_cpd_free_pkg_dir, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_cpd_free_pkg_dir, "INTEL_IPU6"); static int ipu6_cpd_validate_cpd(struct ipu6_device *isp, const void *cpd, unsigned long cpd_size, diff --git a/drivers/media/pci/intel/ipu6/ipu6-dma.c b/drivers/media/pci/intel/ipu6/ipu6-dma.c index 287b77a6aeab153a5b36a98f64a599de2119f5bb..b34022bad83bf339824d9ae1126cfae885c2fd28 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-dma.c +++ b/drivers/media/pci/intel/ipu6/ipu6-dma.c @@ -130,7 +130,7 @@ void ipu6_dma_sync_single(struct ipu6_bus_device *sys, dma_addr_t dma_handle, vaddr = info->vaddr + offset; clflush_cache_range(vaddr, size); } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_single, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_single, "INTEL_IPU6"); void ipu6_dma_sync_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, int nents) @@ -141,13 +141,13 @@ void ipu6_dma_sync_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, for_each_sg(sglist, sg, nents, i) clflush_cache_range(sg_virt(sg), sg->length); } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_sg, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_sg, "INTEL_IPU6"); void ipu6_dma_sync_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt) { ipu6_dma_sync_sg(sys, sgt->sgl, sgt->orig_nents); } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_sgtable, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_sgtable, "INTEL_IPU6"); void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size, dma_addr_t *dma_handle, gfp_t gfp, @@ -239,7 +239,7 @@ out_kfree: return NULL; } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_alloc, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_alloc, "INTEL_IPU6"); void ipu6_dma_free(struct ipu6_bus_device *sys, size_t size, void *vaddr, dma_addr_t dma_handle, unsigned long attrs) @@ -292,7 +292,7 @@ void ipu6_dma_free(struct ipu6_bus_device *sys, size_t size, void *vaddr, kfree(info); } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_free, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_free, "INTEL_IPU6"); int ipu6_dma_mmap(struct ipu6_bus_device *sys, struct vm_area_struct *vma, void *addr, dma_addr_t iova, size_t size, @@ -369,7 +369,7 @@ void ipu6_dma_unmap_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, mmu->tlb_invalidate(mmu); __free_iova(&mmu->dmap->iovad, iova); } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_unmap_sg, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_unmap_sg, "INTEL_IPU6"); int ipu6_dma_map_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, int nents, enum dma_data_direction dir, @@ -434,7 +434,7 @@ out_fail: return 0; } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_map_sg, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_map_sg, "INTEL_IPU6"); int ipu6_dma_map_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs) @@ -449,14 +449,14 @@ int ipu6_dma_map_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt, return 0; } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_map_sgtable, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_map_sgtable, "INTEL_IPU6"); void ipu6_dma_unmap_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs) { ipu6_dma_unmap_sg(sys, sgt->sgl, sgt->nents, dir, attrs); } -EXPORT_SYMBOL_NS_GPL(ipu6_dma_unmap_sgtable, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_dma_unmap_sgtable, "INTEL_IPU6"); /* * Create scatter-list for the already allocated DMA buffer diff --git a/drivers/media/pci/intel/ipu6/ipu6-fw-com.c b/drivers/media/pci/intel/ipu6/ipu6-fw-com.c index 53edb445d9395b01fee392c2f8820fe86a14a438..40d8ce138a67d20433ed3b256313f9b147abcc2f 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-fw-com.c +++ b/drivers/media/pci/intel/ipu6/ipu6-fw-com.c @@ -261,7 +261,7 @@ void *ipu6_fw_com_prepare(struct ipu6_fw_com_cfg *cfg, return ctx; } -EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_prepare, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_prepare, "INTEL_IPU6"); int ipu6_fw_com_open(struct ipu6_fw_com_context *ctx) { @@ -289,7 +289,7 @@ int ipu6_fw_com_open(struct ipu6_fw_com_context *ctx) return 0; } -EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_open, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_open, "INTEL_IPU6"); int ipu6_fw_com_close(struct ipu6_fw_com_context *ctx) { @@ -307,7 +307,7 @@ int ipu6_fw_com_close(struct ipu6_fw_com_context *ctx) return 0; } -EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_close, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_close, "INTEL_IPU6"); int ipu6_fw_com_release(struct ipu6_fw_com_context *ctx, unsigned int force) { @@ -320,7 +320,7 @@ int ipu6_fw_com_release(struct ipu6_fw_com_context *ctx, unsigned int force) kfree(ctx); return 0; } -EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_release, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_release, "INTEL_IPU6"); bool ipu6_fw_com_ready(struct ipu6_fw_com_context *ctx) { @@ -332,7 +332,7 @@ bool ipu6_fw_com_ready(struct ipu6_fw_com_context *ctx) return state == SYSCOM_STATE_READY; } -EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_ready, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_fw_com_ready, "INTEL_IPU6"); void *ipu6_send_get_token(struct ipu6_fw_com_context *ctx, int q_nbr) { @@ -360,7 +360,7 @@ void *ipu6_send_get_token(struct ipu6_fw_com_context *ctx, int q_nbr) return (void *)((uintptr_t)q->host_address + index * q->token_size); } -EXPORT_SYMBOL_NS_GPL(ipu6_send_get_token, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_send_get_token, "INTEL_IPU6"); void ipu6_send_put_token(struct ipu6_fw_com_context *ctx, int q_nbr) { @@ -373,7 +373,7 @@ void ipu6_send_put_token(struct ipu6_fw_com_context *ctx, int q_nbr) writel(wr, q_dmem + FW_COM_WR_REG); } -EXPORT_SYMBOL_NS_GPL(ipu6_send_put_token, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_send_put_token, "INTEL_IPU6"); void *ipu6_recv_get_token(struct ipu6_fw_com_context *ctx, int q_nbr) { @@ -397,7 +397,7 @@ void *ipu6_recv_get_token(struct ipu6_fw_com_context *ctx, int q_nbr) return (void *)((uintptr_t)q->host_address + rd * q->token_size); } -EXPORT_SYMBOL_NS_GPL(ipu6_recv_get_token, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_recv_get_token, "INTEL_IPU6"); void ipu6_recv_put_token(struct ipu6_fw_com_context *ctx, int q_nbr) { @@ -410,4 +410,4 @@ void ipu6_recv_put_token(struct ipu6_fw_com_context *ctx, int q_nbr) writel(rd, q_dmem + FW_COM_RD_REG); } -EXPORT_SYMBOL_NS_GPL(ipu6_recv_put_token, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_recv_put_token, "INTEL_IPU6"); diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys.c b/drivers/media/pci/intel/ipu6/ipu6-isys.c index 7148f8fe23f53575995596886c50ce342150e223..77f9c73198681ba466410b7089dcc775ea6b1a6e 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys.c @@ -1377,5 +1377,5 @@ MODULE_AUTHOR("Yunliang Ding "); MODULE_AUTHOR("Hongju Wang "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Intel IPU6 input system driver"); -MODULE_IMPORT_NS(INTEL_IPU6); -MODULE_IMPORT_NS(INTEL_IPU_BRIDGE); +MODULE_IMPORT_NS("INTEL_IPU6"); +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c index a81e9b09a3c523ec4bb427daf8f9696f57eb8f0d..6d1c0b90169d4086cfa010bdda80ee61c445d90f 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c @@ -542,7 +542,7 @@ int ipu6_mmu_hw_init(struct ipu6_mmu *mmu) return 0; } -EXPORT_SYMBOL_NS_GPL(ipu6_mmu_hw_init, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_mmu_hw_init, "INTEL_IPU6"); static struct ipu6_mmu_info *ipu6_mmu_alloc(struct ipu6_device *isp) { @@ -607,7 +607,7 @@ void ipu6_mmu_hw_cleanup(struct ipu6_mmu *mmu) mmu->ready = false; spin_unlock_irqrestore(&mmu->ready_lock, flags); } -EXPORT_SYMBOL_NS_GPL(ipu6_mmu_hw_cleanup, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_mmu_hw_cleanup, "INTEL_IPU6"); static struct ipu6_dma_mapping *alloc_dma_mapping(struct ipu6_device *isp) { diff --git a/drivers/media/pci/intel/ipu6/ipu6.c b/drivers/media/pci/intel/ipu6/ipu6.c index a38292e8eaac40ac9296999c2b44248682c67c25..277af7cda8eec198408ab566ca522902db824af8 100644 --- a/drivers/media/pci/intel/ipu6/ipu6.c +++ b/drivers/media/pci/intel/ipu6/ipu6.c @@ -281,7 +281,7 @@ void ipu6_configure_spc(struct ipu6_device *isp, ipu6_pkg_dir_configure_spc(isp, hw_variant, pkg_dir_idx, base, pkg_dir, pkg_dir_dma_addr); } -EXPORT_SYMBOL_NS_GPL(ipu6_configure_spc, INTEL_IPU6); +EXPORT_SYMBOL_NS_GPL(ipu6_configure_spc, "INTEL_IPU6"); #define IPU6_ISYS_CSI2_NPORTS 4 #define IPU6SE_ISYS_CSI2_NPORTS 4 @@ -840,7 +840,7 @@ static struct pci_driver ipu6_pci_driver = { module_pci_driver(ipu6_pci_driver); -MODULE_IMPORT_NS(INTEL_IPU_BRIDGE); +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); MODULE_AUTHOR("Sakari Ailus "); MODULE_AUTHOR("Tianshu Qiu "); MODULE_AUTHOR("Bingbu Cao "); diff --git a/drivers/media/pci/intel/ivsc/mei_csi.c b/drivers/media/pci/intel/ivsc/mei_csi.c index 2a9c12c975cac183ebcd4ec7512e744a16b129c6..6a893c4547b28da1f710ad6a9a6199ad3d442c5d 100644 --- a/drivers/media/pci/intel/ivsc/mei_csi.c +++ b/drivers/media/pci/intel/ivsc/mei_csi.c @@ -808,7 +808,7 @@ static struct mei_cl_driver mei_csi_driver = { module_mei_cl_driver(mei_csi_driver); -MODULE_IMPORT_NS(INTEL_IPU_BRIDGE); +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); MODULE_AUTHOR("Wentong Wu "); MODULE_AUTHOR("Zhifeng Wang "); MODULE_DESCRIPTION("Device driver for IVSC CSI"); diff --git a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c index 1c5b94989aec071063e9a1a7721c15ce6100bde2..b34244ea14dd063feef3d13069b2713578c3fd1b 100644 --- a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c +++ b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c @@ -16,7 +16,7 @@ #include "vde.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); struct tegra_vde_cache_entry { enum dma_data_direction dma_dir; diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c index 5028467b2dc97b39d6140d4e0fb7dcc76833cca9..08d9e05b1b33833de160e7fc8d6a5d4b16d9cc44 100644 --- a/drivers/memory/brcmstb_dpfe.c +++ b/drivers/memory/brcmstb_dpfe.c @@ -934,7 +934,7 @@ static struct platform_driver brcmstb_dpfe_driver = { .of_match_table = brcmstb_dpfe_of_match, }, .probe = brcmstb_dpfe_probe, - .remove_new = brcmstb_dpfe_remove, + .remove = brcmstb_dpfe_remove, .resume = brcmstb_dpfe_resume, }; diff --git a/drivers/memory/brcmstb_memc.c b/drivers/memory/brcmstb_memc.c index 4f17a93aa02848c14d414ec35a28eac641b339f8..c87b37e2c1f07cc4a5f5904dfaef2839985a39c0 100644 --- a/drivers/memory/brcmstb_memc.c +++ b/drivers/memory/brcmstb_memc.c @@ -283,7 +283,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(brcmstb_memc_pm_ops, brcmstb_memc_suspend, static struct platform_driver brcmstb_memc_driver = { .probe = brcmstb_memc_probe, - .remove_new = brcmstb_memc_remove, + .remove = brcmstb_memc_remove, .driver = { .name = "brcmstb_memc", .of_match_table = brcmstb_memc_of_match, diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c index 99eb7d1baa5ff6c62fc9738971f2cc7079cf6c31..2e1ecae9e959736a3b7aa6c875613978d8c03c02 100644 --- a/drivers/memory/emif.c +++ b/drivers/memory/emif.c @@ -1159,7 +1159,7 @@ MODULE_DEVICE_TABLE(of, emif_of_match); static struct platform_driver emif_driver = { .probe = emif_probe, - .remove_new = emif_remove, + .remove = emif_remove, .shutdown = emif_shutdown, .driver = { .name = "emif", diff --git a/drivers/memory/fsl-corenet-cf.c b/drivers/memory/fsl-corenet-cf.c index f47d05f7c5c50aa3bbcacae554c0811f66e6522b..ecd6c19551532c4d70910c1eee3523c2e0318528 100644 --- a/drivers/memory/fsl-corenet-cf.c +++ b/drivers/memory/fsl-corenet-cf.c @@ -249,7 +249,7 @@ static struct platform_driver ccf_driver = { .of_match_table = ccf_matches, }, .probe = ccf_probe, - .remove_new = ccf_remove, + .remove = ccf_remove, }; module_platform_driver(ccf_driver); diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c index 15e919c24f817b7de0b5988519735bf2d35ec5c0..e89e0c6cc4bccc48e3a4372305526a5f0b647cab 100644 --- a/drivers/memory/fsl_ifc.c +++ b/drivers/memory/fsl_ifc.c @@ -316,7 +316,7 @@ static struct platform_driver fsl_ifc_ctrl_driver = { .of_match_table = fsl_ifc_match, }, .probe = fsl_ifc_ctrl_probe, - .remove_new = fsl_ifc_ctrl_remove, + .remove = fsl_ifc_ctrl_remove, }; static int __init fsl_ifc_init(void) diff --git a/drivers/memory/jz4780-nemc.c b/drivers/memory/jz4780-nemc.c index fb6db2ffe71b1b3970e4a0a92a198c1d5ec3810f..1a8161514d03e4115cd9d6d8b923aa6e667b7703 100644 --- a/drivers/memory/jz4780-nemc.c +++ b/drivers/memory/jz4780-nemc.c @@ -407,7 +407,7 @@ static const struct of_device_id jz4780_nemc_dt_match[] = { static struct platform_driver jz4780_nemc_driver = { .probe = jz4780_nemc_probe, - .remove_new = jz4780_nemc_remove, + .remove = jz4780_nemc_remove, .driver = { .name = "jz4780-nemc", .of_match_table = of_match_ptr(jz4780_nemc_dt_match), diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 2bc034dff691bff4807ae641417ac20d5ba322d7..5710348f72f6ff33bc50350e1ef71caf91c0a85e 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -616,7 +616,7 @@ static const struct dev_pm_ops smi_larb_pm_ops = { static struct platform_driver mtk_smi_larb_driver = { .probe = mtk_smi_larb_probe, - .remove_new = mtk_smi_larb_remove, + .remove = mtk_smi_larb_remove, .driver = { .name = "mtk-smi-larb", .of_match_table = mtk_smi_larb_of_ids, @@ -838,7 +838,7 @@ static const struct dev_pm_ops smi_common_pm_ops = { static struct platform_driver mtk_smi_common_driver = { .probe = mtk_smi_common_probe, - .remove_new = mtk_smi_common_remove, + .remove = mtk_smi_common_remove, .driver = { .name = "mtk-smi-common", .of_match_table = mtk_smi_common_of_ids, diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index c8a0d82f9c27df4b1e17a5ac937306e65e3ca561..50eb9f49512b447341a7e460016e9de405567d24 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -2743,7 +2743,7 @@ MODULE_DEVICE_TABLE(of, gpmc_dt_ids); static struct platform_driver gpmc_driver = { .probe = gpmc_probe, - .remove_new = gpmc_remove, + .remove = gpmc_remove, .driver = { .name = DEVICE_NAME, .of_match_table = of_match_ptr(gpmc_dt_ids), diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c index 7fbd36fa1a1b46ef9394f54f6c5dc554208c4c66..15b4706aafee9f337f95ed956cd2ed53018e4342 100644 --- a/drivers/memory/renesas-rpc-if.c +++ b/drivers/memory/renesas-rpc-if.c @@ -795,7 +795,7 @@ MODULE_DEVICE_TABLE(of, rpcif_of_match); static struct platform_driver rpcif_driver = { .probe = rpcif_probe, - .remove_new = rpcif_remove, + .remove = rpcif_remove, .driver = { .name = "rpc-if", .of_match_table = rpcif_of_match, diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c index 7d80322754fadac3a524b97c6857b3a5f15578af..788d49c688b1d9d0ffefe28c1e44eeedda288c37 100644 --- a/drivers/memory/samsung/exynos5422-dmc.c +++ b/drivers/memory/samsung/exynos5422-dmc.c @@ -1571,7 +1571,7 @@ MODULE_DEVICE_TABLE(of, exynos5_dmc_of_match); static struct platform_driver exynos5_dmc_platdrv = { .probe = exynos5_dmc_probe, - .remove_new = exynos5_dmc_remove, + .remove = exynos5_dmc_remove, .driver = { .name = "exynos5-dmc", .of_match_table = exynos5_dmc_of_match, diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c index 566c225f71c06e9435cfefee0caa5d82de1dab68..6e386ab54091597704d60b7d7bd0708f63d1cbfb 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -1815,7 +1815,7 @@ MODULE_DEVICE_TABLE(of, stm32_fmc2_ebi_match); static struct platform_driver stm32_fmc2_ebi_driver = { .probe = stm32_fmc2_ebi_probe, - .remove_new = stm32_fmc2_ebi_remove, + .remove = stm32_fmc2_ebi_remove, .driver = { .name = "stm32_fmc2_ebi", .of_match_table = stm32_fmc2_ebi_match, diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c index 33d67d2517194082d429982a0f2fec77f0bf1571..bc807d7fcd4e563a9bb8ba7d89a1114d518eed3a 100644 --- a/drivers/memory/tegra/tegra186-emc.c +++ b/drivers/memory/tegra/tegra186-emc.c @@ -406,7 +406,7 @@ static struct platform_driver tegra186_emc_driver = { .sync_state = icc_sync_state, }, .probe = tegra186_emc_probe, - .remove_new = tegra186_emc_remove, + .remove = tegra186_emc_remove, }; module_platform_driver(tegra186_emc_driver); diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c index 78ca1d6c0977408ebcd40cb0f5a57967555e3d55..2d5d8245a1d3b3ee2961447c85ec9c7a5e89804a 100644 --- a/drivers/memory/tegra/tegra210-emc-core.c +++ b/drivers/memory/tegra/tegra210-emc-core.c @@ -2051,7 +2051,7 @@ static struct platform_driver tegra210_emc_driver = { .pm = &tegra210_emc_pm_ops, }, .probe = tegra210_emc_probe, - .remove_new = tegra210_emc_remove, + .remove = tegra210_emc_remove, }; module_platform_driver(tegra210_emc_driver); diff --git a/drivers/memory/ti-emif-pm.c b/drivers/memory/ti-emif-pm.c index 592f70e9c8e5bbf7c157033ccc2167e9deaaa5ee..df362ecc59e9102ff39eebbebcb680220d44348f 100644 --- a/drivers/memory/ti-emif-pm.c +++ b/drivers/memory/ti-emif-pm.c @@ -330,7 +330,7 @@ static const struct dev_pm_ops ti_emif_pm_ops = { static struct platform_driver ti_emif_driver = { .probe = ti_emif_probe, - .remove_new = ti_emif_remove, + .remove = ti_emif_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = ti_emif_of_match, diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c index ffdd8de9ec5d79ba90689834530b67b33c7a16ed..6eb892fd4d343228aa4d194dcbc198c8952e6513 100644 --- a/drivers/memstick/host/rtsx_usb_ms.c +++ b/drivers/memstick/host/rtsx_usb_ms.c @@ -853,7 +853,7 @@ MODULE_DEVICE_TABLE(platform, rtsx_usb_ms_ids); static struct platform_driver rtsx_usb_ms_driver = { .probe = rtsx_usb_ms_drv_probe, - .remove_new = rtsx_usb_ms_drv_remove, + .remove = rtsx_usb_ms_drv_remove, .id_table = rtsx_usb_ms_ids, .driver = { .name = "rtsx_usb_ms", diff --git a/drivers/mfd/cs40l50-core.c b/drivers/mfd/cs40l50-core.c index 26e7a769eb1427883dc1289e588485074be8b41b..4859a33777a04ca2c39fc2a9418ee3f04b39bbc3 100644 --- a/drivers/mfd/cs40l50-core.c +++ b/drivers/mfd/cs40l50-core.c @@ -567,4 +567,4 @@ EXPORT_GPL_DEV_PM_OPS(cs40l50_pm_ops) = { MODULE_DESCRIPTION("CS40L50 Advanced Haptic Driver"); MODULE_AUTHOR("James Ogletree, Cirrus Logic Inc. "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(FW_CS_DSP); +MODULE_IMPORT_NS("FW_CS_DSP"); diff --git a/drivers/mfd/cs42l43-i2c.c b/drivers/mfd/cs42l43-i2c.c index c9e4ea76149a8880dde2212b0790958e3ecb89a1..f0ad4002652dc447371fcf83a26abaac580f4a1d 100644 --- a/drivers/mfd/cs42l43-i2c.c +++ b/drivers/mfd/cs42l43-i2c.c @@ -92,7 +92,7 @@ static struct i2c_driver cs42l43_i2c_driver = { }; module_i2c_driver(cs42l43_i2c_driver); -MODULE_IMPORT_NS(MFD_CS42L43); +MODULE_IMPORT_NS("MFD_CS42L43"); MODULE_DESCRIPTION("CS42L43 I2C Driver"); MODULE_AUTHOR("Charles Keepax "); diff --git a/drivers/mfd/cs42l43-sdw.c b/drivers/mfd/cs42l43-sdw.c index 65f7b1d7824861041899c0f6bddda4776edc8cf0..3938d48039c4852efefa3ed88441a88ab2d3047a 100644 --- a/drivers/mfd/cs42l43-sdw.c +++ b/drivers/mfd/cs42l43-sdw.c @@ -215,7 +215,7 @@ static struct sdw_driver cs42l43_sdw_driver = { }; module_sdw_driver(cs42l43_sdw_driver); -MODULE_IMPORT_NS(MFD_CS42L43); +MODULE_IMPORT_NS("MFD_CS42L43"); MODULE_DESCRIPTION("CS42L43 SoundWire Driver"); MODULE_AUTHOR("Lucas Tanure "); diff --git a/drivers/mfd/cs42l43.c b/drivers/mfd/cs42l43.c index e5f17fc430e4879b52bf4758af3313ee66614692..b5ab5e613db79c57bb33d5c7b119040e8c468d8c 100644 --- a/drivers/mfd/cs42l43.c +++ b/drivers/mfd/cs42l43.c @@ -264,7 +264,7 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = { { CS42L43_ASRC_MASK, 0x0000000F }, { CS42L43_HPOUT_MASK, 0x00000003 }, }; -EXPORT_SYMBOL_NS_GPL(cs42l43_reg_default, MFD_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_reg_default, "MFD_CS42L43"); bool cs42l43_readable_register(struct device *dev, unsigned int reg) { @@ -392,7 +392,7 @@ bool cs42l43_readable_register(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(cs42l43_readable_register, MFD_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_readable_register, "MFD_CS42L43"); bool cs42l43_precious_register(struct device *dev, unsigned int reg) { @@ -407,7 +407,7 @@ bool cs42l43_precious_register(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(cs42l43_precious_register, MFD_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_precious_register, "MFD_CS42L43"); bool cs42l43_volatile_register(struct device *dev, unsigned int reg) { @@ -435,7 +435,7 @@ bool cs42l43_volatile_register(struct device *dev, unsigned int reg) return cs42l43_precious_register(dev, reg); } } -EXPORT_SYMBOL_NS_GPL(cs42l43_volatile_register, MFD_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_volatile_register, "MFD_CS42L43"); #define CS42L43_IRQ_OFFSET(reg) ((CS42L43_##reg##_INT) - CS42L43_DECIM_INT) @@ -1096,7 +1096,7 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43) return 0; } -EXPORT_SYMBOL_NS_GPL(cs42l43_dev_probe, MFD_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_dev_probe, "MFD_CS42L43"); void cs42l43_dev_remove(struct cs42l43 *cs42l43) { @@ -1104,7 +1104,7 @@ void cs42l43_dev_remove(struct cs42l43 *cs42l43) cs42l43_power_down(cs42l43); } -EXPORT_SYMBOL_NS_GPL(cs42l43_dev_remove, MFD_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_dev_remove, "MFD_CS42L43"); static int cs42l43_suspend(struct device *dev) { diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index 557061856e584e2dc6fa8babfbe0f86cae94b40c..63406026d80966342db691a701822e7be240443e 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -222,4 +222,4 @@ MODULE_AUTHOR("Andy Shevchenko "); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel LPSS ACPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(INTEL_LPSS); +MODULE_IMPORT_NS("INTEL_LPSS"); diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 1d8cdc4d5819b6fc5d585f44c895848c168f23d4..1a5b8b13f8d0b2ed2ba3ccc7465174b9e25b7d6c 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -653,4 +653,4 @@ MODULE_AUTHOR("Andy Shevchenko "); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel LPSS PCI driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(INTEL_LPSS); +MODULE_IMPORT_NS("INTEL_LPSS"); diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c index 2a9018112dfc86aba1499b51bc4a8225b9dc9f26..3ba05ebb90359f38414219f42383d565c7c5d4f0 100644 --- a/drivers/mfd/intel-lpss.c +++ b/drivers/mfd/intel-lpss.c @@ -464,7 +464,7 @@ err_clk_register: return ret; } -EXPORT_SYMBOL_NS_GPL(intel_lpss_probe, INTEL_LPSS); +EXPORT_SYMBOL_NS_GPL(intel_lpss_probe, "INTEL_LPSS"); void intel_lpss_remove(struct device *dev) { @@ -476,7 +476,7 @@ void intel_lpss_remove(struct device *dev) intel_lpss_unregister_clock(lpss); ida_free(&intel_lpss_devid_ida, lpss->devid); } -EXPORT_SYMBOL_NS_GPL(intel_lpss_remove, INTEL_LPSS); +EXPORT_SYMBOL_NS_GPL(intel_lpss_remove, "INTEL_LPSS"); static int resume_lpss_device(struct device *dev, void *data) { diff --git a/drivers/mfd/intel-m10-bmc-core.c b/drivers/mfd/intel-m10-bmc-core.c index 8ad5b382158419883ee3c82d61b7b1fa311e140c..e930161bf65eacc2b8046729d6aa0876c7ae8c45 100644 --- a/drivers/mfd/intel-m10-bmc-core.c +++ b/drivers/mfd/intel-m10-bmc-core.c @@ -22,7 +22,7 @@ void m10bmc_fw_state_set(struct intel_m10bmc *m10bmc, enum m10bmc_fw_state new_s m10bmc->bmcfw_state = new_state; up_write(&m10bmc->bmcfw_lock); } -EXPORT_SYMBOL_NS_GPL(m10bmc_fw_state_set, INTEL_M10_BMC_CORE); +EXPORT_SYMBOL_NS_GPL(m10bmc_fw_state_set, "INTEL_M10_BMC_CORE"); /* * For some Intel FPGA devices, the BMC firmware is not available to service @@ -75,7 +75,7 @@ int m10bmc_sys_read(struct intel_m10bmc *m10bmc, unsigned int offset, unsigned i return ret; } -EXPORT_SYMBOL_NS_GPL(m10bmc_sys_read, INTEL_M10_BMC_CORE); +EXPORT_SYMBOL_NS_GPL(m10bmc_sys_read, "INTEL_M10_BMC_CORE"); int m10bmc_sys_update_bits(struct intel_m10bmc *m10bmc, unsigned int offset, unsigned int msk, unsigned int val) @@ -95,7 +95,7 @@ int m10bmc_sys_update_bits(struct intel_m10bmc *m10bmc, unsigned int offset, return ret; } -EXPORT_SYMBOL_NS_GPL(m10bmc_sys_update_bits, INTEL_M10_BMC_CORE); +EXPORT_SYMBOL_NS_GPL(m10bmc_sys_update_bits, "INTEL_M10_BMC_CORE"); static ssize_t bmc_version_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -183,7 +183,7 @@ const struct attribute_group *m10bmc_dev_groups[] = { &m10bmc_group, NULL, }; -EXPORT_SYMBOL_NS_GPL(m10bmc_dev_groups, INTEL_M10_BMC_CORE); +EXPORT_SYMBOL_NS_GPL(m10bmc_dev_groups, "INTEL_M10_BMC_CORE"); int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platform_info *info) { @@ -201,7 +201,7 @@ int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platf return ret; } -EXPORT_SYMBOL_NS_GPL(m10bmc_dev_init, INTEL_M10_BMC_CORE); +EXPORT_SYMBOL_NS_GPL(m10bmc_dev_init, "INTEL_M10_BMC_CORE"); MODULE_DESCRIPTION("Intel MAX 10 BMC core driver"); MODULE_AUTHOR("Intel Corporation"); diff --git a/drivers/mfd/intel-m10-bmc-pmci.c b/drivers/mfd/intel-m10-bmc-pmci.c index 4fa9d380c62b5f8cf034baae3f9b57411db27124..d213c6ec04bad080d58676e31d70b520dd3334d3 100644 --- a/drivers/mfd/intel-m10-bmc-pmci.c +++ b/drivers/mfd/intel-m10-bmc-pmci.c @@ -454,4 +454,4 @@ module_dfl_driver(m10bmc_pmci_driver); MODULE_DESCRIPTION("MAX10 BMC PMCI-based interface"); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); +MODULE_IMPORT_NS("INTEL_M10_BMC_CORE"); diff --git a/drivers/mfd/intel-m10-bmc-spi.c b/drivers/mfd/intel-m10-bmc-spi.c index 36f631ef7a6774607ce5ecd3b1e93983906ffb48..cfa620f0c70e194c9c94ad08a156e89b8a3a3d5c 100644 --- a/drivers/mfd/intel-m10-bmc-spi.c +++ b/drivers/mfd/intel-m10-bmc-spi.c @@ -181,4 +181,4 @@ MODULE_DESCRIPTION("Intel MAX 10 BMC SPI bus interface"); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:intel-m10-bmc"); -MODULE_IMPORT_NS(INTEL_M10_BMC_CORE); +MODULE_IMPORT_NS("INTEL_M10_BMC_CORE"); diff --git a/drivers/mfd/ocelot-core.c b/drivers/mfd/ocelot-core.c index 9cccf54fc9c885f01ad0b795ffe61a500f045e11..41aff270885488cb1546691f74f1156892c32d2e 100644 --- a/drivers/mfd/ocelot-core.c +++ b/drivers/mfd/ocelot-core.c @@ -113,7 +113,7 @@ int ocelot_chip_reset(struct device *dev) return readx_poll_timeout(ocelot_gcb_chip_rst_status, ddata, val, !val, VSC7512_GCB_RST_SLEEP_US, VSC7512_GCB_RST_TIMEOUT_US); } -EXPORT_SYMBOL_NS(ocelot_chip_reset, MFD_OCELOT); +EXPORT_SYMBOL_NS(ocelot_chip_reset, "MFD_OCELOT"); static const struct resource vsc7512_miim0_resources[] = { DEFINE_RES_REG_NAMED(VSC7512_MIIM0_RES_START, VSC7512_MIIM_RES_SIZE, "gcb_miim0"), @@ -226,9 +226,9 @@ int ocelot_core_init(struct device *dev) return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, vsc7512_devs, ndevs, NULL, 0, NULL); } -EXPORT_SYMBOL_NS(ocelot_core_init, MFD_OCELOT); +EXPORT_SYMBOL_NS(ocelot_core_init, "MFD_OCELOT"); MODULE_DESCRIPTION("Externally Controlled Ocelot Chip Driver"); MODULE_AUTHOR("Colin Foster "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(MFD_OCELOT_SPI); +MODULE_IMPORT_NS("MFD_OCELOT_SPI"); diff --git a/drivers/mfd/ocelot-spi.c b/drivers/mfd/ocelot-spi.c index b015c8683f1bcf2a87b85844197925692a00eaa2..1fed9878c323193018809c5a930ec3337efca68d 100644 --- a/drivers/mfd/ocelot-spi.c +++ b/drivers/mfd/ocelot-spi.c @@ -193,7 +193,7 @@ struct regmap *ocelot_spi_init_regmap(struct device *dev, const struct resource return devm_regmap_init(dev, &ocelot_spi_regmap_bus, dev, ®map_config); } -EXPORT_SYMBOL_NS(ocelot_spi_init_regmap, MFD_OCELOT_SPI); +EXPORT_SYMBOL_NS(ocelot_spi_init_regmap, "MFD_OCELOT_SPI"); static int ocelot_spi_probe(struct spi_device *spi) { @@ -295,4 +295,4 @@ module_spi_driver(ocelot_spi_driver); MODULE_DESCRIPTION("SPI Controlled Ocelot Chip Driver"); MODULE_AUTHOR("Colin Foster "); MODULE_LICENSE("Dual MIT/GPL"); -MODULE_IMPORT_NS(MFD_OCELOT); +MODULE_IMPORT_NS("MFD_OCELOT"); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 902c306bc9722a4abc6ef5cef99724c3d3e52848..09cbe3f0ab1e56f85852c0cb50cfc03cae659d2b 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -637,7 +637,6 @@ config MCHP_LAN966X_PCI source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" -source "drivers/misc/ti-st/Kconfig" source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/altera-stapl/Kconfig" source "drivers/misc/mei/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 885b22989580a214652ae0336f9b95716c77a584..40bf953185c773afa91f7784a286ae0752bb0b53 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -40,7 +40,6 @@ obj-y += eeprom/ obj-y += cb710/ obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o obj-$(CONFIG_PCH_PHUB) += pch_phub.o -obj-y += ti-st/ obj-y += lis3lv02d/ obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI) += mei/ diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index 6d4edd69db126a3ae55bc63a4e7984b3e40cb324..e7d73c972f65dc42520ac49c0d414b89fbccd88a 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1147,7 +1147,7 @@ static int apds990x_probe(struct i2c_client *client) err = chip->pdata->setup_resources(); if (err) { err = -EINVAL; - goto fail3; + goto fail4; } } @@ -1155,7 +1155,7 @@ static int apds990x_probe(struct i2c_client *client) apds990x_attribute_group); if (err < 0) { dev_err(&chip->client->dev, "Sysfs registration failed\n"); - goto fail4; + goto fail5; } err = request_threaded_irq(client->irq, NULL, @@ -1166,15 +1166,17 @@ static int apds990x_probe(struct i2c_client *client) if (err) { dev_err(&client->dev, "could not get IRQ %d\n", client->irq); - goto fail5; + goto fail6; } return err; -fail5: +fail6: sysfs_remove_group(&chip->client->dev.kobj, &apds990x_attribute_group[0]); -fail4: +fail5: if (chip->pdata && chip->pdata->release_resources) chip->pdata->release_resources(); +fail4: + pm_runtime_disable(&client->dev); fail3: regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); fail2: diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 6eac0f33591524f9b76ad912a3ceb1c62556fc48..35a1963415346a9ff29850e3ba0a0a0de69da797 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -153,7 +153,7 @@ static int ssc_sound_dai_probe(struct ssc_device *ssc) ssc->sound_dai = false; - if (!of_property_read_bool(np, "#sound-dai-cells")) + if (!of_property_present(np, "#sound-dai-cells")) return 0; id = of_alias_get_id(np, "ssc"); @@ -176,7 +176,7 @@ static void ssc_sound_dai_remove(struct ssc_device *ssc) #else static inline int ssc_sound_dai_probe(struct ssc_device *ssc) { - if (of_property_read_bool(ssc->pdev->dev.of_node, "#sound-dai-cells")) + if (of_property_present(ssc->pdev->dev.of_node, "#sound-dai-cells")) return -ENOTSUPP; return 0; @@ -269,7 +269,7 @@ static struct platform_driver ssc_driver = { }, .id_table = atmel_ssc_devtypes, .probe = ssc_probe, - .remove_new = ssc_remove, + .remove = ssc_remove, }; module_platform_driver(ssc_driver); diff --git a/drivers/misc/cardreader/alcor_pci.c b/drivers/misc/cardreader/alcor_pci.c index 0142c4bf4f42d448613e4993b197ccc60f88c072..a5549eaf52d089c5c572bac1323b2ab650f24665 100644 --- a/drivers/misc/cardreader/alcor_pci.c +++ b/drivers/misc/cardreader/alcor_pci.c @@ -17,8 +17,6 @@ #include -#define DRV_NAME_ALCOR_PCI "alcor_pci" - static DEFINE_IDA(alcor_pci_idr); static struct mfd_cell alcor_pci_cells[] = { diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c index f150d8769f1986fdab8d16aea6d7f83c4ae25a75..77b0490a1b38d79134d48020bd49a9fa6f0df967 100644 --- a/drivers/misc/cardreader/rtsx_usb.c +++ b/drivers/misc/cardreader/rtsx_usb.c @@ -20,11 +20,11 @@ MODULE_PARM_DESC(polling_pipe, "polling pipe (0: ctl, 1: bulk)"); static const struct mfd_cell rtsx_usb_cells[] = { [RTSX_USB_SD_CARD] = { - .name = "rtsx_usb_sdmmc", + .name = DRV_NAME_RTSX_USB_SDMMC, .pdata_size = 0, }, [RTSX_USB_MS_CARD] = { - .name = "rtsx_usb_ms", + .name = DRV_NAME_RTSX_USB_MS, .pdata_size = 0, }, }; @@ -780,7 +780,7 @@ static const struct usb_device_id rtsx_usb_usb_ids[] = { MODULE_DEVICE_TABLE(usb, rtsx_usb_usb_ids); static struct usb_driver rtsx_usb_driver = { - .name = "rtsx_usb", + .name = DRV_NAME_RTSX_USB, .probe = rtsx_usb_probe, .disconnect = rtsx_usb_disconnect, .suspend = rtsx_usb_suspend, diff --git a/drivers/misc/cxl/of.c b/drivers/misc/cxl/of.c index 03633cccd04389117008336b028cfcc77174616f..cf6bd8a43056e7d92ed9a4efed0fd0106b8c3c0c 100644 --- a/drivers/misc/cxl/of.c +++ b/drivers/misc/cxl/of.c @@ -339,6 +339,6 @@ struct platform_driver cxl_of_driver = { .owner = THIS_MODULE }, .probe = cxl_of_probe, - .remove_new = cxl_of_remove, + .remove = cxl_of_remove, .shutdown = cxl_of_shutdown, }; diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index 9df12399bda37c6d1ace0eef69c2f62446015aae..cb1c4b8e7fd37ad3a76941150a07f4a12e9d97af 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -97,11 +97,11 @@ config EEPROM_DIGSY_MTC_CFG If unsure, say N. config EEPROM_IDT_89HPESX - tristate "IDT 89HPESx PCIe-swtiches EEPROM / CSR support" + tristate "IDT 89HPESx PCIe-switches EEPROM / CSR support" depends on I2C && SYSFS help Enable this driver to get read/write access to EEPROM / CSRs - over IDT PCIe-swtich i2c-slave interface. + over IDT PCIe-switch i2c-slave interface. This driver can also be built as a module. If so, the module will be called idt_89hpesx. diff --git a/drivers/misc/eeprom/eeprom_93cx6.c b/drivers/misc/eeprom/eeprom_93cx6.c index 9627294fe3e9518bbab4fecfc90dc1960780987e..e6f0e0fc1ca204332386f20d1b06a06697a56a43 100644 --- a/drivers/misc/eeprom/eeprom_93cx6.c +++ b/drivers/misc/eeprom/eeprom_93cx6.c @@ -8,6 +8,7 @@ * Supported chipsets: 93c46 & 93c66. */ +#include #include #include #include @@ -102,7 +103,7 @@ static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom, /* * Check if this bit needs to be set. */ - eeprom->reg_data_in = !!(data & (1 << (i - 1))); + eeprom->reg_data_in = !!(data & BIT(i - 1)); /* * Write the bit to the eeprom register. @@ -152,7 +153,7 @@ static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom, * Read if the bit has been set. */ if (eeprom->reg_data_out) - buf |= (1 << (i - 1)); + buf |= BIT(i - 1); eeprom_93cx6_pulse_low(eeprom); } @@ -186,6 +187,11 @@ void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word, eeprom_93cx6_write_bits(eeprom, command, PCI_EEPROM_WIDTH_OPCODE + eeprom->width); + if (has_quirk_extra_read_cycle(eeprom)) { + eeprom_93cx6_pulse_high(eeprom); + eeprom_93cx6_pulse_low(eeprom); + } + /* * Read the requested 16 bits. */ @@ -252,6 +258,11 @@ void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, const u8 byte, eeprom_93cx6_write_bits(eeprom, command, PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1); + if (has_quirk_extra_read_cycle(eeprom)) { + eeprom_93cx6_pulse_high(eeprom); + eeprom_93cx6_pulse_low(eeprom); + } + /* * Read the requested 8 bits. */ diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index e2221be884458fbf98bf92c3e6d86836208b9bdb..9cae6f530679b3e5ee6ed721f952cb6d8f4e216f 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -229,7 +229,7 @@ static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on) static ssize_t eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev, - const char *buf, unsigned off) + const char *buf, unsigned int off) { struct spi_message m; struct spi_transfer t[2] = {}; diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 74181b8c386b7857d27ff961da96c1fa53a4c385..48d08eeb2d20b58f1849bfc63c39d42927d16713 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2215,7 +2215,7 @@ static const struct of_device_id fastrpc_match_table[] = { static struct platform_driver fastrpc_cb_driver = { .probe = fastrpc_cb_probe, - .remove_new = fastrpc_cb_remove, + .remove = fastrpc_cb_remove, .driver = { .name = "qcom,fastrpc-cb", .of_match_table = fastrpc_match_table, @@ -2505,4 +2505,4 @@ module_exit(fastrpc_exit); MODULE_DESCRIPTION("Qualcomm FastRPC"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/misc/hisi_hikey_usb.c b/drivers/misc/hisi_hikey_usb.c index fb9be37057a8dde5916c15ddbef6029a0d71df81..ffe7b945a29857d42a73f6ea01c623f1f108f7fe 100644 --- a/drivers/misc/hisi_hikey_usb.c +++ b/drivers/misc/hisi_hikey_usb.c @@ -260,7 +260,7 @@ MODULE_DEVICE_TABLE(of, id_table_hisi_hikey_usb); static struct platform_driver hisi_hikey_usb_driver = { .probe = hisi_hikey_usb_probe, - .remove_new = hisi_hikey_usb_remove, + .remove = hisi_hikey_usb_remove, .driver = { .name = DEVICE_DRIVER_NAME, .of_match_table = id_table_hisi_hikey_usb, diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 1643ba2ff9644d544996136727e6765ccc1da6d6..c288aeec16c095ba3ea0b8a08fa85ac12afa2e5b 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -68,7 +68,7 @@ static ssize_t als_lux_input_data_show(struct device *dev, if (val < 0) return val; lux = ((((1 << (2 * (val & 3))))*1000) * ret_val) / 65536; - return sprintf(buf, "%ld\n", lux); + return sprintf(buf, "%lu\n", lux); } static ssize_t als_sensing_range_store(struct device *dev, diff --git a/drivers/misc/keba/Kconfig b/drivers/misc/keba/Kconfig index 5fbcbc2252ac1e69d98ce1f1a8b634356369a805..d6d47197a963bd3e64cfc2f87e72e5aa3d510369 100644 --- a/drivers/misc/keba/Kconfig +++ b/drivers/misc/keba/Kconfig @@ -1,7 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 config KEBA_CP500 tristate "KEBA CP500 system FPGA support" + depends on X86_64 || ARM64 || COMPILE_TEST depends on PCI + depends on I2C select AUXILIARY_BUS help This driver supports the KEBA CP500 system FPGA, which is used in @@ -11,3 +13,14 @@ config KEBA_CP500 This driver can also be built as a module. If so, the module will be called cp500. + +config KEBA_LAN9252 + tristate "KEBA CP500 LAN9252 configuration" + depends on SPI + depends on KEBA_CP500 || COMPILE_TEST + help + This driver is used for updating the configuration of the LAN9252 + controller on KEBA CP500 devices. + + This driver can also be built as a module. If so, the module will be + called lan9252. diff --git a/drivers/misc/keba/Makefile b/drivers/misc/keba/Makefile index 0a8b846cda7dcb5b5fbc5d10f41ed1b223c91133..05e9efcad54f2e63d54f1909c7f6f0f5e2d4c45e 100644 --- a/drivers/misc/keba/Makefile +++ b/drivers/misc/keba/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_KEBA_CP500) += cp500.o +obj-$(CONFIG_KEBA_LAN9252) += lan9252.o diff --git a/drivers/misc/keba/cp500.c b/drivers/misc/keba/cp500.c index ae09228178810c7710c57888c9f9b5b6866b6aab..255d3022dae8fee02b7682b6a24ff84bd5658adb 100644 --- a/drivers/misc/keba/cp500.c +++ b/drivers/misc/keba/cp500.c @@ -12,7 +12,12 @@ #include #include #include +#include +#include +#include #include +#include +#include #define CP500 "cp500" @@ -27,6 +32,7 @@ /* BAR 0 registers */ #define CP500_VERSION_REG 0x00 #define CP500_RECONFIG_REG 0x11 /* upper 8-bits of STARTUP register */ +#define CP500_PRESENT_REG 0x20 #define CP500_AXI_REG 0x40 /* Bits in BUILD_REG */ @@ -35,14 +41,35 @@ /* Bits in RECONFIG_REG */ #define CP500_RECFG_REQ 0x01 /* reconfigure FPGA on next reset */ +/* Bits in PRESENT_REG */ +#define CP500_PRESENT_FAN0 0x01 + /* MSIX */ #define CP500_AXI_MSIX 3 +#define CP500_RFB_UART_MSIX 4 +#define CP500_DEBUG_UART_MSIX 5 +#define CP500_SI1_UART_MSIX 6 #define CP500_NUM_MSIX 8 #define CP500_NUM_MSIX_NO_MMI 2 #define CP500_NUM_MSIX_NO_AXI 3 /* EEPROM */ -#define CP500_HW_CPU_EEPROM_NAME "cp500_cpu_eeprom" +#define CP500_EEPROM_DA_OFFSET 0x016F +#define CP500_EEPROM_DA_ESC_TYPE_MASK 0x01 +#define CP500_EEPROM_ESC_LAN9252 0x00 +#define CP500_EEPROM_ESC_ET1100 0x01 +#define CP500_EEPROM_CPU_NAME "cpu_eeprom" +#define CP500_EEPROM_CPU_OFFSET 0 +#define CP500_EEPROM_CPU_SIZE 3072 +#define CP500_EEPROM_USER_NAME "user_eeprom" +#define CP500_EEPROM_USER_OFFSET 3072 +#define CP500_EEPROM_USER_SIZE 1024 + +/* SPI flash running at full speed */ +#define CP500_FLASH_HZ (33 * 1000 * 1000) + +/* LAN9252 */ +#define CP500_LAN9252_HZ (10 * 1000 * 1000) #define CP500_IS_CP035(dev) ((dev)->pci_dev->device == PCI_DEVICE_ID_KEBA_CP035) #define CP500_IS_CP505(dev) ((dev)->pci_dev->device == PCI_DEVICE_ID_KEBA_CP505) @@ -51,29 +78,56 @@ struct cp500_dev_info { off_t offset; size_t size; + unsigned int msix; }; struct cp500_devs { struct cp500_dev_info startup; + struct cp500_dev_info spi; struct cp500_dev_info i2c; + struct cp500_dev_info fan; + struct cp500_dev_info batt; + struct cp500_dev_info uart0_rfb; + struct cp500_dev_info uart1_dbg; + struct cp500_dev_info uart2_si1; }; /* list of devices within FPGA of CP035 family (CP035, CP056, CP057) */ static struct cp500_devs cp035_devices = { .startup = { 0x0000, SZ_4K }, + .spi = { 0x1000, SZ_4K }, .i2c = { 0x4000, SZ_4K }, + .fan = { 0x9000, SZ_4K }, + .batt = { 0xA000, SZ_4K }, + .uart0_rfb = { 0xB000, SZ_4K, CP500_RFB_UART_MSIX }, + .uart2_si1 = { 0xD000, SZ_4K, CP500_SI1_UART_MSIX }, }; /* list of devices within FPGA of CP505 family (CP503, CP505, CP507) */ static struct cp500_devs cp505_devices = { .startup = { 0x0000, SZ_4K }, + .spi = { 0x4000, SZ_4K }, .i2c = { 0x5000, SZ_4K }, + .fan = { 0x9000, SZ_4K }, + .batt = { 0xA000, SZ_4K }, + .uart0_rfb = { 0xB000, SZ_4K, CP500_RFB_UART_MSIX }, + .uart2_si1 = { 0xD000, SZ_4K, CP500_SI1_UART_MSIX }, }; /* list of devices within FPGA of CP520 family (CP520, CP530) */ static struct cp500_devs cp520_devices = { - .startup = { 0x0000, SZ_4K }, - .i2c = { 0x5000, SZ_4K }, + .startup = { 0x0000, SZ_4K }, + .spi = { 0x4000, SZ_4K }, + .i2c = { 0x5000, SZ_4K }, + .fan = { 0x8000, SZ_4K }, + .batt = { 0x9000, SZ_4K }, + .uart0_rfb = { 0xC000, SZ_4K, CP500_RFB_UART_MSIX }, + .uart1_dbg = { 0xD000, SZ_4K, CP500_DEBUG_UART_MSIX }, +}; + +struct cp500_nvmem { + struct nvmem_device *nvmem; + unsigned int offset; }; struct cp500 { @@ -85,18 +139,31 @@ struct cp500 { int minor; int build; } version; + struct notifier_block nvmem_notifier; + atomic_t nvmem_notified; /* system FPGA BAR */ resource_size_t sys_hwbase; + struct keba_spi_auxdev *spi; struct keba_i2c_auxdev *i2c; + struct keba_fan_auxdev *fan; + struct keba_batt_auxdev *batt; + struct keba_uart_auxdev *uart0_rfb; + struct keba_uart_auxdev *uart1_dbg; + struct keba_uart_auxdev *uart2_si1; /* ECM EtherCAT BAR */ resource_size_t ecm_hwbase; + /* NVMEM devices */ + struct cp500_nvmem nvmem_cpu; + struct cp500_nvmem nvmem_user; + void __iomem *system_startup_addr; }; /* I2C devices */ +#define CP500_EEPROM_ADDR 0x50 static struct i2c_board_info cp500_i2c_info[] = { { /* temperature sensor */ I2C_BOARD_INFO("emc1403", 0x4c), @@ -107,30 +174,66 @@ static struct i2c_board_info cp500_i2c_info[] = { * CP505 family: bridge board * CP520 family: carrier board */ - I2C_BOARD_INFO("24c32", 0x50), - .dev_name = CP500_HW_CPU_EEPROM_NAME, + I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR), }, { /* interface board EEPROM */ - I2C_BOARD_INFO("24c32", 0x51), + I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR + 1), }, { /* * EEPROM (optional) * CP505 family: CPU board * CP520 family: MMI board */ - I2C_BOARD_INFO("24c32", 0x52), + I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR + 2), }, { /* extension module 0 EEPROM (optional) */ - I2C_BOARD_INFO("24c32", 0x53), + I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR + 3), }, { /* extension module 1 EEPROM (optional) */ - I2C_BOARD_INFO("24c32", 0x54), + I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR + 4), }, { /* extension module 2 EEPROM (optional) */ - I2C_BOARD_INFO("24c32", 0x55), + I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR + 5), }, { /* extension module 3 EEPROM (optional) */ - I2C_BOARD_INFO("24c32", 0x56), + I2C_BOARD_INFO("24c32", CP500_EEPROM_ADDR + 6), + } +}; + +/* SPI devices */ +static struct mtd_partition cp500_partitions[] = { + { + .name = "system-flash-parts", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = 0 + } +}; +static const struct flash_platform_data cp500_w25q32 = { + .type = "w25q32", + .name = "system-flash", + .parts = cp500_partitions, + .nr_parts = ARRAY_SIZE(cp500_partitions), +}; +static const struct flash_platform_data cp500_m25p16 = { + .type = "m25p16", + .name = "system-flash", + .parts = cp500_partitions, + .nr_parts = ARRAY_SIZE(cp500_partitions), +}; +static struct spi_board_info cp500_spi_info[] = { + { /* system FPGA configuration bitstream flash */ + .modalias = "m25p80", + .platform_data = &cp500_m25p16, + .max_speed_hz = CP500_FLASH_HZ, + .chip_select = 0, + .mode = SPI_MODE_3, + }, { /* LAN9252 EtherCAT slave controller */ + .modalias = "lan9252", + .platform_data = NULL, + .max_speed_hz = CP500_LAN9252_HZ, + .chip_select = 1, + .mode = SPI_MODE_3, } }; @@ -229,7 +332,7 @@ static void cp500_i2c_release(struct device *dev) static int cp500_register_i2c(struct cp500 *cp500) { - int retval; + int ret; cp500->i2c = kzalloc(sizeof(*cp500->i2c), GFP_KERNEL); if (!cp500->i2c) @@ -251,30 +354,412 @@ static int cp500_register_i2c(struct cp500 *cp500) cp500->i2c->info_size = ARRAY_SIZE(cp500_i2c_info); cp500->i2c->info = cp500_i2c_info; - retval = auxiliary_device_init(&cp500->i2c->auxdev); - if (retval) { + ret = auxiliary_device_init(&cp500->i2c->auxdev); + if (ret) { kfree(cp500->i2c); cp500->i2c = NULL; - return retval; + return ret; } - retval = __auxiliary_device_add(&cp500->i2c->auxdev, "keba"); - if (retval) { + ret = __auxiliary_device_add(&cp500->i2c->auxdev, "keba"); + if (ret) { auxiliary_device_uninit(&cp500->i2c->auxdev); cp500->i2c = NULL; - return retval; + return ret; + } + + return 0; +} + +static void cp500_spi_release(struct device *dev) +{ + struct keba_spi_auxdev *spi = + container_of(dev, struct keba_spi_auxdev, auxdev.dev); + + kfree(spi); +} + +static int cp500_register_spi(struct cp500 *cp500, u8 esc_type) +{ + int info_size; + int ret; + + cp500->spi = kzalloc(sizeof(*cp500->spi), GFP_KERNEL); + if (!cp500->spi) + return -ENOMEM; + + if (CP500_IS_CP035(cp500)) + cp500_spi_info[0].platform_data = &cp500_w25q32; + if (esc_type == CP500_EEPROM_ESC_LAN9252) + info_size = ARRAY_SIZE(cp500_spi_info); + else + info_size = ARRAY_SIZE(cp500_spi_info) - 1; + + cp500->spi->auxdev.name = "spi"; + cp500->spi->auxdev.id = 0; + cp500->spi->auxdev.dev.release = cp500_spi_release; + cp500->spi->auxdev.dev.parent = &cp500->pci_dev->dev; + cp500->spi->io = (struct resource) { + /* SPI register area */ + .start = (resource_size_t) cp500->sys_hwbase + + cp500->devs->spi.offset, + .end = (resource_size_t) cp500->sys_hwbase + + cp500->devs->spi.offset + + cp500->devs->spi.size - 1, + .flags = IORESOURCE_MEM, + }; + cp500->spi->info_size = info_size; + cp500->spi->info = cp500_spi_info; + + ret = auxiliary_device_init(&cp500->spi->auxdev); + if (ret) { + kfree(cp500->spi); + cp500->spi = NULL; + + return ret; + } + ret = __auxiliary_device_add(&cp500->spi->auxdev, "keba"); + if (ret) { + auxiliary_device_uninit(&cp500->spi->auxdev); + cp500->spi = NULL; + + return ret; + } + + return 0; +} + +static void cp500_fan_release(struct device *dev) +{ + struct keba_fan_auxdev *fan = + container_of(dev, struct keba_fan_auxdev, auxdev.dev); + + kfree(fan); +} + +static int cp500_register_fan(struct cp500 *cp500) +{ + int ret; + + cp500->fan = kzalloc(sizeof(*cp500->fan), GFP_KERNEL); + if (!cp500->fan) + return -ENOMEM; + + cp500->fan->auxdev.name = "fan"; + cp500->fan->auxdev.id = 0; + cp500->fan->auxdev.dev.release = cp500_fan_release; + cp500->fan->auxdev.dev.parent = &cp500->pci_dev->dev; + cp500->fan->io = (struct resource) { + /* fan register area */ + .start = (resource_size_t) cp500->sys_hwbase + + cp500->devs->fan.offset, + .end = (resource_size_t) cp500->sys_hwbase + + cp500->devs->fan.offset + + cp500->devs->fan.size - 1, + .flags = IORESOURCE_MEM, + }; + + ret = auxiliary_device_init(&cp500->fan->auxdev); + if (ret) { + kfree(cp500->fan); + cp500->fan = NULL; + + return ret; + } + ret = __auxiliary_device_add(&cp500->fan->auxdev, "keba"); + if (ret) { + auxiliary_device_uninit(&cp500->fan->auxdev); + cp500->fan = NULL; + + return ret; + } + + return 0; +} + +static void cp500_batt_release(struct device *dev) +{ + struct keba_batt_auxdev *fan = + container_of(dev, struct keba_batt_auxdev, auxdev.dev); + + kfree(fan); +} + +static int cp500_register_batt(struct cp500 *cp500) +{ + int ret; + + cp500->batt = kzalloc(sizeof(*cp500->batt), GFP_KERNEL); + if (!cp500->batt) + return -ENOMEM; + + cp500->batt->auxdev.name = "batt"; + cp500->batt->auxdev.id = 0; + cp500->batt->auxdev.dev.release = cp500_batt_release; + cp500->batt->auxdev.dev.parent = &cp500->pci_dev->dev; + cp500->batt->io = (struct resource) { + /* battery register area */ + .start = (resource_size_t) cp500->sys_hwbase + + cp500->devs->batt.offset, + .end = (resource_size_t) cp500->sys_hwbase + + cp500->devs->batt.offset + + cp500->devs->batt.size - 1, + .flags = IORESOURCE_MEM, + }; + + ret = auxiliary_device_init(&cp500->batt->auxdev); + if (ret) { + kfree(cp500->batt); + cp500->batt = NULL; + + return ret; + } + ret = __auxiliary_device_add(&cp500->batt->auxdev, "keba"); + if (ret) { + auxiliary_device_uninit(&cp500->batt->auxdev); + cp500->batt = NULL; + + return ret; } return 0; } +static void cp500_uart_release(struct device *dev) +{ + struct keba_uart_auxdev *uart = + container_of(dev, struct keba_uart_auxdev, auxdev.dev); + + kfree(uart); +} + +static int cp500_register_uart(struct cp500 *cp500, + struct keba_uart_auxdev **uart, const char *name, + struct cp500_dev_info *info, unsigned int irq) +{ + int ret; + + *uart = kzalloc(sizeof(**uart), GFP_KERNEL); + if (!*uart) + return -ENOMEM; + + (*uart)->auxdev.name = name; + (*uart)->auxdev.id = 0; + (*uart)->auxdev.dev.release = cp500_uart_release; + (*uart)->auxdev.dev.parent = &cp500->pci_dev->dev; + (*uart)->io = (struct resource) { + /* UART register area */ + .start = (resource_size_t) cp500->sys_hwbase + info->offset, + .end = (resource_size_t) cp500->sys_hwbase + info->offset + + info->size - 1, + .flags = IORESOURCE_MEM, + }; + (*uart)->irq = irq; + + ret = auxiliary_device_init(&(*uart)->auxdev); + if (ret) { + kfree(*uart); + *uart = NULL; + + return ret; + } + ret = __auxiliary_device_add(&(*uart)->auxdev, "keba"); + if (ret) { + auxiliary_device_uninit(&(*uart)->auxdev); + *uart = NULL; + + return ret; + } + + return 0; +} + +static int cp500_nvmem_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct cp500_nvmem *nvmem = priv; + int ret; + + ret = nvmem_device_read(nvmem->nvmem, nvmem->offset + offset, bytes, + val); + if (ret != bytes) + return ret; + + return 0; +} + +static int cp500_nvmem_write(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct cp500_nvmem *nvmem = priv; + int ret; + + ret = nvmem_device_write(nvmem->nvmem, nvmem->offset + offset, bytes, + val); + if (ret != bytes) + return ret; + + return 0; +} + +static int cp500_nvmem_register(struct cp500 *cp500, struct nvmem_device *nvmem) +{ + struct device *dev = &cp500->pci_dev->dev; + struct nvmem_config nvmem_config = {}; + struct nvmem_device *tmp; + + /* + * The main EEPROM of CP500 devices is logically split into two EEPROMs. + * The first logical EEPROM with 3 kB contains the type label which is + * programmed during production of the device. The second logical EEPROM + * with 1 kB is not programmed during production and can be used for + * arbitrary user data. + */ + + nvmem_config.dev = dev; + nvmem_config.owner = THIS_MODULE; + nvmem_config.id = NVMEM_DEVID_NONE; + nvmem_config.type = NVMEM_TYPE_EEPROM; + nvmem_config.root_only = true; + nvmem_config.reg_read = cp500_nvmem_read; + nvmem_config.reg_write = cp500_nvmem_write; + + cp500->nvmem_cpu.nvmem = nvmem; + cp500->nvmem_cpu.offset = CP500_EEPROM_CPU_OFFSET; + nvmem_config.name = CP500_EEPROM_CPU_NAME; + nvmem_config.size = CP500_EEPROM_CPU_SIZE; + nvmem_config.priv = &cp500->nvmem_cpu; + tmp = devm_nvmem_register(dev, &nvmem_config); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + + cp500->nvmem_user.nvmem = nvmem; + cp500->nvmem_user.offset = CP500_EEPROM_USER_OFFSET; + nvmem_config.name = CP500_EEPROM_USER_NAME; + nvmem_config.size = CP500_EEPROM_USER_SIZE; + nvmem_config.priv = &cp500->nvmem_user; + tmp = devm_nvmem_register(dev, &nvmem_config); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + + return 0; +} + +static int cp500_nvmem_match(struct device *dev, const void *data) +{ + const struct cp500 *cp500 = data; + struct i2c_client *client; + + /* match only CPU EEPROM below the cp500 device */ + dev = dev->parent; + client = i2c_verify_client(dev); + if (!client || client->addr != CP500_EEPROM_ADDR) + return 0; + while ((dev = dev->parent)) + if (dev == &cp500->pci_dev->dev) + return 1; + + return 0; +} + +static void cp500_devm_nvmem_put(void *data) +{ + struct nvmem_device *nvmem = data; + + nvmem_device_put(nvmem); +} + +static int cp500_nvmem(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct nvmem_device *nvmem; + struct cp500 *cp500; + struct device *dev; + int notified; + u8 esc_type; + int ret; + + if (action != NVMEM_ADD) + return NOTIFY_DONE; + cp500 = container_of(nb, struct cp500, nvmem_notifier); + dev = &cp500->pci_dev->dev; + + /* process CPU EEPROM content only once */ + notified = atomic_read(&cp500->nvmem_notified); + if (notified) + return NOTIFY_DONE; + nvmem = nvmem_device_find(cp500, cp500_nvmem_match); + if (IS_ERR_OR_NULL(nvmem)) + return NOTIFY_DONE; + if (!atomic_try_cmpxchg_relaxed(&cp500->nvmem_notified, ¬ified, 1)) { + nvmem_device_put(nvmem); + + return NOTIFY_DONE; + } + + ret = devm_add_action_or_reset(dev, cp500_devm_nvmem_put, nvmem); + if (ret) + return ret; + + ret = cp500_nvmem_register(cp500, nvmem); + if (ret) + return ret; + + ret = nvmem_device_read(nvmem, CP500_EEPROM_DA_OFFSET, sizeof(esc_type), + (void *)&esc_type); + if (ret != sizeof(esc_type)) { + dev_warn(dev, "Failed to read device assembly!\n"); + + return NOTIFY_DONE; + } + esc_type &= CP500_EEPROM_DA_ESC_TYPE_MASK; + + if (cp500_register_spi(cp500, esc_type)) + dev_warn(dev, "Failed to register SPI!\n"); + + return NOTIFY_OK; +} + static void cp500_register_auxiliary_devs(struct cp500 *cp500) { struct device *dev = &cp500->pci_dev->dev; + u8 present = ioread8(cp500->system_startup_addr + CP500_PRESENT_REG); if (cp500_register_i2c(cp500)) - dev_warn(dev, "Failed to register i2c!\n"); + dev_warn(dev, "Failed to register I2C!\n"); + if (present & CP500_PRESENT_FAN0) + if (cp500_register_fan(cp500)) + dev_warn(dev, "Failed to register fan!\n"); + if (cp500_register_batt(cp500)) + dev_warn(dev, "Failed to register battery!\n"); + if (cp500->devs->uart0_rfb.size && + cp500->devs->uart0_rfb.msix < cp500->msix_num) { + int irq = pci_irq_vector(cp500->pci_dev, + cp500->devs->uart0_rfb.msix); + + if (cp500_register_uart(cp500, &cp500->uart0_rfb, "rs485-uart", + &cp500->devs->uart0_rfb, irq)) + dev_warn(dev, "Failed to register RFB UART!\n"); + } + if (cp500->devs->uart1_dbg.size && + cp500->devs->uart1_dbg.msix < cp500->msix_num) { + int irq = pci_irq_vector(cp500->pci_dev, + cp500->devs->uart1_dbg.msix); + + if (cp500_register_uart(cp500, &cp500->uart1_dbg, "rs232-uart", + &cp500->devs->uart1_dbg, irq)) + dev_warn(dev, "Failed to register debug UART!\n"); + } + if (cp500->devs->uart2_si1.size && + cp500->devs->uart2_si1.msix < cp500->msix_num) { + int irq = pci_irq_vector(cp500->pci_dev, + cp500->devs->uart2_si1.msix); + + if (cp500_register_uart(cp500, &cp500->uart2_si1, "uart", + &cp500->devs->uart2_si1, irq)) + dev_warn(dev, "Failed to register SI1 UART!\n"); + } } static void cp500_unregister_dev(struct auxiliary_device *auxdev) @@ -285,11 +770,34 @@ static void cp500_unregister_dev(struct auxiliary_device *auxdev) static void cp500_unregister_auxiliary_devs(struct cp500 *cp500) { - + if (cp500->spi) { + cp500_unregister_dev(&cp500->spi->auxdev); + cp500->spi = NULL; + } if (cp500->i2c) { cp500_unregister_dev(&cp500->i2c->auxdev); cp500->i2c = NULL; } + if (cp500->fan) { + cp500_unregister_dev(&cp500->fan->auxdev); + cp500->fan = NULL; + } + if (cp500->batt) { + cp500_unregister_dev(&cp500->batt->auxdev); + cp500->batt = NULL; + } + if (cp500->uart0_rfb) { + cp500_unregister_dev(&cp500->uart0_rfb->auxdev); + cp500->uart0_rfb = NULL; + } + if (cp500->uart1_dbg) { + cp500_unregister_dev(&cp500->uart1_dbg->auxdev); + cp500->uart1_dbg = NULL; + } + if (cp500->uart2_si1) { + cp500_unregister_dev(&cp500->uart2_si1->auxdev); + cp500->uart2_si1 = NULL; + } } static irqreturn_t cp500_axi_handler(int irq, void *dev) @@ -396,15 +904,21 @@ static int cp500_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) pci_set_drvdata(pci_dev, cp500); + cp500->nvmem_notifier.notifier_call = cp500_nvmem; + ret = nvmem_register_notifier(&cp500->nvmem_notifier); + if (ret != 0) + goto out_free_irq; ret = cp500_enable(cp500); if (ret != 0) - goto out_free_irq; + goto out_unregister_nvmem; cp500_register_auxiliary_devs(cp500); return 0; +out_unregister_nvmem: + nvmem_unregister_notifier(&cp500->nvmem_notifier); out_free_irq: pci_free_irq_vectors(pci_dev); out_disable: @@ -422,6 +936,8 @@ static void cp500_remove(struct pci_dev *pci_dev) cp500_disable(cp500); + nvmem_unregister_notifier(&cp500->nvmem_notifier); + pci_set_drvdata(pci_dev, 0); pci_free_irq_vectors(pci_dev); diff --git a/drivers/misc/keba/lan9252.c b/drivers/misc/keba/lan9252.c new file mode 100644 index 0000000000000000000000000000000000000000..fc54afd1d05b8b7c7dfefb130f5d2f850802af44 --- /dev/null +++ b/drivers/misc/keba/lan9252.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) KEBA Industrial Automation Gmbh 2024 + * + * Driver for LAN9252 on KEBA CP500 devices + * + * This driver is used for updating the configuration of the LAN9252 controller + * on KEBA CP500 devices. The LAN9252 is connected over SPI, which is also named + * PDI. + */ + +#include +#include + +/* SPI commands */ +#define LAN9252_SPI_READ 0x3 +#define LAN9252_SPI_WRITE 0x2 + +struct lan9252_read_cmd { + u8 cmd; + u8 addr_0; + u8 addr_1; +} __packed; + +struct lan9252_write_cmd { + u8 cmd; + u8 addr_0; + u8 addr_1; + u32 data; +} __packed; + +/* byte test register */ +#define LAN9252_BYTE_TEST 0x64 +#define LAN9252_BYTE_TEST_VALUE 0x87654321 + +/* hardware configuration register */ +#define LAN9252_HW_CFG 0x74 +#define LAN9252_HW_CFG_READY 0x08000000 + +/* EtherCAT CSR interface data register */ +#define LAN9252_ECAT_CSR_DATA 0x300 + +/* EtherCAT CSR interface command register */ +#define LAN9252_ECAT_CSR_CMD 0x304 +#define LAN9252_ECAT_CSR_BUSY 0x80000000 +#define LAN9252_ECAT_CSR_READ 0x40000000 + +/* EtherCAT slave controller MII register */ +#define LAN9252_ESC_MII 0x510 +#define LAN9252_ESC_MII_BUSY 0x8000 +#define LAN9252_ESC_MII_CMD_ERR 0x4000 +#define LAN9252_ESC_MII_READ_ERR 0x2000 +#define LAN9252_ESC_MII_ERR_MASK (LAN9252_ESC_MII_CMD_ERR | \ + LAN9252_ESC_MII_READ_ERR) +#define LAN9252_ESC_MII_WRITE 0x0200 +#define LAN9252_ESC_MII_READ 0x0100 + +/* EtherCAT slave controller PHY address register */ +#define LAN9252_ESC_PHY_ADDR 0x512 + +/* EtherCAT slave controller PHY register address register */ +#define LAN9252_ESC_PHY_REG_ADDR 0x513 + +/* EtherCAT slave controller PHY data register */ +#define LAN9252_ESC_PHY_DATA 0x514 + +/* EtherCAT slave controller PDI access state register */ +#define LAN9252_ESC_MII_PDI 0x517 +#define LAN9252_ESC_MII_ACCESS_PDI 0x01 +#define LAN9252_ESC_MII_ACCESS_ECAT 0x00 + +/* PHY address */ +#define PHY_ADDRESS 2 + +#define SPI_RETRY_COUNT 10 +#define SPI_WAIT_US 100 +#define SPI_CSR_WAIT_US 500 + +static int lan9252_spi_read(struct spi_device *spi, u16 addr, u32 *data) +{ + struct lan9252_read_cmd cmd; + + cmd.cmd = LAN9252_SPI_READ; + cmd.addr_0 = (addr >> 8) & 0xFF; + cmd.addr_1 = addr & 0xFF; + + return spi_write_then_read(spi, (u8 *)&cmd, + sizeof(struct lan9252_read_cmd), + (u8 *)data, sizeof(u32)); +} + +static int lan9252_spi_write(struct spi_device *spi, u16 addr, u32 data) +{ + struct lan9252_write_cmd cmd; + + cmd.cmd = LAN9252_SPI_WRITE; + cmd.addr_0 = (addr >> 8) & 0xFF; + cmd.addr_1 = addr & 0xFF; + cmd.data = data; + + return spi_write(spi, (u8 *)&cmd, sizeof(struct lan9252_write_cmd)); +} + +static bool lan9252_init(struct spi_device *spi) +{ + u32 data; + int ret; + + ret = lan9252_spi_read(spi, LAN9252_BYTE_TEST, &data); + if (ret || data != LAN9252_BYTE_TEST_VALUE) + return false; + + ret = lan9252_spi_read(spi, LAN9252_HW_CFG, &data); + if (ret || !(data & LAN9252_HW_CFG_READY)) + return false; + + return true; +} + +static u8 lan9252_esc_get_size(u16 addr) +{ + if (addr == LAN9252_ESC_MII || addr == LAN9252_ESC_PHY_DATA) + return 2; + + return 1; +} + +static int lan9252_esc_wait(struct spi_device *spi) +{ + ktime_t timeout = ktime_add_us(ktime_get(), SPI_WAIT_US); + u32 data; + int ret; + + /* wait while CSR command is busy */ + for (;;) { + ret = lan9252_spi_read(spi, LAN9252_ECAT_CSR_CMD, &data); + if (ret) + return ret; + if (!(data & LAN9252_ECAT_CSR_BUSY)) + return 0; + + if (ktime_compare(ktime_get(), timeout) > 0) { + ret = lan9252_spi_read(spi, LAN9252_ECAT_CSR_CMD, &data); + if (ret) + return ret; + break; + } + } + + return (!(data & LAN9252_ECAT_CSR_BUSY)) ? 0 : -ETIMEDOUT; +} + +static int lan9252_esc_read(struct spi_device *spi, u16 addr, u32 *data) +{ + u32 csr_cmd; + u8 size; + int ret; + + size = lan9252_esc_get_size(addr); + csr_cmd = LAN9252_ECAT_CSR_BUSY | LAN9252_ECAT_CSR_READ; + csr_cmd |= (size << 16) | addr; + ret = lan9252_spi_write(spi, LAN9252_ECAT_CSR_CMD, csr_cmd); + if (ret) + return ret; + + ret = lan9252_esc_wait(spi); + if (ret) + return ret; + + ret = lan9252_spi_read(spi, LAN9252_ECAT_CSR_DATA, data); + if (ret) + return ret; + + return 0; +} + +static int lan9252_esc_write(struct spi_device *spi, u16 addr, u32 data) +{ + u32 csr_cmd; + u8 size; + int ret; + + ret = lan9252_spi_write(spi, LAN9252_ECAT_CSR_DATA, data); + if (ret) + return ret; + + size = lan9252_esc_get_size(addr); + csr_cmd = LAN9252_ECAT_CSR_BUSY; + csr_cmd |= (size << 16) | addr; + ret = lan9252_spi_write(spi, LAN9252_ECAT_CSR_CMD, csr_cmd); + if (ret) + return ret; + + ret = lan9252_esc_wait(spi); + if (ret) + return ret; + + return 0; +} + +static int lan9252_access_mii(struct spi_device *spi, bool access) +{ + u32 data; + + if (access) + data = LAN9252_ESC_MII_ACCESS_PDI; + else + data = LAN9252_ESC_MII_ACCESS_ECAT; + + return lan9252_esc_write(spi, LAN9252_ESC_MII_PDI, data); +} + +static int lan9252_mii_wait(struct spi_device *spi) +{ + ktime_t timeout = ktime_add_us(ktime_get(), SPI_CSR_WAIT_US); + u32 data; + int ret; + + /* wait while MII control state machine is busy */ + for (;;) { + ret = lan9252_esc_read(spi, LAN9252_ESC_MII, &data); + if (ret) + return ret; + if (data & LAN9252_ESC_MII_ERR_MASK) + return -EIO; + if (!(data & LAN9252_ESC_MII_BUSY)) + return 0; + + if (ktime_compare(ktime_get(), timeout) > 0) { + ret = lan9252_esc_read(spi, LAN9252_ESC_MII, &data); + if (ret) + return ret; + if (data & LAN9252_ESC_MII_ERR_MASK) + return -EIO; + break; + } + } + + return (!(data & LAN9252_ESC_MII_BUSY)) ? 0 : -ETIMEDOUT; +} + +static int lan9252_mii_read(struct spi_device *spi, u8 phy_addr, u8 reg_addr, + u32 *data) +{ + int ret; + + ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_ADDR, phy_addr); + if (ret) + return ret; + ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_REG_ADDR, reg_addr); + if (ret) + return ret; + + ret = lan9252_esc_write(spi, LAN9252_ESC_MII, LAN9252_ESC_MII_READ); + if (ret) + return ret; + + ret = lan9252_mii_wait(spi); + if (ret) + return ret; + + return lan9252_esc_read(spi, LAN9252_ESC_PHY_DATA, data); +} + +static int lan9252_mii_write(struct spi_device *spi, u8 phy_addr, u8 reg_addr, + u32 data) +{ + int ret; + + ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_ADDR, phy_addr); + if (ret) + return ret; + ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_REG_ADDR, reg_addr); + if (ret) + return ret; + ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_DATA, data); + if (ret) + return ret; + + ret = lan9252_esc_write(spi, LAN9252_ESC_MII, LAN9252_ESC_MII_WRITE); + if (ret) + return ret; + + return lan9252_mii_wait(spi); +} + +static int lan9252_probe(struct spi_device *spi) +{ + u32 data; + int retry = SPI_RETRY_COUNT; + int ret; + + /* execute specified initialization sequence */ + while (retry && !lan9252_init(spi)) + retry--; + if (retry == 0) { + dev_err(&spi->dev, + "Can't initialize LAN9252 SPI communication!"); + return -EIO; + } + + /* enable access to MII management for PDI */ + ret = lan9252_access_mii(spi, true); + if (ret) { + dev_err(&spi->dev, "Can't enable access to MII management!"); + return ret; + } + + /* + * check PHY configuration and configure if necessary + * - full duplex + * - auto negotiation disabled + * - 100 Mbps + */ + ret = lan9252_mii_read(spi, PHY_ADDRESS, MII_BMCR, &data); + if (ret) { + dev_err(&spi->dev, "Can't read LAN9252 configuration!"); + goto out; + } + if (!(data & BMCR_FULLDPLX) || (data & BMCR_ANENABLE) || + !(data & BMCR_SPEED100)) { + /* + */ + data &= ~(BMCR_ANENABLE); + data |= (BMCR_FULLDPLX | BMCR_SPEED100); + ret = lan9252_mii_write(spi, PHY_ADDRESS, MII_BMCR, data); + if (ret) + dev_err(&spi->dev, + "Can't write LAN9252 configuration!"); + } + + dev_info(&spi->dev, "LAN9252 PHY configuration"); + +out: + /* disable access to MII management for PDI */ + lan9252_access_mii(spi, false); + + return ret; +} + +static const struct spi_device_id lan9252_id[] = { + {"lan9252"}, + {} +}; +MODULE_DEVICE_TABLE(spi, lan9252_id); + +static struct spi_driver lan9252_driver = { + .driver = { + .name = "lan9252", + }, + .probe = lan9252_probe, + .id_table = lan9252_id, +}; +module_spi_driver(lan9252_driver); + +MODULE_AUTHOR("Petar Bojanic "); +MODULE_AUTHOR("Gerhard Engleder "); +MODULE_DESCRIPTION("KEBA LAN9252 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 5576146ab13bcb4a009d9012c82642648dd9645c..718ec5d81d940f6e8633a8e866e28a3a331182e4 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -145,8 +145,8 @@ out: * @cl: host client * @buf: buffer to receive * @length: buffer length - * @mode: io mode * @vtag: virtual tag + * @mode: io mode * @timeout: recv timeout, 0 for infinite timeout * * Return: read size in bytes of < 0 on error diff --git a/drivers/misc/mei/platform-vsc.c b/drivers/misc/mei/platform-vsc.c index 20a11b299bcd0088f33c792f50cb3cc695925646..435760b1e86f7ac25ff710753c6b7960ac8ceccf 100644 --- a/drivers/misc/mei/platform-vsc.c +++ b/drivers/misc/mei/platform-vsc.c @@ -256,8 +256,6 @@ static int mei_vsc_hw_reset(struct mei_device *mei_dev, bool intr_enable) vsc_tp_reset(hw->tp); - vsc_tp_intr_disable(hw->tp); - return vsc_tp_init(hw->tp, mei_dev->dev); } @@ -437,7 +435,7 @@ MODULE_DEVICE_TABLE(platform, mei_vsc_id_table); static struct platform_driver mei_vsc_drv = { .probe = mei_vsc_probe, - .remove_new = mei_vsc_remove, + .remove = mei_vsc_remove, .id_table = mei_vsc_id_table, .driver = { .name = MEI_VSC_DRV_NAME, @@ -451,4 +449,4 @@ MODULE_AUTHOR("Wentong Wu "); MODULE_AUTHOR("Zhifeng Wang "); MODULE_DESCRIPTION("Intel Visual Sensing Controller Interface"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(VSC_TP); +MODULE_IMPORT_NS("VSC_TP"); diff --git a/drivers/misc/mei/vsc-fw-loader.c b/drivers/misc/mei/vsc-fw-loader.c index 9f129bc641f6993ff6814957da2cacbd82265ecc..43abefa806e11502bfbde91ab9a648f720df20cd 100644 --- a/drivers/misc/mei/vsc-fw-loader.c +++ b/drivers/misc/mei/vsc-fw-loader.c @@ -317,28 +317,34 @@ static int vsc_identify_silicon(struct vsc_fw_loader *fw_loader) cmd->data.dump_mem.addr = cpu_to_le32(VSC_EFUSE_ADDR); cmd->data.dump_mem.len = cpu_to_le16(sizeof(__le32)); ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE); - if (ret) - return ret; - if (ack->token == VSC_TOKEN_ERROR) - return -EINVAL; + if (ret || ack->token == VSC_TOKEN_ERROR) { + dev_err(fw_loader->dev, "CMD_DUMP_MEM error %d token %d\n", ret, ack->token); + return ret ?: -EINVAL; + } cmd->magic = cpu_to_le32(VSC_MAGIC_NUM); cmd->cmd_id = VSC_CMD_GET_CONT; ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE); - if (ret) - return ret; - if (ack->token != VSC_TOKEN_DUMP_RESP) - return -EINVAL; + if (ret || ack->token != VSC_TOKEN_DUMP_RESP) { + dev_err(fw_loader->dev, "CMD_GETCONT error %d token %d\n", ret, ack->token); + return ret ?: -EINVAL; + } version = FIELD_GET(VSC_MAINSTEPPING_VERSION_MASK, ack->payload[0]); sub_version = FIELD_GET(VSC_SUBSTEPPING_VERSION_MASK, ack->payload[0]); - if (version != VSC_MAINSTEPPING_VERSION_A) + if (version != VSC_MAINSTEPPING_VERSION_A) { + dev_err(fw_loader->dev, "mainstepping mismatch expected %d got %d\n", + VSC_MAINSTEPPING_VERSION_A, version); return -EINVAL; + } if (sub_version != VSC_SUBSTEPPING_VERSION_0 && - sub_version != VSC_SUBSTEPPING_VERSION_1) + sub_version != VSC_SUBSTEPPING_VERSION_1) { + dev_err(fw_loader->dev, "substepping %d is out of supported range %d - %d\n", + sub_version, VSC_SUBSTEPPING_VERSION_0, VSC_SUBSTEPPING_VERSION_1); return -EINVAL; + } dev_info(fw_loader->dev, "silicon stepping version is %u:%u\n", version, sub_version); @@ -767,4 +773,4 @@ err_release_csi: return ret; } -EXPORT_SYMBOL_NS_GPL(vsc_tp_init, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_init, "VSC_TP"); diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c index 1618cca9a7317f5b2631b526b5e996a986f3186f..35d349fee76989ebc4a40f719bf854081d9ac961 100644 --- a/drivers/misc/mei/vsc-tp.c +++ b/drivers/misc/mei/vsc-tp.c @@ -299,7 +299,7 @@ int vsc_tp_xfer(struct vsc_tp *tp, u8 cmd, const void *obuf, size_t olen, return ret; } -EXPORT_SYMBOL_NS_GPL(vsc_tp_xfer, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_xfer, "VSC_TP"); /** * vsc_tp_rom_xfer - transfer data to rom code @@ -364,10 +364,8 @@ void vsc_tp_reset(struct vsc_tp *tp) gpiod_set_value_cansleep(tp->wakeupfw, 1); atomic_set(&tp->assert_cnt, 0); - - enable_irq(tp->spi->irq); } -EXPORT_SYMBOL_NS_GPL(vsc_tp_reset, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_reset, "VSC_TP"); /** * vsc_tp_need_read - check if device has data to sent @@ -385,7 +383,7 @@ bool vsc_tp_need_read(struct vsc_tp *tp) return true; } -EXPORT_SYMBOL_NS_GPL(vsc_tp_need_read, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_need_read, "VSC_TP"); /** * vsc_tp_register_event_cb - register a callback function to receive event @@ -402,7 +400,7 @@ int vsc_tp_register_event_cb(struct vsc_tp *tp, vsc_tp_event_cb_t event_cb, return 0; } -EXPORT_SYMBOL_NS_GPL(vsc_tp_register_event_cb, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_register_event_cb, "VSC_TP"); /** * vsc_tp_request_irq - request irq for vsc_tp device @@ -423,7 +421,7 @@ int vsc_tp_request_irq(struct vsc_tp *tp) return 0; } -EXPORT_SYMBOL_NS_GPL(vsc_tp_request_irq, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_request_irq, "VSC_TP"); /** * vsc_tp_free_irq - free irq for vsc_tp device @@ -433,7 +431,7 @@ void vsc_tp_free_irq(struct vsc_tp *tp) { free_irq(tp->spi->irq, tp); } -EXPORT_SYMBOL_NS_GPL(vsc_tp_free_irq, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_free_irq, "VSC_TP"); /** * vsc_tp_intr_synchronize - synchronize vsc_tp interrupt @@ -443,7 +441,7 @@ void vsc_tp_intr_synchronize(struct vsc_tp *tp) { synchronize_irq(tp->spi->irq); } -EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_synchronize, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_synchronize, "VSC_TP"); /** * vsc_tp_intr_enable - enable vsc_tp interrupt @@ -453,7 +451,7 @@ void vsc_tp_intr_enable(struct vsc_tp *tp) { enable_irq(tp->spi->irq); } -EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_enable, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_enable, "VSC_TP"); /** * vsc_tp_intr_disable - disable vsc_tp interrupt @@ -463,7 +461,7 @@ void vsc_tp_intr_disable(struct vsc_tp *tp) { disable_irq(tp->spi->irq); } -EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_disable, VSC_TP); +EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_disable, "VSC_TP"); static int vsc_tp_match_any(struct acpi_device *adev, void *data) { diff --git a/drivers/misc/ocxl/sysfs.c b/drivers/misc/ocxl/sysfs.c index 405180d47d9bff0aaa7a736bb3fecfbe318db961..07520d6e6dc55702696b8656440914c379e6e27a 100644 --- a/drivers/misc/ocxl/sysfs.c +++ b/drivers/misc/ocxl/sysfs.c @@ -125,7 +125,7 @@ static const struct vm_operations_struct global_mmio_vmops = { }; static int global_mmio_mmap(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, + const struct bin_attribute *bin_attr, struct vm_area_struct *vma) { struct ocxl_afu *afu = to_afu(kobj_to_dev(kobj)); diff --git a/drivers/misc/open-dice.c b/drivers/misc/open-dice.c index e6a61e6d9427fa70f239a2d57e254c5c04e6fb0c..24c29e0f00ef16a35f01e7069089402bcb13c9eb 100644 --- a/drivers/misc/open-dice.c +++ b/drivers/misc/open-dice.c @@ -178,7 +178,7 @@ static const struct of_device_id open_dice_of_match[] = { }; static struct platform_driver open_dice_driver = { - .remove_new = open_dice_remove, + .remove = open_dice_remove, .driver = { .name = DRIVER_NAME, .of_match_table = open_dice_of_match, diff --git a/drivers/misc/rpmb-core.c b/drivers/misc/rpmb-core.c index bc68cde1a8bfd8dada280eb07ba0e92d579fb8f7..2d653926cdbbb03976496f6034a0024cd0fc5fd4 100644 --- a/drivers/misc/rpmb-core.c +++ b/drivers/misc/rpmb-core.c @@ -13,7 +13,6 @@ #include static DEFINE_IDA(rpmb_ida); -static DEFINE_MUTEX(rpmb_mutex); /** * rpmb_dev_get() - increase rpmb device ref counter @@ -63,9 +62,7 @@ static void rpmb_dev_release(struct device *dev) { struct rpmb_dev *rdev = to_rpmb_dev(dev); - mutex_lock(&rpmb_mutex); - ida_simple_remove(&rpmb_ida, rdev->id); - mutex_unlock(&rpmb_mutex); + ida_free(&rpmb_ida, rdev->id); kfree(rdev->descr.dev_id); kfree(rdev); } @@ -175,9 +172,7 @@ struct rpmb_dev *rpmb_dev_register(struct device *dev, goto err_free_rdev; } - mutex_lock(&rpmb_mutex); - ret = ida_simple_get(&rpmb_ida, 0, 0, GFP_KERNEL); - mutex_unlock(&rpmb_mutex); + ret = ida_alloc(&rpmb_ida, GFP_KERNEL); if (ret < 0) goto err_free_dev_id; rdev->id = ret; diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 546eb06a40d045b610e954da156258aeb23fadf3..e40b027a88e25209933a20dc9dbd7db29cb81ba5 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -451,7 +451,7 @@ static struct platform_driver sram_driver = { .of_match_table = sram_dt_ids, }, .probe = sram_probe, - .remove_new = sram_remove, + .remove = sram_remove, }; static int __init sram_init(void) diff --git a/drivers/misc/ti-st/Kconfig b/drivers/misc/ti-st/Kconfig deleted file mode 100644 index 1503a6496f6327af8b4b819c7058329ab18da881..0000000000000000000000000000000000000000 --- a/drivers/misc/ti-st/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# TI's shared transport line discipline and the protocol -# drivers (BT, FM and GPS) -# -menu "Texas Instruments shared transport line discipline" -config TI_ST - tristate "Shared transport core driver" - depends on NET && TTY - depends on GPIOLIB || COMPILE_TEST - select FW_LOADER - help - This enables the shared transport core driver for TI - BT / FM and GPS combo chips. This enables protocol drivers - to register themselves with core and send data, the responses - are returned to relevant protocol drivers based on their - packet types. - -endmenu diff --git a/drivers/misc/ti-st/Makefile b/drivers/misc/ti-st/Makefile deleted file mode 100644 index 93393100952edfdf5261fd7e5cf839d03c92bc88..0000000000000000000000000000000000000000 --- a/drivers/misc/ti-st/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for TI's shared transport line discipline -# and its protocol drivers (BT, FM, GPS) -# -obj-$(CONFIG_TI_ST) += st_drv.o -st_drv-objs := st_core.o st_kim.o st_ll.o diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c deleted file mode 100644 index b878431553abce9aab2f26b18caf89fe9a6eb90e..0000000000000000000000000000000000000000 --- a/drivers/misc/ti-st/st_core.c +++ /dev/null @@ -1,918 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Shared Transport Line discipline driver Core - * This hooks up ST KIM driver and ST LL driver - * Copyright (C) 2009-2010 Texas Instruments - * Author: Pavan Savoy - */ - -#define pr_fmt(fmt) "(stc): " fmt -#include -#include -#include - -#include -#include - -#include -#include - -/* - * function pointer pointing to either, - * st_kim_recv during registration to receive fw download responses - * st_int_recv after registration to receive proto stack responses - */ -static void (*st_recv)(void *disc_data, const u8 *ptr, size_t count); - -/********************************************************************/ -static void add_channel_to_table(struct st_data_s *st_gdata, - struct st_proto_s *new_proto) -{ - pr_info("%s: id %d\n", __func__, new_proto->chnl_id); - /* list now has the channel id as index itself */ - st_gdata->list[new_proto->chnl_id] = new_proto; - st_gdata->is_registered[new_proto->chnl_id] = true; -} - -static void remove_channel_from_table(struct st_data_s *st_gdata, - struct st_proto_s *proto) -{ - pr_info("%s: id %d\n", __func__, proto->chnl_id); -/* st_gdata->list[proto->chnl_id] = NULL; */ - st_gdata->is_registered[proto->chnl_id] = false; -} - -/* - * called from KIM during firmware download. - * - * This is a wrapper function to tty->ops->write_room. - * It returns number of free space available in - * uart tx buffer. - */ -int st_get_uart_wr_room(struct st_data_s *st_gdata) -{ - if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { - pr_err("tty unavailable to perform write"); - return -1; - } - - return tty_write_room(st_gdata->tty); -} - -/* - * can be called in from - * -- KIM (during fw download) - * -- ST Core (during st_write) - * - * This is the internal write function - a wrapper - * to tty->ops->write - */ -int st_int_write(struct st_data_s *st_gdata, - const unsigned char *data, int count) -{ - struct tty_struct *tty; - if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { - pr_err("tty unavailable to perform write"); - return -EINVAL; - } - tty = st_gdata->tty; -#ifdef VERBOSE - print_hex_dump(KERN_DEBUG, "ops->write(tty, data, count); - -} - -/* - * push the skb received to relevant - * protocol stacks - */ -static void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) -{ - pr_debug(" %s(prot:%d) ", __func__, chnl_id); - - if (unlikely - (st_gdata == NULL || st_gdata->rx_skb == NULL - || st_gdata->is_registered[chnl_id] == false)) { - pr_err("chnl_id %d not registered, no data to send?", - chnl_id); - kfree_skb(st_gdata->rx_skb); - return; - } - /* - * this cannot fail - * this shouldn't take long - * - should be just skb_queue_tail for the - * protocol stack driver - */ - if (likely(st_gdata->list[chnl_id]->recv != NULL)) { - if (unlikely - (st_gdata->list[chnl_id]->recv - (st_gdata->list[chnl_id]->priv_data, st_gdata->rx_skb) - != 0)) { - pr_err(" proto stack %d's ->recv failed", chnl_id); - kfree_skb(st_gdata->rx_skb); - return; - } - } else { - pr_err(" proto stack %d's ->recv null", chnl_id); - kfree_skb(st_gdata->rx_skb); - } - return; -} - -/* - * st_reg_complete - to call registration complete callbacks - * of all protocol stack drivers - * This function is being called with spin lock held, protocol drivers are - * only expected to complete their waits and do nothing more than that. - */ -static void st_reg_complete(struct st_data_s *st_gdata, int err) -{ - unsigned char i = 0; - pr_info(" %s ", __func__); - for (i = 0; i < ST_MAX_CHANNELS; i++) { - if (likely(st_gdata != NULL && - st_gdata->is_registered[i] == true && - st_gdata->list[i]->reg_complete_cb != NULL)) { - st_gdata->list[i]->reg_complete_cb - (st_gdata->list[i]->priv_data, err); - pr_info("protocol %d's cb sent %d\n", i, err); - if (err) { /* cleanup registered protocol */ - st_gdata->is_registered[i] = false; - if (st_gdata->protos_registered) - st_gdata->protos_registered--; - } - } - } -} - -static inline int st_check_data_len(struct st_data_s *st_gdata, - unsigned char chnl_id, int len) -{ - int room = skb_tailroom(st_gdata->rx_skb); - - pr_debug("len %d room %d", len, room); - - if (!len) { - /* - * Received packet has only packet header and - * has zero length payload. So, ask ST CORE to - * forward the packet to protocol driver (BT/FM/GPS) - */ - st_send_frame(chnl_id, st_gdata); - - } else if (len > room) { - /* - * Received packet's payload length is larger. - * We can't accommodate it in created skb. - */ - pr_err("Data length is too large len %d room %d", len, - room); - kfree_skb(st_gdata->rx_skb); - } else { - /* - * Packet header has non-zero payload length and - * we have enough space in created skb. Lets read - * payload data */ - st_gdata->rx_state = ST_W4_DATA; - st_gdata->rx_count = len; - return len; - } - - /* Change ST state to continue to process next packet */ - st_gdata->rx_state = ST_W4_PACKET_TYPE; - st_gdata->rx_skb = NULL; - st_gdata->rx_count = 0; - st_gdata->rx_chnl = 0; - - return 0; -} - -/* - * st_wakeup_ack - internal function for action when wake-up ack - * received - */ -static inline void st_wakeup_ack(struct st_data_s *st_gdata, - unsigned char cmd) -{ - struct sk_buff *waiting_skb; - unsigned long flags = 0; - - spin_lock_irqsave(&st_gdata->lock, flags); - /* - * de-Q from waitQ and Q in txQ now that the - * chip is awake - */ - while ((waiting_skb = skb_dequeue(&st_gdata->tx_waitq))) - skb_queue_tail(&st_gdata->txq, waiting_skb); - - /* state forwarded to ST LL */ - st_ll_sleep_state(st_gdata, (unsigned long)cmd); - spin_unlock_irqrestore(&st_gdata->lock, flags); - - /* wake up to send the recently copied skbs from waitQ */ - st_tx_wakeup(st_gdata); -} - -/* - * st_int_recv - ST's internal receive function. - * Decodes received RAW data and forwards to corresponding - * client drivers (Bluetooth,FM,GPS..etc). - * This can receive various types of packets, - * HCI-Events, ACL, SCO, 4 types of HCI-LL PM packets - * CH-8 packets from FM, CH-9 packets from GPS cores. - */ -static void st_int_recv(void *disc_data, const u8 *ptr, size_t count) -{ - struct st_proto_s *proto; - unsigned short payload_len = 0; - int len = 0; - unsigned char type = 0; - unsigned char *plen; - struct st_data_s *st_gdata = (struct st_data_s *)disc_data; - unsigned long flags; - - if (st_gdata == NULL) { - pr_err(" received null from TTY "); - return; - } - - pr_debug("count %zu rx_state %ld" - "rx_count %ld", count, st_gdata->rx_state, - st_gdata->rx_count); - - spin_lock_irqsave(&st_gdata->lock, flags); - /* Decode received bytes here */ - while (count) { - if (st_gdata->rx_count) { - len = min_t(unsigned int, st_gdata->rx_count, count); - skb_put_data(st_gdata->rx_skb, ptr, len); - st_gdata->rx_count -= len; - count -= len; - ptr += len; - - if (st_gdata->rx_count) - continue; - - /* Check ST RX state machine , where are we? */ - switch (st_gdata->rx_state) { - /* Waiting for complete packet ? */ - case ST_W4_DATA: - pr_debug("Complete pkt received"); - /* - * Ask ST CORE to forward - * the packet to protocol driver - */ - st_send_frame(st_gdata->rx_chnl, st_gdata); - - st_gdata->rx_state = ST_W4_PACKET_TYPE; - st_gdata->rx_skb = NULL; - continue; - /* parse the header to know details */ - case ST_W4_HEADER: - proto = st_gdata->list[st_gdata->rx_chnl]; - plen = - &st_gdata->rx_skb->data - [proto->offset_len_in_hdr]; - pr_debug("plen pointing to %x\n", *plen); - if (proto->len_size == 1) /* 1 byte len field */ - payload_len = *(unsigned char *)plen; - else if (proto->len_size == 2) - payload_len = - __le16_to_cpu(*(unsigned short *)plen); - else - pr_info("%s: invalid length " - "for id %d\n", - __func__, proto->chnl_id); - st_check_data_len(st_gdata, proto->chnl_id, - payload_len); - pr_debug("off %d, pay len %d\n", - proto->offset_len_in_hdr, payload_len); - continue; - } /* end of switch rx_state */ - } - - /* end of if rx_count */ - - /* - * Check first byte of packet and identify module - * owner (BT/FM/GPS) - */ - switch (*ptr) { - case LL_SLEEP_IND: - case LL_SLEEP_ACK: - case LL_WAKE_UP_IND: - pr_debug("PM packet"); - /* - * this takes appropriate action based on - * sleep state received -- - */ - st_ll_sleep_state(st_gdata, *ptr); - /* - * if WAKEUP_IND collides copy from waitq to txq - * and assume chip awake - */ - spin_unlock_irqrestore(&st_gdata->lock, flags); - if (st_ll_getstate(st_gdata) == ST_LL_AWAKE) - st_wakeup_ack(st_gdata, LL_WAKE_UP_ACK); - spin_lock_irqsave(&st_gdata->lock, flags); - - ptr++; - count--; - continue; - case LL_WAKE_UP_ACK: - pr_debug("PM packet"); - - spin_unlock_irqrestore(&st_gdata->lock, flags); - /* wake up ack received */ - st_wakeup_ack(st_gdata, *ptr); - spin_lock_irqsave(&st_gdata->lock, flags); - - ptr++; - count--; - continue; - /* Unknown packet? */ - default: - type = *ptr; - - /* - * Default case means non-HCILL packets, - * possibilities are packets for: - * (a) valid protocol - Supported Protocols within - * the ST_MAX_CHANNELS. - * (b) registered protocol - Checked by - * "st_gdata->list[type] == NULL)" are supported - * protocols only. - * Rules out any invalid protocol and - * unregistered protocols with channel ID < 16. - */ - - if ((type >= ST_MAX_CHANNELS) || - (st_gdata->list[type] == NULL)) { - pr_err("chip/interface misbehavior: " - "dropping frame starting " - "with 0x%02x\n", type); - goto done; - } - - st_gdata->rx_skb = alloc_skb( - st_gdata->list[type]->max_frame_size, - GFP_ATOMIC); - if (st_gdata->rx_skb == NULL) { - pr_err("out of memory: dropping\n"); - goto done; - } - - skb_reserve(st_gdata->rx_skb, - st_gdata->list[type]->reserve); - /* next 2 required for BT only */ - st_gdata->rx_skb->cb[0] = type; /*pkt_type*/ - st_gdata->rx_skb->cb[1] = 0; /*incoming*/ - st_gdata->rx_chnl = *ptr; - st_gdata->rx_state = ST_W4_HEADER; - st_gdata->rx_count = st_gdata->list[type]->hdr_len; - pr_debug("rx_count %ld\n", st_gdata->rx_count); - } - ptr++; - count--; - } -done: - spin_unlock_irqrestore(&st_gdata->lock, flags); - pr_debug("done %s", __func__); - return; -} - -/* - * st_int_dequeue - internal de-Q function. - * If the previous data set was not written - * completely, return that skb which has the pending data. - * In normal cases, return top of txq. - */ -static struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata) -{ - struct sk_buff *returning_skb; - - pr_debug("%s", __func__); - if (st_gdata->tx_skb != NULL) { - returning_skb = st_gdata->tx_skb; - st_gdata->tx_skb = NULL; - return returning_skb; - } - return skb_dequeue(&st_gdata->txq); -} - -/* - * st_int_enqueue - internal Q-ing function. - * Will either Q the skb to txq or the tx_waitq - * depending on the ST LL state. - * If the chip is asleep, then Q it onto waitq and - * wakeup the chip. - * txq and waitq needs protection since the other contexts - * may be sending data, waking up chip. - */ -static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) -{ - unsigned long flags = 0; - - pr_debug("%s", __func__); - spin_lock_irqsave(&st_gdata->lock, flags); - - switch (st_ll_getstate(st_gdata)) { - case ST_LL_AWAKE: - pr_debug("ST LL is AWAKE, sending normally"); - skb_queue_tail(&st_gdata->txq, skb); - break; - case ST_LL_ASLEEP_TO_AWAKE: - skb_queue_tail(&st_gdata->tx_waitq, skb); - break; - case ST_LL_AWAKE_TO_ASLEEP: - pr_err("ST LL is illegal state(%ld)," - "purging received skb.", st_ll_getstate(st_gdata)); - dev_kfree_skb_irq(skb); - break; - case ST_LL_ASLEEP: - skb_queue_tail(&st_gdata->tx_waitq, skb); - st_ll_wakeup(st_gdata); - break; - default: - pr_err("ST LL is illegal state(%ld)," - "purging received skb.", st_ll_getstate(st_gdata)); - dev_kfree_skb_irq(skb); - break; - } - - spin_unlock_irqrestore(&st_gdata->lock, flags); - pr_debug("done %s", __func__); - return; -} - -/* - * internal wakeup function - * called from either - * - TTY layer when write's finished - * - st_write (in context of the protocol stack) - */ -static void work_fn_write_wakeup(struct work_struct *work) -{ - struct st_data_s *st_gdata = container_of(work, struct st_data_s, - work_write_wakeup); - - st_tx_wakeup((void *)st_gdata); -} -void st_tx_wakeup(struct st_data_s *st_data) -{ - struct sk_buff *skb; - unsigned long flags; /* for irq save flags */ - pr_debug("%s", __func__); - /* check for sending & set flag sending here */ - if (test_and_set_bit(ST_TX_SENDING, &st_data->tx_state)) { - pr_debug("ST already sending"); - /* keep sending */ - set_bit(ST_TX_WAKEUP, &st_data->tx_state); - return; - /* TX_WAKEUP will be checked in another - * context - */ - } - do { /* come back if st_tx_wakeup is set */ - /* woke-up to write */ - clear_bit(ST_TX_WAKEUP, &st_data->tx_state); - while ((skb = st_int_dequeue(st_data))) { - int len; - spin_lock_irqsave(&st_data->lock, flags); - /* enable wake-up from TTY */ - set_bit(TTY_DO_WRITE_WAKEUP, &st_data->tty->flags); - len = st_int_write(st_data, skb->data, skb->len); - skb_pull(skb, len); - /* if skb->len = len as expected, skb->len=0 */ - if (skb->len) { - /* would be the next skb to be sent */ - st_data->tx_skb = skb; - spin_unlock_irqrestore(&st_data->lock, flags); - break; - } - dev_kfree_skb_irq(skb); - spin_unlock_irqrestore(&st_data->lock, flags); - } - /* if wake-up is set in another context- restart sending */ - } while (test_bit(ST_TX_WAKEUP, &st_data->tx_state)); - - /* clear flag sending */ - clear_bit(ST_TX_SENDING, &st_data->tx_state); -} - -/********************************************************************/ -/* functions called from ST KIM -*/ -void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf) -{ - seq_printf(buf, "[%d]\nBT=%c\nFM=%c\nGPS=%c\n", - st_gdata->protos_registered, - st_gdata->is_registered[0x04] == true ? 'R' : 'U', - st_gdata->is_registered[0x08] == true ? 'R' : 'U', - st_gdata->is_registered[0x09] == true ? 'R' : 'U'); -} - -/********************************************************************/ -/* - * functions called from protocol stack drivers - * to be EXPORT-ed - */ -long st_register(struct st_proto_s *new_proto) -{ - struct st_data_s *st_gdata; - long err = 0; - unsigned long flags = 0; - - st_kim_ref(&st_gdata, 0); - if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL - || new_proto->reg_complete_cb == NULL) { - pr_err("gdata/new_proto/recv or reg_complete_cb not ready"); - return -EINVAL; - } - - if (new_proto->chnl_id >= ST_MAX_CHANNELS) { - pr_err("chnl_id %d not supported", new_proto->chnl_id); - return -EPROTONOSUPPORT; - } - - if (st_gdata->is_registered[new_proto->chnl_id] == true) { - pr_err("chnl_id %d already registered", new_proto->chnl_id); - return -EALREADY; - } - - /* can be from process context only */ - spin_lock_irqsave(&st_gdata->lock, flags); - - if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) { - pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->chnl_id); - /* fw download in progress */ - - add_channel_to_table(st_gdata, new_proto); - st_gdata->protos_registered++; - new_proto->write = st_write; - - set_bit(ST_REG_PENDING, &st_gdata->st_state); - spin_unlock_irqrestore(&st_gdata->lock, flags); - return -EINPROGRESS; - } else if (st_gdata->protos_registered == ST_EMPTY) { - pr_info(" chnl_id list empty :%d ", new_proto->chnl_id); - set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); - st_recv = st_kim_recv; - - /* enable the ST LL - to set default chip state */ - st_ll_enable(st_gdata); - - /* release lock previously held - re-locked below */ - spin_unlock_irqrestore(&st_gdata->lock, flags); - - /* - * this may take a while to complete - * since it involves BT fw download - */ - err = st_kim_start(st_gdata->kim_data); - if (err != 0) { - clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); - if ((st_gdata->protos_registered != ST_EMPTY) && - (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { - pr_err(" KIM failure complete callback "); - spin_lock_irqsave(&st_gdata->lock, flags); - st_reg_complete(st_gdata, err); - spin_unlock_irqrestore(&st_gdata->lock, flags); - clear_bit(ST_REG_PENDING, &st_gdata->st_state); - } - return -EINVAL; - } - - spin_lock_irqsave(&st_gdata->lock, flags); - - clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); - st_recv = st_int_recv; - - /* - * this is where all pending registration - * are signalled to be complete by calling callback functions - */ - if ((st_gdata->protos_registered != ST_EMPTY) && - (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { - pr_debug(" call reg complete callback "); - st_reg_complete(st_gdata, 0); - } - clear_bit(ST_REG_PENDING, &st_gdata->st_state); - - /* - * check for already registered once more, - * since the above check is old - */ - if (st_gdata->is_registered[new_proto->chnl_id] == true) { - pr_err(" proto %d already registered ", - new_proto->chnl_id); - spin_unlock_irqrestore(&st_gdata->lock, flags); - return -EALREADY; - } - - add_channel_to_table(st_gdata, new_proto); - st_gdata->protos_registered++; - new_proto->write = st_write; - spin_unlock_irqrestore(&st_gdata->lock, flags); - return err; - } - /* if fw is already downloaded & new stack registers protocol */ - else { - add_channel_to_table(st_gdata, new_proto); - st_gdata->protos_registered++; - new_proto->write = st_write; - - /* lock already held before entering else */ - spin_unlock_irqrestore(&st_gdata->lock, flags); - return err; - } -} -EXPORT_SYMBOL_GPL(st_register); - -/* - * to unregister a protocol - - * to be called from protocol stack driver - */ -long st_unregister(struct st_proto_s *proto) -{ - long err = 0; - unsigned long flags = 0; - struct st_data_s *st_gdata; - - pr_debug("%s: %d ", __func__, proto->chnl_id); - - st_kim_ref(&st_gdata, 0); - if (!st_gdata || proto->chnl_id >= ST_MAX_CHANNELS) { - pr_err(" chnl_id %d not supported", proto->chnl_id); - return -EPROTONOSUPPORT; - } - - spin_lock_irqsave(&st_gdata->lock, flags); - - if (st_gdata->is_registered[proto->chnl_id] == false) { - pr_err(" chnl_id %d not registered", proto->chnl_id); - spin_unlock_irqrestore(&st_gdata->lock, flags); - return -EPROTONOSUPPORT; - } - - if (st_gdata->protos_registered) - st_gdata->protos_registered--; - - remove_channel_from_table(st_gdata, proto); - spin_unlock_irqrestore(&st_gdata->lock, flags); - - if ((st_gdata->protos_registered == ST_EMPTY) && - (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { - pr_info(" all chnl_ids unregistered "); - - /* stop traffic on tty */ - if (st_gdata->tty) { - tty_ldisc_flush(st_gdata->tty); - stop_tty(st_gdata->tty); - } - - /* all chnl_ids now unregistered */ - st_kim_stop(st_gdata->kim_data); - /* disable ST LL */ - st_ll_disable(st_gdata); - } - return err; -} - -/* - * called in protocol stack drivers - * via the write function pointer - */ -long st_write(struct sk_buff *skb) -{ - struct st_data_s *st_gdata; - long len; - - st_kim_ref(&st_gdata, 0); - if (unlikely(skb == NULL || st_gdata == NULL - || st_gdata->tty == NULL)) { - pr_err("data/tty unavailable to perform write"); - return -EINVAL; - } - - pr_debug("%d to be written", skb->len); - len = skb->len; - - /* st_ll to decide where to enqueue the skb */ - st_int_enqueue(st_gdata, skb); - /* wake up */ - st_tx_wakeup(st_gdata); - - /* return number of bytes written */ - return len; -} - -/* for protocols making use of shared transport */ -EXPORT_SYMBOL_GPL(st_unregister); - -/********************************************************************/ -/* - * functions called from TTY layer - */ -static int st_tty_open(struct tty_struct *tty) -{ - struct st_data_s *st_gdata; - pr_info("%s ", __func__); - - st_kim_ref(&st_gdata, 0); - st_gdata->tty = tty; - tty->disc_data = st_gdata; - - /* don't do an wakeup for now */ - clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - - /* mem already allocated - */ - tty->receive_room = 65536; - /* Flush any pending characters in the driver and discipline. */ - tty_ldisc_flush(tty); - tty_driver_flush_buffer(tty); - /* - * signal to UIM via KIM that - - * installation of N_TI_WL ldisc is complete - */ - st_kim_complete(st_gdata->kim_data); - pr_debug("done %s", __func__); - - return 0; -} - -static void st_tty_close(struct tty_struct *tty) -{ - unsigned char i; - unsigned long flags; - struct st_data_s *st_gdata = tty->disc_data; - - pr_info("%s ", __func__); - - /* - * TODO: - * if a protocol has been registered & line discipline - * un-installed for some reason - what should be done ? - */ - spin_lock_irqsave(&st_gdata->lock, flags); - for (i = ST_BT; i < ST_MAX_CHANNELS; i++) { - if (st_gdata->is_registered[i] == true) - pr_err("%d not un-registered", i); - st_gdata->list[i] = NULL; - st_gdata->is_registered[i] = false; - } - st_gdata->protos_registered = 0; - spin_unlock_irqrestore(&st_gdata->lock, flags); - /* - * signal to UIM via KIM that - - * N_TI_WL ldisc is un-installed - */ - st_kim_complete(st_gdata->kim_data); - st_gdata->tty = NULL; - /* Flush any pending characters in the driver and discipline. */ - tty_ldisc_flush(tty); - tty_driver_flush_buffer(tty); - - spin_lock_irqsave(&st_gdata->lock, flags); - /* empty out txq and tx_waitq */ - skb_queue_purge(&st_gdata->txq); - skb_queue_purge(&st_gdata->tx_waitq); - /* reset the TTY Rx states of ST */ - st_gdata->rx_count = 0; - st_gdata->rx_state = ST_W4_PACKET_TYPE; - kfree_skb(st_gdata->rx_skb); - st_gdata->rx_skb = NULL; - spin_unlock_irqrestore(&st_gdata->lock, flags); - - pr_debug("%s: done ", __func__); -} - -static void st_tty_receive(struct tty_struct *tty, const u8 *data, - const u8 *tty_flags, size_t count) -{ -#ifdef VERBOSE - print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, - 16, 1, data, count, 0); -#endif - - /* - * if fw download is in progress then route incoming data - * to KIM for validation - */ - st_recv(tty->disc_data, data, count); - pr_debug("done %s", __func__); -} - -/* - * wake-up function called in from the TTY layer - * inside the internal wakeup function will be called - */ -static void st_tty_wakeup(struct tty_struct *tty) -{ - struct st_data_s *st_gdata = tty->disc_data; - pr_debug("%s ", __func__); - /* don't do an wakeup for now */ - clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - - /* - * schedule the internal wakeup instead of calling directly to - * avoid lockup (port->lock needed in tty->ops->write is - * already taken here - */ - schedule_work(&st_gdata->work_write_wakeup); -} - -static void st_tty_flush_buffer(struct tty_struct *tty) -{ - struct st_data_s *st_gdata = tty->disc_data; - pr_debug("%s ", __func__); - - kfree_skb(st_gdata->tx_skb); - st_gdata->tx_skb = NULL; - - tty_driver_flush_buffer(tty); - return; -} - -static struct tty_ldisc_ops st_ldisc_ops = { - .num = N_TI_WL, - .name = "n_st", - .open = st_tty_open, - .close = st_tty_close, - .receive_buf = st_tty_receive, - .write_wakeup = st_tty_wakeup, - .flush_buffer = st_tty_flush_buffer, - .owner = THIS_MODULE -}; - -/********************************************************************/ -int st_core_init(struct st_data_s **core_data) -{ - struct st_data_s *st_gdata; - long err; - - err = tty_register_ldisc(&st_ldisc_ops); - if (err) { - pr_err("error registering %d line discipline %ld", - N_TI_WL, err); - return err; - } - pr_debug("registered n_shared line discipline"); - - st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL); - if (!st_gdata) { - pr_err("memory allocation failed"); - err = -ENOMEM; - goto err_unreg_ldisc; - } - - /* Initialize ST TxQ and Tx waitQ queue head. All BT/FM/GPS module skb's - * will be pushed in this queue for actual transmission. - */ - skb_queue_head_init(&st_gdata->txq); - skb_queue_head_init(&st_gdata->tx_waitq); - - /* Locking used in st_int_enqueue() to avoid multiple execution */ - spin_lock_init(&st_gdata->lock); - - err = st_ll_init(st_gdata); - if (err) { - pr_err("error during st_ll initialization(%ld)", err); - goto err_free_gdata; - } - - INIT_WORK(&st_gdata->work_write_wakeup, work_fn_write_wakeup); - - *core_data = st_gdata; - return 0; -err_free_gdata: - kfree(st_gdata); -err_unreg_ldisc: - tty_unregister_ldisc(&st_ldisc_ops); - return err; -} - -void st_core_exit(struct st_data_s *st_gdata) -{ - long err; - /* internal module cleanup */ - err = st_ll_deinit(st_gdata); - if (err) - pr_err("error during deinit of ST LL %ld", err); - - if (st_gdata != NULL) { - /* Free ST Tx Qs and skbs */ - skb_queue_purge(&st_gdata->txq); - skb_queue_purge(&st_gdata->tx_waitq); - kfree_skb(st_gdata->rx_skb); - kfree_skb(st_gdata->tx_skb); - /* TTY ldisc cleanup */ - tty_unregister_ldisc(&st_ldisc_ops); - /* free the global data pointer */ - kfree(st_gdata); - } -} diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c deleted file mode 100644 index ff172cf4614d6b827a2463fb8a2f2d2e9a7c4fa6..0000000000000000000000000000000000000000 --- a/drivers/misc/ti-st/st_kim.c +++ /dev/null @@ -1,839 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Shared Transport Line discipline driver Core - * Init Manager module responsible for GPIO control - * and firmware download - * Copyright (C) 2009-2010 Texas Instruments - * Author: Pavan Savoy - */ - -#define pr_fmt(fmt) "(stk) :" fmt -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */ -static struct platform_device *st_kim_devices[MAX_ST_DEVICES]; - -/**********************************************************************/ -/* internal functions */ - -/* - * st_get_plat_device - - * function which returns the reference to the platform device - * requested by id. As of now only 1 such device exists (id=0) - * the context requesting for reference can get the id to be - * requested by a. The protocol driver which is registering or - * b. the tty device which is opened. - */ -static struct platform_device *st_get_plat_device(int id) -{ - return st_kim_devices[id]; -} - -/* - * validate_firmware_response - - * function to return whether the firmware response was proper - * in case of error don't complete so that waiting for proper - * response times out - */ -static void validate_firmware_response(struct kim_data_s *kim_gdata) -{ - struct sk_buff *skb = kim_gdata->rx_skb; - if (!skb) - return; - - /* - * these magic numbers are the position in the response buffer which - * allows us to distinguish whether the response is for the read - * version info. command - */ - if (skb->data[2] == 0x01 && skb->data[3] == 0x01 && - skb->data[4] == 0x10 && skb->data[5] == 0x00) { - /* fw version response */ - memcpy(kim_gdata->resp_buffer, - kim_gdata->rx_skb->data, - kim_gdata->rx_skb->len); - kim_gdata->rx_state = ST_W4_PACKET_TYPE; - kim_gdata->rx_skb = NULL; - kim_gdata->rx_count = 0; - } else if (unlikely(skb->data[5] != 0)) { - pr_err("no proper response during fw download"); - pr_err("data6 %x", skb->data[5]); - kfree_skb(skb); - return; /* keep waiting for the proper response */ - } - /* becos of all the script being downloaded */ - complete_all(&kim_gdata->kim_rcvd); - kfree_skb(skb); -} - -/* - * check for data len received inside kim_int_recv - * most often hit the last case to update state to waiting for data - */ -static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len) -{ - register int room = skb_tailroom(kim_gdata->rx_skb); - - pr_debug("len %d room %d", len, room); - - if (!len) { - validate_firmware_response(kim_gdata); - } else if (len > room) { - /* - * Received packet's payload length is larger. - * We can't accommodate it in created skb. - */ - pr_err("Data length is too large len %d room %d", len, - room); - kfree_skb(kim_gdata->rx_skb); - } else { - /* - * Packet header has non-zero payload length and - * we have enough space in created skb. Lets read - * payload data */ - kim_gdata->rx_state = ST_W4_DATA; - kim_gdata->rx_count = len; - return len; - } - - /* - * Change ST LL state to continue to process next - * packet - */ - kim_gdata->rx_state = ST_W4_PACKET_TYPE; - kim_gdata->rx_skb = NULL; - kim_gdata->rx_count = 0; - - return 0; -} - -/* - * kim_int_recv - receive function called during firmware download - * firmware download responses on different UART drivers - * have been observed to come in bursts of different - * tty_receive and hence the logic - */ -static void kim_int_recv(struct kim_data_s *kim_gdata, const u8 *ptr, - size_t count) -{ - int len = 0; - unsigned char *plen; - - pr_debug("%s", __func__); - /* Decode received bytes here */ - while (count) { - if (kim_gdata->rx_count) { - len = min_t(unsigned int, kim_gdata->rx_count, count); - skb_put_data(kim_gdata->rx_skb, ptr, len); - kim_gdata->rx_count -= len; - count -= len; - ptr += len; - - if (kim_gdata->rx_count) - continue; - - /* Check ST RX state machine , where are we? */ - switch (kim_gdata->rx_state) { - /* Waiting for complete packet ? */ - case ST_W4_DATA: - pr_debug("Complete pkt received"); - validate_firmware_response(kim_gdata); - kim_gdata->rx_state = ST_W4_PACKET_TYPE; - kim_gdata->rx_skb = NULL; - continue; - /* Waiting for Bluetooth event header ? */ - case ST_W4_HEADER: - plen = - (unsigned char *)&kim_gdata->rx_skb->data[1]; - pr_debug("event hdr: plen 0x%02x\n", *plen); - kim_check_data_len(kim_gdata, *plen); - continue; - } /* end of switch */ - } /* end of if rx_state */ - switch (*ptr) { - /* Bluetooth event packet? */ - case 0x04: - kim_gdata->rx_state = ST_W4_HEADER; - kim_gdata->rx_count = 2; - break; - default: - pr_info("unknown packet"); - ptr++; - count--; - continue; - } - ptr++; - count--; - kim_gdata->rx_skb = - alloc_skb(1024+8, GFP_ATOMIC); - if (!kim_gdata->rx_skb) { - pr_err("can't allocate mem for new packet"); - kim_gdata->rx_state = ST_W4_PACKET_TYPE; - kim_gdata->rx_count = 0; - return; - } - skb_reserve(kim_gdata->rx_skb, 8); - kim_gdata->rx_skb->cb[0] = 4; - kim_gdata->rx_skb->cb[1] = 0; - - } - return; -} - -static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name) -{ - unsigned short version = 0, chip = 0, min_ver = 0, maj_ver = 0; - static const char read_ver_cmd[] = { 0x01, 0x01, 0x10, 0x00 }; - long time_left; - - pr_debug("%s", __func__); - - reinit_completion(&kim_gdata->kim_rcvd); - if (4 != st_int_write(kim_gdata->core_data, read_ver_cmd, 4)) { - pr_err("kim: couldn't write 4 bytes"); - return -EIO; - } - - time_left = wait_for_completion_interruptible_timeout( - &kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME)); - if (time_left <= 0) { - pr_err(" waiting for ver info- timed out or received signal"); - return time_left ? -ERESTARTSYS : -ETIMEDOUT; - } - reinit_completion(&kim_gdata->kim_rcvd); - /* - * the positions 12 & 13 in the response buffer provide with the - * chip, major & minor numbers - */ - - version = - MAKEWORD(kim_gdata->resp_buffer[12], - kim_gdata->resp_buffer[13]); - chip = (version & 0x7C00) >> 10; - min_ver = (version & 0x007F); - maj_ver = (version & 0x0380) >> 7; - - if (version & 0x8000) - maj_ver |= 0x0008; - - sprintf(bts_scr_name, "ti-connectivity/TIInit_%d.%d.%d.bts", - chip, maj_ver, min_ver); - - /* to be accessed later via sysfs entry */ - kim_gdata->version.full = version; - kim_gdata->version.chip = chip; - kim_gdata->version.maj_ver = maj_ver; - kim_gdata->version.min_ver = min_ver; - - pr_info("%s", bts_scr_name); - return 0; -} - -static void skip_change_remote_baud(unsigned char **ptr, long *len) -{ - unsigned char *nxt_action, *cur_action; - cur_action = *ptr; - - nxt_action = cur_action + sizeof(struct bts_action) + - ((struct bts_action *) cur_action)->size; - - if (((struct bts_action *) nxt_action)->type != ACTION_WAIT_EVENT) { - pr_err("invalid action after change remote baud command"); - } else { - *ptr = *ptr + sizeof(struct bts_action) + - ((struct bts_action *)cur_action)->size; - *len = *len - (sizeof(struct bts_action) + - ((struct bts_action *)cur_action)->size); - /* warn user on not commenting these in firmware */ - pr_warn("skipping the wait event of change remote baud"); - } -} - -/* - * download_firmware - - * internal function which parses through the .bts firmware - * script file intreprets SEND, DELAY actions only as of now - */ -static long download_firmware(struct kim_data_s *kim_gdata) -{ - long err = 0; - long len = 0; - unsigned char *ptr = NULL; - unsigned char *action_ptr = NULL; - unsigned char bts_scr_name[40] = { 0 }; /* 40 char long bts scr name? */ - int wr_room_space; - int cmd_size; - unsigned long timeout; - - err = read_local_version(kim_gdata, bts_scr_name); - if (err != 0) { - pr_err("kim: failed to read local ver"); - return err; - } - err = - request_firmware(&kim_gdata->fw_entry, bts_scr_name, - &kim_gdata->kim_pdev->dev); - if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) || - (kim_gdata->fw_entry->size == 0))) { - pr_err(" request_firmware failed(errno %ld) for %s", err, - bts_scr_name); - return -EINVAL; - } - ptr = (void *)kim_gdata->fw_entry->data; - len = kim_gdata->fw_entry->size; - /* - * bts_header to remove out magic number and - * version - */ - ptr += sizeof(struct bts_header); - len -= sizeof(struct bts_header); - - while (len > 0 && ptr) { - pr_debug(" action size %d, type %d ", - ((struct bts_action *)ptr)->size, - ((struct bts_action *)ptr)->type); - - switch (((struct bts_action *)ptr)->type) { - case ACTION_SEND_COMMAND: /* action send */ - pr_debug("S"); - action_ptr = &(((struct bts_action *)ptr)->data[0]); - if (unlikely - (((struct hci_command *)action_ptr)->opcode == - 0xFF36)) { - /* - * ignore remote change - * baud rate HCI VS command - */ - pr_warn("change remote baud" - " rate command in firmware"); - skip_change_remote_baud(&ptr, &len); - break; - } - /* - * Make sure we have enough free space in uart - * tx buffer to write current firmware command - */ - cmd_size = ((struct bts_action *)ptr)->size; - timeout = jiffies + msecs_to_jiffies(CMD_WR_TIME); - do { - wr_room_space = - st_get_uart_wr_room(kim_gdata->core_data); - if (wr_room_space < 0) { - pr_err("Unable to get free " - "space info from uart tx buffer"); - release_firmware(kim_gdata->fw_entry); - return wr_room_space; - } - mdelay(1); /* wait 1ms before checking room */ - } while ((wr_room_space < cmd_size) && - time_before(jiffies, timeout)); - - /* Timeout happened ? */ - if (time_after_eq(jiffies, timeout)) { - pr_err("Timeout while waiting for free " - "free space in uart tx buffer"); - release_firmware(kim_gdata->fw_entry); - return -ETIMEDOUT; - } - /* - * reinit completion before sending for the - * relevant wait - */ - reinit_completion(&kim_gdata->kim_rcvd); - - /* - * Free space found in uart buffer, call st_int_write - * to send current firmware command to the uart tx - * buffer. - */ - err = st_int_write(kim_gdata->core_data, - ((struct bts_action_send *)action_ptr)->data, - ((struct bts_action *)ptr)->size); - if (unlikely(err < 0)) { - release_firmware(kim_gdata->fw_entry); - return err; - } - /* - * Check number of bytes written to the uart tx buffer - * and requested command write size - */ - if (err != cmd_size) { - pr_err("Number of bytes written to uart " - "tx buffer are not matching with " - "requested cmd write size"); - release_firmware(kim_gdata->fw_entry); - return -EIO; - } - break; - case ACTION_WAIT_EVENT: /* wait */ - pr_debug("W"); - err = wait_for_completion_interruptible_timeout( - &kim_gdata->kim_rcvd, - msecs_to_jiffies(CMD_RESP_TIME)); - if (err <= 0) { - pr_err("response timeout/signaled during fw download "); - /* timed out */ - release_firmware(kim_gdata->fw_entry); - return err ? -ERESTARTSYS : -ETIMEDOUT; - } - reinit_completion(&kim_gdata->kim_rcvd); - break; - case ACTION_DELAY: /* sleep */ - pr_info("sleep command in scr"); - action_ptr = &(((struct bts_action *)ptr)->data[0]); - mdelay(((struct bts_action_delay *)action_ptr)->msec); - break; - } - len = - len - (sizeof(struct bts_action) + - ((struct bts_action *)ptr)->size); - ptr = - ptr + sizeof(struct bts_action) + - ((struct bts_action *)ptr)->size; - } - /* fw download complete */ - release_firmware(kim_gdata->fw_entry); - return 0; -} - -/**********************************************************************/ -/* functions called from ST core */ -/* called from ST Core, when REG_IN_PROGRESS (registration in progress) - * can be because of - * 1. response to read local version - * 2. during send/recv's of firmware download - */ -void st_kim_recv(void *disc_data, const u8 *data, size_t count) -{ - struct st_data_s *st_gdata = (struct st_data_s *)disc_data; - struct kim_data_s *kim_gdata = st_gdata->kim_data; - - /* - * proceed to gather all data and distinguish read fw version response - * from other fw responses when data gathering is complete - */ - kim_int_recv(kim_gdata, data, count); - return; -} - -/* - * to signal completion of line discipline installation - * called from ST Core, upon tty_open - */ -void st_kim_complete(void *kim_data) -{ - struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; - complete(&kim_gdata->ldisc_installed); -} - -/* - * st_kim_start - called from ST Core upon 1st registration - * This involves toggling the chip enable gpio, reading - * the firmware version from chip, forming the fw file name - * based on the chip version, requesting the fw, parsing it - * and perform download(send/recv). - */ -long st_kim_start(void *kim_data) -{ - long err = 0; - long retry = POR_RETRY_COUNT; - struct ti_st_plat_data *pdata; - struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; - - pr_info(" %s", __func__); - pdata = kim_gdata->kim_pdev->dev.platform_data; - - do { - /* platform specific enabling code here */ - if (pdata->chip_enable) - pdata->chip_enable(kim_gdata); - - /* Configure BT nShutdown to HIGH state */ - gpio_set_value_cansleep(kim_gdata->nshutdown, GPIO_LOW); - mdelay(5); /* FIXME: a proper toggle */ - gpio_set_value_cansleep(kim_gdata->nshutdown, GPIO_HIGH); - mdelay(100); - /* re-initialize the completion */ - reinit_completion(&kim_gdata->ldisc_installed); - /* send notification to UIM */ - kim_gdata->ldisc_install = 1; - pr_info("ldisc_install = 1"); - sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, - NULL, "install"); - /* wait for ldisc to be installed */ - err = wait_for_completion_interruptible_timeout( - &kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME)); - if (!err) { - /* - * ldisc installation timeout, - * flush uart, power cycle BT_EN - */ - pr_err("ldisc installation timeout"); - err = st_kim_stop(kim_gdata); - continue; - } else { - /* ldisc installed now */ - pr_info("line discipline installed"); - err = download_firmware(kim_gdata); - if (err != 0) { - /* - * ldisc installed but fw download failed, - * flush uart & power cycle BT_EN - */ - pr_err("download firmware failed"); - err = st_kim_stop(kim_gdata); - continue; - } else { /* on success don't retry */ - break; - } - } - } while (retry--); - return err; -} - -/* - * st_kim_stop - stop communication with chip. - * This can be called from ST Core/KIM, on the- - * (a) last un-register when chip need not be powered there-after, - * (b) upon failure to either install ldisc or download firmware. - * The function is responsible to (a) notify UIM about un-installation, - * (b) flush UART if the ldisc was installed. - * (c) reset BT_EN - pull down nshutdown at the end. - * (d) invoke platform's chip disabling routine. - */ -long st_kim_stop(void *kim_data) -{ - long err = 0; - struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; - struct ti_st_plat_data *pdata = - kim_gdata->kim_pdev->dev.platform_data; - struct tty_struct *tty = kim_gdata->core_data->tty; - - reinit_completion(&kim_gdata->ldisc_installed); - - if (tty) { /* can be called before ldisc is installed */ - /* Flush any pending characters in the driver and discipline. */ - tty_ldisc_flush(tty); - tty_driver_flush_buffer(tty); - } - - /* send uninstall notification to UIM */ - pr_info("ldisc_install = 0"); - kim_gdata->ldisc_install = 0; - sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install"); - - /* wait for ldisc to be un-installed */ - err = wait_for_completion_interruptible_timeout( - &kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME)); - if (!err) { /* timeout */ - pr_err(" timed out waiting for ldisc to be un-installed"); - err = -ETIMEDOUT; - } - - /* By default configure BT nShutdown to LOW state */ - gpio_set_value_cansleep(kim_gdata->nshutdown, GPIO_LOW); - mdelay(1); - gpio_set_value_cansleep(kim_gdata->nshutdown, GPIO_HIGH); - mdelay(1); - gpio_set_value_cansleep(kim_gdata->nshutdown, GPIO_LOW); - - /* platform specific disable */ - if (pdata->chip_disable) - pdata->chip_disable(kim_gdata); - return err; -} - -/**********************************************************************/ -/* functions called from subsystems */ -/* called when debugfs entry is read from */ - -static int version_show(struct seq_file *s, void *unused) -{ - struct kim_data_s *kim_gdata = s->private; - seq_printf(s, "%04X %d.%d.%d\n", kim_gdata->version.full, - kim_gdata->version.chip, kim_gdata->version.maj_ver, - kim_gdata->version.min_ver); - return 0; -} - -static int list_show(struct seq_file *s, void *unused) -{ - struct kim_data_s *kim_gdata = s->private; - kim_st_list_protocols(kim_gdata->core_data, s); - return 0; -} - -static ssize_t show_install(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct kim_data_s *kim_data = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", kim_data->ldisc_install); -} - -#ifdef DEBUG -static ssize_t store_dev_name(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct kim_data_s *kim_data = dev_get_drvdata(dev); - pr_debug("storing dev name >%s<", buf); - strscpy(kim_data->dev_name, buf, sizeof(kim_data->dev_name)); - pr_debug("stored dev name >%s<", kim_data->dev_name); - return count; -} - -static ssize_t store_baud_rate(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct kim_data_s *kim_data = dev_get_drvdata(dev); - pr_debug("storing baud rate >%s<", buf); - sscanf(buf, "%ld", &kim_data->baud_rate); - pr_debug("stored baud rate >%ld<", kim_data->baud_rate); - return count; -} -#endif /* if DEBUG */ - -static ssize_t show_dev_name(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct kim_data_s *kim_data = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", kim_data->dev_name); -} - -static ssize_t show_baud_rate(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct kim_data_s *kim_data = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", kim_data->baud_rate); -} - -static ssize_t show_flow_cntrl(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct kim_data_s *kim_data = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", kim_data->flow_cntrl); -} - -/* structures specific for sysfs entries */ -static struct kobj_attribute ldisc_install = -__ATTR(install, 0444, (void *)show_install, NULL); - -static struct kobj_attribute uart_dev_name = -#ifdef DEBUG /* TODO: move this to debug-fs if possible */ -__ATTR(dev_name, 0644, (void *)show_dev_name, (void *)store_dev_name); -#else -__ATTR(dev_name, 0444, (void *)show_dev_name, NULL); -#endif - -static struct kobj_attribute uart_baud_rate = -#ifdef DEBUG /* TODO: move to debugfs */ -__ATTR(baud_rate, 0644, (void *)show_baud_rate, (void *)store_baud_rate); -#else -__ATTR(baud_rate, 0444, (void *)show_baud_rate, NULL); -#endif - -static struct kobj_attribute uart_flow_cntrl = -__ATTR(flow_cntrl, 0444, (void *)show_flow_cntrl, NULL); - -static struct attribute *uim_attrs[] = { - &ldisc_install.attr, - &uart_dev_name.attr, - &uart_baud_rate.attr, - &uart_flow_cntrl.attr, - NULL, -}; - -static const struct attribute_group uim_attr_grp = { - .attrs = uim_attrs, -}; - -/* - * st_kim_ref - reference the core's data - * This references the per-ST platform device in the arch/xx/ - * board-xx.c file. - * This would enable multiple such platform devices to exist - * on a given platform - */ -void st_kim_ref(struct st_data_s **core_data, int id) -{ - struct platform_device *pdev; - struct kim_data_s *kim_gdata; - /* get kim_gdata reference from platform device */ - pdev = st_get_plat_device(id); - if (!pdev) - goto err; - kim_gdata = platform_get_drvdata(pdev); - if (!kim_gdata) - goto err; - - *core_data = kim_gdata->core_data; - return; -err: - *core_data = NULL; -} - -DEFINE_SHOW_ATTRIBUTE(version); -DEFINE_SHOW_ATTRIBUTE(list); - -/**********************************************************************/ -/* functions called from platform device driver subsystem - * need to have a relevant platform device entry in the platform's - * board-*.c file - */ - -static struct dentry *kim_debugfs_dir; -static int kim_probe(struct platform_device *pdev) -{ - struct kim_data_s *kim_gdata; - struct ti_st_plat_data *pdata = pdev->dev.platform_data; - int err; - - if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) { - /* multiple devices could exist */ - st_kim_devices[pdev->id] = pdev; - } else { - /* platform's sure about existence of 1 device */ - st_kim_devices[0] = pdev; - } - - kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_KERNEL); - if (!kim_gdata) { - pr_err("no mem to allocate"); - return -ENOMEM; - } - platform_set_drvdata(pdev, kim_gdata); - - err = st_core_init(&kim_gdata->core_data); - if (err != 0) { - pr_err(" ST core init failed"); - err = -EIO; - goto err_core_init; - } - /* refer to itself */ - kim_gdata->core_data->kim_data = kim_gdata; - - /* Claim the chip enable nShutdown gpio from the system */ - kim_gdata->nshutdown = pdata->nshutdown_gpio; - err = gpio_request(kim_gdata->nshutdown, "kim"); - if (unlikely(err)) { - pr_err(" gpio %d request failed ", kim_gdata->nshutdown); - goto err_sysfs_group; - } - - /* Configure nShutdown GPIO as output=0 */ - err = gpio_direction_output(kim_gdata->nshutdown, 0); - if (unlikely(err)) { - pr_err(" unable to configure gpio %d", kim_gdata->nshutdown); - goto err_sysfs_group; - } - /* get reference of pdev for request_firmware */ - kim_gdata->kim_pdev = pdev; - init_completion(&kim_gdata->kim_rcvd); - init_completion(&kim_gdata->ldisc_installed); - - err = sysfs_create_group(&pdev->dev.kobj, &uim_attr_grp); - if (err) { - pr_err("failed to create sysfs entries"); - goto err_sysfs_group; - } - - /* copying platform data */ - strscpy(kim_gdata->dev_name, pdata->dev_name, - sizeof(kim_gdata->dev_name)); - kim_gdata->flow_cntrl = pdata->flow_cntrl; - kim_gdata->baud_rate = pdata->baud_rate; - pr_info("sysfs entries created\n"); - - kim_debugfs_dir = debugfs_create_dir("ti-st", NULL); - - debugfs_create_file("version", S_IRUGO, kim_debugfs_dir, - kim_gdata, &version_fops); - debugfs_create_file("protocols", S_IRUGO, kim_debugfs_dir, - kim_gdata, &list_fops); - return 0; - -err_sysfs_group: - st_core_exit(kim_gdata->core_data); - -err_core_init: - kfree(kim_gdata); - - return err; -} - -static void kim_remove(struct platform_device *pdev) -{ - /* free the GPIOs requested */ - struct ti_st_plat_data *pdata = pdev->dev.platform_data; - struct kim_data_s *kim_gdata; - - kim_gdata = platform_get_drvdata(pdev); - - /* - * Free the Bluetooth/FM/GPIO - * nShutdown gpio from the system - */ - gpio_free(pdata->nshutdown_gpio); - pr_info("nshutdown GPIO Freed"); - - debugfs_remove_recursive(kim_debugfs_dir); - sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp); - pr_info("sysfs entries removed"); - - kim_gdata->kim_pdev = NULL; - st_core_exit(kim_gdata->core_data); - - kfree(kim_gdata); - kim_gdata = NULL; -} - -static int kim_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct ti_st_plat_data *pdata = pdev->dev.platform_data; - - if (pdata->suspend) - return pdata->suspend(pdev, state); - - return 0; -} - -static int kim_resume(struct platform_device *pdev) -{ - struct ti_st_plat_data *pdata = pdev->dev.platform_data; - - if (pdata->resume) - return pdata->resume(pdev); - - return 0; -} - -/**********************************************************************/ -/* entry point for ST KIM module, called in from ST Core */ -static struct platform_driver kim_platform_driver = { - .probe = kim_probe, - .remove_new = kim_remove, - .suspend = kim_suspend, - .resume = kim_resume, - .driver = { - .name = "kim", - }, -}; - -module_platform_driver(kim_platform_driver); - -MODULE_AUTHOR("Pavan Savoy "); -MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips "); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c deleted file mode 100644 index 07406140d2770e6e607430abb8a4c6e415ad74d7..0000000000000000000000000000000000000000 --- a/drivers/misc/ti-st/st_ll.c +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Shared Transport driver - * HCI-LL module responsible for TI proprietary HCI_LL protocol - * Copyright (C) 2009-2010 Texas Instruments - * Author: Pavan Savoy - */ - -#define pr_fmt(fmt) "(stll) :" fmt -#include -#include -#include -#include - -/**********************************************************************/ -/* internal functions */ -static void send_ll_cmd(struct st_data_s *st_data, - unsigned char cmd) -{ - - pr_debug("%s: writing %x", __func__, cmd); - st_int_write(st_data, &cmd, 1); - return; -} - -static void ll_device_want_to_sleep(struct st_data_s *st_data) -{ - struct kim_data_s *kim_data; - struct ti_st_plat_data *pdata; - - pr_debug("%s", __func__); - /* sanity check */ - if (st_data->ll_state != ST_LL_AWAKE) - pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND" - "in state %ld", st_data->ll_state); - - send_ll_cmd(st_data, LL_SLEEP_ACK); - /* update state */ - st_data->ll_state = ST_LL_ASLEEP; - - /* communicate to platform about chip asleep */ - kim_data = st_data->kim_data; - pdata = kim_data->kim_pdev->dev.platform_data; - if (pdata->chip_asleep) - pdata->chip_asleep(NULL); -} - -static void ll_device_want_to_wakeup(struct st_data_s *st_data) -{ - struct kim_data_s *kim_data; - struct ti_st_plat_data *pdata; - - /* diff actions in diff states */ - switch (st_data->ll_state) { - case ST_LL_ASLEEP: - send_ll_cmd(st_data, LL_WAKE_UP_ACK); /* send wake_ack */ - break; - case ST_LL_ASLEEP_TO_AWAKE: - /* duplicate wake_ind */ - pr_err("duplicate wake_ind while waiting for Wake ack"); - break; - case ST_LL_AWAKE: - /* duplicate wake_ind */ - pr_err("duplicate wake_ind already AWAKE"); - break; - case ST_LL_AWAKE_TO_ASLEEP: - /* duplicate wake_ind */ - pr_err("duplicate wake_ind"); - break; - } - /* update state */ - st_data->ll_state = ST_LL_AWAKE; - - /* communicate to platform about chip wakeup */ - kim_data = st_data->kim_data; - pdata = kim_data->kim_pdev->dev.platform_data; - if (pdata->chip_awake) - pdata->chip_awake(NULL); -} - -/**********************************************************************/ -/* functions invoked by ST Core */ - -/* called when ST Core wants to - * enable ST LL */ -void st_ll_enable(struct st_data_s *ll) -{ - ll->ll_state = ST_LL_AWAKE; -} - -/* called when ST Core /local module wants to - * disable ST LL */ -void st_ll_disable(struct st_data_s *ll) -{ - ll->ll_state = ST_LL_INVALID; -} - -/* called when ST Core wants to update the state */ -void st_ll_wakeup(struct st_data_s *ll) -{ - if (likely(ll->ll_state != ST_LL_AWAKE)) { - send_ll_cmd(ll, LL_WAKE_UP_IND); /* WAKE_IND */ - ll->ll_state = ST_LL_ASLEEP_TO_AWAKE; - } else { - /* don't send the duplicate wake_indication */ - pr_err(" Chip already AWAKE "); - } -} - -/* called when ST Core wants the state */ -unsigned long st_ll_getstate(struct st_data_s *ll) -{ - pr_debug(" returning state %ld", ll->ll_state); - return ll->ll_state; -} - -/* called from ST Core, when a PM related packet arrives */ -unsigned long st_ll_sleep_state(struct st_data_s *st_data, - unsigned char cmd) -{ - switch (cmd) { - case LL_SLEEP_IND: /* sleep ind */ - pr_debug("sleep indication recvd"); - ll_device_want_to_sleep(st_data); - break; - case LL_SLEEP_ACK: /* sleep ack */ - pr_err("sleep ack rcvd: host shouldn't"); - break; - case LL_WAKE_UP_IND: /* wake ind */ - pr_debug("wake indication recvd"); - ll_device_want_to_wakeup(st_data); - break; - case LL_WAKE_UP_ACK: /* wake ack */ - pr_debug("wake ack rcvd"); - st_data->ll_state = ST_LL_AWAKE; - break; - default: - pr_err(" unknown input/state "); - return -EINVAL; - } - return 0; -} - -/* Called from ST CORE to initialize ST LL */ -long st_ll_init(struct st_data_s *ll) -{ - /* set state to invalid */ - ll->ll_state = ST_LL_INVALID; - return 0; -} - -/* Called from ST CORE to de-initialize ST LL */ -long st_ll_deinit(struct st_data_s *ll) -{ - return 0; -} diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c index b4d67a1a24e44e946ee707f381056ede9d7be753..2fbd3fbdf713a24ca11fe09eed29d341eac62b92 100644 --- a/drivers/misc/tps6594-esm.c +++ b/drivers/misc/tps6594-esm.c @@ -135,7 +135,7 @@ static struct platform_driver tps6594_esm_driver = { .pm = pm_sleep_ptr(&tps6594_esm_pm_ops), }, .probe = tps6594_esm_probe, - .remove_new = tps6594_esm_remove, + .remove = tps6594_esm_remove, }; module_platform_driver(tps6594_esm_driver); diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c index 9bcca1856bfeea15b4fd9ef92153e6ac79b9eb56..0a24ce44cc37c412165b71a36a2bc2c6c111ef52 100644 --- a/drivers/misc/tps6594-pfsm.c +++ b/drivers/misc/tps6594-pfsm.c @@ -314,7 +314,7 @@ static struct platform_driver tps6594_pfsm_driver = { .name = "tps6594-pfsm", }, .probe = tps6594_pfsm_probe, - .remove_new = tps6594_pfsm_remove, + .remove = tps6594_pfsm_remove, }; module_platform_driver(tps6594_pfsm_driver); diff --git a/drivers/misc/vcpu_stall_detector.c b/drivers/misc/vcpu_stall_detector.c index 41b8c2119e20e5f29ad0e66feed56cc030f2d639..f0b1fc87490ec6989b96c39e67b47e7dd62c40c3 100644 --- a/drivers/misc/vcpu_stall_detector.c +++ b/drivers/misc/vcpu_stall_detector.c @@ -233,7 +233,7 @@ MODULE_DEVICE_TABLE(of, vcpu_stall_detect_of_match); static struct platform_driver vcpu_stall_detect_driver = { .probe = vcpu_stall_detect_probe, - .remove_new = vcpu_stall_detect_remove, + .remove = vcpu_stall_detect_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = vcpu_stall_detect_of_match, diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c index ea433695f4c470549fdb307b1ca86f6f2846af9d..3135ba3a58ee045e9c09548d111293db6d4eb2b9 100644 --- a/drivers/misc/xilinx_sdfec.c +++ b/drivers/misc/xilinx_sdfec.c @@ -1444,7 +1444,7 @@ static struct platform_driver xsdfec_driver = { .of_match_table = xsdfec_of_match, }, .probe = xsdfec_probe, - .remove_new = xsdfec_remove, + .remove = xsdfec_remove, }; module_platform_driver(xsdfec_driver); diff --git a/drivers/misc/xilinx_tmr_inject.c b/drivers/misc/xilinx_tmr_inject.c index 734fdfac19ef3c5554a49d5749f7eb6a9342d014..6284606ffb9ff6a05041f81e7412081e3e80050f 100644 --- a/drivers/misc/xilinx_tmr_inject.c +++ b/drivers/misc/xilinx_tmr_inject.c @@ -164,7 +164,7 @@ static struct platform_driver xtmr_inject_driver = { .of_match_table = xtmr_inject_of_match, }, .probe = xtmr_inject_probe, - .remove_new = xtmr_inject_remove, + .remove = xtmr_inject_remove, }; module_platform_driver(xtmr_inject_driver); MODULE_AUTHOR("Advanced Micro Devices, Inc"); diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c index 96064e4babf01f6950c81586764386e7671cbf97..5e9eb268073d18e0a46089000f18a3200b4bf13d 100644 --- a/drivers/mtd/spi-nor/sysfs.c +++ b/drivers/mtd/spi-nor/sysfs.c @@ -87,7 +87,7 @@ static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj, } static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj, - struct bin_attribute *attr, int n) + const struct bin_attribute *attr, int n) { struct spi_device *spi = to_spi_device(kobj_to_dev(kobj)); struct spi_mem *spimem = spi_get_drvdata(spi); diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index ae5abe492b52abc2ed405f3a87fba025b877a750..adc47b87b38a5f89a35aa064913a2c503690efa5 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1447,7 +1447,7 @@ out_ech: return err; } -static struct ubi_attach_info *alloc_ai(void) +static struct ubi_attach_info *alloc_ai(const char *slab_name) { struct ubi_attach_info *ai; @@ -1461,7 +1461,7 @@ static struct ubi_attach_info *alloc_ai(void) INIT_LIST_HEAD(&ai->alien); INIT_LIST_HEAD(&ai->fastmap); ai->volumes = RB_ROOT; - ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", + ai->aeb_slab_cache = kmem_cache_create(slab_name, sizeof(struct ubi_ainf_peb), 0, 0, NULL); if (!ai->aeb_slab_cache) { @@ -1491,7 +1491,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai) err = -ENOMEM; - scan_ai = alloc_ai(); + scan_ai = alloc_ai("ubi_aeb_slab_cache_fastmap"); if (!scan_ai) goto out; @@ -1557,7 +1557,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) int err; struct ubi_attach_info *ai; - ai = alloc_ai(); + ai = alloc_ai("ubi_aeb_slab_cache"); if (!ai) return -ENOMEM; @@ -1575,7 +1575,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) if (err > 0 || mtd_is_eccerr(err)) { if (err != UBI_NO_FASTMAP) { destroy_ai(ai); - ai = alloc_ai(); + ai = alloc_ai("ubi_aeb_slab_cache"); if (!ai) return -ENOMEM; @@ -1614,7 +1614,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) { struct ubi_attach_info *scan_ai; - scan_ai = alloc_ai(); + scan_ai = alloc_ai("ubi_aeb_slab_cache_dbg_chk_fastmap"); if (!scan_ai) { err = -ENOMEM; goto out_wl; diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index 2a9cc9413c427dfb4b70774e0a2ddf23e9bbfe5d..9bdb6525f1281f28f5b9fc9ddc5db87bf86e9b0f 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -346,14 +346,27 @@ out: * WL sub-system. * * @ubi: UBI device description object + * @need_fill: whether to fill wear-leveling pool when no PEBs are found */ -static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi) +static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi, + bool need_fill) { struct ubi_fm_pool *pool = &ubi->fm_wl_pool; int pnum; - if (pool->used == pool->size) + if (pool->used == pool->size) { + if (need_fill && !ubi->fm_work_scheduled) { + /* + * We cannot update the fastmap here because this + * function is called in atomic context. + * Let's fail here and refill/update it as soon as + * possible. + */ + ubi->fm_work_scheduled = 1; + schedule_work(&ubi->fm_work); + } return NULL; + } pnum = pool->pebs[pool->used]; return ubi->lookuptbl[pnum]; @@ -375,7 +388,7 @@ static bool need_wear_leveling(struct ubi_device *ubi) if (!ubi->used.rb_node) return false; - e = next_peb_for_wl(ubi); + e = next_peb_for_wl(ubi, false); if (!e) { if (!ubi->free.rb_node) return false; diff --git a/drivers/mtd/ubi/nvmem.c b/drivers/mtd/ubi/nvmem.c index a94a1a9aaec10e4add3154e2bbec572f200439ac..34f8c1d3cdeed4207cd073684bb2e00fe7661a1a 100644 --- a/drivers/mtd/ubi/nvmem.c +++ b/drivers/mtd/ubi/nvmem.c @@ -55,7 +55,7 @@ static int ubi_nvmem_reg_read(void *priv, unsigned int from, if (err) return err; - return bytes_left == 0 ? 0 : -EIO; + return 0; } static int ubi_nvmem_add(struct ubi_volume_info *vi) diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 1c9e874e8edeae982b3f97ee643090fc97c93886..26cc53ad34ec77a5affcad0575800deee9b55129 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -549,6 +549,7 @@ struct ubi_debug_info { * @peb_buf: a buffer of PEB size used for different purposes * @buf_mutex: protects @peb_buf * @ckvol_mutex: serializes static volume checking when opening + * @wl_reboot_notifier: close all wear-leveling work before reboot * * @dbg: debugging information for this UBI device */ @@ -651,6 +652,7 @@ struct ubi_device { void *peb_buf; struct mutex buf_mutex; struct mutex ckvol_mutex; + struct notifier_block wl_reboot_notifier; struct ubi_debug_info dbg; }; @@ -831,7 +833,6 @@ void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); int ubi_attach(struct ubi_device *ubi, int force_scan); -void ubi_destroy_ai(struct ubi_attach_info *ai); /* vtbl.c */ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 5a3558bbb90356f0e1394b9b882b8992e4c8d019..e5cf3bdca3b012e9d3e82a64fe851176a083cc5f 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -143,8 +143,10 @@ static struct fwnode_handle *find_volume_fwnode(struct ubi_volume *vol) vol->vol_id != volid) continue; + fwnode_handle_put(fw_vols); return fw_vol; } + fwnode_handle_put(fw_vols); return NULL; } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index a357f3d27f2f3ddce617de80b6f13719b7dccd9b..4f6f339d8fb8ab9e6cfd7c5b6217886879020dba 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -89,6 +89,7 @@ #include #include #include +#include #include "ubi.h" #include "wl.h" @@ -127,6 +128,8 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi, struct ubi_wl_entry *e, struct rb_root *root); static int self_check_in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *e); +static int ubi_wl_reboot_notifier(struct notifier_block *n, + unsigned long state, void *cmd); /** * wl_tree_add - add a wear-leveling entry to a WL RB-tree. @@ -683,7 +686,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, ubi_assert(!ubi->move_to_put); #ifdef CONFIG_MTD_UBI_FASTMAP - if (!next_peb_for_wl(ubi) || + if (!next_peb_for_wl(ubi, true) || #else if (!ubi->free.rb_node || #endif @@ -846,7 +849,14 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, goto out_not_moved; } if (err == MOVE_RETRY) { - scrubbing = 1; + /* + * For source PEB: + * 1. The scrubbing is set for scrub type PEB, it will + * be put back into ubi->scrub list. + * 2. Non-scrub type PEB will be put back into ubi->used + * list. + */ + keep = 1; dst_leb_clean = 1; goto out_not_moved; } @@ -1943,6 +1953,13 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) if (!ubi->ro_mode && !ubi->fm_disabled) ubi_ensure_anchor_pebs(ubi); #endif + + if (!ubi->wl_reboot_notifier.notifier_call) { + ubi->wl_reboot_notifier.notifier_call = ubi_wl_reboot_notifier; + ubi->wl_reboot_notifier.priority = 1; /* Higher than MTD */ + register_reboot_notifier(&ubi->wl_reboot_notifier); + } + return 0; out_free: @@ -1988,6 +2005,17 @@ void ubi_wl_close(struct ubi_device *ubi) kfree(ubi->lookuptbl); } +static int ubi_wl_reboot_notifier(struct notifier_block *n, + unsigned long state, void *cmd) +{ + struct ubi_device *ubi; + + ubi = container_of(n, struct ubi_device, wl_reboot_notifier); + ubi_wl_close(ubi); + + return NOTIFY_DONE; +} + /** * self_check_ec - make sure that the erase counter of a PEB is correct. * @ubi: UBI device description object diff --git a/drivers/mtd/ubi/wl.h b/drivers/mtd/ubi/wl.h index 7b6715ef6d4a356905e8805c4ec23a3b27a9e113..a69169c35e310fa72b344871fa7cabe78123e006 100644 --- a/drivers/mtd/ubi/wl.h +++ b/drivers/mtd/ubi/wl.h @@ -5,7 +5,8 @@ static void update_fastmap_work_fn(struct work_struct *wrk); static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root); static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi); -static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi); +static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi, + bool need_fill); static bool need_wear_leveling(struct ubi_device *ubi); static void ubi_fastmap_close(struct ubi_device *ubi); static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count) diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c index 511615dc334196183849dede182f4fc80874ef3e..cc371d0c9f3c769051ff1e0a8954d8c52dbcdbf6 100644 --- a/drivers/net/can/c_can/c_can_main.c +++ b/drivers/net/can/c_can/c_can_main.c @@ -1014,49 +1014,57 @@ static int c_can_handle_bus_err(struct net_device *dev, /* propagate the error condition to the CAN stack */ skb = alloc_can_err_skb(dev, &cf); - if (unlikely(!skb)) - return 0; /* check for 'last error code' which tells us the * type of the last error to occur on the CAN bus */ - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + if (likely(skb)) + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; switch (lec_type) { case LEC_STUFF_ERROR: netdev_dbg(dev, "stuff error\n"); - cf->data[2] |= CAN_ERR_PROT_STUFF; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_STUFF; stats->rx_errors++; break; case LEC_FORM_ERROR: netdev_dbg(dev, "form error\n"); - cf->data[2] |= CAN_ERR_PROT_FORM; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_FORM; stats->rx_errors++; break; case LEC_ACK_ERROR: netdev_dbg(dev, "ack error\n"); - cf->data[3] = CAN_ERR_PROT_LOC_ACK; + if (likely(skb)) + cf->data[3] = CAN_ERR_PROT_LOC_ACK; stats->tx_errors++; break; case LEC_BIT1_ERROR: netdev_dbg(dev, "bit1 error\n"); - cf->data[2] |= CAN_ERR_PROT_BIT1; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_BIT1; stats->tx_errors++; break; case LEC_BIT0_ERROR: netdev_dbg(dev, "bit0 error\n"); - cf->data[2] |= CAN_ERR_PROT_BIT0; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_BIT0; stats->tx_errors++; break; case LEC_CRC_ERROR: netdev_dbg(dev, "CRC error\n"); - cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; + if (likely(skb)) + cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; stats->rx_errors++; break; default: break; } + if (unlikely(!skb)) + return 0; + netif_receive_skb(skb); return 1; } diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index 6792c14fd7eb009d551ac22bab1f0ee2cd0f0398..681643ab37804e9904cc4a899d44c55cefab7b6e 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -468,7 +468,7 @@ static int can_set_termination(struct net_device *ndev, u16 term) else set = 0; - gpiod_set_value(priv->termination_gpio, set); + gpiod_set_value_cansleep(priv->termination_gpio, set); return 0; } diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index d32b10900d2f621308922fb45b3a0eee3c313cfc..c86b57d47085fdf61f6b8ed8eb3197c0428d59e1 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c @@ -390,36 +390,55 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev) return 0; priv->can.can_stats.bus_error++; - stats->rx_errors++; /* Propagate the error condition to the CAN stack. */ skb = alloc_can_err_skb(ndev, &cf); - if (unlikely(!skb)) - return 0; /* Read the error counter register and check for new errors. */ - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + if (likely(skb)) + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; - if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST) - cf->data[2] |= CAN_ERR_PROT_OVERLOAD; + if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST) { + stats->rx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_OVERLOAD; + } - if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST) - cf->data[3] = CAN_ERR_PROT_LOC_ACK; + if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST) { + stats->tx_errors++; + if (likely(skb)) + cf->data[3] = CAN_ERR_PROT_LOC_ACK; + } - if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST) - cf->data[2] |= CAN_ERR_PROT_BIT0; + if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST) { + stats->tx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_BIT0; + } - if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST) - cf->data[2] |= CAN_ERR_PROT_BIT1; + if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST) { + stats->tx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_BIT1; + } - if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST) - cf->data[2] |= CAN_ERR_PROT_STUFF; + if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST) { + stats->rx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_STUFF; + } - if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST) - cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; + if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST) { + stats->rx_errors++; + if (likely(skb)) + cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; + } - if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST) - cf->data[2] |= CAN_ERR_PROT_FORM; + if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST) { + stats->rx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_FORM; + } /* Reset the error counter, ack the IRQ and re-enable the counter. */ writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR); @@ -427,6 +446,9 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev) priv->base + IFI_CANFD_INTERRUPT); writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR); + if (unlikely(!skb)) + return 0; + netif_receive_skb(skb); return 1; diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 16e9e7d7527d9762d73a7ec47940c73c0976e05d..533bcb77c9f934e5840b076ded948f8256ad2ad0 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -695,47 +695,60 @@ static int m_can_handle_lec_err(struct net_device *dev, u32 timestamp = 0; cdev->can.can_stats.bus_error++; - stats->rx_errors++; /* propagate the error condition to the CAN stack */ skb = alloc_can_err_skb(dev, &cf); - if (unlikely(!skb)) - return 0; /* check for 'last error code' which tells us the * type of the last error to occur on the CAN bus */ - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + if (likely(skb)) + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; switch (lec_type) { case LEC_STUFF_ERROR: netdev_dbg(dev, "stuff error\n"); - cf->data[2] |= CAN_ERR_PROT_STUFF; + stats->rx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_STUFF; break; case LEC_FORM_ERROR: netdev_dbg(dev, "form error\n"); - cf->data[2] |= CAN_ERR_PROT_FORM; + stats->rx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_FORM; break; case LEC_ACK_ERROR: netdev_dbg(dev, "ack error\n"); - cf->data[3] = CAN_ERR_PROT_LOC_ACK; + stats->tx_errors++; + if (likely(skb)) + cf->data[3] = CAN_ERR_PROT_LOC_ACK; break; case LEC_BIT1_ERROR: netdev_dbg(dev, "bit1 error\n"); - cf->data[2] |= CAN_ERR_PROT_BIT1; + stats->tx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_BIT1; break; case LEC_BIT0_ERROR: netdev_dbg(dev, "bit0 error\n"); - cf->data[2] |= CAN_ERR_PROT_BIT0; + stats->tx_errors++; + if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_BIT0; break; case LEC_CRC_ERROR: netdev_dbg(dev, "CRC error\n"); - cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; + stats->rx_errors++; + if (likely(skb)) + cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; break; default: break; } + if (unlikely(!skb)) + return 0; + if (cdev->is_peripheral) timestamp = m_can_get_timestamp(cdev); diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index ddb3247948ad2fba657741d7e442c571311506f7..4d245857ef1cec0ae1ee82008b96912bbb1f2638 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -416,8 +416,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) int ret = 0; skb = alloc_can_err_skb(dev, &cf); - if (skb == NULL) - return -ENOMEM; txerr = priv->read_reg(priv, SJA1000_TXERR); rxerr = priv->read_reg(priv, SJA1000_RXERR); @@ -425,8 +423,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (isrc & IRQ_DOI) { /* data overrun interrupt */ netdev_dbg(dev, "data overrun interrupt\n"); - cf->can_id |= CAN_ERR_CRTL; - cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + if (skb) { + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + } + stats->rx_over_errors++; stats->rx_errors++; sja1000_write_cmdreg(priv, CMD_CDO); /* clear bit */ @@ -452,7 +453,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) else state = CAN_STATE_ERROR_ACTIVE; } - if (state != CAN_STATE_BUS_OFF) { + if (state != CAN_STATE_BUS_OFF && skb) { cf->can_id |= CAN_ERR_CNT; cf->data[6] = txerr; cf->data[7] = rxerr; @@ -460,33 +461,38 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (isrc & IRQ_BEI) { /* bus error interrupt */ priv->can.can_stats.bus_error++; - stats->rx_errors++; ecc = priv->read_reg(priv, SJA1000_ECC); + if (skb) { + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; - - /* set error type */ - switch (ecc & ECC_MASK) { - case ECC_BIT: - cf->data[2] |= CAN_ERR_PROT_BIT; - break; - case ECC_FORM: - cf->data[2] |= CAN_ERR_PROT_FORM; - break; - case ECC_STUFF: - cf->data[2] |= CAN_ERR_PROT_STUFF; - break; - default: - break; - } + /* set error type */ + switch (ecc & ECC_MASK) { + case ECC_BIT: + cf->data[2] |= CAN_ERR_PROT_BIT; + break; + case ECC_FORM: + cf->data[2] |= CAN_ERR_PROT_FORM; + break; + case ECC_STUFF: + cf->data[2] |= CAN_ERR_PROT_STUFF; + break; + default: + break; + } - /* set error location */ - cf->data[3] = ecc & ECC_SEG; + /* set error location */ + cf->data[3] = ecc & ECC_SEG; + } /* Error occurred during transmission? */ - if ((ecc & ECC_DIR) == 0) - cf->data[2] |= CAN_ERR_PROT_TX; + if ((ecc & ECC_DIR) == 0) { + stats->tx_errors++; + if (skb) + cf->data[2] |= CAN_ERR_PROT_TX; + } else { + stats->rx_errors++; + } } if (isrc & IRQ_EPI) { /* error passive interrupt */ @@ -502,8 +508,10 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) netdev_dbg(dev, "arbitration lost interrupt\n"); alc = priv->read_reg(priv, SJA1000_ALC); priv->can.can_stats.arbitration_lost++; - cf->can_id |= CAN_ERR_LOSTARB; - cf->data[0] = alc & 0x1f; + if (skb) { + cf->can_id |= CAN_ERR_LOSTARB; + cf->data[0] = alc & 0x1f; + } } if (state != priv->can.state) { @@ -516,6 +524,9 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) can_bus_off(dev); } + if (!skb) + return -ENOMEM; + netif_rx(skb); return ret; diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index 148d974ebb210778cb1b0b96305a513b4e7af52c..09ae218315d73d49c2ec4280707911966fce1c31 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c @@ -663,27 +663,27 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) u8 rxerr, txerr; skb = alloc_can_err_skb(net, &cf); - if (!skb) - break; txerr = hi3110_read(spi, HI3110_READ_TEC); rxerr = hi3110_read(spi, HI3110_READ_REC); tx_state = txerr >= rxerr ? new_state : 0; rx_state = txerr <= rxerr ? new_state : 0; can_change_state(net, cf, tx_state, rx_state); - netif_rx(skb); if (new_state == CAN_STATE_BUS_OFF) { + if (skb) + netif_rx(skb); can_bus_off(net); if (priv->can.restart_ms == 0) { priv->force_quit = 1; hi3110_hw_sleep(spi); break; } - } else { + } else if (skb) { cf->can_id |= CAN_ERR_CNT; cf->data[6] = txerr; cf->data[7] = rxerr; + netif_rx(skb); } } @@ -696,27 +696,38 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) /* Check for protocol errors */ if (eflag & HI3110_ERR_PROTOCOL_MASK) { skb = alloc_can_err_skb(net, &cf); - if (!skb) - break; + if (skb) + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; priv->can.can_stats.bus_error++; - priv->net->stats.rx_errors++; - if (eflag & HI3110_ERR_BITERR) - cf->data[2] |= CAN_ERR_PROT_BIT; - else if (eflag & HI3110_ERR_FRMERR) - cf->data[2] |= CAN_ERR_PROT_FORM; - else if (eflag & HI3110_ERR_STUFERR) - cf->data[2] |= CAN_ERR_PROT_STUFF; - else if (eflag & HI3110_ERR_CRCERR) - cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; - else if (eflag & HI3110_ERR_ACKERR) - cf->data[3] |= CAN_ERR_PROT_LOC_ACK; - - cf->data[6] = hi3110_read(spi, HI3110_READ_TEC); - cf->data[7] = hi3110_read(spi, HI3110_READ_REC); + if (eflag & HI3110_ERR_BITERR) { + priv->net->stats.tx_errors++; + if (skb) + cf->data[2] |= CAN_ERR_PROT_BIT; + } else if (eflag & HI3110_ERR_FRMERR) { + priv->net->stats.rx_errors++; + if (skb) + cf->data[2] |= CAN_ERR_PROT_FORM; + } else if (eflag & HI3110_ERR_STUFERR) { + priv->net->stats.rx_errors++; + if (skb) + cf->data[2] |= CAN_ERR_PROT_STUFF; + } else if (eflag & HI3110_ERR_CRCERR) { + priv->net->stats.rx_errors++; + if (skb) + cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; + } else if (eflag & HI3110_ERR_ACKERR) { + priv->net->stats.tx_errors++; + if (skb) + cf->data[3] |= CAN_ERR_PROT_LOC_ACK; + } + netdev_dbg(priv->net, "Bus Error\n"); - netif_rx(skb); + if (skb) { + cf->data[6] = hi3110_read(spi, HI3110_READ_TEC); + cf->data[7] = hi3110_read(spi, HI3110_READ_REC); + netif_rx(skb); + } } } diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c index d3ac865933fdf6c4ecdd80ad4d7accbff51eb0f8..e94321849fd7e69ed045eaeac3efec52fe077d96 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c @@ -21,6 +21,11 @@ static inline bool mcp251xfd_tx_fifo_sta_empty(u32 fifo_sta) return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF; } +static inline bool mcp251xfd_tx_fifo_sta_less_than_half_full(u32 fifo_sta) +{ + return fifo_sta & MCP251XFD_REG_FIFOSTA_TFHRFHIF; +} + static inline int mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, u8 *tef_tail) @@ -147,7 +152,29 @@ mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p) BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len)); len = (chip_tx_tail << shift) - (tail << shift); - *len_p = len >> shift; + len >>= shift; + + /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI + * bits of a FIFOSTA register, here the TX-FIFO tail index + * might be corrupted. + * + * However here it seems the bit indicating that the TX-FIFO + * is empty (MCP251XFD_REG_FIFOSTA_TFERFFIF) is not correct + * while the TX-FIFO tail index is. + * + * We assume the TX-FIFO is empty, i.e. all pending CAN frames + * haven been send, if: + * - Chip's head and tail index are equal (len == 0). + * - The TX-FIFO is less than half full. + * (The TX-FIFO empty case has already been checked at the + * beginning of this function.) + * - No free buffers in the TX ring. + */ + if (len == 0 && mcp251xfd_tx_fifo_sta_less_than_half_full(fifo_sta) && + mcp251xfd_get_tx_free(tx_ring) == 0) + len = tx_ring->obj_num; + + *len_p = len; return 0; } diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index 360158c295d348efc5547826f7dbf9c848bb80a9..4311c1f0eafd8d793e39373146b33a64a9328048 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -579,11 +579,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) /* bus error interrupt */ netdev_dbg(dev, "bus error interrupt\n"); priv->can.can_stats.bus_error++; - stats->rx_errors++; + ecc = readl(priv->base + SUN4I_REG_STA_ADDR); if (likely(skb)) { - ecc = readl(priv->base + SUN4I_REG_STA_ADDR); - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; switch (ecc & SUN4I_STA_MASK_ERR) { @@ -601,9 +599,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) >> 16; break; } - /* error occurred during transmission? */ - if ((ecc & SUN4I_STA_ERR_DIR) == 0) + } + + /* error occurred during transmission? */ + if ((ecc & SUN4I_STA_ERR_DIR) == 0) { + if (likely(skb)) cf->data[2] |= CAN_ERR_PROT_TX; + stats->tx_errors++; + } else { + stats->rx_errors++; } } if (isrc & SUN4I_INT_ERR_PASSIVE) { @@ -629,10 +633,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) tx_state = txerr >= rxerr ? state : 0; rx_state = txerr <= rxerr ? state : 0; - if (likely(skb)) - can_change_state(dev, cf, tx_state, rx_state); - else - priv->can.state = state; + /* The skb allocation might fail, but can_change_state() + * handles cf == NULL. + */ + can_change_state(dev, cf, tx_state, rx_state); if (state == CAN_STATE_BUS_OFF) can_bus_off(dev); } diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 050c0b49938a42a1cd84024ab98ad33cbe8bccca..5355bac4dccbe0e31ba115909b0537a9b92c2fa6 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -335,15 +335,14 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) struct net_device_stats *stats = &dev->netdev->stats; skb = alloc_can_err_skb(dev->netdev, &cf); - if (skb == NULL) - return; if (msg->type == CPC_MSG_TYPE_CAN_STATE) { u8 state = msg->msg.can_state; if (state & SJA1000_SR_BS) { dev->can.state = CAN_STATE_BUS_OFF; - cf->can_id |= CAN_ERR_BUSOFF; + if (skb) + cf->can_id |= CAN_ERR_BUSOFF; dev->can.can_stats.bus_off++; can_bus_off(dev->netdev); @@ -361,44 +360,53 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) /* bus error interrupt */ dev->can.can_stats.bus_error++; - stats->rx_errors++; - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + if (skb) { + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; - switch (ecc & SJA1000_ECC_MASK) { - case SJA1000_ECC_BIT: - cf->data[2] |= CAN_ERR_PROT_BIT; - break; - case SJA1000_ECC_FORM: - cf->data[2] |= CAN_ERR_PROT_FORM; - break; - case SJA1000_ECC_STUFF: - cf->data[2] |= CAN_ERR_PROT_STUFF; - break; - default: - cf->data[3] = ecc & SJA1000_ECC_SEG; - break; + switch (ecc & SJA1000_ECC_MASK) { + case SJA1000_ECC_BIT: + cf->data[2] |= CAN_ERR_PROT_BIT; + break; + case SJA1000_ECC_FORM: + cf->data[2] |= CAN_ERR_PROT_FORM; + break; + case SJA1000_ECC_STUFF: + cf->data[2] |= CAN_ERR_PROT_STUFF; + break; + default: + cf->data[3] = ecc & SJA1000_ECC_SEG; + break; + } } /* Error occurred during transmission? */ - if ((ecc & SJA1000_ECC_DIR) == 0) - cf->data[2] |= CAN_ERR_PROT_TX; + if ((ecc & SJA1000_ECC_DIR) == 0) { + stats->tx_errors++; + if (skb) + cf->data[2] |= CAN_ERR_PROT_TX; + } else { + stats->rx_errors++; + } - if (dev->can.state == CAN_STATE_ERROR_WARNING || - dev->can.state == CAN_STATE_ERROR_PASSIVE) { + if (skb && (dev->can.state == CAN_STATE_ERROR_WARNING || + dev->can.state == CAN_STATE_ERROR_PASSIVE)) { cf->can_id |= CAN_ERR_CRTL; cf->data[1] = (txerr > rxerr) ? CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE; } } else if (msg->type == CPC_MSG_TYPE_OVERRUN) { - cf->can_id |= CAN_ERR_CRTL; - cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + if (skb) { + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + } stats->rx_over_errors++; stats->rx_errors++; } - netif_rx(skb); + if (skb) + netif_rx(skb); } /* diff --git a/drivers/net/can/usb/f81604.c b/drivers/net/can/usb/f81604.c index bc0c8903fe77946e252660118d15e015da6e6cdd..e0cfa1460b0b83110d5ce7ffe07bac442ce8a682 100644 --- a/drivers/net/can/usb/f81604.c +++ b/drivers/net/can/usb/f81604.c @@ -526,7 +526,6 @@ static void f81604_handle_can_bus_errors(struct f81604_port_priv *priv, netdev_dbg(netdev, "bus error interrupt\n"); priv->can.can_stats.bus_error++; - stats->rx_errors++; if (skb) { cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; @@ -548,10 +547,15 @@ static void f81604_handle_can_bus_errors(struct f81604_port_priv *priv, /* set error location */ cf->data[3] = data->ecc & F81604_SJA1000_ECC_SEG; + } - /* Error occurred during transmission? */ - if ((data->ecc & F81604_SJA1000_ECC_DIR) == 0) + /* Error occurred during transmission? */ + if ((data->ecc & F81604_SJA1000_ECC_DIR) == 0) { + stats->tx_errors++; + if (skb) cf->data[2] |= CAN_ERR_PROT_TX; + } else { + stats->rx_errors++; } set_bit(F81604_CLEAR_ECC, &priv->clear_flags); diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index bc86e9b329fd1079d71f43435e0469b32fbe02c2..b6f4de375df75d27b90cf703f345f1542bf7ca70 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -43,9 +43,6 @@ #define USB_XYLANTA_SAINT3_VENDOR_ID 0x16d0 #define USB_XYLANTA_SAINT3_PRODUCT_ID 0x0f30 -#define GS_USB_ENDPOINT_IN 1 -#define GS_USB_ENDPOINT_OUT 2 - /* Timestamp 32 bit timer runs at 1 MHz (1 µs tick). Worker accounts * for timer overflow (will be after ~71 minutes) */ @@ -336,6 +333,9 @@ struct gs_usb { unsigned int hf_size_rx; u8 active_channels; + + unsigned int pipe_in; + unsigned int pipe_out; }; /* 'allocate' a tx context. @@ -687,7 +687,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) resubmit_urb: usb_fill_bulk_urb(urb, parent->udev, - usb_rcvbulkpipe(parent->udev, GS_USB_ENDPOINT_IN), + parent->pipe_in, hf, dev->parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); @@ -819,7 +819,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, } usb_fill_bulk_urb(urb, dev->udev, - usb_sndbulkpipe(dev->udev, GS_USB_ENDPOINT_OUT), + dev->parent->pipe_out, hf, dev->hf_size_tx, gs_usb_xmit_callback, txc); @@ -925,8 +925,7 @@ static int gs_can_open(struct net_device *netdev) /* fill, anchor, and submit rx urb */ usb_fill_bulk_urb(urb, dev->udev, - usb_rcvbulkpipe(dev->udev, - GS_USB_ENDPOINT_IN), + dev->parent->pipe_in, buf, dev->parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); @@ -1413,6 +1412,7 @@ static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); + struct usb_endpoint_descriptor *ep_in, *ep_out; struct gs_host_frame *hf; struct gs_usb *parent; struct gs_host_config hconf = { @@ -1422,6 +1422,13 @@ static int gs_usb_probe(struct usb_interface *intf, unsigned int icount, i; int rc; + rc = usb_find_common_endpoints(intf->cur_altsetting, + &ep_in, &ep_out, NULL, NULL); + if (rc) { + dev_err(&intf->dev, "Required endpoints not found\n"); + return rc; + } + /* send host config */ rc = usb_control_msg_send(udev, 0, GS_USB_BREQ_HOST_FORMAT, @@ -1466,6 +1473,10 @@ static int gs_usb_probe(struct usb_interface *intf, usb_set_intfdata(intf, parent); parent->udev = udev; + /* store the detected endpoints */ + parent->pipe_in = usb_rcvbulkpipe(parent->udev, ep_in->bEndpointAddress); + parent->pipe_out = usb_sndbulkpipe(parent->udev, ep_out->bEndpointAddress); + for (i = 0; i < icount; i++) { unsigned int hf_size_rx = 0; diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c index da7c72105fb6e6cfd6bfe8a335f92befb43d5987..ca88119410852f7869cf32cbc31e47a3e17c21e6 100644 --- a/drivers/net/can/vxcan.c +++ b/drivers/net/can/vxcan.c @@ -172,13 +172,12 @@ static void vxcan_setup(struct net_device *dev) /* forward declaration for rtnl_create_link() */ static struct rtnl_link_ops vxcan_link_ops; -static int vxcan_newlink(struct net *net, struct net_device *dev, +static int vxcan_newlink(struct net *peer_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { struct vxcan_priv *priv; struct net_device *peer; - struct net *peer_net; struct nlattr *peer_tb[IFLA_MAX + 1], **tbp = tb; char ifname[IFNAMSIZ]; @@ -203,20 +202,15 @@ static int vxcan_newlink(struct net *net, struct net_device *dev, name_assign_type = NET_NAME_ENUM; } - peer_net = rtnl_link_get_net(net, tbp); peer = rtnl_create_link(peer_net, ifname, name_assign_type, &vxcan_link_ops, tbp, extack); - if (IS_ERR(peer)) { - put_net(peer_net); + if (IS_ERR(peer)) return PTR_ERR(peer); - } if (ifmp && dev->ifindex) peer->ifindex = ifmp->ifi_index; err = register_netdevice(peer); - put_net(peer_net); - peer_net = NULL; if (err < 0) { free_netdev(peer); return err; diff --git a/drivers/net/dsa/ocelot/ocelot_ext.c b/drivers/net/dsa/ocelot/ocelot_ext.c index 450bda18ef37d9295542c0ba1ede56a9fc84c633..d5c557a20292ede5e0de7e5587393b2e3ffb2b9d 100644 --- a/drivers/net/dsa/ocelot/ocelot_ext.c +++ b/drivers/net/dsa/ocelot/ocelot_ext.c @@ -109,4 +109,4 @@ module_platform_driver(ocelot_ext_switch_driver); MODULE_DESCRIPTION("External Ocelot Switch driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(MFD_OCELOT); +MODULE_IMPORT_NS("MFD_OCELOT"); diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c index 5f545dda702b7305e619642411364e0cebaaa669..a5e7dff96e91b598b5665a1c4264764c9b399937 100644 --- a/drivers/net/dsa/realtek/realtek-mdio.c +++ b/drivers/net/dsa/realtek/realtek-mdio.c @@ -140,7 +140,7 @@ int realtek_mdio_probe(struct mdio_device *mdiodev) return 0; } -EXPORT_SYMBOL_NS_GPL(realtek_mdio_probe, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(realtek_mdio_probe, "REALTEK_DSA"); /** * realtek_mdio_remove() - Remove the driver of an MDIO-connected switch @@ -163,7 +163,7 @@ void realtek_mdio_remove(struct mdio_device *mdiodev) rtl83xx_remove(priv); } -EXPORT_SYMBOL_NS_GPL(realtek_mdio_remove, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(realtek_mdio_remove, "REALTEK_DSA"); /** * realtek_mdio_shutdown() - Shutdown the driver of a MDIO-connected switch @@ -184,4 +184,4 @@ void realtek_mdio_shutdown(struct mdio_device *mdiodev) rtl83xx_shutdown(priv); } -EXPORT_SYMBOL_NS_GPL(realtek_mdio_shutdown, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(realtek_mdio_shutdown, "REALTEK_DSA"); diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c index d750bddf27b446fe7f8afb00661901205d066ef5..972e2221841858c20b971e608976b1553a0fc4e9 100644 --- a/drivers/net/dsa/realtek/realtek-smi.c +++ b/drivers/net/dsa/realtek/realtek-smi.c @@ -361,7 +361,7 @@ int realtek_smi_probe(struct platform_device *pdev) return 0; } -EXPORT_SYMBOL_NS_GPL(realtek_smi_probe, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(realtek_smi_probe, "REALTEK_DSA"); /** * realtek_smi_remove() - Remove the driver of a SMI-connected switch @@ -384,7 +384,7 @@ void realtek_smi_remove(struct platform_device *pdev) rtl83xx_remove(priv); } -EXPORT_SYMBOL_NS_GPL(realtek_smi_remove, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(realtek_smi_remove, "REALTEK_DSA"); /** * realtek_smi_shutdown() - Shutdown the driver of a SMI-connected switch @@ -405,4 +405,4 @@ void realtek_smi_shutdown(struct platform_device *pdev) rtl83xx_shutdown(priv); } -EXPORT_SYMBOL_NS_GPL(realtek_smi_shutdown, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(realtek_smi_shutdown, "REALTEK_DSA"); diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index 6b9dbdb009412baac34657be7888070c2342aafb..7e96355c28bd4e7f2fce34a6c167c9310a3adcf3 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -2206,4 +2206,4 @@ module_exit(rtl8365mb_exit); MODULE_AUTHOR("Alvin Šipraga "); MODULE_DESCRIPTION("Driver for RTL8365MB-VC ethernet switch"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(REALTEK_DSA); +MODULE_IMPORT_NS("REALTEK_DSA"); diff --git a/drivers/net/dsa/realtek/rtl8366-core.c b/drivers/net/dsa/realtek/rtl8366-core.c index 7c6520ba3a26cfc4bb0143a3d6b98fee597162c9..047feeed96a2fdac181b223f632d6b2c76848c7d 100644 --- a/drivers/net/dsa/realtek/rtl8366-core.c +++ b/drivers/net/dsa/realtek/rtl8366-core.c @@ -34,7 +34,7 @@ int rtl8366_mc_is_used(struct realtek_priv *priv, int mc_index, int *used) return 0; } -EXPORT_SYMBOL_NS_GPL(rtl8366_mc_is_used, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_mc_is_used, "REALTEK_DSA"); /** * rtl8366_obtain_mc() - retrieve or allocate a VLAN member configuration @@ -187,7 +187,7 @@ int rtl8366_set_vlan(struct realtek_priv *priv, int vid, u32 member, return ret; } -EXPORT_SYMBOL_NS_GPL(rtl8366_set_vlan, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_set_vlan, "REALTEK_DSA"); int rtl8366_set_pvid(struct realtek_priv *priv, unsigned int port, unsigned int vid) @@ -217,7 +217,7 @@ int rtl8366_set_pvid(struct realtek_priv *priv, unsigned int port, return 0; } -EXPORT_SYMBOL_NS_GPL(rtl8366_set_pvid, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_set_pvid, "REALTEK_DSA"); int rtl8366_enable_vlan4k(struct realtek_priv *priv, bool enable) { @@ -243,7 +243,7 @@ int rtl8366_enable_vlan4k(struct realtek_priv *priv, bool enable) priv->vlan4k_enabled = enable; return 0; } -EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan4k, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan4k, "REALTEK_DSA"); int rtl8366_enable_vlan(struct realtek_priv *priv, bool enable) { @@ -265,7 +265,7 @@ int rtl8366_enable_vlan(struct realtek_priv *priv, bool enable) return ret; } -EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan, "REALTEK_DSA"); int rtl8366_reset_vlan(struct realtek_priv *priv) { @@ -290,7 +290,7 @@ int rtl8366_reset_vlan(struct realtek_priv *priv) return 0; } -EXPORT_SYMBOL_NS_GPL(rtl8366_reset_vlan, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_reset_vlan, "REALTEK_DSA"); int rtl8366_vlan_add(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan, @@ -345,7 +345,7 @@ int rtl8366_vlan_add(struct dsa_switch *ds, int port, return 0; } -EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_add, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_add, "REALTEK_DSA"); int rtl8366_vlan_del(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan) @@ -389,7 +389,7 @@ int rtl8366_vlan_del(struct dsa_switch *ds, int port, return 0; } -EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_del, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_del, "REALTEK_DSA"); void rtl8366_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) @@ -403,7 +403,7 @@ void rtl8366_get_strings(struct dsa_switch *ds, int port, u32 stringset, for (i = 0; i < priv->num_mib_counters; i++) ethtool_puts(&data, priv->mib_counters[i].name); } -EXPORT_SYMBOL_NS_GPL(rtl8366_get_strings, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_get_strings, "REALTEK_DSA"); int rtl8366_get_sset_count(struct dsa_switch *ds, int port, int sset) { @@ -417,7 +417,7 @@ int rtl8366_get_sset_count(struct dsa_switch *ds, int port, int sset) return priv->num_mib_counters; } -EXPORT_SYMBOL_NS_GPL(rtl8366_get_sset_count, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_get_sset_count, "REALTEK_DSA"); void rtl8366_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) { @@ -441,4 +441,4 @@ void rtl8366_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) data[i] = mibvalue; } } -EXPORT_SYMBOL_NS_GPL(rtl8366_get_ethtool_stats, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl8366_get_ethtool_stats, "REALTEK_DSA"); diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c index 6ba03f81c8824966cc51d5755731d8f6a8a0c289..23374178a176072717dfce9948b162e81fd6c257 100644 --- a/drivers/net/dsa/realtek/rtl8366rb.c +++ b/drivers/net/dsa/realtek/rtl8366rb.c @@ -2144,4 +2144,4 @@ module_exit(rtl8366rb_exit); MODULE_AUTHOR("Linus Walleij "); MODULE_DESCRIPTION("Driver for RTL8366RB ethernet switch"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(REALTEK_DSA); +MODULE_IMPORT_NS("REALTEK_DSA"); diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c index 3c5018d5e1f93b9e37a8b55bfa0986c75adf82cb..2b9bd4462714bf08a1f41eb25d52fad2f7d3885c 100644 --- a/drivers/net/dsa/realtek/rtl83xx.c +++ b/drivers/net/dsa/realtek/rtl83xx.c @@ -25,7 +25,7 @@ void rtl83xx_lock(void *ctx) mutex_lock(&priv->map_lock); } -EXPORT_SYMBOL_NS_GPL(rtl83xx_lock, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_lock, "REALTEK_DSA"); /** * rtl83xx_unlock() - Unlocks the mutex used by regmaps @@ -42,7 +42,7 @@ void rtl83xx_unlock(void *ctx) mutex_unlock(&priv->map_lock); } -EXPORT_SYMBOL_NS_GPL(rtl83xx_unlock, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_unlock, "REALTEK_DSA"); static int rtl83xx_user_mdio_read(struct mii_bus *bus, int addr, int regnum) { @@ -109,7 +109,7 @@ err_put_node: return ret; } -EXPORT_SYMBOL_NS_GPL(rtl83xx_setup_user_mdio, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_setup_user_mdio, "REALTEK_DSA"); /** * rtl83xx_probe() - probe a Realtek switch @@ -208,7 +208,7 @@ rtl83xx_probe(struct device *dev, return priv; } -EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, "REALTEK_DSA"); /** * rtl83xx_register_switch() - detects and register a switch @@ -245,7 +245,7 @@ int rtl83xx_register_switch(struct realtek_priv *priv) return 0; } -EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, "REALTEK_DSA"); /** * rtl83xx_unregister_switch() - unregister a switch @@ -262,7 +262,7 @@ void rtl83xx_unregister_switch(struct realtek_priv *priv) dsa_unregister_switch(ds); } -EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, "REALTEK_DSA"); /** * rtl83xx_shutdown() - shutdown a switch @@ -283,7 +283,7 @@ void rtl83xx_shutdown(struct realtek_priv *priv) dev_set_drvdata(priv->dev, NULL); } -EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, "REALTEK_DSA"); /** * rtl83xx_remove() - Cleanup a realtek switch driver @@ -297,7 +297,7 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA); void rtl83xx_remove(struct realtek_priv *priv) { } -EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA); +EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, "REALTEK_DSA"); void rtl83xx_reset_assert(struct realtek_priv *priv) { diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 4ec4934a4eddd34c67463ddd06a7bc680adf1230..6b963086c1d3b512352cb946f6642e0285821524 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3421,15 +3421,11 @@ static void bnxt_free_one_rx_agg_ring(struct bnxt *bp, struct bnxt_rx_ring_info } } -static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, int ring_nr) +static void bnxt_free_one_tpa_info_data(struct bnxt *bp, + struct bnxt_rx_ring_info *rxr) { - struct bnxt_rx_ring_info *rxr = &bp->rx_ring[ring_nr]; - struct bnxt_tpa_idx_map *map; int i; - if (!rxr->rx_tpa) - goto skip_rx_tpa_free; - for (i = 0; i < bp->max_tpa; i++) { struct bnxt_tpa_info *tpa_info = &rxr->rx_tpa[i]; u8 *data = tpa_info->data; @@ -3440,6 +3436,17 @@ static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, int ring_nr) tpa_info->data = NULL; page_pool_free_va(rxr->head_pool, data, false); } +} + +static void bnxt_free_one_rx_ring_skbs(struct bnxt *bp, + struct bnxt_rx_ring_info *rxr) +{ + struct bnxt_tpa_idx_map *map; + + if (!rxr->rx_tpa) + goto skip_rx_tpa_free; + + bnxt_free_one_tpa_info_data(bp, rxr); skip_rx_tpa_free: if (!rxr->rx_buf_ring) @@ -3467,7 +3474,7 @@ static void bnxt_free_rx_skbs(struct bnxt *bp) return; for (i = 0; i < bp->rx_nr_rings; i++) - bnxt_free_one_rx_ring_skbs(bp, i); + bnxt_free_one_rx_ring_skbs(bp, &bp->rx_ring[i]); } static void bnxt_free_skbs(struct bnxt *bp) @@ -3608,29 +3615,64 @@ static int bnxt_alloc_ring(struct bnxt *bp, struct bnxt_ring_mem_info *rmem) return 0; } +static void bnxt_free_one_tpa_info(struct bnxt *bp, + struct bnxt_rx_ring_info *rxr) +{ + int i; + + kfree(rxr->rx_tpa_idx_map); + rxr->rx_tpa_idx_map = NULL; + if (rxr->rx_tpa) { + for (i = 0; i < bp->max_tpa; i++) { + kfree(rxr->rx_tpa[i].agg_arr); + rxr->rx_tpa[i].agg_arr = NULL; + } + } + kfree(rxr->rx_tpa); + rxr->rx_tpa = NULL; +} + static void bnxt_free_tpa_info(struct bnxt *bp) { - int i, j; + int i; for (i = 0; i < bp->rx_nr_rings; i++) { struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; - kfree(rxr->rx_tpa_idx_map); - rxr->rx_tpa_idx_map = NULL; - if (rxr->rx_tpa) { - for (j = 0; j < bp->max_tpa; j++) { - kfree(rxr->rx_tpa[j].agg_arr); - rxr->rx_tpa[j].agg_arr = NULL; - } - } - kfree(rxr->rx_tpa); - rxr->rx_tpa = NULL; + bnxt_free_one_tpa_info(bp, rxr); + } +} + +static int bnxt_alloc_one_tpa_info(struct bnxt *bp, + struct bnxt_rx_ring_info *rxr) +{ + struct rx_agg_cmp *agg; + int i; + + rxr->rx_tpa = kcalloc(bp->max_tpa, sizeof(struct bnxt_tpa_info), + GFP_KERNEL); + if (!rxr->rx_tpa) + return -ENOMEM; + + if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS)) + return 0; + for (i = 0; i < bp->max_tpa; i++) { + agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL); + if (!agg) + return -ENOMEM; + rxr->rx_tpa[i].agg_arr = agg; } + rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map), + GFP_KERNEL); + if (!rxr->rx_tpa_idx_map) + return -ENOMEM; + + return 0; } static int bnxt_alloc_tpa_info(struct bnxt *bp) { - int i, j; + int i, rc; bp->max_tpa = MAX_TPA; if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { @@ -3641,25 +3683,10 @@ static int bnxt_alloc_tpa_info(struct bnxt *bp) for (i = 0; i < bp->rx_nr_rings; i++) { struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; - struct rx_agg_cmp *agg; - - rxr->rx_tpa = kcalloc(bp->max_tpa, sizeof(struct bnxt_tpa_info), - GFP_KERNEL); - if (!rxr->rx_tpa) - return -ENOMEM; - if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS)) - continue; - for (j = 0; j < bp->max_tpa; j++) { - agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL); - if (!agg) - return -ENOMEM; - rxr->rx_tpa[j].agg_arr = agg; - } - rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map), - GFP_KERNEL); - if (!rxr->rx_tpa_idx_map) - return -ENOMEM; + rc = bnxt_alloc_one_tpa_info(bp, rxr); + if (rc) + return rc; } return 0; } @@ -3683,7 +3710,7 @@ static void bnxt_free_rx_rings(struct bnxt *bp) xdp_rxq_info_unreg(&rxr->xdp_rxq); page_pool_destroy(rxr->page_pool); - if (rxr->page_pool != rxr->head_pool) + if (bnxt_separate_head_pool()) page_pool_destroy(rxr->head_pool); rxr->page_pool = rxr->head_pool = NULL; @@ -3737,6 +3764,19 @@ err_destroy_pp: return PTR_ERR(pool); } +static int bnxt_alloc_rx_agg_bmap(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) +{ + u16 mem_size; + + rxr->rx_agg_bmap_size = bp->rx_agg_ring_mask + 1; + mem_size = rxr->rx_agg_bmap_size / 8; + rxr->rx_agg_bmap = kzalloc(mem_size, GFP_KERNEL); + if (!rxr->rx_agg_bmap) + return -ENOMEM; + + return 0; +} + static int bnxt_alloc_rx_rings(struct bnxt *bp) { int numa_node = dev_to_node(&bp->pdev->dev); @@ -3781,19 +3821,15 @@ static int bnxt_alloc_rx_rings(struct bnxt *bp) ring->grp_idx = i; if (agg_rings) { - u16 mem_size; - ring = &rxr->rx_agg_ring_struct; rc = bnxt_alloc_ring(bp, &ring->ring_mem); if (rc) return rc; ring->grp_idx = i; - rxr->rx_agg_bmap_size = bp->rx_agg_ring_mask + 1; - mem_size = rxr->rx_agg_bmap_size / 8; - rxr->rx_agg_bmap = kzalloc(mem_size, GFP_KERNEL); - if (!rxr->rx_agg_bmap) - return -ENOMEM; + rc = bnxt_alloc_rx_agg_bmap(bp, rxr); + if (rc) + return rc; } } if (bp->flags & BNXT_FLAG_TPA) @@ -4268,10 +4304,31 @@ static void bnxt_alloc_one_rx_ring_page(struct bnxt *bp, rxr->rx_agg_prod = prod; } +static int bnxt_alloc_one_tpa_info_data(struct bnxt *bp, + struct bnxt_rx_ring_info *rxr) +{ + dma_addr_t mapping; + u8 *data; + int i; + + for (i = 0; i < bp->max_tpa; i++) { + data = __bnxt_alloc_rx_frag(bp, &mapping, rxr, + GFP_KERNEL); + if (!data) + return -ENOMEM; + + rxr->rx_tpa[i].data = data; + rxr->rx_tpa[i].data_ptr = data + bp->rx_offset; + rxr->rx_tpa[i].mapping = mapping; + } + + return 0; +} + static int bnxt_alloc_one_rx_ring(struct bnxt *bp, int ring_nr) { struct bnxt_rx_ring_info *rxr = &bp->rx_ring[ring_nr]; - int i; + int rc; bnxt_alloc_one_rx_ring_skb(bp, rxr, ring_nr); @@ -4281,19 +4338,9 @@ static int bnxt_alloc_one_rx_ring(struct bnxt *bp, int ring_nr) bnxt_alloc_one_rx_ring_page(bp, rxr, ring_nr); if (rxr->rx_tpa) { - dma_addr_t mapping; - u8 *data; - - for (i = 0; i < bp->max_tpa; i++) { - data = __bnxt_alloc_rx_frag(bp, &mapping, rxr, - GFP_KERNEL); - if (!data) - return -ENOMEM; - - rxr->rx_tpa[i].data = data; - rxr->rx_tpa[i].data_ptr = data + bp->rx_offset; - rxr->rx_tpa[i].mapping = mapping; - } + rc = bnxt_alloc_one_tpa_info_data(bp, rxr); + if (rc) + return rc; } return 0; } @@ -13663,7 +13710,7 @@ static void bnxt_rx_ring_reset(struct bnxt *bp) bnxt_reset_task(bp, true); break; } - bnxt_free_one_rx_ring_skbs(bp, i); + bnxt_free_one_rx_ring_skbs(bp, rxr); rxr->rx_prod = 0; rxr->rx_agg_prod = 0; rxr->rx_sw_agg_prod = 0; @@ -15293,19 +15340,6 @@ static const struct netdev_stat_ops bnxt_stat_ops = { .get_base_stats = bnxt_get_base_stats, }; -static int bnxt_alloc_rx_agg_bmap(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) -{ - u16 mem_size; - - rxr->rx_agg_bmap_size = bp->rx_agg_ring_mask + 1; - mem_size = rxr->rx_agg_bmap_size / 8; - rxr->rx_agg_bmap = kzalloc(mem_size, GFP_KERNEL); - if (!rxr->rx_agg_bmap) - return -ENOMEM; - - return 0; -} - static int bnxt_queue_mem_alloc(struct net_device *dev, void *qmem, int idx) { struct bnxt_rx_ring_info *rxr, *clone; @@ -15354,15 +15388,25 @@ static int bnxt_queue_mem_alloc(struct net_device *dev, void *qmem, int idx) goto err_free_rx_agg_ring; } + if (bp->flags & BNXT_FLAG_TPA) { + rc = bnxt_alloc_one_tpa_info(bp, clone); + if (rc) + goto err_free_tpa_info; + } + bnxt_init_one_rx_ring_rxbd(bp, clone); bnxt_init_one_rx_agg_ring_rxbd(bp, clone); bnxt_alloc_one_rx_ring_skb(bp, clone, idx); if (bp->flags & BNXT_FLAG_AGG_RINGS) bnxt_alloc_one_rx_ring_page(bp, clone, idx); + if (bp->flags & BNXT_FLAG_TPA) + bnxt_alloc_one_tpa_info_data(bp, clone); return 0; +err_free_tpa_info: + bnxt_free_one_tpa_info(bp, clone); err_free_rx_agg_ring: bnxt_free_ring(bp, &clone->rx_agg_ring_struct.ring_mem); err_free_rx_ring: @@ -15370,9 +15414,11 @@ err_free_rx_ring: err_rxq_info_unreg: xdp_rxq_info_unreg(&clone->xdp_rxq); err_page_pool_destroy: - clone->page_pool->p.napi = NULL; page_pool_destroy(clone->page_pool); + if (bnxt_separate_head_pool()) + page_pool_destroy(clone->head_pool); clone->page_pool = NULL; + clone->head_pool = NULL; return rc; } @@ -15382,13 +15428,15 @@ static void bnxt_queue_mem_free(struct net_device *dev, void *qmem) struct bnxt *bp = netdev_priv(dev); struct bnxt_ring_struct *ring; - bnxt_free_one_rx_ring(bp, rxr); - bnxt_free_one_rx_agg_ring(bp, rxr); + bnxt_free_one_rx_ring_skbs(bp, rxr); xdp_rxq_info_unreg(&rxr->xdp_rxq); page_pool_destroy(rxr->page_pool); + if (bnxt_separate_head_pool()) + page_pool_destroy(rxr->head_pool); rxr->page_pool = NULL; + rxr->head_pool = NULL; ring = &rxr->rx_ring_struct; bnxt_free_ring(bp, &ring->ring_mem); @@ -15470,7 +15518,10 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx) rxr->rx_agg_prod = clone->rx_agg_prod; rxr->rx_sw_agg_prod = clone->rx_sw_agg_prod; rxr->rx_next_cons = clone->rx_next_cons; + rxr->rx_tpa = clone->rx_tpa; + rxr->rx_tpa_idx_map = clone->rx_tpa_idx_map; rxr->page_pool = clone->page_pool; + rxr->head_pool = clone->head_pool; rxr->xdp_rxq = clone->xdp_rxq; bnxt_copy_rx_ring(bp, rxr, clone); @@ -15529,6 +15580,8 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx) bnxt_hwrm_rx_agg_ring_free(bp, rxr, false); rxr->rx_next_cons = 0; page_pool_disable_direct_recycling(rxr->page_pool); + if (bnxt_separate_head_pool()) + page_pool_disable_direct_recycling(rxr->head_pool); memcpy(qmem, rxr, sizeof(*rxr)); bnxt_init_rx_ring_struct(bp, qmem); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index f1f6bb328a55ba5a0d2f936e492816b4cabe43be..d87681d711067c73ef42b77033f7aa15bec51f7e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1187,10 +1187,14 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd) } } - if (fltr->base.flags & BNXT_ACT_DROP) + if (fltr->base.flags & BNXT_ACT_DROP) { fs->ring_cookie = RX_CLS_FLOW_DISC; - else + } else if (fltr->base.flags & BNXT_ACT_RSS_CTX) { + fs->flow_type |= FLOW_RSS; + cmd->rss_context = fltr->base.fw_vnic_id; + } else { fs->ring_cookie = fltr->base.rxq; + } rc = 0; fltr_err: diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 35634c516e266e69812dff35fc8312d895062cfd..535969fa0fdbef8c6840bf335fce603b666d85a1 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -29,6 +29,9 @@ EXPORT_SYMBOL_GPL(enetc_port_mac_wr); static void enetc_change_preemptible_tcs(struct enetc_ndev_priv *priv, u8 preemptible_tcs) { + if (!(priv->si->hw_features & ENETC_SI_F_QBU)) + return; + priv->preemptible_tcs = preemptible_tcs; enetc_mm_commit_preemptible_tcs(priv); } @@ -1756,15 +1759,6 @@ void enetc_get_si_caps(struct enetc_si *si) rss = enetc_rd(hw, ENETC_SIRSSCAPR); si->num_rss = ENETC_SIRSSCAPR_GET_NUM_RSS(rss); } - - if (val & ENETC_SIPCAPR0_QBV) - si->hw_features |= ENETC_SI_F_QBV; - - if (val & ENETC_SIPCAPR0_QBU) - si->hw_features |= ENETC_SI_F_QBU; - - if (val & ENETC_SIPCAPR0_PSFP) - si->hw_features |= ENETC_SI_F_PSFP; } EXPORT_SYMBOL_GPL(enetc_get_si_caps); diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h index 7c3285584f8a5bcc6f8640ba60ba0b97a8604649..55ba949230ffd097d894046d37ad369e303ba44c 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -23,10 +23,7 @@ #define ENETC_SICTR0 0x18 #define ENETC_SICTR1 0x1c #define ENETC_SIPCAPR0 0x20 -#define ENETC_SIPCAPR0_PSFP BIT(9) #define ENETC_SIPCAPR0_RSS BIT(8) -#define ENETC_SIPCAPR0_QBV BIT(4) -#define ENETC_SIPCAPR0_QBU BIT(3) #define ENETC_SIPCAPR0_RFS BIT(2) #define ENETC_SIPCAPR1 0x24 #define ENETC_SITGTGR 0x30 @@ -194,6 +191,9 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_PCAPR0 0x0900 #define ENETC_PCAPR0_RXBDR(val) ((val) >> 24) #define ENETC_PCAPR0_TXBDR(val) (((val) >> 16) & 0xff) +#define ENETC_PCAPR0_PSFP BIT(9) +#define ENETC_PCAPR0_QBV BIT(4) +#define ENETC_PCAPR0_QBU BIT(3) #define ENETC_PCAPR1 0x0904 #define ENETC_PSICFGR0(n) (0x0940 + (n) * 0xc) /* n = SI index */ #define ENETC_PSICFGR0_SET_TXBDR(val) ((val) & 0xff) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index c47b4a743d93b97493db4cb393ca6a57f9bfdb1e..203862ec111427b857c920d135cc764b4e6f1c55 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -409,6 +409,23 @@ static void enetc_port_assign_rfs_entries(struct enetc_si *si) enetc_port_wr(hw, ENETC_PRFSMR, ENETC_PRFSMR_RFSE); } +static void enetc_port_get_caps(struct enetc_si *si) +{ + struct enetc_hw *hw = &si->hw; + u32 val; + + val = enetc_port_rd(hw, ENETC_PCAPR0); + + if (val & ENETC_PCAPR0_QBV) + si->hw_features |= ENETC_SI_F_QBV; + + if (val & ENETC_PCAPR0_QBU) + si->hw_features |= ENETC_SI_F_QBU; + + if (val & ENETC_PCAPR0_PSFP) + si->hw_features |= ENETC_SI_F_PSFP; +} + static void enetc_port_si_configure(struct enetc_si *si) { struct enetc_pf *pf = enetc_si_priv(si); @@ -416,6 +433,8 @@ static void enetc_port_si_configure(struct enetc_si *si) int num_rings, i; u32 val; + enetc_port_get_caps(si); + val = enetc_port_rd(hw, ENETC_PCAPR0); num_rings = min(ENETC_PCAPR0_RXBDR(val), ENETC_PCAPR0_TXBDR(val)); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index ab5febf83ec338db0741ea27cc0030fc664fbbfd..0e1d9e2fbf38cc132b0cc6a6bf76d556f086c96e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -99,7 +99,7 @@ module_param(debug, uint, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all), Debug mask (0x8XXXXXXX)"); MODULE_DESCRIPTION("Intel(R) Ethernet Connection XL710 Network Driver"); -MODULE_IMPORT_NS(LIBIE); +MODULE_IMPORT_NS("LIBIE"); MODULE_LICENSE("GPL v2"); static struct workqueue_struct *i40e_wq; diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 12ef160425aa81dc901363ff74d12a92fac47bed..a9e54866ae6bfa4a792368c1b1d8ed140bb159dc 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -46,8 +46,8 @@ MODULE_DEVICE_TABLE(pci, iavf_pci_tbl); MODULE_ALIAS("i40evf"); MODULE_DESCRIPTION("Intel(R) Ethernet Adaptive Virtual Function Network Driver"); -MODULE_IMPORT_NS(LIBETH); -MODULE_IMPORT_NS(LIBIE); +MODULE_IMPORT_NS("LIBETH"); +MODULE_IMPORT_NS("LIBIE"); MODULE_LICENSE("GPL v2"); static const struct net_device_ops iavf_netdev_ops; diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index b22e71dc59d4e4ec0efea96e5afd812859a98bdd..496d86cbd13fc3439e69c62eed8d730906e4d45b 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -542,7 +542,8 @@ ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd, /** * ice_find_netlist_node * @hw: pointer to the hw struct - * @node_type_ctx: type of netlist node to look for + * @node_type: type of netlist node to look for + * @ctx: context of the search * @node_part_number: node part number to look for * @node_handle: output parameter if node found - optional * @@ -552,10 +553,12 @@ ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd, * valid if the function returns zero, and should be ignored on any non-zero * return value. * - * Returns: 0 if the node is found, -ENOENT if no handle was found, and - * a negative error code on failure to access the AQ. + * Return: + * * 0 if the node is found, + * * -ENOENT if no handle was found, + * * negative error code on failure to access the AQ. */ -static int ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, +static int ice_find_netlist_node(struct ice_hw *hw, u8 node_type, u8 ctx, u8 node_part_number, u16 *node_handle) { u8 idx; @@ -566,8 +569,8 @@ static int ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, int status; cmd.addr.topo_params.node_type_ctx = - FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_TYPE_M, - node_type_ctx); + FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_TYPE_M, node_type) | + FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M, ctx); cmd.addr.topo_params.index = idx; status = ice_aq_get_netlist_node(hw, &cmd, @@ -2747,9 +2750,11 @@ bool ice_is_pf_c827(struct ice_hw *hw) */ bool ice_is_phy_rclk_in_netlist(struct ice_hw *hw) { - if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL, + if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_PHY, + ICE_AQC_LINK_TOPO_NODE_CTX_PORT, ICE_AQC_GET_LINK_TOPO_NODE_NR_C827, NULL) && - ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL, + ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_PHY, + ICE_AQC_LINK_TOPO_NODE_CTX_PORT, ICE_AQC_GET_LINK_TOPO_NODE_NR_E822_PHY, NULL)) return false; @@ -2765,6 +2770,7 @@ bool ice_is_phy_rclk_in_netlist(struct ice_hw *hw) bool ice_is_clock_mux_in_netlist(struct ice_hw *hw) { if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX, + ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL, ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX, NULL)) return false; @@ -2785,12 +2791,14 @@ bool ice_is_clock_mux_in_netlist(struct ice_hw *hw) bool ice_is_cgu_in_netlist(struct ice_hw *hw) { if (!ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL, + ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL, ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032, NULL)) { hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032; return true; } else if (!ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL, + ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL, ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384, NULL)) { hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384; @@ -2809,6 +2817,7 @@ bool ice_is_cgu_in_netlist(struct ice_hw *hw) bool ice_is_gps_in_netlist(struct ice_hw *hw) { if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS, + ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL, ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL)) return false; diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 1eaa4428fd2482133525fd1e90e486e7fa3c204c..0ab35607e5d569b987ad1b0400ee00c666beb228 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -37,7 +37,7 @@ static const char ice_copyright[] = "Copyright (c) 2018, Intel Corporation."; #define ICE_DDP_PKG_FILE ICE_DDP_PKG_PATH "ice.pkg" MODULE_DESCRIPTION(DRV_SUMMARY); -MODULE_IMPORT_NS(LIBIE); +MODULE_IMPORT_NS("LIBIE"); MODULE_LICENSE("GPL v2"); MODULE_FIRMWARE(ICE_DDP_PKG_FILE); @@ -6408,10 +6408,12 @@ ice_set_vlan_filtering_features(struct ice_vsi *vsi, netdev_features_t features) int err = 0; /* support Single VLAN Mode (SVM) and Double VLAN Mode (DVM) by checking - * if either bit is set + * if either bit is set. In switchdev mode Rx filtering should never be + * enabled. */ - if (features & - (NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)) + if ((features & + (NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)) && + !ice_is_eswitch_mode_switchdev(vsi->back)) err = vlan_ops->ena_rx_filtering(vsi); else err = vlan_ops->dis_rx_filtering(vsi); diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c index dfd49732bd5b55b4ec4a09e06172055eceb3d3b9..518893f23372bf6c50c171a96d198c2c41961b2a 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -1518,7 +1518,8 @@ static int ice_read_ptp_tstamp_eth56g(struct ice_hw *hw, u8 port, u8 idx, * lower 8 bits in the low register, and the upper 32 bits in the high * register. */ - *tstamp = ((u64)hi) << TS_PHY_HIGH_S | ((u64)lo & TS_PHY_LOW_M); + *tstamp = FIELD_PREP(TS_PHY_HIGH_M, hi) | + FIELD_PREP(TS_PHY_LOW_M, lo); return 0; } diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h index 47af7c5c79b8198839beac5f0900dafb8b5d44ed..1cee0f1bba2df3af2ab8f0ad448a96cc6fe7ab8e 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -682,9 +682,8 @@ static inline bool ice_is_dual(struct ice_hw *hw) #define TS_HIGH_M 0xFF #define TS_HIGH_S 32 -#define TS_PHY_LOW_M 0xFF -#define TS_PHY_HIGH_M 0xFFFFFFFF -#define TS_PHY_HIGH_S 8 +#define TS_PHY_LOW_M GENMASK(7, 0) +#define TS_PHY_HIGH_M GENMASK_ULL(39, 8) #define BYTES_PER_IDX_ADDR_L_U 8 #define BYTES_PER_IDX_ADDR_L 4 diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c index f445e33b2028fa703bc53cf7aa28cc317c4f25d1..ff4ad788d96ac5b8cff0b02dbbf081b2b0a22cc0 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c @@ -4128,6 +4128,9 @@ static const struct ice_virtchnl_ops ice_virtchnl_dflt_ops = { .get_qos_caps = ice_vc_get_qos_caps, .cfg_q_bw = ice_vc_cfg_q_bw, .cfg_q_quanta = ice_vc_cfg_q_quanta, + /* If you add a new op here please make sure to add it to + * ice_virtchnl_repr_ops as well. + */ }; /** @@ -4258,6 +4261,9 @@ static const struct ice_virtchnl_ops ice_virtchnl_repr_ops = { .dis_vlan_stripping_v2_msg = ice_vc_dis_vlan_stripping_v2_msg, .ena_vlan_insertion_v2_msg = ice_vc_ena_vlan_insertion_v2_msg, .dis_vlan_insertion_v2_msg = ice_vc_dis_vlan_insertion_v2_msg, + .get_qos_caps = ice_vc_get_qos_caps, + .cfg_q_bw = ice_vc_cfg_q_bw, + .cfg_q_quanta = ice_vc_cfg_q_quanta, }; /** diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c index db476b3314c8a517e26fad531a076a507b760725..f71d3182580b6a25089abc9ecb5b4e9a5a39390d 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_main.c +++ b/drivers/net/ethernet/intel/idpf/idpf_main.c @@ -8,7 +8,7 @@ #define DRV_SUMMARY "Intel(R) Infrastructure Data Path Function Linux Driver" MODULE_DESCRIPTION(DRV_SUMMARY); -MODULE_IMPORT_NS(LIBETH); +MODULE_IMPORT_NS("LIBETH"); MODULE_LICENSE("GPL"); /** diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c index da2a5becf62f127e7fc16854c391723ce80c4f64..34f4118c7bc0de478ccc98540c161283c6e501f9 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c @@ -2448,6 +2448,7 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q, * rest of the packet. */ tx_buf->type = LIBETH_SQE_EMPTY; + idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag; /* Adjust the DMA offset and the remaining size of the * fragment. On the first iteration of this loop, diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 08578980b651802c191c0ec9be050810d6a93844..288a4bb2683a92fae7b75bc967bfb85fe13270ff 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -637,6 +637,10 @@ static int __init igb_init_module(void) dca_register_notify(&dca_notifier); #endif ret = pci_register_driver(&igb_driver); +#ifdef CONFIG_IGB_DCA + if (ret) + dca_unregister_notify(&dca_notifier); +#endif return ret; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h index 6493abf189de5edd8bf885a880c19b83cdd9283c..6639069ad5283433005bf0044b73a6a8f7f1e57d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h @@ -194,6 +194,8 @@ u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg); dev_err(&adapter->pdev->dev, format, ## arg) #define e_dev_notice(format, arg...) \ dev_notice(&adapter->pdev->dev, format, ## arg) +#define e_dbg(msglvl, format, arg...) \ + netif_dbg(adapter, msglvl, adapter->netdev, format, ## arg) #define e_info(msglvl, format, arg...) \ netif_info(adapter, msglvl, adapter->netdev, format, ## arg) #define e_err(msglvl, format, arg...) \ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h index 14aa2ca51f70ec81f9e286c217681f5feb7b32af..81179c60af4e0199a8b9d0fcdf34654b02eedfac 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h @@ -40,7 +40,7 @@ #define IXGBE_SFF_1GBASESX_CAPABLE 0x1 #define IXGBE_SFF_1GBASELX_CAPABLE 0x2 #define IXGBE_SFF_1GBASET_CAPABLE 0x8 -#define IXGBE_SFF_BASEBX10_CAPABLE 0x64 +#define IXGBE_SFF_BASEBX10_CAPABLE 0x40 #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 #define IXGBE_SFF_10GBASELR_CAPABLE 0x20 #define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8 diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 9631559a5aeacdf19377ec0acd512bfa9660bf78..ccdce80edd14229b326d354855e9392bbd792575 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1048,7 +1048,7 @@ static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter, break; } - e_info(drv, "VF %d requested invalid api version %u\n", vf, api); + e_dbg(drv, "VF %d requested unsupported api version %u\n", vf, api); return -1; } diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c index 66cf17f1940820eb31924b50bff67569f161f431..f804b35d79c726c9caf18a303a07fc5fe864edc0 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c +++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c @@ -629,7 +629,6 @@ void ixgbevf_init_ipsec_offload(struct ixgbevf_adapter *adapter) switch (adapter->hw.api_version) { case ixgbe_mbox_api_14: - case ixgbe_mbox_api_15: break; default: return; diff --git a/drivers/net/ethernet/intel/libeth/rx.c b/drivers/net/ethernet/intel/libeth/rx.c index f209266693185bf346c0bdf437540264d22f6634..66d1d23b8ad2403fd23a2671a6ef902771aa3473 100644 --- a/drivers/net/ethernet/intel/libeth/rx.c +++ b/drivers/net/ethernet/intel/libeth/rx.c @@ -186,7 +186,7 @@ err_buf: return -ENOMEM; } -EXPORT_SYMBOL_NS_GPL(libeth_rx_fq_create, LIBETH); +EXPORT_SYMBOL_NS_GPL(libeth_rx_fq_create, "LIBETH"); /** * libeth_rx_fq_destroy - destroy a &page_pool created by libeth @@ -197,7 +197,7 @@ void libeth_rx_fq_destroy(struct libeth_fq *fq) kvfree(fq->fqes); page_pool_destroy(fq->pp); } -EXPORT_SYMBOL_NS_GPL(libeth_rx_fq_destroy, LIBETH); +EXPORT_SYMBOL_NS_GPL(libeth_rx_fq_destroy, "LIBETH"); /** * libeth_rx_recycle_slow - recycle a libeth page from the NAPI context @@ -209,7 +209,7 @@ void libeth_rx_recycle_slow(struct page *page) { page_pool_recycle_direct(page->pp, page); } -EXPORT_SYMBOL_NS_GPL(libeth_rx_recycle_slow, LIBETH); +EXPORT_SYMBOL_NS_GPL(libeth_rx_recycle_slow, "LIBETH"); /* Converting abstract packet type numbers into a software structure with * the packet parameters to do O(1) lookup on Rx. @@ -251,7 +251,7 @@ void libeth_rx_pt_gen_hash_type(struct libeth_rx_pt *pt) pt->hash_type |= libeth_rx_pt_xdp_iprot[pt->inner_prot]; pt->hash_type |= libeth_rx_pt_xdp_pl[pt->payload_layer]; } -EXPORT_SYMBOL_NS_GPL(libeth_rx_pt_gen_hash_type, LIBETH); +EXPORT_SYMBOL_NS_GPL(libeth_rx_pt_gen_hash_type, "LIBETH"); /* Module */ diff --git a/drivers/net/ethernet/intel/libie/rx.c b/drivers/net/ethernet/intel/libie/rx.c index aceb8d8813c4cb9bd274e482a511dd23cbea4f98..66a9825fe11f74e1373eea7fc10f131709f52432 100644 --- a/drivers/net/ethernet/intel/libie/rx.c +++ b/drivers/net/ethernet/intel/libie/rx.c @@ -116,8 +116,8 @@ const struct libeth_rx_pt libie_rx_pt_lut[LIBIE_RX_PT_NUM] = { LIBIE_RX_PT_IP(4), LIBIE_RX_PT_IP(6), }; -EXPORT_SYMBOL_NS_GPL(libie_rx_pt_lut, LIBIE); +EXPORT_SYMBOL_NS_GPL(libie_rx_pt_lut, "LIBIE"); MODULE_DESCRIPTION("Intel(R) Ethernet common library"); -MODULE_IMPORT_NS(LIBETH); +MODULE_IMPORT_NS("LIBETH"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/common.h b/drivers/net/ethernet/marvell/octeontx2/af/common.h index 5d84386ed22da2ee0bec5dbbc2dd30aa5ac935ba..406c59100a35a1c6ed2770846fa6657f06aacb8a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/common.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/common.h @@ -159,6 +159,7 @@ enum nix_scheduler { #define SDP_HW_MIN_FRS 16 #define CN10K_LMAC_LINK_MAX_FRS 16380 /* 16k - FCS */ #define CN10K_LBK_LINK_MAX_FRS 65535 /* 64k */ +#define SDP_LINK_CREDIT 0x320202 /* NIX RX action operation*/ #define NIX_RX_ACTIONOP_DROP (0x0ull) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c index 5d5a01dbbca11530904bf71531ffca66b93fc4cd..a5d1e2bddd58db8966a1a59b43d777e6f011db3c 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -4672,6 +4672,9 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, rvu_get_lbk_link_max_frs(rvu, &lbk_max_frs); rvu_get_lmac_link_max_frs(rvu, &lmac_max_frs); + /* Set SDP link credit */ + rvu_write64(rvu, blkaddr, NIX_AF_SDP_LINK_CREDIT, SDP_LINK_CREDIT); + /* Set default min/max packet lengths allowed on NIX Rx links. * * With HW reset minlen value of 60byte, HW will treat ARP pkts diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c index 878cbdbf5ec8b42abfb3ce6c1e4384899e02d3f7..e7e01f3298efb0c78e83e85a52062dcd8a2864a0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c @@ -5,6 +5,7 @@ #include #include #include "tc_tun_encap.h" +#include "fs_core.h" #include "en_tc.h" #include "tc_tun.h" #include "rep/tc.h" @@ -24,10 +25,18 @@ static int mlx5e_set_int_port_tunnel(struct mlx5e_priv *priv, route_dev = dev_get_by_index(dev_net(e->out_dev), e->route_dev_ifindex); - if (!route_dev || !netif_is_ovs_master(route_dev) || - attr->parse_attr->filter_dev == e->out_dev) + if (!route_dev || !netif_is_ovs_master(route_dev)) goto out; + if (priv->mdev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS && + mlx5e_eswitch_uplink_rep(attr->parse_attr->filter_dev) && + (attr->esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP)) { + mlx5_core_warn(priv->mdev, + "Matching on external port with encap + fwd to table actions is not allowed for firmware steering\n"); + err = -EINVAL; + goto out; + } + err = mlx5e_set_fwd_to_int_port_actions(priv, attr, e->route_dev_ifindex, MLX5E_TC_INT_PORT_EGRESS, &attr->action, out_index); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index d0b80b520397f9e62d51f28015ab7d7896d72f83..dd16d73000c3120a7be70d95e2d0457e00d2c39f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -2680,11 +2680,11 @@ void mlx5e_trigger_napi_sched(struct napi_struct *napi) static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, struct mlx5e_params *params, - struct mlx5e_channel_param *cparam, struct xsk_buff_pool *xsk_pool, struct mlx5e_channel **cp) { struct net_device *netdev = priv->netdev; + struct mlx5e_channel_param *cparam; struct mlx5_core_dev *mdev; struct mlx5e_xsk_param xsk; struct mlx5e_channel *c; @@ -2706,8 +2706,15 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, return err; c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); - if (!c) - return -ENOMEM; + cparam = kvzalloc(sizeof(*cparam), GFP_KERNEL); + if (!c || !cparam) { + err = -ENOMEM; + goto err_free; + } + + err = mlx5e_build_channel_param(mdev, params, cparam); + if (err) + goto err_free; c->priv = priv; c->mdev = mdev; @@ -2741,6 +2748,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, *cp = c; + kvfree(cparam); return 0; err_close_queues: @@ -2749,6 +2757,8 @@ err_close_queues: err_napi_del: netif_napi_del(&c->napi); +err_free: + kvfree(cparam); kvfree(c); return err; @@ -2807,20 +2817,14 @@ static void mlx5e_close_channel(struct mlx5e_channel *c) int mlx5e_open_channels(struct mlx5e_priv *priv, struct mlx5e_channels *chs) { - struct mlx5e_channel_param *cparam; int err = -ENOMEM; int i; chs->num = chs->params.num_channels; chs->c = kcalloc(chs->num, sizeof(struct mlx5e_channel *), GFP_KERNEL); - cparam = kvzalloc(sizeof(struct mlx5e_channel_param), GFP_KERNEL); - if (!chs->c || !cparam) - goto err_free; - - err = mlx5e_build_channel_param(priv->mdev, &chs->params, cparam); - if (err) - goto err_free; + if (!chs->c) + goto err_out; for (i = 0; i < chs->num; i++) { struct xsk_buff_pool *xsk_pool = NULL; @@ -2828,7 +2832,7 @@ int mlx5e_open_channels(struct mlx5e_priv *priv, if (chs->params.xdp_prog) xsk_pool = mlx5e_xsk_get_pool(&chs->params, chs->params.xsk, i); - err = mlx5e_open_channel(priv, i, &chs->params, cparam, xsk_pool, &chs->c[i]); + err = mlx5e_open_channel(priv, i, &chs->params, xsk_pool, &chs->c[i]); if (err) goto err_close_channels; } @@ -2846,7 +2850,6 @@ int mlx5e_open_channels(struct mlx5e_priv *priv, } mlx5e_health_channels_update(priv); - kvfree(cparam); return 0; err_close_ptp: @@ -2857,9 +2860,8 @@ err_close_channels: for (i--; i >= 0; i--) mlx5e_close_channel(chs->c[i]); -err_free: kfree(chs->c); - kvfree(cparam); +err_out: chs->num = 0; return err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index d6ff2dc4c19e9df18992de2eab07fc68a5f63dcb..d5b42b3a19fdf776060e679edb8c714f165e1c4d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -2335,9 +2335,10 @@ out_free: static void esw_mode_change(struct mlx5_eswitch *esw, u16 mode) { mlx5_devcom_comp_lock(esw->dev->priv.hca_devcom_comp); - - if (esw->dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_IB_ADEV) { + if (esw->dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_IB_ADEV || + mlx5_core_mp_enabled(esw->dev)) { esw->mode = mode; + mlx5_rescan_drivers_locked(esw->dev); mlx5_devcom_comp_unlock(esw->dev->priv.hca_devcom_comp); return; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c index c00010ca86bdc16798c70630944e8da6e7f7cfc5..9fb059a6511f7f99cd7944241f6a389097420b3e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c @@ -39,6 +39,8 @@ bool mlx5hws_bwc_match_params_is_complex(struct mlx5hws_context *ctx, } else { mlx5hws_err(ctx, "Failed to calculate matcher definer layout\n"); } + } else { + kfree(mt->fc); } mlx5hws_match_template_destroy(mt); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c index 424797b6d8020de4ecc09d3aa240bdc4c035f9f5..883b4ed30892c4cac6c92cb4de27190e655a5e7b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c @@ -990,6 +990,7 @@ static int hws_bwc_send_queues_init(struct mlx5hws_context *ctx) for (i = 0; i < bwc_queues; i++) { mutex_init(&ctx->bwc_send_queue_locks[i]); lockdep_register_key(ctx->bwc_lock_class_keys + i); + lockdep_set_class(ctx->bwc_send_queue_locks + i, ctx->bwc_lock_class_keys + i); } return 0; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c index 6fe185ea6732cca76d8def6e284abae5a2959fd4..1850a975b3804431eb9e92267ed45f3b69cf7e7e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c @@ -324,6 +324,10 @@ static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 9, -1, true), /* RX_ACL_SYSTEM_PORT */ }; +static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1b[] = { + MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4), +}; + static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5b[] = { MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER, 0x04, 20, 12), }; @@ -341,7 +345,7 @@ static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = { MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4), MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x1A, mlxsw_sp_afk_element_info_mac_5b), MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x38, mlxsw_sp_afk_element_info_ipv4_0), - MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x39, mlxsw_sp_afk_element_info_ipv4_1), + MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x3F, mlxsw_sp_afk_element_info_ipv4_1b), MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2), MLXSW_AFK_BLOCK(0x36, mlxsw_sp_afk_element_info_ipv4_5b), MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0), diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c index e97af7ac2bb2af9957f9a5c576dc163e23c14ea8..550be6dc305db3d943432f7d4a5dc8adfb9455a8 100644 --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c @@ -177,7 +177,7 @@ int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req, return mana_hwc_send_request(hwc, req_len, req, resp_len, resp); } -EXPORT_SYMBOL_NS(mana_gd_send_request, NET_MANA); +EXPORT_SYMBOL_NS(mana_gd_send_request, "NET_MANA"); int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length, struct gdma_mem_info *gmi) @@ -716,7 +716,7 @@ int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle) return 0; } -EXPORT_SYMBOL_NS(mana_gd_destroy_dma_region, NET_MANA); +EXPORT_SYMBOL_NS(mana_gd_destroy_dma_region, "NET_MANA"); static int mana_gd_create_dma_region(struct gdma_dev *gd, struct gdma_mem_info *gmi) @@ -820,7 +820,7 @@ free_q: kfree(queue); return err; } -EXPORT_SYMBOL_NS(mana_gd_create_mana_eq, NET_MANA); +EXPORT_SYMBOL_NS(mana_gd_create_mana_eq, "NET_MANA"); int mana_gd_create_mana_wq_cq(struct gdma_dev *gd, const struct gdma_queue_spec *spec, @@ -897,7 +897,7 @@ void mana_gd_destroy_queue(struct gdma_context *gc, struct gdma_queue *queue) mana_gd_free_memory(gmi); kfree(queue); } -EXPORT_SYMBOL_NS(mana_gd_destroy_queue, NET_MANA); +EXPORT_SYMBOL_NS(mana_gd_destroy_queue, "NET_MANA"); int mana_gd_verify_vf_version(struct pci_dev *pdev) { @@ -974,7 +974,7 @@ int mana_gd_register_device(struct gdma_dev *gd) return 0; } -EXPORT_SYMBOL_NS(mana_gd_register_device, NET_MANA); +EXPORT_SYMBOL_NS(mana_gd_register_device, "NET_MANA"); int mana_gd_deregister_device(struct gdma_dev *gd) { @@ -1005,7 +1005,7 @@ int mana_gd_deregister_device(struct gdma_dev *gd) return err; } -EXPORT_SYMBOL_NS(mana_gd_deregister_device, NET_MANA); +EXPORT_SYMBOL_NS(mana_gd_deregister_device, "NET_MANA"); u32 mana_gd_wq_avail_space(struct gdma_queue *wq) { diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c index 57ac732e77074b38a305a6311b269582e688c3fe..aa1e47233fe50cc5b9f06ce9aa97a9e6d1dd8f0d 100644 --- a/drivers/net/ethernet/microsoft/mana/mana_en.c +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c @@ -1022,7 +1022,7 @@ void mana_uncfg_vport(struct mana_port_context *apc) WARN_ON(apc->vport_use_count < 0); mutex_unlock(&apc->vport_mutex); } -EXPORT_SYMBOL_NS(mana_uncfg_vport, NET_MANA); +EXPORT_SYMBOL_NS(mana_uncfg_vport, "NET_MANA"); int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id, u32 doorbell_pg_id) @@ -1092,7 +1092,7 @@ out: return err; } -EXPORT_SYMBOL_NS(mana_cfg_vport, NET_MANA); +EXPORT_SYMBOL_NS(mana_cfg_vport, "NET_MANA"); static int mana_cfg_vport_steering(struct mana_port_context *apc, enum TRI_STATE rx, @@ -1214,7 +1214,7 @@ int mana_create_wq_obj(struct mana_port_context *apc, out: return err; } -EXPORT_SYMBOL_NS(mana_create_wq_obj, NET_MANA); +EXPORT_SYMBOL_NS(mana_create_wq_obj, "NET_MANA"); void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type, mana_handle_t wq_obj) @@ -1242,7 +1242,7 @@ void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type, netdev_err(ndev, "Failed to destroy WQ object: %d, 0x%x\n", err, resp.hdr.status); } -EXPORT_SYMBOL_NS(mana_destroy_wq_obj, NET_MANA); +EXPORT_SYMBOL_NS(mana_destroy_wq_obj, "NET_MANA"); static void mana_destroy_eq(struct mana_context *ac) { @@ -2536,6 +2536,7 @@ void mana_query_gf_stats(struct mana_port_context *apc) mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_GF_STAT, sizeof(req), sizeof(resp)); + req.hdr.resp.msg_version = GDMA_MESSAGE_V2; req.req_stats = STATISTICS_FLAGS_RX_DISCARDS_NO_WQE | STATISTICS_FLAGS_RX_ERRORS_VPORT_DISABLED | STATISTICS_FLAGS_HC_RX_BYTES | @@ -3147,4 +3148,4 @@ struct net_device *mana_get_primary_netdev_rcu(struct mana_context *ac, u32 port return ndev; } -EXPORT_SYMBOL_NS(mana_get_primary_netdev_rcu, NET_MANA); +EXPORT_SYMBOL_NS(mana_get_primary_netdev_rcu, "NET_MANA"); diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index 26a714bfad4ecfb5a1565ef8ac57676e6a6f7c3e..b45efc272fdbb33eb4113f5c910a9ec4f1c2b30f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -3301,7 +3301,9 @@ int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn, if (rc) return rc; - if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK)) + if (((rsp & FW_MSG_CODE_MASK) == FW_MSG_CODE_UNSUPPORTED)) + rc = -EOPNOTSUPP; + else if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK)) rc = -EINVAL; return rc; diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 2f29b1386b1c81640562e6ce91d6e8d88f0ffe1c..bc658bc6088546d5d1f116988b93d4dda915a799 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -895,7 +895,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, if (geneve->cfg.df == GENEVE_DF_SET) { df = htons(IP_DF); } else if (geneve->cfg.df == GENEVE_DF_INHERIT) { - struct ethhdr *eth = eth_hdr(skb); + struct ethhdr *eth = skb_eth_hdr(skb); if (ntohs(eth->h_proto) == ETH_P_IPV6) { df = htons(IP_DF); diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c index bb07725d1c72b1332ec052af190a563456469c5f..c1d881dc6409a4dae9bd99562a4f11e93cce3d68 100644 --- a/drivers/net/netkit.c +++ b/drivers/net/netkit.c @@ -327,7 +327,7 @@ static int netkit_validate(struct nlattr *tb[], struct nlattr *data[], static struct rtnl_link_ops netkit_link_ops; -static int netkit_new_link(struct net *src_net, struct net_device *dev, +static int netkit_new_link(struct net *peer_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { @@ -342,7 +342,6 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev, struct net_device *peer; char ifname[IFNAMSIZ]; struct netkit *nk; - struct net *net; int err; if (data) { @@ -385,13 +384,10 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev, (tb[IFLA_ADDRESS] || tbp[IFLA_ADDRESS])) return -EOPNOTSUPP; - net = rtnl_link_get_net(src_net, tbp); - peer = rtnl_create_link(net, ifname, ifname_assign_type, + peer = rtnl_create_link(peer_net, ifname, ifname_assign_type, &netkit_link_ops, tbp, extack); - if (IS_ERR(peer)) { - put_net(net); + if (IS_ERR(peer)) return PTR_ERR(peer); - } netif_inherit_tso_max(peer, dev); @@ -408,7 +404,6 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev, bpf_mprog_bundle_init(&nk->bundle); err = register_netdevice(peer); - put_net(net); if (err < 0) goto err_register_peer; netif_carrier_off(peer); diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c index d3273bc0da4a1feac5ec22349783c0891b3665c1..691969a4910f2b4821d4ed53bd1458e7c4834339 100644 --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -351,6 +351,22 @@ static int lan88xx_config_aneg(struct phy_device *phydev) static void lan88xx_link_change_notify(struct phy_device *phydev) { int temp; + int ret; + + /* Reset PHY to ensure MII_LPA provides up-to-date information. This + * issue is reproducible only after parallel detection, as described + * in IEEE 802.3-2022, Section 28.2.3.1 ("Parallel detection function"), + * where the link partner does not support auto-negotiation. + */ + if (phydev->state == PHY_NOLINK) { + ret = phy_init_hw(phydev); + if (ret < 0) + goto link_change_notify_failed; + + ret = _phy_start_aneg(phydev); + if (ret < 0) + goto link_change_notify_failed; + } /* At forced 100 F/H mode, chip may fail to set mode correctly * when cable is switched between long(~50+m) and short one. @@ -377,6 +393,11 @@ static void lan88xx_link_change_notify(struct phy_device *phydev) temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; phy_write(phydev, LAN88XX_INT_MASK, temp); } + + return; + +link_change_notify_failed: + phydev_err(phydev, "Link change process failed %pe\n", ERR_PTR(ret)); } /** diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 0d6d0d749d440e11714b7476d7138567039f16dc..07ebb800edf170e6fa662a44e26715fef2308930 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -1765,7 +1765,7 @@ static int veth_init_queues(struct net_device *dev, struct nlattr *tb[]) return 0; } -static int veth_newlink(struct net *src_net, struct net_device *dev, +static int veth_newlink(struct net *peer_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { @@ -1776,7 +1776,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, struct nlattr *peer_tb[IFLA_MAX + 1], **tbp; unsigned char name_assign_type; struct ifinfomsg *ifmp; - struct net *net; /* * create and register peer first @@ -1800,13 +1799,10 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, name_assign_type = NET_NAME_ENUM; } - net = rtnl_link_get_net(src_net, tbp); - peer = rtnl_create_link(net, ifname, name_assign_type, + peer = rtnl_create_link(peer_net, ifname, name_assign_type, &veth_link_ops, tbp, extack); - if (IS_ERR(peer)) { - put_net(net); + if (IS_ERR(peer)) return PTR_ERR(peer); - } if (!ifmp || !tbp[IFLA_ADDRESS]) eth_hw_addr_random(peer); @@ -1817,8 +1813,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, netif_inherit_tso_max(peer, dev); err = register_netdevice(peer); - put_net(net); - net = NULL; if (err < 0) goto err_register_peer; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c index 4f0c1e1a8e605daa4bcf907006bbd8e9a07490fa..1e1c79b18c5bcdf78468db52b7c4bc40336126a6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/module.c @@ -22,7 +22,7 @@ static void __exit brcmf_bca_exit(void) MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Broadcom AP chipsets"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(BRCMFMAC); +MODULE_IMPORT_NS("BRCMFMAC"); module_init(brcmf_bca_init); module_exit(brcmf_bca_exit); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index 39226b9c0fa8349e39fdadbf1f4dd1a664b0c98b..d53839f855d726e4e60ffeb658485a572a498f18 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -14,7 +14,7 @@ #include "fweh.h" #if IS_MODULE(CONFIG_BRCMFMAC) -#define BRCMF_EXPORT_SYMBOL_GPL(__sym) EXPORT_SYMBOL_NS_GPL(__sym, BRCMFMAC) +#define BRCMF_EXPORT_SYMBOL_GPL(__sym) EXPORT_SYMBOL_NS_GPL(__sym, "BRCMFMAC") #else #define BRCMF_EXPORT_SYMBOL_GPL(__sym) #endif diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c index 90d06cda03a2f007e9f00c636a22a4a130670dff..ce5fcfd42a7ea0cd82d09b93beb86782d9488c39 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/module.c @@ -22,7 +22,7 @@ static void __exit brcmf_cyw_exit(void) MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Cypress/Infineon chipsets"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(BRCMFMAC); +MODULE_IMPORT_NS("BRCMFMAC"); module_init(brcmf_cyw_init); module_exit(brcmf_cyw_exit); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c index b66135e3cff476a95c5482e099975fd01849bedf..cfe01ca63ba63b05c1081f7d7501a93cdbfa75ed 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/module.c @@ -22,7 +22,7 @@ static void __exit brcmf_wcc_exit(void) MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Broadcom mobility chipsets"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(BRCMFMAC); +MODULE_IMPORT_NS("BRCMFMAC"); module_init(brcmf_wcc_init); module_exit(brcmf_wcc_exit); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index e0b14be25b023802a5f781f54de97c942e3c731e..769b75c3fa5b911827e51f8f0d2668a34d5c4de9 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -48,7 +48,7 @@ #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux" MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IWLWIFI); +MODULE_IMPORT_NS("IWLWIFI"); /* Please keep this array *SORTED* by hex value. * Access is done through binary search. diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h index 6a1d31892417b45fa24859b7ba7e133a5b8944cf..854957bdf79dcda3554d41c57d1540148ee279d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h @@ -85,7 +85,7 @@ void iwl_drv_stop(struct iwl_drv *drv); * everything is built-in, then we can avoid that. */ #ifdef CONFIG_IWLWIFI_OPMODE_MODULAR -#define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_NS_GPL(sym, IWLWIFI) +#define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_NS_GPL(sym, "IWLWIFI") #else #define IWL_EXPORT_SYMBOL(sym) #endif diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index e25d7570ffab56613802620dada5ec491856a3a8..30fcc733395eb3e6fe3613884002416d861f952f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -34,7 +34,7 @@ #define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IWLWIFI); +MODULE_IMPORT_NS("IWLWIFI"); static const struct iwl_op_mode_ops iwl_mvm_ops; static const struct iwl_op_mode_ops iwl_mvm_ops_mq; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c b/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c index 47b8e7b64ead46195ba4edf7945d89d5736cd102..1dc57e02219130b6bfae8cd641768910a32096e0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c @@ -8,7 +8,7 @@ #include "../mvm.h" #include -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static struct wiphy wiphy = { .mtx = __MUTEX_INITIALIZER(wiphy.mtx), diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/tests/scan.c index d3b6a57c3ebe794a2ec8df8165d4638f07ce818a..7a3275199ace2e4c51dbf22c613ba622b7c768c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tests/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/scan.c @@ -8,7 +8,7 @@ #include "../mvm.h" #include -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static const struct acs_average_db_case { const char *desc; diff --git a/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c b/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c index 7361b6d0cdb8e5541a6f055a485a4026dfd79c12..d0bda23c628aa6542932057012f0b92f4b11a930 100644 --- a/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c +++ b/drivers/net/wireless/intel/iwlwifi/tests/devinfo.c @@ -9,7 +9,7 @@ #include "iwl-drv.h" #include "iwl-config.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static void iwl_pci_print_dev_info(const char *pfx, const struct iwl_dev_info *di) { diff --git a/drivers/nvdimm/e820.c b/drivers/nvdimm/e820.c index 0982215371ba0ded18b860828101bb938e86f756..41c67dfa80158e031c1d3f5e04ac12f5c27d281f 100644 --- a/drivers/nvdimm/e820.c +++ b/drivers/nvdimm/e820.c @@ -59,7 +59,7 @@ err: static struct platform_driver e820_pmem_driver = { .probe = e820_pmem_probe, - .remove_new = e820_pmem_remove, + .remove = e820_pmem_remove, .driver = { .name = "e820_pmem", }, diff --git a/drivers/nvdimm/of_pmem.c b/drivers/nvdimm/of_pmem.c index b4a1cf70e8b703c7b55bbf97ee9b200e03234751..68bddab3fb46e63964203756dc829d37ffe0c214 100644 --- a/drivers/nvdimm/of_pmem.c +++ b/drivers/nvdimm/of_pmem.c @@ -100,7 +100,7 @@ static const struct of_device_id of_pmem_region_match[] = { static struct platform_driver of_pmem_region_driver = { .probe = of_pmem_region_probe, - .remove_new = of_pmem_region_remove, + .remove = of_pmem_region_remove, .driver = { .name = "of_pmem", .of_match_table = of_pmem_region_match, diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 9e4f7ff024a00048fbe30d4e2080f41d3dc22567..37417ce5ec7bec0b13640cc934f30f2dbf3f33b3 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -1270,4 +1270,4 @@ int nd_region_conflict(struct nd_region *nd_region, resource_size_t start, return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict); } -MODULE_IMPORT_NS(DEVMEM); +MODULE_IMPORT_NS("DEVMEM"); diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index 7cd1102a8d2c5bb5b6f1562d78b9d880ab072145..4319ab50c10d11ed81dcc002275f190e053c1be6 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -1618,7 +1618,7 @@ static struct platform_driver apple_nvme_driver = { .pm = pm_sleep_ptr(&apple_nvme_pm_ops), }, .probe = apple_nvme_probe, - .remove_new = apple_nvme_remove, + .remove = apple_nvme_remove, .shutdown = apple_nvme_shutdown, }; module_platform_driver(apple_nvme_driver); diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1a8d32a4a5c31b5ddef1ae38cb22f8eb803a2745..52b01a15aad18b1adbe48ea75a00f91a3d0129f8 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -702,7 +702,7 @@ void nvme_put_ns(struct nvme_ns *ns) { kref_put(&ns->kref, nvme_free_ns); } -EXPORT_SYMBOL_NS_GPL(nvme_put_ns, NVME_TARGET_PASSTHRU); +EXPORT_SYMBOL_NS_GPL(nvme_put_ns, "NVME_TARGET_PASSTHRU"); static inline void nvme_clear_nvme_request(struct request *req) { @@ -1123,7 +1123,7 @@ int nvme_execute_rq(struct request *rq, bool at_head) return nvme_req(rq)->status; return blk_status_to_errno(status); } -EXPORT_SYMBOL_NS_GPL(nvme_execute_rq, NVME_TARGET_PASSTHRU); +EXPORT_SYMBOL_NS_GPL(nvme_execute_rq, "NVME_TARGET_PASSTHRU"); /* * Returns 0 on success. If the result is negative, it's a Linux error code; @@ -1203,7 +1203,7 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode) return effects; } -EXPORT_SYMBOL_NS_GPL(nvme_command_effects, NVME_TARGET_PASSTHRU); +EXPORT_SYMBOL_NS_GPL(nvme_command_effects, "NVME_TARGET_PASSTHRU"); u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode) { @@ -1223,7 +1223,7 @@ u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode) } return effects; } -EXPORT_SYMBOL_NS_GPL(nvme_passthru_start, NVME_TARGET_PASSTHRU); +EXPORT_SYMBOL_NS_GPL(nvme_passthru_start, "NVME_TARGET_PASSTHRU"); void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects, struct nvme_command *cmd, int status) @@ -1268,7 +1268,7 @@ void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects, break; } } -EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, NVME_TARGET_PASSTHRU); +EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, "NVME_TARGET_PASSTHRU"); /* * Recommended frequency for KATO commands per NVMe 1.4 section 7.12.1: @@ -1305,9 +1305,10 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); } -static void nvme_keep_alive_finish(struct request *rq, - blk_status_t status, struct nvme_ctrl *ctrl) +static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, + blk_status_t status) { + struct nvme_ctrl *ctrl = rq->end_io_data; unsigned long rtt = jiffies - (rq->deadline - rq->timeout); unsigned long delay = nvme_keep_alive_work_period(ctrl); enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); @@ -1324,17 +1325,20 @@ static void nvme_keep_alive_finish(struct request *rq, delay = 0; } + blk_mq_free_request(rq); + if (status) { dev_err(ctrl->device, "failed nvme_keep_alive_end_io error=%d\n", status); - return; + return RQ_END_IO_NONE; } ctrl->ka_last_check_time = jiffies; ctrl->comp_seen = false; if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); + return RQ_END_IO_NONE; } static void nvme_keep_alive_work(struct work_struct *work) @@ -1343,7 +1347,6 @@ static void nvme_keep_alive_work(struct work_struct *work) struct nvme_ctrl, ka_work); bool comp_seen = ctrl->comp_seen; struct request *rq; - blk_status_t status; ctrl->ka_last_check_time = jiffies; @@ -1366,9 +1369,9 @@ static void nvme_keep_alive_work(struct work_struct *work) nvme_init_request(rq, &ctrl->ka_cmd); rq->timeout = ctrl->kato * HZ; - status = blk_execute_rq(rq, false); - nvme_keep_alive_finish(rq, status, ctrl); - blk_mq_free_request(rq); + rq->end_io = nvme_keep_alive_end_io; + rq->end_io_data = ctrl; + blk_execute_rq_nowait(rq, false); } static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) @@ -3817,7 +3820,7 @@ struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid) srcu_read_unlock(&ctrl->srcu, srcu_idx); return ret; } -EXPORT_SYMBOL_NS_GPL(nvme_find_get_ns, NVME_TARGET_PASSTHRU); +EXPORT_SYMBOL_NS_GPL(nvme_find_get_ns, "NVME_TARGET_PASSTHRU"); /* * Add the namespace to the controller list while keeping the list ordered. @@ -4600,6 +4603,11 @@ EXPORT_SYMBOL_GPL(nvme_alloc_admin_tag_set); void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl) { + /* + * As we're about to destroy the queue and free tagset + * we can not have keep-alive work running. + */ + nvme_stop_keep_alive(ctrl); blk_mq_destroy_queue(ctrl->admin_q); blk_put_queue(ctrl->admin_q); if (ctrl->ops->flags & NVME_F_FABRICS) { @@ -5022,7 +5030,7 @@ struct nvme_ctrl *nvme_ctrl_from_file(struct file *file) return NULL; return file->private_data; } -EXPORT_SYMBOL_NS_GPL(nvme_ctrl_from_file, NVME_TARGET_PASSTHRU); +EXPORT_SYMBOL_NS_GPL(nvme_ctrl_from_file, "NVME_TARGET_PASSTHRU"); /* * Check we didn't inadvertently grow the command structure sizes: diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 6522ae16531c54d91be5250b0554b1f442014ba6..e8930146847af487a8f6f0ba1c0d2c70e32ec0a5 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -120,12 +120,20 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer, struct nvme_ns *ns = q->queuedata; struct block_device *bdev = ns ? ns->disk->part0 : NULL; bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk); + struct nvme_ctrl *ctrl = nvme_req(req)->ctrl; bool has_metadata = meta_buffer && meta_len; struct bio *bio = NULL; int ret; - if (has_metadata && !supports_metadata) - return -EINVAL; + if (!nvme_ctrl_sgl_supported(ctrl)) + dev_warn_once(ctrl->device, "using unchecked data buffer\n"); + if (has_metadata) { + if (!supports_metadata) + return -EINVAL; + if (!nvme_ctrl_meta_sgl_supported(ctrl)) + dev_warn_once(ctrl->device, + "using unchecked metadata buffer\n"); + } if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) { struct iov_iter iter; diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index f04cfe3fb936cef11dba0999e202ce3eb7f7c4b1..a85d190942bdf990244c1b40be84130ef5a57e20 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -165,7 +165,8 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl) int srcu_idx; srcu_idx = srcu_read_lock(&ctrl->srcu); - list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + list_for_each_entry_srcu(ns, &ctrl->namespaces, list, + srcu_read_lock_held(&ctrl->srcu)) { if (!ns->head->disk) continue; kblockd_schedule_work(&ns->head->requeue_work); @@ -209,7 +210,8 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) int srcu_idx; srcu_idx = srcu_read_lock(&ctrl->srcu); - list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + list_for_each_entry_srcu(ns, &ctrl->namespaces, list, + srcu_read_lock_held(&ctrl->srcu)) { nvme_mpath_clear_current_path(ns); kblockd_schedule_work(&ns->head->requeue_work); } @@ -224,7 +226,8 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns) int srcu_idx; srcu_idx = srcu_read_lock(&head->srcu); - list_for_each_entry_rcu(ns, &head->list, siblings) { + list_for_each_entry_srcu(ns, &head->list, siblings, + srcu_read_lock_held(&head->srcu)) { if (capacity != get_capacity(ns->disk)) clear_bit(NVME_NS_READY, &ns->flags); } @@ -257,7 +260,8 @@ static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node) int found_distance = INT_MAX, fallback_distance = INT_MAX, distance; struct nvme_ns *found = NULL, *fallback = NULL, *ns; - list_for_each_entry_rcu(ns, &head->list, siblings) { + list_for_each_entry_srcu(ns, &head->list, siblings, + srcu_read_lock_held(&head->srcu)) { if (nvme_path_is_disabled(ns)) continue; @@ -356,7 +360,8 @@ static struct nvme_ns *nvme_queue_depth_path(struct nvme_ns_head *head) unsigned int min_depth_opt = UINT_MAX, min_depth_nonopt = UINT_MAX; unsigned int depth; - list_for_each_entry_rcu(ns, &head->list, siblings) { + list_for_each_entry_srcu(ns, &head->list, siblings, + srcu_read_lock_held(&head->srcu)) { if (nvme_path_is_disabled(ns)) continue; @@ -424,7 +429,8 @@ static bool nvme_available_path(struct nvme_ns_head *head) if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) return NULL; - list_for_each_entry_rcu(ns, &head->list, siblings) { + list_for_each_entry_srcu(ns, &head->list, siblings, + srcu_read_lock_held(&head->srcu)) { if (test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ns->ctrl->flags)) continue; switch (nvme_ctrl_state(ns->ctrl)) { @@ -783,7 +789,8 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl, return 0; srcu_idx = srcu_read_lock(&ctrl->srcu); - list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + list_for_each_entry_srcu(ns, &ctrl->namespaces, list, + srcu_read_lock_held(&ctrl->srcu)) { unsigned nsid; again: nsid = le32_to_cpu(desc->nsids[n]); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 900719c4c70c15af480d13bb08bf7119ae5f0e69..611b02c8a8b37bcffacfc4cc8c65eb8921c4014b 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -1123,7 +1123,15 @@ static inline void nvme_start_request(struct request *rq) static inline bool nvme_ctrl_sgl_supported(struct nvme_ctrl *ctrl) { - return ctrl->sgls & ((1 << 0) | (1 << 1)); + return ctrl->sgls & (NVME_CTRL_SGLS_BYTE_ALIGNED | + NVME_CTRL_SGLS_DWORD_ALIGNED); +} + +static inline bool nvme_ctrl_meta_sgl_supported(struct nvme_ctrl *ctrl) +{ + if (ctrl->ops->flags & NVME_F_FABRICS) + return true; + return ctrl->sgls & NVME_CTRL_SGLS_MSDS; } #ifdef CONFIG_NVME_HOST_AUTH diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 5f2e3ad2cc521be206540ad2df0e66565a1fab9b..4c644bb7f069270e72317636d6660beeb24f916d 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -43,6 +43,7 @@ */ #define NVME_MAX_KB_SZ 8192 #define NVME_MAX_SEGS 128 +#define NVME_MAX_META_SEGS 15 #define NVME_MAX_NR_ALLOCATIONS 5 static int use_threaded_interrupts; @@ -144,6 +145,7 @@ struct nvme_dev { struct sg_table *hmb_sgt; mempool_t *iod_mempool; + mempool_t *iod_meta_mempool; /* shadow doorbell buffer support: */ __le32 *dbbuf_dbs; @@ -239,6 +241,8 @@ struct nvme_iod { dma_addr_t first_dma; dma_addr_t meta_dma; struct sg_table sgt; + struct sg_table meta_sgt; + union nvme_descriptor meta_list; union nvme_descriptor list[NVME_MAX_NR_ALLOCATIONS]; }; @@ -506,6 +510,15 @@ static void nvme_commit_rqs(struct blk_mq_hw_ctx *hctx) spin_unlock(&nvmeq->sq_lock); } +static inline bool nvme_pci_metadata_use_sgls(struct nvme_dev *dev, + struct request *req) +{ + if (!nvme_ctrl_meta_sgl_supported(&dev->ctrl)) + return false; + return req->nr_integrity_segments > 1 || + nvme_req(req)->flags & NVME_REQ_USERCMD; +} + static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req, int nseg) { @@ -518,8 +531,10 @@ static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req, return false; if (!nvmeq->qid) return false; + if (nvme_pci_metadata_use_sgls(dev, req)) + return true; if (!sgl_threshold || avg_seg_size < sgl_threshold) - return false; + return nvme_req(req)->flags & NVME_REQ_USERCMD; return true; } @@ -780,7 +795,8 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, struct bio_vec bv = req_bvec(req); if (!is_pci_p2pdma_page(bv.bv_page)) { - if ((bv.bv_offset & (NVME_CTRL_PAGE_SIZE - 1)) + + if (!nvme_pci_metadata_use_sgls(dev, req) && + (bv.bv_offset & (NVME_CTRL_PAGE_SIZE - 1)) + bv.bv_len <= NVME_CTRL_PAGE_SIZE * 2) return nvme_setup_prp_simple(dev, req, &cmnd->rw, &bv); @@ -824,11 +840,69 @@ out_free_sg: return ret; } -static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req, - struct nvme_command *cmnd) +static blk_status_t nvme_pci_setup_meta_sgls(struct nvme_dev *dev, + struct request *req) +{ + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + struct nvme_rw_command *cmnd = &iod->cmd.rw; + struct nvme_sgl_desc *sg_list; + struct scatterlist *sgl, *sg; + unsigned int entries; + dma_addr_t sgl_dma; + int rc, i; + + iod->meta_sgt.sgl = mempool_alloc(dev->iod_meta_mempool, GFP_ATOMIC); + if (!iod->meta_sgt.sgl) + return BLK_STS_RESOURCE; + + sg_init_table(iod->meta_sgt.sgl, req->nr_integrity_segments); + iod->meta_sgt.orig_nents = blk_rq_map_integrity_sg(req, + iod->meta_sgt.sgl); + if (!iod->meta_sgt.orig_nents) + goto out_free_sg; + + rc = dma_map_sgtable(dev->dev, &iod->meta_sgt, rq_dma_dir(req), + DMA_ATTR_NO_WARN); + if (rc) + goto out_free_sg; + + sg_list = dma_pool_alloc(dev->prp_small_pool, GFP_ATOMIC, &sgl_dma); + if (!sg_list) + goto out_unmap_sg; + + entries = iod->meta_sgt.nents; + iod->meta_list.sg_list = sg_list; + iod->meta_dma = sgl_dma; + + cmnd->flags = NVME_CMD_SGL_METASEG; + cmnd->metadata = cpu_to_le64(sgl_dma); + + sgl = iod->meta_sgt.sgl; + if (entries == 1) { + nvme_pci_sgl_set_data(sg_list, sgl); + return BLK_STS_OK; + } + + sgl_dma += sizeof(*sg_list); + nvme_pci_sgl_set_seg(sg_list, sgl_dma, entries); + for_each_sg(sgl, sg, entries, i) + nvme_pci_sgl_set_data(&sg_list[i + 1], sg); + + return BLK_STS_OK; + +out_unmap_sg: + dma_unmap_sgtable(dev->dev, &iod->meta_sgt, rq_dma_dir(req), 0); +out_free_sg: + mempool_free(iod->meta_sgt.sgl, dev->iod_meta_mempool); + return BLK_STS_RESOURCE; +} + +static blk_status_t nvme_pci_setup_meta_mptr(struct nvme_dev *dev, + struct request *req) { struct nvme_iod *iod = blk_mq_rq_to_pdu(req); struct bio_vec bv = rq_integrity_vec(req); + struct nvme_command *cmnd = &iod->cmd; iod->meta_dma = dma_map_bvec(dev->dev, &bv, rq_dma_dir(req), 0); if (dma_mapping_error(dev->dev, iod->meta_dma)) @@ -837,6 +911,13 @@ static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req, return BLK_STS_OK; } +static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req) +{ + if (nvme_pci_metadata_use_sgls(dev, req)) + return nvme_pci_setup_meta_sgls(dev, req); + return nvme_pci_setup_meta_mptr(dev, req); +} + static blk_status_t nvme_prep_rq(struct nvme_dev *dev, struct request *req) { struct nvme_iod *iod = blk_mq_rq_to_pdu(req); @@ -845,6 +926,7 @@ static blk_status_t nvme_prep_rq(struct nvme_dev *dev, struct request *req) iod->aborted = false; iod->nr_allocations = -1; iod->sgt.nents = 0; + iod->meta_sgt.nents = 0; ret = nvme_setup_cmd(req->q->queuedata, req); if (ret) @@ -857,7 +939,7 @@ static blk_status_t nvme_prep_rq(struct nvme_dev *dev, struct request *req) } if (blk_integrity_rq(req)) { - ret = nvme_map_metadata(dev, req, &iod->cmd); + ret = nvme_map_metadata(dev, req); if (ret) goto out_unmap_data; } @@ -955,17 +1037,31 @@ static void nvme_queue_rqs(struct rq_list *rqlist) *rqlist = requeue_list; } +static __always_inline void nvme_unmap_metadata(struct nvme_dev *dev, + struct request *req) +{ + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + + if (!iod->meta_sgt.nents) { + dma_unmap_page(dev->dev, iod->meta_dma, + rq_integrity_vec(req).bv_len, + rq_dma_dir(req)); + return; + } + + dma_pool_free(dev->prp_small_pool, iod->meta_list.sg_list, + iod->meta_dma); + dma_unmap_sgtable(dev->dev, &iod->meta_sgt, rq_dma_dir(req), 0); + mempool_free(iod->meta_sgt.sgl, dev->iod_meta_mempool); +} + static __always_inline void nvme_pci_unmap_rq(struct request *req) { struct nvme_queue *nvmeq = req->mq_hctx->driver_data; struct nvme_dev *dev = nvmeq->dev; - if (blk_integrity_rq(req)) { - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - - dma_unmap_page(dev->dev, iod->meta_dma, - rq_integrity_vec(req).bv_len, rq_dma_dir(req)); - } + if (blk_integrity_rq(req)) + nvme_unmap_metadata(dev, req); if (blk_rq_nr_phys_segments(req)) nvme_unmap_data(dev, req); @@ -2761,6 +2857,7 @@ static void nvme_release_prp_pools(struct nvme_dev *dev) static int nvme_pci_alloc_iod_mempool(struct nvme_dev *dev) { + size_t meta_size = sizeof(struct scatterlist) * (NVME_MAX_META_SEGS + 1); size_t alloc_size = sizeof(struct scatterlist) * NVME_MAX_SEGS; dev->iod_mempool = mempool_create_node(1, @@ -2769,7 +2866,18 @@ static int nvme_pci_alloc_iod_mempool(struct nvme_dev *dev) dev_to_node(dev->dev)); if (!dev->iod_mempool) return -ENOMEM; + + dev->iod_meta_mempool = mempool_create_node(1, + mempool_kmalloc, mempool_kfree, + (void *)meta_size, GFP_KERNEL, + dev_to_node(dev->dev)); + if (!dev->iod_meta_mempool) + goto free; + return 0; +free: + mempool_destroy(dev->iod_mempool); + return -ENOMEM; } static void nvme_free_tagset(struct nvme_dev *dev) @@ -2834,6 +2942,11 @@ static void nvme_reset_work(struct work_struct *work) if (result) goto out; + if (nvme_ctrl_meta_sgl_supported(&dev->ctrl)) + dev->ctrl.max_integrity_segments = NVME_MAX_META_SEGS; + else + dev->ctrl.max_integrity_segments = 1; + nvme_dbbuf_dma_alloc(dev); result = nvme_setup_host_mem(dev); @@ -3101,11 +3214,6 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, dev->ctrl.max_hw_sectors = min_t(u32, NVME_MAX_KB_SZ << 1, dma_opt_mapping_size(&pdev->dev) >> 9); dev->ctrl.max_segments = NVME_MAX_SEGS; - - /* - * There is no support for SGLs for metadata (yet), so we are limited to - * a single integrity segment for the separate metadata pointer. - */ dev->ctrl.max_integrity_segments = 1; return dev; @@ -3168,6 +3276,11 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (result) goto out_disable; + if (nvme_ctrl_meta_sgl_supported(&dev->ctrl)) + dev->ctrl.max_integrity_segments = NVME_MAX_META_SEGS; + else + dev->ctrl.max_integrity_segments = 1; + nvme_dbbuf_dma_alloc(dev); result = nvme_setup_host_mem(dev); @@ -3210,6 +3323,7 @@ out_disable: nvme_free_queues(dev, 0); out_release_iod_mempool: mempool_destroy(dev->iod_mempool); + mempool_destroy(dev->iod_meta_mempool); out_release_prp_pools: nvme_release_prp_pools(dev); out_dev_unmap: @@ -3275,6 +3389,7 @@ static void nvme_remove(struct pci_dev *pdev) nvme_dbbuf_dma_free(dev); nvme_free_queues(dev, 0); mempool_destroy(dev->iod_mempool); + mempool_destroy(dev->iod_meta_mempool); nvme_release_prp_pools(dev); nvme_dev_unmap(dev); nvme_uninit_ctrl(&dev->ctrl); diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c index dc7922f226004f60c165556066284bdd4f60c7f6..cf2d2c5039ddbf411d1515c6c3687d5f3c681695 100644 --- a/drivers/nvme/host/pr.c +++ b/drivers/nvme/host/pr.c @@ -94,109 +94,137 @@ static int nvme_status_to_pr_err(int status) } } -static int nvme_send_pr_command(struct block_device *bdev, - struct nvme_command *c, void *data, unsigned int data_len) +static int __nvme_send_pr_command(struct block_device *bdev, u32 cdw10, + u32 cdw11, u8 op, void *data, unsigned int data_len) { - if (nvme_disk_is_ns_head(bdev->bd_disk)) - return nvme_send_ns_head_pr_command(bdev, c, data, data_len); + struct nvme_command c = { 0 }; - return nvme_send_ns_pr_command(bdev->bd_disk->private_data, c, data, - data_len); + c.common.opcode = op; + c.common.cdw10 = cpu_to_le32(cdw10); + c.common.cdw11 = cpu_to_le32(cdw11); + + if (nvme_disk_is_ns_head(bdev->bd_disk)) + return nvme_send_ns_head_pr_command(bdev, &c, data, data_len); + return nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c, + data, data_len); } -static int nvme_pr_command(struct block_device *bdev, u32 cdw10, - u64 key, u64 sa_key, u8 op) +static int nvme_send_pr_command(struct block_device *bdev, u32 cdw10, u32 cdw11, + u8 op, void *data, unsigned int data_len) { - struct nvme_command c = { }; - u8 data[16] = { 0, }; int ret; - put_unaligned_le64(key, &data[0]); - put_unaligned_le64(sa_key, &data[8]); - - c.common.opcode = op; - c.common.cdw10 = cpu_to_le32(cdw10); - - ret = nvme_send_pr_command(bdev, &c, data, sizeof(data)); - if (ret < 0) - return ret; - - return nvme_status_to_pr_err(ret); + ret = __nvme_send_pr_command(bdev, cdw10, cdw11, op, data, data_len); + return ret < 0 ? ret : nvme_status_to_pr_err(ret); } -static int nvme_pr_register(struct block_device *bdev, u64 old, - u64 new, unsigned flags) +static int nvme_pr_register(struct block_device *bdev, u64 old_key, u64 new_key, + unsigned int flags) { + struct nvmet_pr_register_data data = { 0 }; u32 cdw10; if (flags & ~PR_FL_IGNORE_KEY) return -EOPNOTSUPP; - cdw10 = old ? 2 : 0; - cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0; - cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */ - return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register); + data.crkey = cpu_to_le64(old_key); + data.nrkey = cpu_to_le64(new_key); + + cdw10 = old_key ? NVME_PR_REGISTER_ACT_REPLACE : + NVME_PR_REGISTER_ACT_REG; + cdw10 |= (flags & PR_FL_IGNORE_KEY) ? NVME_PR_IGNORE_KEY : 0; + cdw10 |= NVME_PR_CPTPL_PERSIST; + + return nvme_send_pr_command(bdev, cdw10, 0, nvme_cmd_resv_register, + &data, sizeof(data)); } static int nvme_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type, unsigned flags) { + struct nvmet_pr_acquire_data data = { 0 }; u32 cdw10; if (flags & ~PR_FL_IGNORE_KEY) return -EOPNOTSUPP; - cdw10 = nvme_pr_type_from_blk(type) << 8; - cdw10 |= ((flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0); - return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire); + data.crkey = cpu_to_le64(key); + + cdw10 = NVME_PR_ACQUIRE_ACT_ACQUIRE; + cdw10 |= nvme_pr_type_from_blk(type) << 8; + cdw10 |= (flags & PR_FL_IGNORE_KEY) ? NVME_PR_IGNORE_KEY : 0; + + return nvme_send_pr_command(bdev, cdw10, 0, nvme_cmd_resv_acquire, + &data, sizeof(data)); } static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new, enum pr_type type, bool abort) { - u32 cdw10 = nvme_pr_type_from_blk(type) << 8 | (abort ? 2 : 1); + struct nvmet_pr_acquire_data data = { 0 }; + u32 cdw10; + + data.crkey = cpu_to_le64(old); + data.prkey = cpu_to_le64(new); - return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire); + cdw10 = abort ? NVME_PR_ACQUIRE_ACT_PREEMPT_AND_ABORT : + NVME_PR_ACQUIRE_ACT_PREEMPT; + cdw10 |= nvme_pr_type_from_blk(type) << 8; + + return nvme_send_pr_command(bdev, cdw10, 0, nvme_cmd_resv_acquire, + &data, sizeof(data)); } static int nvme_pr_clear(struct block_device *bdev, u64 key) { - u32 cdw10 = 1 | (key ? 0 : 1 << 3); + struct nvmet_pr_release_data data = { 0 }; + u32 cdw10; + + data.crkey = cpu_to_le64(key); - return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release); + cdw10 = NVME_PR_RELEASE_ACT_CLEAR; + cdw10 |= key ? 0 : NVME_PR_IGNORE_KEY; + + return nvme_send_pr_command(bdev, cdw10, 0, nvme_cmd_resv_release, + &data, sizeof(data)); } static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type) { - u32 cdw10 = nvme_pr_type_from_blk(type) << 8 | (key ? 0 : 1 << 3); + struct nvmet_pr_release_data data = { 0 }; + u32 cdw10; + + data.crkey = cpu_to_le64(key); - return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release); + cdw10 = NVME_PR_RELEASE_ACT_RELEASE; + cdw10 |= nvme_pr_type_from_blk(type) << 8; + cdw10 |= key ? 0 : NVME_PR_IGNORE_KEY; + + return nvme_send_pr_command(bdev, cdw10, 0, nvme_cmd_resv_release, + &data, sizeof(data)); } static int nvme_pr_resv_report(struct block_device *bdev, void *data, u32 data_len, bool *eds) { - struct nvme_command c = { }; + u32 cdw10, cdw11; int ret; - c.common.opcode = nvme_cmd_resv_report; - c.common.cdw10 = cpu_to_le32(nvme_bytes_to_numd(data_len)); - c.common.cdw11 = cpu_to_le32(NVME_EXTENDED_DATA_STRUCT); + cdw10 = nvme_bytes_to_numd(data_len); + cdw11 = NVME_EXTENDED_DATA_STRUCT; *eds = true; retry: - ret = nvme_send_pr_command(bdev, &c, data, data_len); + ret = __nvme_send_pr_command(bdev, cdw10, cdw11, nvme_cmd_resv_report, + data, data_len); if (ret == NVME_SC_HOST_ID_INCONSIST && - c.common.cdw11 == cpu_to_le32(NVME_EXTENDED_DATA_STRUCT)) { - c.common.cdw11 = 0; + cdw11 == NVME_EXTENDED_DATA_STRUCT) { + cdw11 = 0; *eds = false; goto retry; } - if (ret < 0) - return ret; - - return nvme_status_to_pr_err(ret); + return ret < 0 ? ret : nvme_status_to_pr_err(ret); } static int nvme_pr_read_keys(struct block_device *bdev, diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 24a2759798d01e9f38928b1662bf0aeedd8cc284..baf7d2490152821ba0d206737cb87fc7e93030d9 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1019,7 +1019,7 @@ static int nvme_rdma_setup_ctrl(struct nvme_rdma_ctrl *ctrl, bool new) goto destroy_admin; } - if (!(ctrl->ctrl.sgls & (1 << 2))) { + if (!(ctrl->ctrl.sgls & NVME_CTRL_SGLS_KSDBDS)) { ret = -EOPNOTSUPP; dev_err(ctrl->ctrl.device, "Mandatory keyed sgls are not supported!\n"); @@ -1051,7 +1051,7 @@ static int nvme_rdma_setup_ctrl(struct nvme_rdma_ctrl *ctrl, bool new) ctrl->ctrl.sqsize = ctrl->ctrl.maxcmd - 1; } - if (ctrl->ctrl.sgls & (1 << 20)) + if (ctrl->ctrl.sgls & NVME_CTRL_SGLS_SAOS) ctrl->use_inline_data = true; if (ctrl->ctrl.queue_count > 1) { diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 934b401fbc2ffb2168cb5cf5ce3f077f513215c8..4fa8496a4d96752114522b5321ff83a953447ce5 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -601,11 +601,12 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) id->awun = 0; id->awupf = 0; - id->sgls = cpu_to_le32(1 << 0); /* we always support SGLs */ + /* we always support SGLs */ + id->sgls = cpu_to_le32(NVME_CTRL_SGLS_BYTE_ALIGNED); if (ctrl->ops->flags & NVMF_KEYED_SGLS) - id->sgls |= cpu_to_le32(1 << 2); + id->sgls |= cpu_to_le32(NVME_CTRL_SGLS_KSDBDS); if (req->port->inline_data_size) - id->sgls |= cpu_to_le32(1 << 20); + id->sgls |= cpu_to_le32(NVME_CTRL_SGLS_SAOS); strscpy(id->subnqn, ctrl->subsys->subsysnqn, sizeof(id->subnqn)); diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c index 0f9b280c438d98dbcf1d3dd65d25709ebdb4e575..30b21936b0c62286d3778f538838379ea363fd97 100644 --- a/drivers/nvme/target/passthru.c +++ b/drivers/nvme/target/passthru.c @@ -13,7 +13,7 @@ #include "../host/nvme.h" #include "nvmet.h" -MODULE_IMPORT_NS(NVME_TARGET_PASSTHRU); +MODULE_IMPORT_NS("NVME_TARGET_PASSTHRU"); /* * xarray to maintain one passthru subsystem per nvme controller. diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index d2c384f58028dce4e8fd23b273b66c4f97082746..8671b7c974b933e147154bb40b5d41b5730518d2 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -246,6 +246,17 @@ config NVMEM_RAVE_SP_EEPROM help Say y here to enable Rave SP EEPROM support. +config NVMEM_RCAR_EFUSE + tristate "Renesas R-Car Gen4 E-FUSE support" + depends on (ARCH_RENESAS && ARM64) || COMPILE_TEST + depends on NVMEM + help + Enable support for reading the fuses in the E-FUSE or OTP + non-volatile memory block on Renesas R-Car Gen4 SoCs. + + This driver can also be built as a module. If so, the module + will be called nvmem-rcar-efuse. + config NVMEM_RMEM tristate "Reserved Memory Based Driver Support" depends on HAS_IOMEM diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index cdd01fbf1313b58c61f71066997e2f0fadaae823..5b77bbb6488bf89bfb305750a1cbf4a6731a0a58 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -52,6 +52,8 @@ obj-$(CONFIG_NVMEM_QCOM_SEC_QFPROM) += nvmem_sec_qfprom.o nvmem_sec_qfprom-y := sec-qfprom.o obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o +obj-$(CONFIG_NVMEM_RCAR_EFUSE) += nvmem-rcar-efuse.o +nvmem-rcar-efuse-y := rcar-efuse.o obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o nvmem-rmem-y := rmem.o obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c index 3d8c87835f4d6cb05d6e7ddf38582ed4f86739c8..b810df727b446b1762a1851750f743e0de6e8788 100644 --- a/drivers/nvmem/brcm_nvram.c +++ b/drivers/nvmem/brcm_nvram.c @@ -22,7 +22,7 @@ * * @dev: NVMEM device pointer * @nvmem_size: Size of the whole space available for NVRAM - * @data: NVRAM data copy stored to avoid poking underlaying flash controller + * @data: NVRAM data copy stored to avoid poking underlying flash controller * @data_len: NVRAM data size * @padding_byte: Padding value used to fill remaining space * @cells: Array of discovered NVMEM cells diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 33ffa2aa4c1152398ec66b8dd7b30384c5346a6e..d6494dfc20a7324bde6415776dcabbb0bfdd334b 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -267,7 +267,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, count = round_down(count, nvmem->word_size); - if (!nvmem->reg_write) + if (!nvmem->reg_write || nvmem->read_only) return -EPERM; rc = nvmem_reg_write(nvmem, pos, buf, count); @@ -298,16 +298,25 @@ static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem) } static umode_t nvmem_bin_attr_is_visible(struct kobject *kobj, - struct bin_attribute *attr, int i) + const struct bin_attribute *attr, + int i) { struct device *dev = kobj_to_dev(kobj); struct nvmem_device *nvmem = to_nvmem_device(dev); - attr->size = nvmem->size; - return nvmem_bin_attr_get_umode(nvmem); } +static size_t nvmem_bin_attr_size(struct kobject *kobj, + const struct bin_attribute *attr, + int i) +{ + struct device *dev = kobj_to_dev(kobj); + struct nvmem_device *nvmem = to_nvmem_device(dev); + + return nvmem->size; +} + static umode_t nvmem_attr_is_visible(struct kobject *kobj, struct attribute *attr, int i) { @@ -383,6 +392,7 @@ static const struct attribute_group nvmem_bin_group = { .bin_attrs = nvmem_bin_attributes, .attrs = nvmem_attrs, .is_bin_visible = nvmem_bin_attr_is_visible, + .bin_size = nvmem_bin_attr_size, .is_visible = nvmem_attr_is_visible, }; @@ -1247,7 +1257,7 @@ static void devm_nvmem_device_release(struct device *dev, void *res) } /** - * devm_nvmem_device_put() - put alredy got nvmem device + * devm_nvmem_device_put() - put already got nvmem device * * @dev: Device that uses the nvmem device. * @nvmem: pointer to nvmem device allocated by devm_nvmem_cell_get(), @@ -1265,7 +1275,7 @@ void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem) EXPORT_SYMBOL_GPL(devm_nvmem_device_put); /** - * nvmem_device_put() - put alredy got nvmem device + * nvmem_device_put() - put already got nvmem device * * @nvmem: pointer to nvmem device that needs to be released. */ diff --git a/drivers/nvmem/imx-iim.c b/drivers/nvmem/imx-iim.c index f13bbd16408682359a6b9186984a02306f26e719..8cfbe55a56cb30b6987c8685f9f6f7d9cb47fb34 100644 --- a/drivers/nvmem/imx-iim.c +++ b/drivers/nvmem/imx-iim.c @@ -115,11 +115,11 @@ static int imx_iim_probe(struct platform_device *pdev) if (IS_ERR(iim->clk)) return PTR_ERR(iim->clk); - cfg.name = "imx-iim", - cfg.read_only = true, - cfg.word_size = 1, - cfg.stride = 1, - cfg.reg_read = imx_iim_read, + cfg.name = "imx-iim"; + cfg.read_only = true; + cfg.word_size = 1; + cfg.stride = 1; + cfg.reg_read = imx_iim_read; cfg.dev = dev; cfg.size = drvdata->nregs; cfg.priv = iim; diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c index a73acc7377d251fce415355131c3ff885e2520cd..aa43f5f612f96229e22cfb475d1df79d6473954e 100644 --- a/drivers/nvmem/lpc18xx_eeprom.c +++ b/drivers/nvmem/lpc18xx_eeprom.c @@ -264,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_of_match); static struct platform_driver lpc18xx_eeprom_driver = { .probe = lpc18xx_eeprom_probe, - .remove_new = lpc18xx_eeprom_remove, + .remove = lpc18xx_eeprom_remove, .driver = { .name = "lpc18xx-eeprom", .of_match_table = lpc18xx_eeprom_of_match, diff --git a/drivers/nvmem/lpc18xx_otp.c b/drivers/nvmem/lpc18xx_otp.c index adc9948e7b2ec9ca62e0dfa829c3e3c69b0c73d3..c41a0c58bec765deb2f05786af530dc41855d998 100644 --- a/drivers/nvmem/lpc18xx_otp.c +++ b/drivers/nvmem/lpc18xx_otp.c @@ -21,7 +21,7 @@ * LPC18xx OTP memory contains 4 banks with 4 32-bit words. Bank 0 starts * at offset 0 from the base. * - * Bank 0 contains the part ID for Flashless devices and is reseverd for + * Bank 0 contains the part ID for Flashless devices and is reserved for * devices with Flash. * Bank 1/2 is generale purpose or AES key storage for secure devices. * Bank 3 contains control data, USB ID and generale purpose words. diff --git a/drivers/nvmem/microchip-otpc.c b/drivers/nvmem/microchip-otpc.c index 7cf81738a3e0a50500a3460ae57002c61d94ba07..df979e8549fdb43b5185fbc425d3e02451b76479 100644 --- a/drivers/nvmem/microchip-otpc.c +++ b/drivers/nvmem/microchip-otpc.c @@ -156,7 +156,7 @@ static int mchp_otpc_read(void *priv, unsigned int off, void *val, /* * We reach this point with off being multiple of stride = 4 to * be able to cross the subsystem. Inside the driver we use continuous - * unsigned integer numbers for packet id, thus devide off by 4 + * unsigned integer numbers for packet id, thus divide off by 4 * before passing it to mchp_otpc_id_to_packet(). */ packet = mchp_otpc_id_to_packet(otpc, off / 4); diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c index 9caf046673410129e5fd595e23adceb6bd0772a8..af953e1d9230234c655de751d5a07b729ff1a6d0 100644 --- a/drivers/nvmem/mtk-efuse.c +++ b/drivers/nvmem/mtk-efuse.c @@ -127,7 +127,7 @@ static void mtk_efuse_remove(struct platform_device *pdev) static struct platform_driver mtk_efuse_driver = { .probe = mtk_efuse_probe, - .remove_new = mtk_efuse_remove, + .remove = mtk_efuse_remove, .driver = { .name = "mediatek,efuse", .of_match_table = mtk_efuse_of_match, diff --git a/drivers/nvmem/rcar-efuse.c b/drivers/nvmem/rcar-efuse.c new file mode 100644 index 0000000000000000000000000000000000000000..f24bdb9cb5a7296f1e39eb547af866a159958830 --- /dev/null +++ b/drivers/nvmem/rcar-efuse.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Renesas R-Car E-FUSE/OTP Driver + * + * Copyright (C) 2024 Glider bv + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct rcar_fuse { + struct nvmem_keepout keepouts[2]; + struct nvmem_device *nvmem; + struct device *dev; + void __iomem *base; +}; + +struct rcar_fuse_data { + unsigned int bank; /* 0: PFC + E-FUSE, 1: OPT_MEM + E-FUSE */ + unsigned int start; /* inclusive */ + unsigned int end; /* exclusive */ +}; + +static int rcar_fuse_reg_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct rcar_fuse *fuse = priv; + int ret; + + ret = pm_runtime_resume_and_get(fuse->dev); + if (ret < 0) + return ret; + + __ioread32_copy(val, fuse->base + offset, bytes / 4); + + pm_runtime_put(fuse->dev); + + return 0; +} + +static int rcar_fuse_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct rcar_fuse_data *data = device_get_match_data(dev); + struct nvmem_config config = { + .dev = dev, + .name = "rcar-fuse", + .id = NVMEM_DEVID_NONE, + .owner = THIS_MODULE, + .type = NVMEM_TYPE_OTP, + .read_only = true, + .root_only = true, + .reg_read = rcar_fuse_reg_read, + .word_size = 4, + .stride = 4, + }; + struct rcar_fuse *fuse; + struct resource *res; + int ret; + + ret = devm_pm_runtime_enable(dev); + if (ret < 0) + return ret; + + fuse = devm_kzalloc(dev, sizeof(*fuse), GFP_KERNEL); + if (!fuse) + return -ENOMEM; + + fuse->base = devm_platform_get_and_ioremap_resource(pdev, data->bank, + &res); + if (IS_ERR(fuse->base)) + return PTR_ERR(fuse->base); + + fuse->dev = dev; + fuse->keepouts[0].start = 0; + fuse->keepouts[0].end = data->start; + fuse->keepouts[1].start = data->end; + fuse->keepouts[1].end = resource_size(res); + + config.keepout = fuse->keepouts; + config.nkeepout = ARRAY_SIZE(fuse->keepouts); + config.size = resource_size(res); + config.priv = fuse; + + fuse->nvmem = devm_nvmem_register(dev, &config); + if (IS_ERR(fuse->nvmem)) + return dev_err_probe(dev, PTR_ERR(fuse->nvmem), + "Failed to register NVMEM device\n"); + + return 0; +} + +static const struct rcar_fuse_data rcar_fuse_v3u = { + .bank = 0, + .start = 0x0c0, + .end = 0x0e8, +}; + +static const struct rcar_fuse_data rcar_fuse_s4 = { + .bank = 0, + .start = 0x0c0, + .end = 0x14c, +}; + +static const struct rcar_fuse_data rcar_fuse_v4h = { + .bank = 1, + .start = 0x100, + .end = 0x1a0, +}; + +static const struct rcar_fuse_data rcar_fuse_v4m = { + .bank = 1, + .start = 0x100, + .end = 0x110, +}; + +static const struct of_device_id rcar_fuse_match[] = { + { .compatible = "renesas,r8a779a0-efuse", .data = &rcar_fuse_v3u }, + { .compatible = "renesas,r8a779f0-efuse", .data = &rcar_fuse_s4 }, + { .compatible = "renesas,r8a779g0-otp", .data = &rcar_fuse_v4h }, + { .compatible = "renesas,r8a779h0-otp", .data = &rcar_fuse_v4m }, + { /* sentinel */ } +}; + +static struct platform_driver rcar_fuse_driver = { + .probe = rcar_fuse_probe, + .driver = { + .name = "rcar_fuse", + .of_match_table = rcar_fuse_match, + }, +}; +module_platform_driver(rcar_fuse_driver); + +MODULE_DESCRIPTION("Renesas R-Car E-FUSE/OTP driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Geert Uytterhoeven"); diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index f0b8cc23c46d377f8cce792893cdf1c39fe2d1f1..50697cc3b07ebeb24283e22299797ce4612db89c 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -2,6 +2,12 @@ config DTC bool +config GENERIC_BUILTIN_DTB + bool + +config BUILTIN_DTB_ALL + bool + menuconfig OF bool "Device Tree and Open Firmware support" help diff --git a/drivers/of/base.c b/drivers/of/base.c index a8b0c42bdc8e9c352b0af9f9a8540aa6a3afd771..7dc394255a0a14cd1aed02ec79c2f787a222b44c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -644,6 +644,42 @@ struct device_node *of_get_next_child(const struct device_node *node, } EXPORT_SYMBOL(of_get_next_child); +/** + * of_get_next_child_with_prefix - Find the next child node with prefix + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * @prefix: prefix that the node name should have + * + * This function is like of_get_next_child(), except that it automatically + * skips any nodes whose name doesn't have the given prefix. + * + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child_with_prefix(const struct device_node *node, + struct device_node *prev, + const char *prefix) +{ + struct device_node *next; + unsigned long flags; + + if (!node) + return NULL; + + raw_spin_lock_irqsave(&devtree_lock, flags); + next = prev ? prev->sibling : node->child; + for (; next; next = next->sibling) { + if (!of_node_name_prefix(next, prefix)) + continue; + if (of_node_get(next)) + break; + } + of_node_put(prev); + raw_spin_unlock_irqrestore(&devtree_lock, flags); + return next; +} +EXPORT_SYMBOL(of_get_next_child_with_prefix); + static struct device_node *of_get_next_status_child(const struct device_node *node, struct device_node *prev, bool (*checker)(const struct device_node *)) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index d45a8df61380159af831b6f9b1650c4e46264b87..0aba760f7577ef604183e37139168c2520d0787f 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -1072,3 +1072,47 @@ int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np, return of_changeset_add_prop_helper(ocs, np, &prop); } EXPORT_SYMBOL_GPL(of_changeset_add_prop_bool); + +static int of_changeset_update_prop_helper(struct of_changeset *ocs, + struct device_node *np, + const struct property *pp) +{ + struct property *new_pp; + int ret; + + new_pp = __of_prop_dup(pp, GFP_KERNEL); + if (!new_pp) + return -ENOMEM; + + ret = of_changeset_update_property(ocs, np, new_pp); + if (ret) + __of_prop_free(new_pp); + + return ret; +} + +/** + * of_changeset_update_prop_string - Add a string property update to a changeset + * + * @ocs: changeset pointer + * @np: device node pointer + * @prop_name: name of the property to be updated + * @str: pointer to null terminated string + * + * Create a string property to be updated and add it to a changeset. + * + * Return: 0 on success, a negative error value in case of an error. + */ +int of_changeset_update_prop_string(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, const char *str) +{ + struct property prop = { + .name = (char *)prop_name, + .length = strlen(str) + 1, + .value = (void *)str, + }; + + return of_changeset_update_prop_helper(ocs, np, &prop); +} +EXPORT_SYMBOL_GPL(of_changeset_update_prop_string); diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index daf9a2dddd7e0dbc680f708496b6dce6d23999cf..42b411f32b1b69134958c37a06a9b81e0049fcda 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1970,7 +1970,7 @@ static const struct of_device_id unittest_match[] = { static struct platform_driver unittest_driver = { .probe = unittest_probe, - .remove_new = unittest_remove, + .remove = unittest_remove, .driver = { .name = "unittest", .of_match_table = unittest_match, @@ -2071,7 +2071,7 @@ static const struct of_device_id unittest_gpio_id[] = { static struct platform_driver unittest_gpio_driver = { .probe = unittest_gpio_probe, - .remove_new = unittest_gpio_remove, + .remove = unittest_gpio_remove, .driver = { .name = "unittest-gpio", .of_match_table = unittest_gpio_id, @@ -2891,7 +2891,7 @@ static const struct of_device_id unittest_i2c_bus_match[] = { static struct platform_driver unittest_i2c_bus_driver = { .probe = unittest_i2c_bus_probe, - .remove_new = unittest_i2c_bus_remove, + .remove = unittest_i2c_bus_remove, .driver = { .name = "unittest-i2c-bus", .of_match_table = unittest_i2c_bus_match, diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index b49cb010a4d80ce75d8c7cafa98c3a9d5f53506f..e71674753711ee7ca6be85764e330e958a632eb9 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -369,7 +369,7 @@ MODULE_ALIAS("platform:platform-leds"); static struct platform_driver hppa_mainboard_led_driver = { .probe = platform_led_probe, - .remove_new = platform_led_remove, + .remove = platform_led_remove, .driver = { .name = "platform-leds", }, diff --git a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c index e06c7b2aac5c46f4e06389aaa5992766331d7c67..6a819bd00866188ccf44f9004355e019e33536cc 100644 --- a/drivers/parport/parport_amiga.c +++ b/drivers/parport/parport_amiga.c @@ -236,7 +236,7 @@ static void __exit amiga_parallel_remove(struct platform_device *pdev) * triggering a section mismatch warning. */ static struct platform_driver amiga_parallel_driver __refdata = { - .remove_new = __exit_p(amiga_parallel_remove), + .remove = __exit_p(amiga_parallel_remove), .driver = { .name = "amiga-parallel", }, diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 949236a7a27c97b7fcd7a85599320fa38af21edc..d6495f2f90a7f69d157041383210b8e0f3ad8dd2 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -368,7 +368,7 @@ static struct platform_driver bpp_sbus_driver = { .of_match_table = bpp_match, }, .probe = bpp_probe, - .remove_new = bpp_remove, + .remove = bpp_remove, }; module_platform_driver(bpp_sbus_driver); diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index 4f47a13cb500ff5339cde426b6ccb020fcd74ae7..7abd4f546d3c071f31e622d881f5c5ac3e4de55e 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@ -90,7 +90,7 @@ static ssize_t published_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(published); static int p2pmem_alloc_mmap(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, struct vm_area_struct *vma) + const struct bin_attribute *attr, struct vm_area_struct *vma) { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); size_t len = vma->vm_end - vma->vm_start; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 3e5a117f5b5d60cea40f84554ca0d4b1231b2ef5..7679d75d71e534d4f3d1e1b4ae6c5ee5f8518ea1 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -844,21 +844,20 @@ static struct bin_attribute *pci_dev_config_attrs[] = { NULL, }; -static umode_t pci_dev_config_attr_is_visible(struct kobject *kobj, - struct bin_attribute *a, int n) +static size_t pci_dev_config_attr_bin_size(struct kobject *kobj, + const struct bin_attribute *a, + int n) { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); - a->size = PCI_CFG_SPACE_SIZE; if (pdev->cfg_size > PCI_CFG_SPACE_SIZE) - a->size = PCI_CFG_SPACE_EXP_SIZE; - - return a->attr.mode; + return PCI_CFG_SPACE_EXP_SIZE; + return PCI_CFG_SPACE_SIZE; } static const struct attribute_group pci_dev_config_attr_group = { .bin_attrs = pci_dev_config_attrs, - .is_bin_visible = pci_dev_config_attr_is_visible, + .bin_size = pci_dev_config_attr_bin_size, }; /* @@ -868,7 +867,7 @@ static const struct attribute_group pci_dev_config_attr_group = { static __maybe_unused loff_t pci_llseek_resource(struct file *filep, struct kobject *kobj __always_unused, - struct bin_attribute *attr, + const struct bin_attribute *attr, loff_t offset, int whence) { return fixed_size_llseek(filep, offset, whence, attr->size); @@ -937,7 +936,7 @@ static ssize_t pci_write_legacy_io(struct file *filp, struct kobject *kobj, * memory space. */ static int pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj)); @@ -957,7 +956,7 @@ static int pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj, * memory space. Returns -ENOSYS if the operation isn't supported */ static int pci_mmap_legacy_io(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj)); @@ -1061,7 +1060,7 @@ void pci_remove_legacy_files(struct pci_bus *b) * * Use the regular PCI mapping routines to map a PCI resource into userspace. */ -static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, +static int pci_mmap_resource(struct kobject *kobj, const struct bin_attribute *attr, struct vm_area_struct *vma, int write_combine) { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); @@ -1086,14 +1085,14 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, } static int pci_mmap_resource_uc(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 0); } static int pci_mmap_resource_wc(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 1); @@ -1353,24 +1352,29 @@ static struct bin_attribute *pci_dev_rom_attrs[] = { }; static umode_t pci_dev_rom_attr_is_visible(struct kobject *kobj, - struct bin_attribute *a, int n) + const struct bin_attribute *a, int n) { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); - size_t rom_size; /* If the device has a ROM, try to expose it in sysfs. */ - rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); - if (!rom_size) + if (!pci_resource_end(pdev, PCI_ROM_RESOURCE)) return 0; - a->size = rom_size; - return a->attr.mode; } +static size_t pci_dev_rom_attr_bin_size(struct kobject *kobj, + const struct bin_attribute *a, int n) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + + return pci_resource_len(pdev, PCI_ROM_RESOURCE); +} + static const struct attribute_group pci_dev_rom_attr_group = { .bin_attrs = pci_dev_rom_attrs, .is_bin_visible = pci_dev_rom_attr_is_visible, + .bin_size = pci_dev_rom_attr_bin_size, }; static ssize_t reset_store(struct device *dev, struct device_attribute *attr, diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index 80c5ba8d829625a947044e03bd121688ccd0db56..34ce9f834d0ccc1edfb8e4055eeae88b9dc8b389 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -231,7 +231,7 @@ int pcie_aer_is_native(struct pci_dev *dev) return pcie_ports_native || host->native_aer; } -EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, CXL); +EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, "CXL"); static int pci_enable_pcie_error_reporting(struct pci_dev *dev) { @@ -802,7 +802,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity, trace_aer_event(dev_name(&dev->dev), (status & ~mask), aer_severity, tlp_header_valid, &aer->header_log); } -EXPORT_SYMBOL_NS_GPL(pci_print_aer, CXL); +EXPORT_SYMBOL_NS_GPL(pci_print_aer, "CXL"); /** * add_error_device - list device to be handled diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 963b8d2855c1abd7b89a691d0af36f4e5375e7ff..efc37fcb73e24da1abd5989e82bc93e2e5153194 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -19,14 +19,19 @@ static void pci_free_resources(struct pci_dev *dev) static void pci_pwrctrl_unregister(struct device *dev) { + struct device_node *np; struct platform_device *pdev; - pdev = of_find_device_by_node(dev_of_node(dev)); + np = dev_of_node(dev); + if (!np) + return; + + pdev = of_find_device_by_node(np); if (!pdev) return; of_device_unregister(pdev); - of_node_clear_flag(dev_of_node(dev), OF_POPULATED); + of_node_clear_flag(np, OF_POPULATED); } static void pci_stop_dev(struct pci_dev *dev) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index e4300f5f304f3ca55a657fd25a1fa5ed919737a7..a469bcbc0da7f7677485c7f999f8dfb58b8ae8a3 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -325,7 +325,7 @@ static struct bin_attribute *vpd_attrs[] = { }; static umode_t vpd_attr_is_visible(struct kobject *kobj, - struct bin_attribute *a, int n) + const struct bin_attribute *a, int n) { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c index 5bda3e6d43d83e8efa2b3b97146bceb638e30b17..85874b7a9f36853028d187079eb1dbde9f9b758b 100644 --- a/drivers/pcmcia/bcm63xx_pcmcia.c +++ b/drivers/pcmcia/bcm63xx_pcmcia.c @@ -453,7 +453,7 @@ static void bcm63xx_drv_pcmcia_remove(struct platform_device *pdev) struct platform_driver bcm63xx_pcmcia_driver = { .probe = bcm63xx_drv_pcmcia_probe, - .remove_new = bcm63xx_drv_pcmcia_remove, + .remove = bcm63xx_drv_pcmcia_remove, .driver = { .name = "bcm63xx_pcmcia", }, diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 509713b9a502b7ed57caa1c451043a8669fc3f2c..85d2616061dda60dce3400e6bb0e6bda6472cf2d 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -592,7 +592,7 @@ static struct platform_driver db1x_pcmcia_socket_driver = { .name = "db1xxx_pcmcia", }, .probe = db1x_pcmcia_socket_probe, - .remove_new = db1x_pcmcia_socket_remove, + .remove = db1x_pcmcia_socket_remove, }; module_platform_driver(db1x_pcmcia_socket_driver); diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 5ae826e548116cbdfbf5e17845cee6074274f13f..3bdd939dd2f4a54808ddc2c554dbb7d455caf3c7 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -342,7 +342,7 @@ static struct platform_driver electra_cf_driver = { .of_match_table = electra_cf_match, }, .probe = electra_cf_probe, - .remove_new = electra_cf_remove, + .remove = electra_cf_remove, }; module_platform_driver(electra_cf_driver); diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 80137c7afe0d9bcf08741280ff2924a8cb3ced16..f0ccf479f36e52232225eee65eb5b7a3f7b0ecf4 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -306,7 +306,7 @@ static struct platform_driver omap_cf_driver = { .driver = { .name = driver_name, }, - .remove_new = __exit_p(omap_cf_remove), + .remove = __exit_p(omap_cf_remove), }; static int __init omap_cf_init(void) diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 457fb81b497a10de69ec58973df4247bad244bbc..370a8e16dc817f32bd0c0af15e51b17d8552e93f 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -336,7 +336,7 @@ static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = { static struct platform_driver pxa2xx_pcmcia_driver = { .probe = pxa2xx_drv_pcmcia_probe, - .remove_new = pxa2xx_drv_pcmcia_remove, + .remove = pxa2xx_drv_pcmcia_remove, .driver = { .name = "pxa2xx-pcmcia", .pm = &pxa2xx_drv_pcmcia_pm_ops, diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index ccb219c3876170fe7e6580c791472a7e716aa461..7b5ac8fe811df93a30148aa0f88e9b68d213fe89 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -177,7 +177,7 @@ static struct platform_driver sa11x0_pcmcia_driver = { .name = "sa11x0-pcmcia", }, .probe = sa11x0_drv_pcmcia_probe, - .remove_new = sa11x0_drv_pcmcia_remove, + .remove = sa11x0_drv_pcmcia_remove, }; /* sa11x0_pcmcia_init() diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index 2a93fbbd128da99a422ed6f86c11d033bd6af45c..f84dd5914a6bdaa183137ee01a0be0d9d796f516 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c @@ -316,7 +316,7 @@ static struct platform_driver xxs1500_pcmcia_socket_driver = { .name = "xxs1500_pcmcia", }, .probe = xxs1500_pcmcia_probe, - .remove_new = xxs1500_pcmcia_remove, + .remove = xxs1500_pcmcia_remove, }; module_platform_driver(xxs1500_pcmcia_socket_driver); diff --git a/drivers/peci/controller/peci-aspeed.c b/drivers/peci/controller/peci-aspeed.c index b93eb6f43b98faa71fde7efe87d8880e9b122cdf..ad3a7d71ed4c61e6123dcbbad264812cb83cbb07 100644 --- a/drivers/peci/controller/peci-aspeed.c +++ b/drivers/peci/controller/peci-aspeed.c @@ -597,4 +597,4 @@ MODULE_AUTHOR("Ryan Chen "); MODULE_AUTHOR("Jae Hyun Yoo "); MODULE_DESCRIPTION("ASPEED PECI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PECI); +MODULE_IMPORT_NS("PECI"); diff --git a/drivers/peci/controller/peci-npcm.c b/drivers/peci/controller/peci-npcm.c index ec613d35c7962e6e0e5ed2d5f4565a0ad634b7ab..c77591ca583d8d5c6c70b663345013a22b14a1af 100644 --- a/drivers/peci/controller/peci-npcm.c +++ b/drivers/peci/controller/peci-npcm.c @@ -224,7 +224,7 @@ static const struct regmap_config npcm_peci_regmap_config = { .fast_io = true, }; -static struct peci_controller_ops npcm_ops = { +static const struct peci_controller_ops npcm_ops = { .xfer = npcm_peci_xfer, }; @@ -295,4 +295,4 @@ module_platform_driver(npcm_peci_driver); MODULE_AUTHOR("Tomer Maimon "); MODULE_DESCRIPTION("NPCM PECI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PECI); +MODULE_IMPORT_NS("PECI"); diff --git a/drivers/peci/core.c b/drivers/peci/core.c index 25e46579dd9c440349d13b03a2753abc77c2c545..936c1fadefe5fdca74786aa443a2f71a2c9e8842 100644 --- a/drivers/peci/core.c +++ b/drivers/peci/core.c @@ -158,7 +158,7 @@ err_put: return ERR_PTR(ret); } -EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI); +EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, "PECI"); static const struct peci_device_id * peci_bus_match_device_id(const struct peci_device_id *id, struct peci_device *device) diff --git a/drivers/peci/cpu.c b/drivers/peci/cpu.c index 152bbd8e717a60eada8547aadbe52eec113fa6b9..2dac8ba827872810833d3b3d9cc408fd3bb0ae31 100644 --- a/drivers/peci/cpu.c +++ b/drivers/peci/cpu.c @@ -32,7 +32,7 @@ int peci_temp_read(struct peci_device *device, s16 *temp_raw) return 0; } -EXPORT_SYMBOL_NS_GPL(peci_temp_read, PECI_CPU); +EXPORT_SYMBOL_NS_GPL(peci_temp_read, "PECI_CPU"); /** * peci_pcs_read() - read PCS register @@ -64,7 +64,7 @@ out_req_free: return ret; } -EXPORT_SYMBOL_NS_GPL(peci_pcs_read, PECI_CPU); +EXPORT_SYMBOL_NS_GPL(peci_pcs_read, "PECI_CPU"); /** * peci_pci_local_read() - read 32-bit memory location using raw address @@ -99,7 +99,7 @@ out_req_free: return ret; } -EXPORT_SYMBOL_NS_GPL(peci_pci_local_read, PECI_CPU); +EXPORT_SYMBOL_NS_GPL(peci_pci_local_read, "PECI_CPU"); /** * peci_ep_pci_local_read() - read 32-bit memory location using raw address @@ -135,7 +135,7 @@ out_req_free: return ret; } -EXPORT_SYMBOL_NS_GPL(peci_ep_pci_local_read, PECI_CPU); +EXPORT_SYMBOL_NS_GPL(peci_ep_pci_local_read, "PECI_CPU"); /** * peci_mmio_read() - read 32-bit memory location using 64-bit bar offset address @@ -172,7 +172,7 @@ out_req_free: return ret; } -EXPORT_SYMBOL_NS_GPL(peci_mmio_read, PECI_CPU); +EXPORT_SYMBOL_NS_GPL(peci_mmio_read, "PECI_CPU"); static const char * const peci_adev_types[] = { "cputemp", @@ -337,4 +337,4 @@ module_peci_driver(peci_cpu_driver); MODULE_AUTHOR("Iwona Winiarska "); MODULE_DESCRIPTION("PECI CPU driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(PECI); +MODULE_IMPORT_NS("PECI"); diff --git a/drivers/peci/device.c b/drivers/peci/device.c index 37ca7dd61807c7db5d0ccf684883b05b64d97cb1..416635029f55b3305b68426930c9039634905ac4 100644 --- a/drivers/peci/device.c +++ b/drivers/peci/device.c @@ -230,13 +230,13 @@ int __peci_driver_register(struct peci_driver *driver, struct module *owner, return driver_register(&driver->driver); } -EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI); +EXPORT_SYMBOL_NS_GPL(__peci_driver_register, "PECI"); void peci_driver_unregister(struct peci_driver *driver) { driver_unregister(&driver->driver); } -EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI); +EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, "PECI"); static void peci_device_release(struct device *dev) { diff --git a/drivers/peci/request.c b/drivers/peci/request.c index 87eefe66743f2de13791f58f475364e916e704bb..e6327af45fc7c0644f4eaffab99124689a26cbea 100644 --- a/drivers/peci/request.c +++ b/drivers/peci/request.c @@ -128,7 +128,7 @@ int peci_request_status(struct peci_request *req) return -EIO; } -EXPORT_SYMBOL_NS_GPL(peci_request_status, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_status, "PECI"); static int peci_request_xfer(struct peci_request *req) { @@ -213,7 +213,7 @@ struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u return req; } -EXPORT_SYMBOL_NS_GPL(peci_request_alloc, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_alloc, "PECI"); /** * peci_request_free() - free peci_request @@ -223,7 +223,7 @@ void peci_request_free(struct peci_request *req) { kfree(req); } -EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_free, "PECI"); struct peci_request *peci_xfer_get_dib(struct peci_device *device) { @@ -244,7 +244,7 @@ struct peci_request *peci_xfer_get_dib(struct peci_device *device) return req; } -EXPORT_SYMBOL_NS_GPL(peci_xfer_get_dib, PECI); +EXPORT_SYMBOL_NS_GPL(peci_xfer_get_dib, "PECI"); struct peci_request *peci_xfer_get_temp(struct peci_device *device) { @@ -265,7 +265,7 @@ struct peci_request *peci_xfer_get_temp(struct peci_device *device) return req; } -EXPORT_SYMBOL_NS_GPL(peci_xfer_get_temp, PECI); +EXPORT_SYMBOL_NS_GPL(peci_xfer_get_temp, "PECI"); static struct peci_request * __pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len) @@ -397,44 +397,44 @@ u8 peci_request_data_readb(struct peci_request *req) { return req->rx.buf[1]; } -EXPORT_SYMBOL_NS_GPL(peci_request_data_readb, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_data_readb, "PECI"); u16 peci_request_data_readw(struct peci_request *req) { return get_unaligned_le16(&req->rx.buf[1]); } -EXPORT_SYMBOL_NS_GPL(peci_request_data_readw, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_data_readw, "PECI"); u32 peci_request_data_readl(struct peci_request *req) { return get_unaligned_le32(&req->rx.buf[1]); } -EXPORT_SYMBOL_NS_GPL(peci_request_data_readl, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_data_readl, "PECI"); u64 peci_request_data_readq(struct peci_request *req) { return get_unaligned_le64(&req->rx.buf[1]); } -EXPORT_SYMBOL_NS_GPL(peci_request_data_readq, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_data_readq, "PECI"); u64 peci_request_dib_read(struct peci_request *req) { return get_unaligned_le64(&req->rx.buf[0]); } -EXPORT_SYMBOL_NS_GPL(peci_request_dib_read, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_dib_read, "PECI"); s16 peci_request_temp_read(struct peci_request *req) { return get_unaligned_le16(&req->rx.buf[0]); } -EXPORT_SYMBOL_NS_GPL(peci_request_temp_read, PECI); +EXPORT_SYMBOL_NS_GPL(peci_request_temp_read, "PECI"); #define __read_pkg_config(x, type) \ struct peci_request *peci_xfer_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \ { \ return __pkg_cfg_read(device, index, param, sizeof(type)); \ } \ -EXPORT_SYMBOL_NS_GPL(peci_xfer_pkg_cfg_##x, PECI) +EXPORT_SYMBOL_NS_GPL(peci_xfer_pkg_cfg_##x, "PECI") __read_pkg_config(readb, u8); __read_pkg_config(readw, u16); @@ -447,7 +447,7 @@ peci_xfer_pci_cfg_local_##x(struct peci_device *device, u8 bus, u8 dev, u8 func, { \ return __pci_cfg_local_read(device, bus, dev, func, reg, sizeof(type)); \ } \ -EXPORT_SYMBOL_NS_GPL(peci_xfer_pci_cfg_local_##x, PECI) +EXPORT_SYMBOL_NS_GPL(peci_xfer_pci_cfg_local_##x, "PECI") __read_pci_config_local(readb, u8); __read_pci_config_local(readw, u16); @@ -459,7 +459,7 @@ peci_xfer_ep_pci_cfg_##x(struct peci_device *device, u8 seg, u8 bus, u8 dev, u8 { \ return __ep_pci_cfg_read(device, msg_type, seg, bus, dev, func, reg, sizeof(type)); \ } \ -EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_pci_cfg_##x, PECI) +EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_pci_cfg_##x, "PECI") __read_ep_pci_config(local_readb, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u8); __read_ep_pci_config(local_readw, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u16); @@ -476,7 +476,7 @@ struct peci_request *peci_xfer_ep_mmio##y##_##x(struct peci_device *device, u8 b offset, PECI_RDENDPTCFG_MMIO_WR_LEN_BASE + sizeof(type1), \ sizeof(type2)); \ } \ -EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_mmio##y##_##x, PECI) +EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_mmio##y##_##x, "PECI") __read_ep_mmio(readl, 32, PECI_ENDPTCFG_ADDR_TYPE_MMIO_D, u32, u32); __read_ep_mmio(readl, 64, PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q, u64, u32); diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 49bd811c6fd6efdd9f7b6a4d1cf1813c31b1bea9..b20fa600e510c54ff73ff8aff9c036f0e444092b 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -2178,8 +2178,6 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) continue; xp = arm_cmn_node_to_xp(cmn, dn); - dn->portid_bits = xp->portid_bits; - dn->deviceid_bits = xp->deviceid_bits; dn->dtc = xp->dtc; dn->dtm = xp->dtm; if (cmn->multi_dtm) @@ -2420,6 +2418,8 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) } arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn); + dn->portid_bits = xp->portid_bits; + dn->deviceid_bits = xp->deviceid_bits; switch (dn->type) { case CMN_TYPE_DTC: diff --git a/drivers/perf/arm-ni.c b/drivers/perf/arm-ni.c index 90fcfe693439ef3e18e23c6351433ac3c5ea78b5..fd7a5e60e96302fada29cd44e7bf9c582e93e4ce 100644 --- a/drivers/perf/arm-ni.c +++ b/drivers/perf/arm-ni.c @@ -247,7 +247,6 @@ static struct attribute *arm_ni_other_attrs[] = { static const struct attribute_group arm_ni_other_attr_group = { .attrs = arm_ni_other_attrs, - NULL }; static const struct attribute_group *arm_ni_attr_groups[] = { diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c index b1510f660c7a6931823ebac8eeccbade36950d1b..621f02a7f43be364e5c260fd97aa375f5e8e3404 100644 --- a/drivers/perf/arm_smmuv3_pmu.c +++ b/drivers/perf/arm_smmuv3_pmu.c @@ -431,6 +431,17 @@ static int smmu_pmu_event_init(struct perf_event *event) return -EINVAL; } + /* + * Ensure all events are on the same cpu so all events are in the + * same cpu context, to avoid races on pmu_enable etc. + */ + event->cpu = smmu_pmu->on_cpu; + + hwc->idx = -1; + + if (event->group_leader == event) + return 0; + for_each_sibling_event(sibling, event->group_leader) { if (is_software_event(sibling)) continue; @@ -442,14 +453,6 @@ static int smmu_pmu_event_init(struct perf_event *event) return -EINVAL; } - hwc->idx = -1; - - /* - * Ensure all events are on the same cpu so all events are in the - * same cpu context, to avoid races on pmu_enable etc. - */ - event->cpu = smmu_pmu->on_cpu; - return 0; } diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c index bee4b5b52ec6f824d58c936209cf09dda3defe99..d6693519eaee2ee8ef45714c09cb33681478efe9 100644 --- a/drivers/perf/cxl_pmu.c +++ b/drivers/perf/cxl_pmu.c @@ -977,7 +977,7 @@ static __exit void cxl_pmu_exit(void) MODULE_DESCRIPTION("CXL Performance Monitor Driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); module_init(cxl_pmu_init); module_exit(cxl_pmu_exit); MODULE_ALIAS_CXL(CXL_DEVICE_PMU); diff --git a/drivers/phy/realtek/phy-rtk-usb2.c b/drivers/phy/realtek/phy-rtk-usb2.c index c3e131a64131af140749c4917127e57478a3b840..248550ef98cab23c3d06f58cb93a3e5b0e6c1d87 100644 --- a/drivers/phy/realtek/phy-rtk-usb2.c +++ b/drivers/phy/realtek/phy-rtk-usb2.c @@ -1023,6 +1023,8 @@ static int rtk_usb2phy_probe(struct platform_device *pdev) rtk_phy->dev = &pdev->dev; rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL); + if (!rtk_phy->phy_cfg) + return -ENOMEM; memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg)); diff --git a/drivers/phy/realtek/phy-rtk-usb3.c b/drivers/phy/realtek/phy-rtk-usb3.c index 0cef29a7ddd9592b472eef0be1683c32c6b5c2f5..cce453686db214866a37bf3afe84d75506785957 100644 --- a/drivers/phy/realtek/phy-rtk-usb3.c +++ b/drivers/phy/realtek/phy-rtk-usb3.c @@ -577,6 +577,8 @@ static int rtk_usb3phy_probe(struct platform_device *pdev) rtk_phy->dev = &pdev->dev; rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL); + if (!rtk_phy->phy_cfg) + return -ENOMEM; memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg)); diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index f9b862c1c438e90f7068d464755c76d3898912a1..79d4814d758d5e1f0e8200d61e131606adbb0e2d 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -543,7 +543,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port, device_initialize(&port->dev); port->dev.type = &tegra_xusb_port_type; - port->dev.of_node = of_node_get(np); + device_set_node(&port->dev, of_fwnode_handle(of_node_get(np))); port->dev.parent = padctl->dev; err = dev_set_name(&port->dev, "%s-%u", name, index); diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c index fd5ce52d05b1d40c57a0f6cfe84546256ed061e0..c9a3d3aa8c108663109e22b2dd88f7151c2588f3 100644 --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c @@ -309,7 +309,7 @@ static void iproc_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct iproc_gpio *chip = gpiochip_get_data(gc); - seq_printf(p, dev_name(chip->dev)); + seq_puts(p, dev_name(chip->dev)); } static const struct irq_chip iproc_gpio_irq_chip = { diff --git a/drivers/pinctrl/intel/pinctrl-alderlake.c b/drivers/pinctrl/intel/pinctrl-alderlake.c index 7d9948e5f422f6bd029861af6b209e2084e04abc..108eac205aa9dc1a34108e88f7012de3456ad2d4 100644 --- a/drivers/pinctrl/intel/pinctrl-alderlake.c +++ b/drivers/pinctrl/intel/pinctrl-alderlake.c @@ -747,4 +747,4 @@ module_platform_driver(adl_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Alder Lake PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 4533c4d0a9e750a8aeb0d31a790211650dae4a84..7340dc20349c7369bb287cab3b1b4f29f2826ef3 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1723,4 +1723,4 @@ static int __init byt_gpio_init(void) } subsys_initcall(byt_gpio_init); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c index d99541676630deb8b405774f2de9042035aa9f55..140b299563406483bd4d430e5d64e36f42a9386b 100644 --- a/drivers/pinctrl/intel/pinctrl-broxton.c +++ b/drivers/pinctrl/intel/pinctrl-broxton.c @@ -1026,4 +1026,4 @@ module_exit(bxt_pinctrl_exit); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c index 1aa09f950be1ebacef7c574f410c9e40ff0b3b76..14a5d339385d34a24cf2873184e173ca94e9d6ee 100644 --- a/drivers/pinctrl/intel/pinctrl-cannonlake.c +++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c @@ -838,4 +838,4 @@ module_platform_driver(cnl_pinctrl_driver); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Cannon Lake PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-cedarfork.c b/drivers/pinctrl/intel/pinctrl-cedarfork.c index 48af8930dd1f951241d3a32a9cd820076c8b6165..2ce97abeb0e411450506bc87a8bbf0d002d55861 100644 --- a/drivers/pinctrl/intel/pinctrl-cedarfork.c +++ b/drivers/pinctrl/intel/pinctrl-cedarfork.c @@ -350,4 +350,4 @@ module_exit(cdf_pinctrl_exit); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Cedar Fork PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 9f938718927bd4d23db9818bb6749079189087a4..c673e262e1dbcc938503bf2136cc043838678651 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1815,4 +1815,4 @@ module_exit(chv_pinctrl_exit); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Cherryview/Braswell pinctrl driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-denverton.c b/drivers/pinctrl/intel/pinctrl-denverton.c index 666507f54f2761a6d08e24d6f4fedd6e9640a832..fef44c663be6027ef7b64f6ec9710d4b6d02227d 100644 --- a/drivers/pinctrl/intel/pinctrl-denverton.c +++ b/drivers/pinctrl/intel/pinctrl-denverton.c @@ -287,4 +287,4 @@ module_exit(dnv_pinctrl_exit); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Denverton SoC pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-elkhartlake.c b/drivers/pinctrl/intel/pinctrl-elkhartlake.c index 3e45d7fb003acc721cf3ffbbaa2c27075190fa6b..ab414e07555a8f1c0564fcab0c7183a706471bd1 100644 --- a/drivers/pinctrl/intel/pinctrl-elkhartlake.c +++ b/drivers/pinctrl/intel/pinctrl-elkhartlake.c @@ -537,4 +537,4 @@ module_platform_driver(ehl_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Elkhart Lake PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-emmitsburg.c b/drivers/pinctrl/intel/pinctrl-emmitsburg.c index e4798d32492c5888e4052553e73f28a5b422690c..9d8a32aca177e331294d133961a6d8e4079b287e 100644 --- a/drivers/pinctrl/intel/pinctrl-emmitsburg.c +++ b/drivers/pinctrl/intel/pinctrl-emmitsburg.c @@ -372,4 +372,4 @@ module_platform_driver(ebg_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Emmitsburg PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-geminilake.c b/drivers/pinctrl/intel/pinctrl-geminilake.c index 6dcf0ac2059f5da3ef6c898093c7c05e2c8f6e7c..8dcac4fe8493c314554ecf29f86ddc4fa182b6c2 100644 --- a/drivers/pinctrl/intel/pinctrl-geminilake.c +++ b/drivers/pinctrl/intel/pinctrl-geminilake.c @@ -472,4 +472,4 @@ module_exit(glk_pinctrl_exit); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Gemini Lake SoC pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-icelake.c b/drivers/pinctrl/intel/pinctrl-icelake.c index fe3042de891a61d41b17dce76b471c37887150a5..7e028c61ed0ff11289756744a1125306a3a05fa1 100644 --- a/drivers/pinctrl/intel/pinctrl-icelake.c +++ b/drivers/pinctrl/intel/pinctrl-icelake.c @@ -690,4 +690,4 @@ MODULE_AUTHOR("Andy Shevchenko "); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Ice Lake PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-intel-platform.c b/drivers/pinctrl/intel/pinctrl-intel-platform.c index 016a9f62eecc10353fb763c78b6d8bfec241443d..dd5dbede0f591a5403673239ddf12554261a26a7 100644 --- a/drivers/pinctrl/intel/pinctrl-intel-platform.c +++ b/drivers/pinctrl/intel/pinctrl-intel-platform.c @@ -221,4 +221,4 @@ module_platform_driver(intel_platform_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 04b438f63ccbb754a37dc8d2ac05e28fe585bd59..527e4b87ae52e85b6f2997c37b7f5b24d3f62964 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -158,7 +158,7 @@ const struct intel_community *intel_get_community(const struct intel_pinctrl *pc dev_warn(pctrl->dev, "failed to find community for pin %u\n", pin); return NULL; } -EXPORT_SYMBOL_NS_GPL(intel_get_community, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_community, "PINCTRL_INTEL"); static const struct intel_padgroup * intel_community_get_padgroup(const struct intel_community *community, @@ -315,7 +315,7 @@ int intel_get_groups_count(struct pinctrl_dev *pctldev) return pctrl->soc->ngroups; } -EXPORT_SYMBOL_NS_GPL(intel_get_groups_count, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_groups_count, "PINCTRL_INTEL"); const char *intel_get_group_name(struct pinctrl_dev *pctldev, unsigned int group) { @@ -323,7 +323,7 @@ const char *intel_get_group_name(struct pinctrl_dev *pctldev, unsigned int group return pctrl->soc->groups[group].grp.name; } -EXPORT_SYMBOL_NS_GPL(intel_get_group_name, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_group_name, "PINCTRL_INTEL"); int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, const unsigned int **pins, unsigned int *npins) @@ -334,7 +334,7 @@ int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, *npins = pctrl->soc->groups[group].grp.npins; return 0; } -EXPORT_SYMBOL_NS_GPL(intel_get_group_pins, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_group_pins, "PINCTRL_INTEL"); static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int pin) @@ -400,7 +400,7 @@ int intel_get_functions_count(struct pinctrl_dev *pctldev) return pctrl->soc->nfunctions; } -EXPORT_SYMBOL_NS_GPL(intel_get_functions_count, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_functions_count, "PINCTRL_INTEL"); const char *intel_get_function_name(struct pinctrl_dev *pctldev, unsigned int function) { @@ -408,7 +408,7 @@ const char *intel_get_function_name(struct pinctrl_dev *pctldev, unsigned int fu return pctrl->soc->functions[function].func.name; } -EXPORT_SYMBOL_NS_GPL(intel_get_function_name, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_function_name, "PINCTRL_INTEL"); int intel_get_function_groups(struct pinctrl_dev *pctldev, unsigned int function, const char * const **groups, unsigned int * const ngroups) @@ -419,7 +419,7 @@ int intel_get_function_groups(struct pinctrl_dev *pctldev, unsigned int function *ngroups = pctrl->soc->functions[function].func.ngroups; return 0; } -EXPORT_SYMBOL_NS_GPL(intel_get_function_groups, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_function_groups, "PINCTRL_INTEL"); static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, unsigned int group) @@ -1676,7 +1676,7 @@ int intel_pinctrl_probe(struct platform_device *pdev, return 0; } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe, "PINCTRL_INTEL"); int intel_pinctrl_probe_by_hid(struct platform_device *pdev) { @@ -1688,7 +1688,7 @@ int intel_pinctrl_probe_by_hid(struct platform_device *pdev) return intel_pinctrl_probe(pdev, data); } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_hid, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_hid, "PINCTRL_INTEL"); int intel_pinctrl_probe_by_uid(struct platform_device *pdev) { @@ -1700,7 +1700,7 @@ int intel_pinctrl_probe_by_uid(struct platform_device *pdev) return intel_pinctrl_probe(pdev, data); } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_uid, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_uid, "PINCTRL_INTEL"); const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev) { @@ -1731,7 +1731,7 @@ const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_ return data ?: ERR_PTR(-ENODATA); } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_get_soc_data, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_get_soc_data, "PINCTRL_INTEL"); static bool __intel_gpio_is_direct_irq(u32 value) { diff --git a/drivers/pinctrl/intel/pinctrl-jasperlake.c b/drivers/pinctrl/intel/pinctrl-jasperlake.c index 3525480428ea66b226d896dbe51d9926738fddd5..aef0e7f921549eccfd329a39a539ebca28164ffd 100644 --- a/drivers/pinctrl/intel/pinctrl-jasperlake.c +++ b/drivers/pinctrl/intel/pinctrl-jasperlake.c @@ -340,4 +340,4 @@ module_platform_driver(jsl_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Jasper Lake PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-lakefield.c b/drivers/pinctrl/intel/pinctrl-lakefield.c index adef85db82ca7626732973ac3c768a496bd4a5f3..60281f4216085fa1b72f710ed05da6bfec987ce0 100644 --- a/drivers/pinctrl/intel/pinctrl-lakefield.c +++ b/drivers/pinctrl/intel/pinctrl-lakefield.c @@ -361,4 +361,4 @@ module_platform_driver(lkf_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Lakefield PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-lewisburg.c b/drivers/pinctrl/intel/pinctrl-lewisburg.c index a304d30ea9ed33503f9486ca18bcf2d58493df88..9fe651370f32f4e4873b97596892e6c43131e270 100644 --- a/drivers/pinctrl/intel/pinctrl-lewisburg.c +++ b/drivers/pinctrl/intel/pinctrl-lewisburg.c @@ -321,4 +321,4 @@ module_platform_driver(lbg_pinctrl_driver); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Lewisburg pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index bcce97f3b8975e639c7ecbd239b3b568fc0d57f4..cc5ede17c38384a429925cf460a9d6bd77bd0c7e 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -859,4 +859,4 @@ MODULE_AUTHOR("Andy Shevchenko (Intel)"); MODULE_DESCRIPTION("Intel Lynxpoint pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:lp_gpio"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 1a556f5822b6e9c05bd0acfd96bb82efc0789c2c..2f4d73dda41d323b2836815e4f2eed7764db6372 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -380,4 +380,4 @@ MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Merrifield SoC pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:pinctrl-merrifield"); -MODULE_IMPORT_NS(PINCTRL_TANGIER); +MODULE_IMPORT_NS("PINCTRL_TANGIER"); diff --git a/drivers/pinctrl/intel/pinctrl-meteorlake.c b/drivers/pinctrl/intel/pinctrl-meteorlake.c index 885fa3b0d6d95fa027ed50b9750e06a93f61cc3e..f564376ce437311b9a19ff1846d21575c07e1c52 100644 --- a/drivers/pinctrl/intel/pinctrl-meteorlake.c +++ b/drivers/pinctrl/intel/pinctrl-meteorlake.c @@ -604,4 +604,4 @@ module_platform_driver(mtl_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Meteor Lake PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-meteorpoint.c b/drivers/pinctrl/intel/pinctrl-meteorpoint.c index 77e97775a60b1d2b547c967a0d9083f46cc89c2b..ab46ac5f3b159fdd6eb71af8d433b6cecf2538e7 100644 --- a/drivers/pinctrl/intel/pinctrl-meteorpoint.c +++ b/drivers/pinctrl/intel/pinctrl-meteorpoint.c @@ -462,4 +462,4 @@ module_platform_driver(mtp_pinctrl_driver); MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Meteor Point PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-moorefield.c b/drivers/pinctrl/intel/pinctrl-moorefield.c index 7b995fbf5c84b65251ac64c9ee4b0d6f99047732..6a79207e6b2a3350fb3d42b7dc76b7b2a145b949 100644 --- a/drivers/pinctrl/intel/pinctrl-moorefield.c +++ b/drivers/pinctrl/intel/pinctrl-moorefield.c @@ -341,4 +341,4 @@ MODULE_AUTHOR("Andy Shevchenko "); MODULE_DESCRIPTION("Intel Moorefield SoC pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:pinctrl-moorefield"); -MODULE_IMPORT_NS(PINCTRL_TANGIER); +MODULE_IMPORT_NS("PINCTRL_TANGIER"); diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c index 55df9d2cfb1beead5f6ca290386046886c26ac27..a7a5fa65fd9d04251519d806943ae52b1028c611 100644 --- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c +++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c @@ -605,4 +605,4 @@ MODULE_AUTHOR("Mathias Nyman "); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Sunrisepoint PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/intel/pinctrl-tangier.c b/drivers/pinctrl/intel/pinctrl-tangier.c index 2cb0b4758269ee1d7808ec56b16a61209cc95985..d3baf0f4eea098efbad2e3ea39221801aa4a78a5 100644 --- a/drivers/pinctrl/intel/pinctrl-tangier.c +++ b/drivers/pinctrl/intel/pinctrl-tangier.c @@ -579,7 +579,7 @@ int devm_tng_pinctrl_probe(struct platform_device *pdev) return tng_pinctrl_probe(pdev, data); } -EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, PINCTRL_TANGIER); +EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, "PINCTRL_TANGIER"); MODULE_AUTHOR("Andy Shevchenko "); MODULE_AUTHOR("Raag Jadav "); diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c index 80cd7a06fe5ad68d6e096bf28c646d5111eb75f9..c43576e10273e0d62225129a97166b02393845c9 100644 --- a/drivers/pinctrl/intel/pinctrl-tigerlake.c +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -758,4 +758,4 @@ MODULE_AUTHOR("Andy Shevchenko "); MODULE_AUTHOR("Mika Westerberg "); MODULE_DESCRIPTION("Intel Tiger Lake PCH pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PINCTRL_INTEL); +MODULE_IMPORT_NS("PINCTRL_INTEL"); diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 4c4ada06423d7242bb9f3ae86380257fbbdc328f..335744ac831057576473dd62c5533168b243a656 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -734,7 +734,7 @@ static void armada_37xx_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gpio_chip *chip = irq_data_get_irq_chip_data(d); struct armada_37xx_pinctrl *info = gpiochip_get_data(chip); - seq_printf(p, info->data->name); + seq_puts(p, info->data->name); } static const struct irq_chip armada_37xx_irqchip = { diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 737d0ae3d0b66266c4c46db8733eb96944689ece..d66c3a3e842924ba96adaed970a2bf1419c3c9b2 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -569,7 +569,7 @@ static void mcp23s08_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct mcp23s08 *mcp = gpiochip_get_data(gc); - seq_printf(p, dev_name(mcp->dev)); + seq_puts(p, dev_name(mcp->dev)); } static const struct irq_chip mcp23s08_irq_chip = { diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index bfeb2edbeec5b23ab9cc7ba7ff470ee82e06b6c6..521f6fef0b9f681f1a3fe9d8da92392edcd664c9 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -599,7 +599,7 @@ static void stmfx_pinctrl_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gpio_chip *gpio_chip = irq_data_get_irq_chip_data(d); struct stmfx_pinctrl *pctl = gpiochip_get_data(gpio_chip); - seq_printf(p, dev_name(pctl->dev)); + seq_puts(p, dev_name(pctl->dev)); } static const struct irq_chip stmfx_pinctrl_irq_chip = { diff --git a/drivers/pinctrl/pinctrl-sx150x.c b/drivers/pinctrl/pinctrl-sx150x.c index ab87de319ad861ae675ae6b75c7ff57e39f486c3..98262b8ce43ac44f9952e956322b60909b5f9b48 100644 --- a/drivers/pinctrl/pinctrl-sx150x.c +++ b/drivers/pinctrl/pinctrl-sx150x.c @@ -584,7 +584,7 @@ static void sx150x_irq_print_chip(struct irq_data *d, struct seq_file *p) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct sx150x_pinctrl *pctl = gpiochip_get_data(gc); - seq_printf(p, pctl->client->name); + seq_puts(p, pctl->client->name); } static const struct irq_chip sx150x_irq_chip = { diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 8ffb9430a1342583151cf53b46b6e80cf1d4d49d..1df9cec2873fff910f86669c1c1ce13ee3737225 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -2332,7 +2332,7 @@ static void rzg2l_gpio_irq_print_chip(struct irq_data *data, struct seq_file *p) { struct gpio_chip *gc = irq_data_get_irq_chip_data(data); - seq_printf(p, dev_name(gc->parent)); + seq_puts(p, dev_name(gc->parent)); } static int rzg2l_gpio_irq_set_wake(struct irq_data *data, unsigned int on) diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index 7dbeb786352af75949f0e702c81b7b33100ed1f2..b7dbaf77b6db468a9b1cc55c0c9689ce07580f07 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -61,6 +61,17 @@ config CHROMEOS_TBMC To compile this driver as a module, choose M here: the module will be called chromeos_tbmc. +config CHROMEOS_OF_HW_PROBER + tristate "ChromeOS Device Tree Hardware Prober" + depends on OF + depends on I2C + select OF_DYNAMIC + default OF + help + This option enables the device tree hardware prober for ChromeOS + devices. The driver will probe the correct component variant in + devices that have multiple drop-in options for one component. + config CROS_EC tristate "ChromeOS Embedded Controller" select CROS_EC_PROTO diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index 2dcc6ccc23022b18f2743b786ac4535d1b435e0e..fb8335458a2216133e1e1712b2dedc684fea4ff8 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile @@ -6,6 +6,7 @@ CFLAGS_cros_ec_sensorhub_ring.o:= -I$(src) obj-$(CONFIG_CHROMEOS_ACPI) += chromeos_acpi.o obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o +obj-$(CONFIG_CHROMEOS_OF_HW_PROBER) += chromeos_of_hw_prober.o obj-$(CONFIG_CHROMEOS_PRIVACY_SCREEN) += chromeos_privacy_screen.o obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o diff --git a/drivers/platform/chrome/chromeos_of_hw_prober.c b/drivers/platform/chrome/chromeos_of_hw_prober.c new file mode 100644 index 0000000000000000000000000000000000000000..c6992f5cdc7660a58f1d9075ccfa1ed496e6d197 --- /dev/null +++ b/drivers/platform/chrome/chromeos_of_hw_prober.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ChromeOS Device Tree Hardware Prober + * + * Copyright (c) 2024 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "chromeos_of_hw_prober" + +/** + * struct hw_prober_entry - Holds an entry for the hardware prober + * + * @compatible: compatible string to match against the machine + * @prober: prober function to call when machine matches + * @data: extra data for the prober function + */ +struct hw_prober_entry { + const char *compatible; + int (*prober)(struct device *dev, const void *data); + const void *data; +}; + +struct chromeos_i2c_probe_data { + const struct i2c_of_probe_cfg *cfg; + const struct i2c_of_probe_simple_opts *opts; +}; + +static int chromeos_i2c_component_prober(struct device *dev, const void *_data) +{ + const struct chromeos_i2c_probe_data *data = _data; + struct i2c_of_probe_simple_ctx ctx = { + .opts = data->opts, + }; + + return i2c_of_probe_component(dev, data->cfg, &ctx); +} + +#define DEFINE_CHROMEOS_I2C_PROBE_CFG_SIMPLE_BY_TYPE(_type) \ + static const struct i2c_of_probe_cfg chromeos_i2c_probe_simple_ ## _type ## _cfg = { \ + .type = #_type, \ + .ops = &i2c_of_probe_simple_ops, \ + } + +#define DEFINE_CHROMEOS_I2C_PROBE_DATA_DUMB_BY_TYPE(_type) \ + static const struct chromeos_i2c_probe_data chromeos_i2c_probe_dumb_ ## _type = { \ + .cfg = &(const struct i2c_of_probe_cfg) { \ + .type = #_type, \ + }, \ + } + +DEFINE_CHROMEOS_I2C_PROBE_DATA_DUMB_BY_TYPE(touchscreen); + +DEFINE_CHROMEOS_I2C_PROBE_CFG_SIMPLE_BY_TYPE(trackpad); + +static const struct chromeos_i2c_probe_data chromeos_i2c_probe_hana_trackpad = { + .cfg = &chromeos_i2c_probe_simple_trackpad_cfg, + .opts = &(const struct i2c_of_probe_simple_opts) { + .res_node_compatible = "elan,ekth3000", + .supply_name = "vcc", + /* + * ELAN trackpad needs 2 ms for H/W init and 100 ms for F/W init. + * Synaptics trackpad needs 100 ms. + * However, the regulator is set to "always-on", presumably to + * avoid this delay. The ELAN driver is also missing delays. + */ + .post_power_on_delay_ms = 0, + }, +}; + +static const struct hw_prober_entry hw_prober_platforms[] = { + { + .compatible = "google,hana", + .prober = chromeos_i2c_component_prober, + .data = &chromeos_i2c_probe_dumb_touchscreen, + }, { + .compatible = "google,hana", + .prober = chromeos_i2c_component_prober, + .data = &chromeos_i2c_probe_hana_trackpad, + }, +}; + +static int chromeos_of_hw_prober_probe(struct platform_device *pdev) +{ + for (size_t i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++) { + int ret; + + if (!of_machine_is_compatible(hw_prober_platforms[i].compatible)) + continue; + + ret = hw_prober_platforms[i].prober(&pdev->dev, hw_prober_platforms[i].data); + /* Ignore unrecoverable errors and keep going through other probers */ + if (ret == -EPROBE_DEFER) + return ret; + } + + return 0; +} + +static struct platform_driver chromeos_of_hw_prober_driver = { + .probe = chromeos_of_hw_prober_probe, + .driver = { + .name = DRV_NAME, + }, +}; + +static struct platform_device *chromeos_of_hw_prober_pdev; + +static int chromeos_of_hw_prober_driver_init(void) +{ + size_t i; + int ret; + + for (i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++) + if (of_machine_is_compatible(hw_prober_platforms[i].compatible)) + break; + if (i == ARRAY_SIZE(hw_prober_platforms)) + return -ENODEV; + + ret = platform_driver_register(&chromeos_of_hw_prober_driver); + if (ret) + return ret; + + chromeos_of_hw_prober_pdev = + platform_device_register_simple(DRV_NAME, PLATFORM_DEVID_NONE, NULL, 0); + if (IS_ERR(chromeos_of_hw_prober_pdev)) + goto err; + + return 0; + +err: + platform_driver_unregister(&chromeos_of_hw_prober_driver); + + return PTR_ERR(chromeos_of_hw_prober_pdev); +} +module_init(chromeos_of_hw_prober_driver_init); + +static void chromeos_of_hw_prober_driver_exit(void) +{ + platform_device_unregister(chromeos_of_hw_prober_pdev); + platform_driver_unregister(&chromeos_of_hw_prober_driver); +} +module_exit(chromeos_of_hw_prober_driver_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ChromeOS device tree hardware prober"); +MODULE_IMPORT_NS("I2C_OF_PROBER"); diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index c2aab0cfab338376d09e4243271e378fecc9de8c..abc31971fe6a3a51ef06eb27ea8c5a0064af8b8a 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c @@ -61,7 +61,6 @@ #include #include #include -#include #include #include "goldfish_pipe_qemu.h" @@ -936,11 +935,11 @@ MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match); static struct platform_driver goldfish_pipe_driver = { .probe = goldfish_pipe_probe, - .remove_new = goldfish_pipe_remove, + .remove = goldfish_pipe_remove, .driver = { .name = "goldfish_pipe", .of_match_table = goldfish_pipe_of_match, - .acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match), + .acpi_match_table = goldfish_pipe_acpi_match, } }; diff --git a/drivers/platform/mellanox/mlxbf-bootctl.c b/drivers/platform/mellanox/mlxbf-bootctl.c index dd5f370c316823260bf83ccb6bce49aa90f7817b..c5b36837e6943ab2cfb8908b03e3d0fe387f2cb0 100644 --- a/drivers/platform/mellanox/mlxbf-bootctl.c +++ b/drivers/platform/mellanox/mlxbf-bootctl.c @@ -1049,7 +1049,7 @@ static void mlxbf_bootctl_remove(struct platform_device *pdev) static struct platform_driver mlxbf_bootctl_driver = { .probe = mlxbf_bootctl_probe, - .remove_new = mlxbf_bootctl_remove, + .remove = mlxbf_bootctl_remove, .driver = { .name = "mlxbf-bootctl", .dev_groups = mlxbf_bootctl_groups, diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c index 6c834e39352d61952f644597937ac9cbbbb84544..300cdaa75a1770f27effc768a28dd049e94c3f5c 100644 --- a/drivers/platform/mellanox/mlxbf-tmfifo.c +++ b/drivers/platform/mellanox/mlxbf-tmfifo.c @@ -1446,7 +1446,7 @@ MODULE_DEVICE_TABLE(acpi, mlxbf_tmfifo_acpi_match); static struct platform_driver mlxbf_tmfifo_driver = { .probe = mlxbf_tmfifo_probe, - .remove_new = mlxbf_tmfifo_remove, + .remove = mlxbf_tmfifo_remove, .driver = { .name = "bf-tmfifo", .acpi_match_table = mlxbf_tmfifo_acpi_match, diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c index 0ce9fff1f7d4d41cf3891d26ae91bff45d87e891..6aa2a465036707032af269cde85f09846b8c7555 100644 --- a/drivers/platform/mellanox/mlxreg-hotplug.c +++ b/drivers/platform/mellanox/mlxreg-hotplug.c @@ -786,7 +786,7 @@ static struct platform_driver mlxreg_hotplug_driver = { .name = "mlxreg-hotplug", }, .probe = mlxreg_hotplug_probe, - .remove_new = mlxreg_hotplug_remove, + .remove = mlxreg_hotplug_remove, }; module_platform_driver(mlxreg_hotplug_driver); diff --git a/drivers/platform/mellanox/mlxreg-io.c b/drivers/platform/mellanox/mlxreg-io.c index ee7bd623ba44f4e0feec51de890dbc4bf11b7701..595276206baf121c3cf0fff994490def408fe26a 100644 --- a/drivers/platform/mellanox/mlxreg-io.c +++ b/drivers/platform/mellanox/mlxreg-io.c @@ -275,7 +275,7 @@ static struct platform_driver mlxreg_io_driver = { .name = "mlxreg-io", }, .probe = mlxreg_io_probe, - .remove_new = mlxreg_io_remove, + .remove = mlxreg_io_remove, }; module_platform_driver(mlxreg_io_driver); diff --git a/drivers/platform/mellanox/mlxreg-lc.c b/drivers/platform/mellanox/mlxreg-lc.c index 43d119e3a47342244825c57ebf04bbb950906201..aee395bb48ae44e4174bb5873dd773fb541b91de 100644 --- a/drivers/platform/mellanox/mlxreg-lc.c +++ b/drivers/platform/mellanox/mlxreg-lc.c @@ -944,7 +944,7 @@ static void mlxreg_lc_remove(struct platform_device *pdev) static struct platform_driver mlxreg_lc_driver = { .probe = mlxreg_lc_probe, - .remove_new = mlxreg_lc_remove, + .remove = mlxreg_lc_remove, .driver = { .name = "mlxreg-lc", }, diff --git a/drivers/platform/mellanox/nvsw-sn2201.c b/drivers/platform/mellanox/nvsw-sn2201.c index abe7be602f846e3bbed10ff70d1dc111f0651438..0c047aa2345b36add85d34be3bfd74a17c07445c 100644 --- a/drivers/platform/mellanox/nvsw-sn2201.c +++ b/drivers/platform/mellanox/nvsw-sn2201.c @@ -1253,7 +1253,7 @@ MODULE_DEVICE_TABLE(acpi, nvsw_sn2201_acpi_ids); static struct platform_driver nvsw_sn2201_driver = { .probe = nvsw_sn2201_probe, - .remove_new = nvsw_sn2201_remove, + .remove = nvsw_sn2201_remove, .driver = { .name = "nvsw-sn2201", .acpi_match_table = nvsw_sn2201_acpi_ids, diff --git a/drivers/platform/surface/surface3-wmi.c b/drivers/platform/surface/surface3-wmi.c index c15ed7a12784aede3fc96190b4c76c93197d166d..6c8fb7a4dde4447748ed3edd3eb7c7f5bdd69369 100644 --- a/drivers/platform/surface/surface3-wmi.c +++ b/drivers/platform/surface/surface3-wmi.c @@ -247,7 +247,7 @@ static struct platform_driver s3_wmi_driver = { .name = "surface3-wmi", .pm = &s3_wmi_pm, }, - .remove_new = s3_wmi_remove, + .remove = s3_wmi_remove, }; static int __init s3_wmi_init(void) diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c index 14a9d8a267cbbecc9d92be896a147eb03431dbe7..3b30cfe3466b8ffb1694b597d2ef9624e7fada82 100644 --- a/drivers/platform/surface/surface_acpi_notify.c +++ b/drivers/platform/surface/surface_acpi_notify.c @@ -850,7 +850,7 @@ MODULE_DEVICE_TABLE(acpi, san_match); static struct platform_driver surface_acpi_notify = { .probe = san_probe, - .remove_new = san_remove, + .remove = san_remove, .driver = { .name = "surface_acpi_notify", .acpi_match_table = san_match, diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c index 165b1416230d712008627fd4f162bb1898c11db1..bfaa09d1648bcf84f342345114fc7cb1b72afc67 100644 --- a/drivers/platform/surface/surface_aggregator_cdev.c +++ b/drivers/platform/surface/surface_aggregator_cdev.c @@ -762,7 +762,7 @@ static struct platform_device *ssam_cdev_device; static struct platform_driver ssam_cdev_driver = { .probe = ssam_dbg_device_probe, - .remove_new = ssam_dbg_device_remove, + .remove = ssam_dbg_device_remove, .driver = { .name = SSAM_CDEV_DEVICE_NAME, .probe_type = PROBE_PREFER_ASYNCHRONOUS, diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c index 06e45f0b9817d189df4df86f663cb3757b8cf8ac..d4f32ad6653054c220d18966498c87bb813beb0b 100644 --- a/drivers/platform/surface/surface_aggregator_registry.c +++ b/drivers/platform/surface/surface_aggregator_registry.c @@ -554,7 +554,7 @@ static void ssam_platform_hub_remove(struct platform_device *pdev) static struct platform_driver ssam_platform_hub_driver = { .probe = ssam_platform_hub_probe, - .remove_new = ssam_platform_hub_remove, + .remove = ssam_platform_hub_remove, .driver = { .name = "surface_aggregator_platform_hub", .acpi_match_table = ssam_platform_hub_acpi_match, diff --git a/drivers/platform/surface/surface_dtx.c b/drivers/platform/surface/surface_dtx.c index 89ca6b50e8129bd13c8e5b4ad5e85ec70eadca78..97ae010069e40ac4c0f7d9afa84c716de7f43293 100644 --- a/drivers/platform/surface/surface_dtx.c +++ b/drivers/platform/surface/surface_dtx.c @@ -1180,7 +1180,7 @@ MODULE_DEVICE_TABLE(acpi, surface_dtx_acpi_match); static struct platform_driver surface_dtx_platform_driver = { .probe = surface_dtx_platform_probe, - .remove_new = surface_dtx_platform_remove, + .remove = surface_dtx_platform_remove, .driver = { .name = "surface_dtx_pltf", .acpi_match_table = surface_dtx_acpi_match, diff --git a/drivers/platform/surface/surface_gpe.c b/drivers/platform/surface/surface_gpe.c index 62fd4004db31a0ad2cfbdb71dbf285f06c84cdbc..b359413903b13c4f8e8b284ef7ae6f6db3f47d72 100644 --- a/drivers/platform/surface/surface_gpe.c +++ b/drivers/platform/surface/surface_gpe.c @@ -278,7 +278,7 @@ static void surface_gpe_remove(struct platform_device *pdev) static struct platform_driver surface_gpe_driver = { .probe = surface_gpe_probe, - .remove_new = surface_gpe_remove, + .remove = surface_gpe_remove, .driver = { .name = "surface_gpe", .pm = &surface_gpe_pm, diff --git a/drivers/platform/surface/surface_hotplug.c b/drivers/platform/surface/surface_hotplug.c index a404f26cfae8d7b3f985e9349c587c7007c4e098..c0d83ed5a208c4076a33b3be7754a68394572da4 100644 --- a/drivers/platform/surface/surface_hotplug.c +++ b/drivers/platform/surface/surface_hotplug.c @@ -259,7 +259,7 @@ MODULE_DEVICE_TABLE(acpi, surface_hotplug_acpi_match); static struct platform_driver surface_hotplug_driver = { .probe = surface_hotplug_probe, - .remove_new = surface_hotplug_remove, + .remove = surface_hotplug_remove, .driver = { .name = "surface_hotplug", .acpi_match_table = surface_hotplug_acpi_match, diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c index 4aa4d66f491af4e0075d25bd35b583881d57718d..e981d45e1c127973059e07203610bfdf3685c9f0 100644 --- a/drivers/platform/x86/amd/hsmp/acpi.c +++ b/drivers/platform/x86/amd/hsmp/acpi.c @@ -236,7 +236,7 @@ static ssize_t hsmp_metric_tbl_acpi_read(struct file *filp, struct kobject *kobj } static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj, - struct bin_attribute *battr, int id) + const struct bin_attribute *battr, int id) { if (hsmp_pdev->proto_ver == HSMP_PROTO_VER6) return battr->attr.mode; @@ -372,7 +372,7 @@ static struct platform_driver amd_hsmp_driver = { module_platform_driver(amd_hsmp_driver); -MODULE_IMPORT_NS(AMD_HSMP); +MODULE_IMPORT_NS("AMD_HSMP"); MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver"); MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c index f29dd93fbf0b495421f0891b81553edd856a336c..227b4ad4a51afbcd747d61192702b6e2a751206f 100644 --- a/drivers/platform/x86/amd/hsmp/hsmp.c +++ b/drivers/platform/x86/amd/hsmp/hsmp.c @@ -206,7 +206,7 @@ int hsmp_send_message(struct hsmp_message *msg) return ret; } -EXPORT_SYMBOL_NS_GPL(hsmp_send_message, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(hsmp_send_message, "AMD_HSMP"); int hsmp_test(u16 sock_ind, u32 value) { @@ -237,7 +237,7 @@ int hsmp_test(u16 sock_ind, u32 value) return ret; } -EXPORT_SYMBOL_NS_GPL(hsmp_test, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(hsmp_test, "AMD_HSMP"); long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { @@ -319,7 +319,7 @@ ssize_t hsmp_metric_tbl_read(struct hsmp_socket *sock, char *buf, size_t size) return size; } -EXPORT_SYMBOL_NS_GPL(hsmp_metric_tbl_read, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(hsmp_metric_tbl_read, "AMD_HSMP"); int hsmp_get_tbl_dram_base(u16 sock_ind) { @@ -353,7 +353,7 @@ int hsmp_get_tbl_dram_base(u16 sock_ind) } return 0; } -EXPORT_SYMBOL_NS_GPL(hsmp_get_tbl_dram_base, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(hsmp_get_tbl_dram_base, "AMD_HSMP"); int hsmp_cache_proto_ver(u16 sock_ind) { @@ -370,7 +370,7 @@ int hsmp_cache_proto_ver(u16 sock_ind) return ret; } -EXPORT_SYMBOL_NS_GPL(hsmp_cache_proto_ver, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(hsmp_cache_proto_ver, "AMD_HSMP"); static const struct file_operations hsmp_fops = { .owner = THIS_MODULE, @@ -389,19 +389,19 @@ int hsmp_misc_register(struct device *dev) return misc_register(&hsmp_pdev.mdev); } -EXPORT_SYMBOL_NS_GPL(hsmp_misc_register, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(hsmp_misc_register, "AMD_HSMP"); void hsmp_misc_deregister(void) { misc_deregister(&hsmp_pdev.mdev); } -EXPORT_SYMBOL_NS_GPL(hsmp_misc_deregister, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(hsmp_misc_deregister, "AMD_HSMP"); struct hsmp_plat_device *get_hsmp_pdev(void) { return &hsmp_pdev; } -EXPORT_SYMBOL_NS_GPL(get_hsmp_pdev, AMD_HSMP); +EXPORT_SYMBOL_NS_GPL(get_hsmp_pdev, "AMD_HSMP"); MODULE_DESCRIPTION("AMD HSMP Common driver"); MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c index f8e74c0392ba0e2b8334f1c3d1e9b95de14fa98e..a61f815c9f8065385fa390cddaf4682035d74ce8 100644 --- a/drivers/platform/x86/amd/hsmp/plat.c +++ b/drivers/platform/x86/amd/hsmp/plat.c @@ -75,7 +75,7 @@ static ssize_t hsmp_metric_tbl_plat_read(struct file *filp, struct kobject *kobj } static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj, - struct bin_attribute *battr, int id) + const struct bin_attribute *battr, int id) { u16 sock_ind; @@ -332,7 +332,7 @@ static void __exit hsmp_plt_exit(void) device_initcall(hsmp_plt_init); module_exit(hsmp_plt_exit); -MODULE_IMPORT_NS(AMD_HSMP); +MODULE_IMPORT_NS("AMD_HSMP"); MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver"); MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index ef04d396f61c7738d5620ea1abe4a317da2efef2..a5933980ade3d6e5a2f46c56c9b2c318e1bc8d28 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -623,6 +623,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = { { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ + { KE_IGNORE, 0xCF, }, /* AC mode */ { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */ { KE_KEY, 0xBD, { KEY_PROG2 } }, /* Lid flip action on ROG xflow laptops */ { KE_END, 0}, diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index ba8b6d028f9fea0a2b1933fb225668adaaad2b9a..8bd187e8b47f8009a382e4ca73e9864a6b4dee7e 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -3696,7 +3696,6 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus) /* Throttle thermal policy ****************************************************/ static int throttle_thermal_policy_write(struct asus_wmi *asus) { - u32 retval; u8 value; int err; @@ -3718,8 +3717,8 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus) value = asus->throttle_thermal_policy_mode; } - err = asus_wmi_set_devstate(asus->throttle_thermal_policy_dev, - value, &retval); + /* Some machines do not return an error code as a result, so we ignore it */ + err = asus_wmi_set_devstate(asus->throttle_thermal_policy_dev, value, NULL); sysfs_notify(&asus->platform_device->dev.kobj, NULL, "throttle_thermal_policy"); @@ -3729,12 +3728,6 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus) return err; } - if (retval != 1) { - pr_warn("Failed to set throttle thermal policy (retval): 0x%x\n", - retval); - return -EIO; - } - /* Must set to disabled if mode is toggled */ if (asus->cpu_fan_curve_available) asus->custom_fan_curves[FAN_CURVE_DEV_CPU].enabled = false; diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 5d2c1f0d1e9fbc2602fb74bbd1082f153645b9bb..e980dd18e5f6caf0ad1b41eca052a72927ab98bf 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -1826,19 +1826,19 @@ int ideapad_laptop_register_notifier(struct notifier_block *nb) { return blocking_notifier_chain_register(&ideapad_laptop_chain_head, nb); } -EXPORT_SYMBOL_NS_GPL(ideapad_laptop_register_notifier, IDEAPAD_LAPTOP); +EXPORT_SYMBOL_NS_GPL(ideapad_laptop_register_notifier, "IDEAPAD_LAPTOP"); int ideapad_laptop_unregister_notifier(struct notifier_block *nb) { return blocking_notifier_chain_unregister(&ideapad_laptop_chain_head, nb); } -EXPORT_SYMBOL_NS_GPL(ideapad_laptop_unregister_notifier, IDEAPAD_LAPTOP); +EXPORT_SYMBOL_NS_GPL(ideapad_laptop_unregister_notifier, "IDEAPAD_LAPTOP"); void ideapad_laptop_call_notifier(unsigned long action, void *data) { blocking_notifier_call_chain(&ideapad_laptop_chain_head, action, data); } -EXPORT_SYMBOL_NS_GPL(ideapad_laptop_call_notifier, IDEAPAD_LAPTOP); +EXPORT_SYMBOL_NS_GPL(ideapad_laptop_call_notifier, "IDEAPAD_LAPTOP"); static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) { diff --git a/drivers/platform/x86/intel/plr_tpmi.c b/drivers/platform/x86/intel/plr_tpmi.c index 69ace6a629bc7959792bd34ba03bb037065b5b24..691d43c3592c27bfe8ec544cc82a0da6b24c487c 100644 --- a/drivers/platform/x86/intel/plr_tpmi.c +++ b/drivers/platform/x86/intel/plr_tpmi.c @@ -348,7 +348,7 @@ static struct auxiliary_driver intel_plr_aux_driver = { }; module_auxiliary_driver(intel_plr_aux_driver); -MODULE_IMPORT_NS(INTEL_TPMI); -MODULE_IMPORT_NS(INTEL_TPMI_POWER_DOMAIN); +MODULE_IMPORT_NS("INTEL_TPMI"); +MODULE_IMPORT_NS("INTEL_TPMI_POWER_DOMAIN"); MODULE_DESCRIPTION("Intel TPMI PLR Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/intel/pmc/core_ssram.c b/drivers/platform/x86/intel/pmc/core_ssram.c index 8504154b649f47de9ec94fefb1a48e2b58548472..50ebfd586d3f786aa05e76c12d5d3142fa068ceb 100644 --- a/drivers/platform/x86/intel/pmc/core_ssram.c +++ b/drivers/platform/x86/intel/pmc/core_ssram.c @@ -324,5 +324,5 @@ release_dev: return ret; } -MODULE_IMPORT_NS(INTEL_VSEC); -MODULE_IMPORT_NS(INTEL_PMT_TELEMETRY); +MODULE_IMPORT_NS("INTEL_VSEC"); +MODULE_IMPORT_NS("INTEL_PMT_TELEMETRY"); diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c index 375695cc0d60cc382bb5ab023a8348e05707b2c9..8ed54b7a333313a0ae4f4b1f56c071f4196e367f 100644 --- a/drivers/platform/x86/intel/pmt/class.c +++ b/drivers/platform/x86/intel/pmt/class.c @@ -33,7 +33,7 @@ bool intel_pmt_is_early_client_hw(struct device *dev) */ return !!(ivdev->quirks & VSEC_QUIRK_EARLY_HW); } -EXPORT_SYMBOL_NS_GPL(intel_pmt_is_early_client_hw, INTEL_PMT); +EXPORT_SYMBOL_NS_GPL(intel_pmt_is_early_client_hw, "INTEL_PMT"); static inline int pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count) @@ -74,7 +74,7 @@ int pmt_telem_read_mmio(struct pci_dev *pdev, struct pmt_callbacks *cb, u32 guid return count; } -EXPORT_SYMBOL_NS_GPL(pmt_telem_read_mmio, INTEL_PMT); +EXPORT_SYMBOL_NS_GPL(pmt_telem_read_mmio, "INTEL_PMT"); /* * sysfs @@ -105,7 +105,7 @@ intel_pmt_read(struct file *filp, struct kobject *kobj, static int intel_pmt_mmap(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, struct vm_area_struct *vma) + const struct bin_attribute *attr, struct vm_area_struct *vma) { struct intel_pmt_entry *entry = container_of(attr, struct intel_pmt_entry, @@ -359,7 +359,7 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa return intel_pmt_dev_register(entry, ns, dev); } -EXPORT_SYMBOL_NS_GPL(intel_pmt_dev_create, INTEL_PMT); +EXPORT_SYMBOL_NS_GPL(intel_pmt_dev_create, "INTEL_PMT"); void intel_pmt_dev_destroy(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns) @@ -375,7 +375,7 @@ void intel_pmt_dev_destroy(struct intel_pmt_entry *entry, device_unregister(dev); xa_erase(ns->xa, entry->devid); } -EXPORT_SYMBOL_NS_GPL(intel_pmt_dev_destroy, INTEL_PMT); +EXPORT_SYMBOL_NS_GPL(intel_pmt_dev_destroy, "INTEL_PMT"); static int __init pmt_class_init(void) { diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c index 9079d5dffc031a6c225ae7ecb94380d00000e3f2..6a9eb3c4b313783035c4b209fd079ad931c8e1d6 100644 --- a/drivers/platform/x86/intel/pmt/crashlog.c +++ b/drivers/platform/x86/intel/pmt/crashlog.c @@ -328,4 +328,4 @@ module_exit(pmt_crashlog_exit); MODULE_AUTHOR("Alexander Duyck "); MODULE_DESCRIPTION("Intel PMT Crashlog driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(INTEL_PMT); +MODULE_IMPORT_NS("INTEL_PMT"); diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c index 0cea617c6c2e255fcd543fd92023dad1b94c2664..ac3a9bdf5601578ed01df3376903ce70caddfb10 100644 --- a/drivers/platform/x86/intel/pmt/telemetry.c +++ b/drivers/platform/x86/intel/pmt/telemetry.c @@ -153,7 +153,7 @@ unsigned long pmt_telem_get_next_endpoint(unsigned long start) return found_idx == start ? 0 : found_idx; } -EXPORT_SYMBOL_NS_GPL(pmt_telem_get_next_endpoint, INTEL_PMT_TELEMETRY); +EXPORT_SYMBOL_NS_GPL(pmt_telem_get_next_endpoint, "INTEL_PMT_TELEMETRY"); struct telem_endpoint *pmt_telem_register_endpoint(int devid) { @@ -172,13 +172,13 @@ struct telem_endpoint *pmt_telem_register_endpoint(int devid) return entry->ep; } -EXPORT_SYMBOL_NS_GPL(pmt_telem_register_endpoint, INTEL_PMT_TELEMETRY); +EXPORT_SYMBOL_NS_GPL(pmt_telem_register_endpoint, "INTEL_PMT_TELEMETRY"); void pmt_telem_unregister_endpoint(struct telem_endpoint *ep) { kref_put(&ep->kref, pmt_telem_ep_release); } -EXPORT_SYMBOL_NS_GPL(pmt_telem_unregister_endpoint, INTEL_PMT_TELEMETRY); +EXPORT_SYMBOL_NS_GPL(pmt_telem_unregister_endpoint, "INTEL_PMT_TELEMETRY"); int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info) { @@ -204,7 +204,7 @@ unlock: return err; } -EXPORT_SYMBOL_NS_GPL(pmt_telem_get_endpoint_info, INTEL_PMT_TELEMETRY); +EXPORT_SYMBOL_NS_GPL(pmt_telem_get_endpoint_info, "INTEL_PMT_TELEMETRY"); int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count) { @@ -224,7 +224,7 @@ int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count) return ep->present ? 0 : -EPIPE; } -EXPORT_SYMBOL_NS_GPL(pmt_telem_read, INTEL_PMT_TELEMETRY); +EXPORT_SYMBOL_NS_GPL(pmt_telem_read, "INTEL_PMT_TELEMETRY"); int pmt_telem_read32(struct telem_endpoint *ep, u32 id, u32 *data, u32 count) { @@ -243,7 +243,7 @@ int pmt_telem_read32(struct telem_endpoint *ep, u32 id, u32 *data, u32 count) return ep->present ? 0 : -EPIPE; } -EXPORT_SYMBOL_NS_GPL(pmt_telem_read32, INTEL_PMT_TELEMETRY); +EXPORT_SYMBOL_NS_GPL(pmt_telem_read32, "INTEL_PMT_TELEMETRY"); struct telem_endpoint * pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev, u32 guid, u16 pos) @@ -268,7 +268,7 @@ pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev, u32 guid, u16 pos) return ERR_PTR(-ENXIO); } -EXPORT_SYMBOL_NS_GPL(pmt_telem_find_and_register_endpoint, INTEL_PMT_TELEMETRY); +EXPORT_SYMBOL_NS_GPL(pmt_telem_find_and_register_endpoint, "INTEL_PMT_TELEMETRY"); static void pmt_telem_remove(struct auxiliary_device *auxdev) { @@ -347,4 +347,4 @@ module_exit(pmt_telem_exit); MODULE_AUTHOR("David E. Box "); MODULE_DESCRIPTION("Intel PMT Telemetry driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(INTEL_PMT); +MODULE_IMPORT_NS("INTEL_PMT"); diff --git a/drivers/platform/x86/intel/sdsi.c b/drivers/platform/x86/intel/sdsi.c index 9d137621f0e6e7a23be0e0bbc6175c51c403169f..33f33b1070fdc949c1373251c3bca4234d9da119 100644 --- a/drivers/platform/x86/intel/sdsi.c +++ b/drivers/platform/x86/intel/sdsi.c @@ -541,7 +541,7 @@ static struct bin_attribute *sdsi_bin_attrs[] = { }; static umode_t -sdsi_battr_is_visible(struct kobject *kobj, struct bin_attribute *attr, int n) +sdsi_battr_is_visible(struct kobject *kobj, const struct bin_attribute *attr, int n) { struct device *dev = kobj_to_dev(kobj); struct sdsi_priv *priv = dev_get_drvdata(dev); diff --git a/drivers/platform/x86/intel/speed_select_if/isst_tpmi.c b/drivers/platform/x86/intel/speed_select_if/isst_tpmi.c index 17972191538a390acaa6d1650cbed3e826219bd9..bcf0a5cbc68d59ddb616835b939900f157a054a0 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_tpmi.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_tpmi.c @@ -67,6 +67,6 @@ static struct auxiliary_driver intel_sst_aux_driver = { module_auxiliary_driver(intel_sst_aux_driver); -MODULE_IMPORT_NS(INTEL_TPMI_SST); +MODULE_IMPORT_NS("INTEL_TPMI_SST"); MODULE_DESCRIPTION("Intel TPMI SST Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c index 4045823071091a1af76d3dfc40481dc1b80e4788..9978cdd1985185d947179bd350aa48edaf03481c 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c @@ -1593,7 +1593,7 @@ unlock_exit: return ret; } -EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_add, INTEL_TPMI_SST); +EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_add, "INTEL_TPMI_SST"); void tpmi_sst_dev_remove(struct auxiliary_device *auxdev) { @@ -1614,7 +1614,7 @@ void tpmi_sst_dev_remove(struct auxiliary_device *auxdev) } mutex_unlock(&isst_tpmi_dev_lock); } -EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_remove, INTEL_TPMI_SST); +EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_remove, "INTEL_TPMI_SST"); void tpmi_sst_dev_suspend(struct auxiliary_device *auxdev) { @@ -1642,7 +1642,7 @@ void tpmi_sst_dev_suspend(struct auxiliary_device *auxdev) power_domain_info->sst_header.pp_offset + SST_PP_CONTROL_OFFSET); } -EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_suspend, INTEL_TPMI_SST); +EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_suspend, "INTEL_TPMI_SST"); void tpmi_sst_dev_resume(struct auxiliary_device *auxdev) { @@ -1669,7 +1669,7 @@ void tpmi_sst_dev_resume(struct auxiliary_device *auxdev) writeq(power_domain_info->saved_pp_control, power_domain_info->sst_base + power_domain_info->sst_header.pp_offset + SST_PP_CONTROL_OFFSET); } -EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_resume, INTEL_TPMI_SST); +EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_resume, "INTEL_TPMI_SST"); #define ISST_TPMI_API_VERSION 0x03 @@ -1709,7 +1709,7 @@ init_done: mutex_unlock(&isst_tpmi_dev_lock); return ret; } -EXPORT_SYMBOL_NS_GPL(tpmi_sst_init, INTEL_TPMI_SST); +EXPORT_SYMBOL_NS_GPL(tpmi_sst_init, "INTEL_TPMI_SST"); void tpmi_sst_exit(void) { @@ -1723,10 +1723,10 @@ void tpmi_sst_exit(void) } mutex_unlock(&isst_tpmi_dev_lock); } -EXPORT_SYMBOL_NS_GPL(tpmi_sst_exit, INTEL_TPMI_SST); +EXPORT_SYMBOL_NS_GPL(tpmi_sst_exit, "INTEL_TPMI_SST"); -MODULE_IMPORT_NS(INTEL_TPMI); -MODULE_IMPORT_NS(INTEL_TPMI_POWER_DOMAIN); +MODULE_IMPORT_NS("INTEL_TPMI"); +MODULE_IMPORT_NS("INTEL_TPMI_POWER_DOMAIN"); MODULE_DESCRIPTION("ISST TPMI interface module"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/intel/tpmi_power_domains.c b/drivers/platform/x86/intel/tpmi_power_domains.c index 0609a8320f7ec14c821b8a824e7c82f20c0a6257..603e7ded06a91bc21ee2c73d1ee0984397a53ac1 100644 --- a/drivers/platform/x86/intel/tpmi_power_domains.c +++ b/drivers/platform/x86/intel/tpmi_power_domains.c @@ -110,7 +110,7 @@ int tpmi_get_linux_cpu_number(int package_id, int domain_id, int punit_core_id) return ret; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_linux_cpu_number, INTEL_TPMI_POWER_DOMAIN); +EXPORT_SYMBOL_NS_GPL(tpmi_get_linux_cpu_number, "INTEL_TPMI_POWER_DOMAIN"); int tpmi_get_punit_core_number(int cpu_no) { @@ -119,7 +119,7 @@ int tpmi_get_punit_core_number(int cpu_no) return per_cpu(tpmi_cpu_info, cpu_no).punit_core_id; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_punit_core_number, INTEL_TPMI_POWER_DOMAIN); +EXPORT_SYMBOL_NS_GPL(tpmi_get_punit_core_number, "INTEL_TPMI_POWER_DOMAIN"); int tpmi_get_power_domain_id(int cpu_no) { @@ -128,7 +128,7 @@ int tpmi_get_power_domain_id(int cpu_no) return per_cpu(tpmi_cpu_info, cpu_no).punit_domain_id; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_power_domain_id, INTEL_TPMI_POWER_DOMAIN); +EXPORT_SYMBOL_NS_GPL(tpmi_get_power_domain_id, "INTEL_TPMI_POWER_DOMAIN"); cpumask_t *tpmi_get_power_domain_mask(int cpu_no) { @@ -149,7 +149,7 @@ cpumask_t *tpmi_get_power_domain_mask(int cpu_no) return mask; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_power_domain_mask, INTEL_TPMI_POWER_DOMAIN); +EXPORT_SYMBOL_NS_GPL(tpmi_get_power_domain_mask, "INTEL_TPMI_POWER_DOMAIN"); static int tpmi_get_logical_id(unsigned int cpu, struct tpmi_cpu_info *info) { diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c index e22b683a7a434c7eddfe608d092a8450f5322689..4e2c6a2d7e6e1f8f9a81e2b85092d92f90866ac0 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c @@ -257,7 +257,7 @@ uncore_unlock: return ret; } -EXPORT_SYMBOL_NS_GPL(uncore_freq_add_entry, INTEL_UNCORE_FREQUENCY); +EXPORT_SYMBOL_NS_GPL(uncore_freq_add_entry, "INTEL_UNCORE_FREQUENCY"); void uncore_freq_remove_die_entry(struct uncore_data *data) { @@ -270,7 +270,7 @@ void uncore_freq_remove_die_entry(struct uncore_data *data) mutex_unlock(&uncore_lock); } -EXPORT_SYMBOL_NS_GPL(uncore_freq_remove_die_entry, INTEL_UNCORE_FREQUENCY); +EXPORT_SYMBOL_NS_GPL(uncore_freq_remove_die_entry, "INTEL_UNCORE_FREQUENCY"); int uncore_freq_common_init(int (*read)(struct uncore_data *data, unsigned int *value, enum uncore_index index), @@ -297,7 +297,7 @@ int uncore_freq_common_init(int (*read)(struct uncore_data *data, unsigned int * return uncore_root_kobj ? 0 : -ENOMEM; } -EXPORT_SYMBOL_NS_GPL(uncore_freq_common_init, INTEL_UNCORE_FREQUENCY); +EXPORT_SYMBOL_NS_GPL(uncore_freq_common_init, "INTEL_UNCORE_FREQUENCY"); void uncore_freq_common_exit(void) { @@ -309,7 +309,7 @@ void uncore_freq_common_exit(void) } mutex_unlock(&uncore_lock); } -EXPORT_SYMBOL_NS_GPL(uncore_freq_common_exit, INTEL_UNCORE_FREQUENCY); +EXPORT_SYMBOL_NS_GPL(uncore_freq_common_exit, "INTEL_UNCORE_FREQUENCY"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c index 0591053813a2833f5b262a1e34f1e20ba67b862e..4aa6c227ec8202b8b85d5b5bcab5984156af5103 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c @@ -629,7 +629,7 @@ static struct auxiliary_driver intel_uncore_aux_driver = { module_auxiliary_driver(intel_uncore_aux_driver); -MODULE_IMPORT_NS(INTEL_TPMI); -MODULE_IMPORT_NS(INTEL_UNCORE_FREQUENCY); +MODULE_IMPORT_NS("INTEL_TPMI"); +MODULE_IMPORT_NS("INTEL_UNCORE_FREQUENCY"); MODULE_DESCRIPTION("Intel TPMI UFS Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c index a450b8a6bcec10c45003f0b3fdc21420a4fbd27e..40bbf8e45fa4bb2e6bbba825897c1d75bb68bdef 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c @@ -316,6 +316,6 @@ static void __exit intel_uncore_exit(void) } module_exit(intel_uncore_exit) -MODULE_IMPORT_NS(INTEL_UNCORE_FREQUENCY); +MODULE_IMPORT_NS("INTEL_UNCORE_FREQUENCY"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Intel Uncore Frequency Limits Driver"); diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c index 9e0f8e38178c2abf84139f488f6515133b656f44..4a85aad2475a73f513e93bf4009ca567fad9a656 100644 --- a/drivers/platform/x86/intel/vsec.c +++ b/drivers/platform/x86/intel/vsec.c @@ -137,7 +137,7 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, return devm_add_action_or_reset(parent, intel_vsec_remove_aux, auxdev); } -EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC); +EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, "INTEL_VSEC"); static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header, struct intel_vsec_platform_info *info) @@ -340,7 +340,7 @@ void intel_vsec_register(struct pci_dev *pdev, intel_vsec_walk_header(pdev, info); } -EXPORT_SYMBOL_NS_GPL(intel_vsec_register, INTEL_VSEC); +EXPORT_SYMBOL_NS_GPL(intel_vsec_register, "INTEL_VSEC"); static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { diff --git a/drivers/platform/x86/intel/vsec_tpmi.c b/drivers/platform/x86/intel/vsec_tpmi.c index c637e32048a38b2a1309d482cf94a9e6e5703a73..5c383a27bbe8d16af4f49b738357e19cb7cfdd78 100644 --- a/drivers/platform/x86/intel/vsec_tpmi.c +++ b/drivers/platform/x86/intel/vsec_tpmi.c @@ -193,7 +193,7 @@ struct intel_tpmi_plat_info *tpmi_get_platform_data(struct auxiliary_device *aux return vsec_dev->priv_data; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_platform_data, INTEL_TPMI); +EXPORT_SYMBOL_NS_GPL(tpmi_get_platform_data, "INTEL_TPMI"); int tpmi_get_resource_count(struct auxiliary_device *auxdev) { @@ -204,7 +204,7 @@ int tpmi_get_resource_count(struct auxiliary_device *auxdev) return 0; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_resource_count, INTEL_TPMI); +EXPORT_SYMBOL_NS_GPL(tpmi_get_resource_count, "INTEL_TPMI"); struct resource *tpmi_get_resource_at_index(struct auxiliary_device *auxdev, int index) { @@ -215,7 +215,7 @@ struct resource *tpmi_get_resource_at_index(struct auxiliary_device *auxdev, int return NULL; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_resource_at_index, INTEL_TPMI); +EXPORT_SYMBOL_NS_GPL(tpmi_get_resource_at_index, "INTEL_TPMI"); /* TPMI Control Interface */ @@ -354,7 +354,7 @@ int tpmi_get_feature_status(struct auxiliary_device *auxdev, return 0; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_feature_status, INTEL_TPMI); +EXPORT_SYMBOL_NS_GPL(tpmi_get_feature_status, "INTEL_TPMI"); struct dentry *tpmi_get_debugfs_dir(struct auxiliary_device *auxdev) { @@ -363,7 +363,7 @@ struct dentry *tpmi_get_debugfs_dir(struct auxiliary_device *auxdev) return tpmi_info->dbgfs_dir; } -EXPORT_SYMBOL_NS_GPL(tpmi_get_debugfs_dir, INTEL_TPMI); +EXPORT_SYMBOL_NS_GPL(tpmi_get_debugfs_dir, "INTEL_TPMI"); static int tpmi_pfs_dbg_show(struct seq_file *s, void *unused) { @@ -852,6 +852,6 @@ static struct auxiliary_driver tpmi_aux_driver = { module_auxiliary_driver(tpmi_aux_driver); -MODULE_IMPORT_NS(INTEL_VSEC); +MODULE_IMPORT_NS("INTEL_VSEC"); MODULE_DESCRIPTION("Intel TPMI enumeration module"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/lenovo-ymc.c b/drivers/platform/x86/lenovo-ymc.c index bd9f95404c7cb0cf901d64cc2da5ce82e2a49ff1..470d53e3c9d299f9a49e9da1f1ffb4c8fd51109e 100644 --- a/drivers/platform/x86/lenovo-ymc.c +++ b/drivers/platform/x86/lenovo-ymc.c @@ -162,4 +162,4 @@ module_wmi_driver(lenovo_ymc_driver); MODULE_AUTHOR("Gergo Koteles "); MODULE_DESCRIPTION("Lenovo Yoga Mode Control driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IDEAPAD_LAPTOP); +MODULE_IMPORT_NS("IDEAPAD_LAPTOP"); diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index 0d3e3ca20b1bfe77c0b1f616d09c609e10a7440b..decde4c9a3d97695e17694472f5b6abceadb8285 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -1653,5 +1653,5 @@ module_init(samsung_init); module_exit(samsung_exit); MODULE_AUTHOR("Greg Kroah-Hartman "); -MODULE_DESCRIPTION("Samsung Backlight driver"); +MODULE_DESCRIPTION("Samsung Laptop driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c index fbb4c90b72c4976809d37d78fc85a15896f63bd7..f18c7e6e75ddc502e25b9e6130ed3b2c2e14e255 100644 --- a/drivers/pmdomain/imx/gpc.c +++ b/drivers/pmdomain/imx/gpc.c @@ -233,7 +233,7 @@ static struct platform_driver imx_pgc_power_domain_driver = { .name = "imx-pgc-pd", }, .probe = imx_pgc_power_domain_probe, - .remove_new = imx_pgc_power_domain_remove, + .remove = imx_pgc_power_domain_remove, .id_table = imx_pgc_power_domain_id, }; builtin_platform_driver(imx_pgc_power_domain_driver) @@ -545,6 +545,6 @@ static struct platform_driver imx_gpc_driver = { .of_match_table = imx_gpc_dt_ids, }, .probe = imx_gpc_probe, - .remove_new = imx_gpc_remove, + .remove = imx_gpc_remove, }; builtin_platform_driver(imx_gpc_driver) diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c index 6e6ecbf2e152f6344082fc8d2c79489b45288bf8..165e6b163d5878d39c163c3975c57975f40e6ba5 100644 --- a/drivers/pmdomain/imx/gpcv2.c +++ b/drivers/pmdomain/imx/gpcv2.c @@ -1439,7 +1439,7 @@ static struct platform_driver imx_pgc_domain_driver = { .pm = &imx_pgc_domain_pm_ops, }, .probe = imx_pgc_domain_probe, - .remove_new = imx_pgc_domain_remove, + .remove = imx_pgc_domain_remove, .id_table = imx_pgc_domain_id, }; builtin_platform_driver(imx_pgc_domain_driver) diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c index ca942d7929c2ba9a93ca82603262e5b89e47e7d3..23db85b7aa9e68a7f3b304fac9b12ad7d5545519 100644 --- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c @@ -889,7 +889,7 @@ MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match); static struct platform_driver imx8m_blk_ctrl_driver = { .probe = imx8m_blk_ctrl_probe, - .remove_new = imx8m_blk_ctrl_remove, + .remove = imx8m_blk_ctrl_remove, .driver = { .name = "imx8m-blk-ctrl", .pm = &imx8m_blk_ctrl_pm_ops, diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c index 77e889165eed3c91a6f765496d1121d30d27f8bd..e3a0f64c144ca9016dc9cc2e05fae1a5229fff0d 100644 --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c @@ -857,7 +857,7 @@ MODULE_DEVICE_TABLE(of, imx8mp_blk_ctrl_of_match); static struct platform_driver imx8mp_blk_ctrl_driver = { .probe = imx8mp_blk_ctrl_probe, - .remove_new = imx8mp_blk_ctrl_remove, + .remove = imx8mp_blk_ctrl_remove, .driver = { .name = "imx8mp-blk-ctrl", .pm = &imx8mp_blk_ctrl_pm_ops, diff --git a/drivers/pmdomain/imx/imx93-blk-ctrl.c b/drivers/pmdomain/imx/imx93-blk-ctrl.c index b10348ac10f06d703b5d50eea6c58efb15695100..0e2ba8ec55d7575cc99213ccf0054f6c380b02a3 100644 --- a/drivers/pmdomain/imx/imx93-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx93-blk-ctrl.c @@ -438,7 +438,7 @@ MODULE_DEVICE_TABLE(of, imx93_blk_ctrl_of_match); static struct platform_driver imx93_blk_ctrl_driver = { .probe = imx93_blk_ctrl_probe, - .remove_new = imx93_blk_ctrl_remove, + .remove = imx93_blk_ctrl_remove, .driver = { .name = "imx93-blk-ctrl", .of_match_table = imx93_blk_ctrl_of_match, diff --git a/drivers/pmdomain/imx/imx93-pd.c b/drivers/pmdomain/imx/imx93-pd.c index 25ab592945bd7b4d45f127e71bc003058de81f4d..d68273330687a8c769cd4bbd597d86ae5c8bb2e5 100644 --- a/drivers/pmdomain/imx/imx93-pd.c +++ b/drivers/pmdomain/imx/imx93-pd.c @@ -162,7 +162,7 @@ static struct platform_driver imx93_power_domain_driver = { .of_match_table = imx93_pd_ids, }, .probe = imx93_pd_probe, - .remove_new = imx93_pd_remove, + .remove = imx93_pd_remove, }; module_platform_driver(imx93_power_domain_driver); diff --git a/drivers/pmdomain/qcom/cpr.c b/drivers/pmdomain/qcom/cpr.c index 26a60a101e42a03919fe4117b45fba3f85315e19..3ee8184e4be36dce52bb5876c3f62618557df18f 100644 --- a/drivers/pmdomain/qcom/cpr.c +++ b/drivers/pmdomain/qcom/cpr.c @@ -1717,7 +1717,7 @@ MODULE_DEVICE_TABLE(of, cpr_match_table); static struct platform_driver cpr_driver = { .probe = cpr_probe, - .remove_new = cpr_remove, + .remove = cpr_remove, .driver = { .name = "qcom-cpr", .of_match_table = cpr_match_table, diff --git a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c index 0b5831e5ba1bfdac6aef88d7a3a7677dec22fbe2..d579220a4500a76413b3859b5916661b20f94484 100644 --- a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c +++ b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c @@ -313,7 +313,7 @@ static struct platform_driver zynqmp_power_domain_driver = { .sync_state = zynqmp_gpd_sync_state, }, .probe = zynqmp_gpd_probe, - .remove_new = zynqmp_gpd_remove, + .remove = zynqmp_gpd_remove, }; module_platform_driver(zynqmp_power_domain_driver); diff --git a/drivers/powercap/idle_inject.c b/drivers/powercap/idle_inject.c index bafc59904ed354f3c14ecbbdef17f34114218577..04c212953ded6ae5bb75fff0e85cc1faa52bbe8e 100644 --- a/drivers/powercap/idle_inject.c +++ b/drivers/powercap/idle_inject.c @@ -179,7 +179,7 @@ void idle_inject_set_duration(struct idle_inject_device *ii_dev, if (!run_duration_us) pr_debug("CPU is forced to 100 percent idle\n"); } -EXPORT_SYMBOL_NS_GPL(idle_inject_set_duration, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_set_duration, "IDLE_INJECT"); /** * idle_inject_get_duration - idle and run duration retrieval helper @@ -194,7 +194,7 @@ void idle_inject_get_duration(struct idle_inject_device *ii_dev, *run_duration_us = READ_ONCE(ii_dev->run_duration_us); *idle_duration_us = READ_ONCE(ii_dev->idle_duration_us); } -EXPORT_SYMBOL_NS_GPL(idle_inject_get_duration, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_get_duration, "IDLE_INJECT"); /** * idle_inject_set_latency - set the maximum latency allowed @@ -206,7 +206,7 @@ void idle_inject_set_latency(struct idle_inject_device *ii_dev, { WRITE_ONCE(ii_dev->latency_us, latency_us); } -EXPORT_SYMBOL_NS_GPL(idle_inject_set_latency, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_set_latency, "IDLE_INJECT"); /** * idle_inject_start - start idle injections @@ -238,7 +238,7 @@ int idle_inject_start(struct idle_inject_device *ii_dev) return 0; } -EXPORT_SYMBOL_NS_GPL(idle_inject_start, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_start, "IDLE_INJECT"); /** * idle_inject_stop - stops idle injections @@ -285,7 +285,7 @@ void idle_inject_stop(struct idle_inject_device *ii_dev) cpu_hotplug_enable(); } -EXPORT_SYMBOL_NS_GPL(idle_inject_stop, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_stop, "IDLE_INJECT"); /** * idle_inject_setup - prepare the current task for idle injection @@ -367,7 +367,7 @@ out_rollback: return NULL; } -EXPORT_SYMBOL_NS_GPL(idle_inject_register_full, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_register_full, "IDLE_INJECT"); /** * idle_inject_register - initialize idle injection on a set of CPUs @@ -384,7 +384,7 @@ struct idle_inject_device *idle_inject_register(struct cpumask *cpumask) { return idle_inject_register_full(cpumask, NULL); } -EXPORT_SYMBOL_NS_GPL(idle_inject_register, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_register, "IDLE_INJECT"); /** * idle_inject_unregister - unregister idle injection control device @@ -405,7 +405,7 @@ void idle_inject_unregister(struct idle_inject_device *ii_dev) kfree(ii_dev); } -EXPORT_SYMBOL_NS_GPL(idle_inject_unregister, IDLE_INJECT); +EXPORT_SYMBOL_NS_GPL(idle_inject_unregister, "IDLE_INJECT"); static struct smp_hotplug_thread idle_inject_threads = { .store = &idle_inject_thread.tsk, diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c index cbe07450de933b869d9fbb4955c46c6b1c3838a0..2b81aabdb0db7cc25f8e4b83305956b4fafce76e 100644 --- a/drivers/powercap/intel_rapl_msr.c +++ b/drivers/powercap/intel_rapl_msr.c @@ -213,7 +213,7 @@ MODULE_DEVICE_TABLE(platform, rapl_msr_ids); static struct platform_driver intel_rapl_msr_driver = { .probe = rapl_msr_probe, - .remove_new = rapl_msr_remove, + .remove = rapl_msr_remove, .id_table = rapl_msr_ids, .driver = { .name = "intel_rapl_msr", diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c index 645fd1dc51a982edd6ac1edebfb598eed7f79384..af2368f4db10a5f5b7cd2aabf6db73fad079f6b4 100644 --- a/drivers/powercap/intel_rapl_tpmi.c +++ b/drivers/powercap/intel_rapl_tpmi.c @@ -347,7 +347,7 @@ static struct auxiliary_driver intel_rapl_tpmi_driver = { module_auxiliary_driver(intel_rapl_tpmi_driver) -MODULE_IMPORT_NS(INTEL_TPMI); +MODULE_IMPORT_NS("INTEL_TPMI"); MODULE_DESCRIPTION("Intel RAPL TPMI Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c index 791fdc9326dd60bc2a1dd8331a2ed7c0058864b2..634c3b2f8c2654f4c6de1a3b0ccd6cf49c529828 100644 --- a/drivers/pps/clients/pps-gpio.c +++ b/drivers/pps/clients/pps-gpio.c @@ -239,7 +239,7 @@ MODULE_DEVICE_TABLE(of, pps_gpio_dt_ids); static struct platform_driver pps_gpio_driver = { .probe = pps_gpio_probe, - .remove_new = pps_gpio_remove, + .remove = pps_gpio_remove, .driver = { .name = PPS_GPIO_NAME, .of_match_table = pps_gpio_dt_ids, diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index c56cd0f63909a21c10803bed0df8fdd259f67b83..77a36e7bddd54e8f45eab317e687f033f57cc5bc 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -150,7 +150,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) if (ppb > ops->max_adj || ppb < -ops->max_adj) return -ERANGE; err = ops->adjfine(ops, tx->freq); - ptp->dialed_frequency = tx->freq; + if (!err) + ptp->dialed_frequency = tx->freq; } else if (tx->modes & ADJ_OFFSET) { if (ops->adjphase) { s32 max_phase_adj = ops->getmaxphase(ops); diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c index b6f1941308b17ac6a65be6ef1269ccc40ca8fc4e..fbb3fa8fc60b2f6571519491620ace7d7a9f8a1a 100644 --- a/drivers/ptp/ptp_clockmatrix.c +++ b/drivers/ptp/ptp_clockmatrix.c @@ -2471,7 +2471,7 @@ static struct platform_driver idtcm_driver = { .name = "8a3400x-phc", }, .probe = idtcm_probe, - .remove_new = idtcm_remove, + .remove = idtcm_remove, }; module_platform_driver(idtcm_driver); diff --git a/drivers/ptp/ptp_dte.c b/drivers/ptp/ptp_dte.c index 449ff90927beb0044d799ccec12455f24f6ef73f..847276c6900836258cc4cae2e704c9200ad01419 100644 --- a/drivers/ptp/ptp_dte.c +++ b/drivers/ptp/ptp_dte.c @@ -327,7 +327,7 @@ static struct platform_driver ptp_dte_driver = { .of_match_table = ptp_dte_of_match, }, .probe = ptp_dte_probe, - .remove_new = ptp_dte_remove, + .remove = ptp_dte_remove, }; module_platform_driver(ptp_dte_driver); diff --git a/drivers/ptp/ptp_fc3.c b/drivers/ptp/ptp_fc3.c index 879b82f03535256ad55f785a61053a9f4be50c8c..cfced36c70bcb2bca4bfd21b9524c32c4999dba9 100644 --- a/drivers/ptp/ptp_fc3.c +++ b/drivers/ptp/ptp_fc3.c @@ -1003,7 +1003,7 @@ static struct platform_driver idtfc3_driver = { .name = "rc38xxx-phc", }, .probe = idtfc3_probe, - .remove_new = idtfc3_remove, + .remove = idtfc3_remove, }; module_platform_driver(idtfc3_driver); diff --git a/drivers/ptp/ptp_idt82p33.c b/drivers/ptp/ptp_idt82p33.c index d5732490ed9d16641e1bd1bcfbe1e04dd96b0f27..b2fd94d4f863129a5fccbb1233ce0c94602de2a5 100644 --- a/drivers/ptp/ptp_idt82p33.c +++ b/drivers/ptp/ptp_idt82p33.c @@ -1461,7 +1461,7 @@ static struct platform_driver idt82p33_driver = { .name = "82p33x1x-phc", }, .probe = idt82p33_probe, - .remove_new = idt82p33_remove, + .remove = idt82p33_remove, }; module_platform_driver(idt82p33_driver); diff --git a/drivers/ptp/ptp_ines.c b/drivers/ptp/ptp_ines.c index 14a23d3a27f2c9f261151fbe7f40b0a302863099..68f1f7fdaa9deb02c640880702ef5395bc0eebb3 100644 --- a/drivers/ptp/ptp_ines.c +++ b/drivers/ptp/ptp_ines.c @@ -782,7 +782,7 @@ MODULE_DEVICE_TABLE(of, ines_ptp_ctrl_of_match); static struct platform_driver ines_ptp_ctrl_driver = { .probe = ines_ptp_ctrl_probe, - .remove_new = ines_ptp_ctrl_remove, + .remove = ines_ptp_ctrl_remove, .driver = { .name = "ines_ptp_ctrl", .of_match_table = ines_ptp_ctrl_of_match, diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c index 879cfc1537ac85c062575f75b6d4a628d809f9cb..4d488c1f1941bf564ed41dbaf13644835a9daf2e 100644 --- a/drivers/ptp/ptp_qoriq.c +++ b/drivers/ptp/ptp_qoriq.c @@ -670,7 +670,7 @@ static struct platform_driver ptp_qoriq_driver = { .of_match_table = match_table, }, .probe = ptp_qoriq_probe, - .remove_new = ptp_qoriq_remove, + .remove = ptp_qoriq_remove, }; module_platform_driver(ptp_qoriq_driver); diff --git a/drivers/ptp/ptp_vmclock.c b/drivers/ptp/ptp_vmclock.c index cdca8a3ad1aa1432015a8a50e50da31ccea8dd50..0a2cfc8ad3c5408a87fd8fedeff274ab895de3dd 100644 --- a/drivers/ptp/ptp_vmclock.c +++ b/drivers/ptp/ptp_vmclock.c @@ -601,7 +601,7 @@ MODULE_DEVICE_TABLE(acpi, vmclock_acpi_ids); static struct platform_driver vmclock_platform_driver = { .probe = vmclock_probe, - .remove_new = vmclock_remove, + .remove = vmclock_remove, .driver = { .name = "vmclock", .acpi_match_table = vmclock_acpi_ids, diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 9c733877e98e47ac6548932cb040e91dd1008f81..675b252d9c8ce74705ef245faae42e2c1330ed15 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -6,7 +6,7 @@ * Copyright (C) 2011-2012 Avionic Design GmbH */ -#define DEFAULT_SYMBOL_NAMESPACE PWM +#define DEFAULT_SYMBOL_NAMESPACE "PWM" #include #include diff --git a/drivers/pwm/pwm-dwc-core.c b/drivers/pwm/pwm-dwc-core.c index c8425493b95d855a7562406501b7c803ef481b22..6dabec93a3c641583c59a65682fa48fa4be7936c 100644 --- a/drivers/pwm/pwm-dwc-core.c +++ b/drivers/pwm/pwm-dwc-core.c @@ -9,7 +9,7 @@ * Author: Raymond Tan */ -#define DEFAULT_SYMBOL_NAMESPACE dwc_pwm +#define DEFAULT_SYMBOL_NAMESPACE "dwc_pwm" #include #include diff --git a/drivers/pwm/pwm-dwc.h b/drivers/pwm/pwm-dwc.h index c6e2df5a61227131c50fc3c6351326217371c3a3..1562594e7f85a853ca30842c579655816476429f 100644 --- a/drivers/pwm/pwm-dwc.h +++ b/drivers/pwm/pwm-dwc.h @@ -9,7 +9,7 @@ * Author: Raymond Tan */ -MODULE_IMPORT_NS(dwc_pwm); +MODULE_IMPORT_NS("dwc_pwm"); #define DWC_TIM_LD_CNT(n) ((n) * 0x14) #define DWC_TIM_LD_CNT2(n) (((n) * 4) + 0xb0) diff --git a/drivers/pwm/pwm-lpss-pci.c b/drivers/pwm/pwm-lpss-pci.c index f7ece2809e6bba49b6b9fa3e43bf9dfb051b8dde..ddc2a4ca90fd6d4cb3e2a19edfed00c3bf52a708 100644 --- a/drivers/pwm/pwm-lpss-pci.c +++ b/drivers/pwm/pwm-lpss-pci.c @@ -70,4 +70,4 @@ module_pci_driver(pwm_lpss_driver_pci); MODULE_DESCRIPTION("PWM PCI driver for Intel LPSS"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PWM_LPSS); +MODULE_IMPORT_NS("PWM_LPSS"); diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c index 5130238a45670c363249993e70b40ec202e52100..653ec9d0c8bf6a1d5236d239142a9efb9783a606 100644 --- a/drivers/pwm/pwm-lpss-platform.c +++ b/drivers/pwm/pwm-lpss-platform.c @@ -78,5 +78,5 @@ module_platform_driver(pwm_lpss_driver_platform); MODULE_DESCRIPTION("PWM platform driver for Intel LPSS"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(PWM_LPSS); +MODULE_IMPORT_NS("PWM_LPSS"); MODULE_ALIAS("platform:pwm-lpss"); diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index 867e2bc8c601c8eb66ee635b16d516c8d26d4b55..3b99feb3bb4918ed4e097b1c03ba012c69b18cf7 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c @@ -19,7 +19,7 @@ #include #include -#define DEFAULT_SYMBOL_NAMESPACE PWM_LPSS +#define DEFAULT_SYMBOL_NAMESPACE "PWM_LPSS" #include "pwm-lpss.h" diff --git a/drivers/reset/amlogic/reset-meson-audio-arb.c b/drivers/reset/amlogic/reset-meson-audio-arb.c index 421ccb40da8c7392ed292badf6286f40293551dc..6ec253976bed07b83ed76d84912e5a4e11fc5eb8 100644 --- a/drivers/reset/amlogic/reset-meson-audio-arb.c +++ b/drivers/reset/amlogic/reset-meson-audio-arb.c @@ -180,7 +180,7 @@ static int meson_audio_arb_probe(struct platform_device *pdev) static struct platform_driver meson_audio_arb_pdrv = { .probe = meson_audio_arb_probe, - .remove_new = meson_audio_arb_remove, + .remove = meson_audio_arb_remove, .driver = { .name = "meson-audio-arb-reset", .of_match_table = meson_audio_arb_of_match, diff --git a/drivers/reset/amlogic/reset-meson-aux.c b/drivers/reset/amlogic/reset-meson-aux.c index dd8453001db9cadd2f555d38356c1477f052668e..61ce515d92a2d1fd0bb7b9a6d52cc7aa788c2ee9 100644 --- a/drivers/reset/amlogic/reset-meson-aux.c +++ b/drivers/reset/amlogic/reset-meson-aux.c @@ -133,4 +133,4 @@ EXPORT_SYMBOL_GPL(devm_meson_rst_aux_register); MODULE_DESCRIPTION("Amlogic Meson Reset Auxiliary driver"); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(MESON_RESET); +MODULE_IMPORT_NS("MESON_RESET"); diff --git a/drivers/reset/amlogic/reset-meson-common.c b/drivers/reset/amlogic/reset-meson-common.c index 38a767c06fc71b6dd8a998958b20592499db3c8a..a90e0ecaaadf078cc922fdc25ca2a516287952ea 100644 --- a/drivers/reset/amlogic/reset-meson-common.c +++ b/drivers/reset/amlogic/reset-meson-common.c @@ -105,7 +105,7 @@ const struct reset_control_ops meson_reset_ops = { .deassert = meson_reset_deassert, .status = meson_reset_status, }; -EXPORT_SYMBOL_NS_GPL(meson_reset_ops, MESON_RESET); +EXPORT_SYMBOL_NS_GPL(meson_reset_ops, "MESON_RESET"); const struct reset_control_ops meson_reset_toggle_ops = { .reset = meson_reset_level_toggle, @@ -113,7 +113,7 @@ const struct reset_control_ops meson_reset_toggle_ops = { .deassert = meson_reset_deassert, .status = meson_reset_status, }; -EXPORT_SYMBOL_NS_GPL(meson_reset_toggle_ops, MESON_RESET); +EXPORT_SYMBOL_NS_GPL(meson_reset_toggle_ops, "MESON_RESET"); int meson_reset_controller_register(struct device *dev, struct regmap *map, const struct meson_reset_param *param) @@ -133,10 +133,10 @@ int meson_reset_controller_register(struct device *dev, struct regmap *map, return devm_reset_controller_register(dev, &data->rcdev); } -EXPORT_SYMBOL_NS_GPL(meson_reset_controller_register, MESON_RESET); +EXPORT_SYMBOL_NS_GPL(meson_reset_controller_register, "MESON_RESET"); MODULE_DESCRIPTION("Amlogic Meson Reset Core function"); MODULE_AUTHOR("Neil Armstrong "); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(MESON_RESET); +MODULE_IMPORT_NS("MESON_RESET"); diff --git a/drivers/reset/amlogic/reset-meson.c b/drivers/reset/amlogic/reset-meson.c index 6ae4ed6b7f8ba35e891b3cc784657fc97386dfa3..84610365a823ca61b4f74955e56bdf77dfededd0 100644 --- a/drivers/reset/amlogic/reset-meson.c +++ b/drivers/reset/amlogic/reset-meson.c @@ -102,4 +102,4 @@ MODULE_DESCRIPTION("Amlogic Meson Reset Controller driver"); MODULE_AUTHOR("Neil Armstrong "); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(MESON_RESET); +MODULE_IMPORT_NS("MESON_RESET"); diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c index 710f9c1676f938e56fa88810425c27b3c1b5bd4b..574e59db83a4fcf30b60cb5f638607a2ec7b0580 100644 --- a/drivers/reset/reset-mpfs.c +++ b/drivers/reset/reset-mpfs.c @@ -212,7 +212,7 @@ int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base) return devm_add_action_or_reset(clk_dev, mpfs_reset_unregister_adev, adev); } -EXPORT_SYMBOL_NS_GPL(mpfs_reset_controller_register, MCHP_CLK_MPFS); +EXPORT_SYMBOL_NS_GPL(mpfs_reset_controller_register, "MCHP_CLK_MPFS"); static const struct auxiliary_device_id mpfs_reset_ids[] = { { @@ -231,4 +231,4 @@ module_auxiliary_driver(mpfs_reset_driver); MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver"); MODULE_AUTHOR("Conor Dooley "); -MODULE_IMPORT_NS(MCHP_CLK_MPFS); +MODULE_IMPORT_NS("MCHP_CLK_MPFS"); diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index 1cd157f4f03b4713ebee95cabe0f21d7c7f13933..12d0535a874bb42fe94ed12f1ed76d68909841fb 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -208,7 +208,7 @@ static struct platform_driver rzg2l_usbphy_ctrl_driver = { .of_match_table = rzg2l_usbphy_ctrl_match_table, }, .probe = rzg2l_usbphy_ctrl_probe, - .remove_new = rzg2l_usbphy_ctrl_remove, + .remove = rzg2l_usbphy_ctrl_remove, }; module_platform_driver(rzg2l_usbphy_ctrl_driver); diff --git a/drivers/reset/reset-ti-sci.c b/drivers/reset/reset-ti-sci.c index d384da0982fa1e053bf79530801a9ca692f1303b..1dc5b766aac1fe12c8ba69f5fc52f8b7e47c270d 100644 --- a/drivers/reset/reset-ti-sci.c +++ b/drivers/reset/reset-ti-sci.c @@ -246,7 +246,7 @@ static void ti_sci_reset_remove(struct platform_device *pdev) static struct platform_driver ti_sci_reset_driver = { .probe = ti_sci_reset_probe, - .remove_new = ti_sci_reset_remove, + .remove = ti_sci_reset_remove, .driver = { .name = "ti-sci-reset", .of_match_table = ti_sci_reset_of_match, diff --git a/drivers/rpmsg/qcom_glink_rpm.c b/drivers/rpmsg/qcom_glink_rpm.c index 357272d7062e361549812cfa86f506d9c8a3269f..e3ba2c63a5fce52e93df1c0f0632439a759f1350 100644 --- a/drivers/rpmsg/qcom_glink_rpm.c +++ b/drivers/rpmsg/qcom_glink_rpm.c @@ -381,7 +381,7 @@ MODULE_DEVICE_TABLE(of, glink_rpm_of_match); static struct platform_driver glink_rpm_driver = { .probe = glink_rpm_probe, - .remove_new = glink_rpm_remove, + .remove = glink_rpm_remove, .driver = { .name = "qcom_glink_rpm", .of_match_table = glink_rpm_of_match, diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 43f601c84b4fcbf969d17e2d2fd829bc920ced99..40d386809d6b78e209861c23d934e1b9fd743606 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1596,7 +1596,7 @@ MODULE_DEVICE_TABLE(of, qcom_smd_of_match); static struct platform_driver qcom_smd_driver = { .probe = qcom_smd_probe, - .remove_new = qcom_smd_remove, + .remove = qcom_smd_remove, .driver = { .name = "qcom-smd", .of_match_table = qcom_smd_of_match, diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 66eb1122248b652acc126787c219efa370c8f88d..a60bcc791a4803b78da3da31b9889b2a214954e1 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -182,6 +182,16 @@ config RTC_DRV_88PM80X This driver can also be built as a module. If so, the module will be called rtc-88pm80x. +config RTC_DRV_88PM886 + tristate "Marvell 88PM886 RTC driver" + depends on MFD_88PM886_PMIC + help + If you say yes here you will get support for the RTC function in the + Marvell 88PM886 chip. + + This driver can also be built as a module. If so, the module + will be called rtc-88pm886. + config RTC_DRV_ABB5ZES3 select REGMAP_I2C tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" @@ -496,6 +506,7 @@ config RTC_DRV_PCF85363 config RTC_DRV_PCF8563 tristate "Philips PCF8563/Epson RTC8564" + select REGMAP_I2C help If you say yes here you get support for the Philips PCF8563 RTC chip. The Epson RTC8564 @@ -2005,6 +2016,16 @@ config RTC_DRV_MA35D1 This driver can also be built as a module, if so, the module will be called "rtc-ma35d1". +config RTC_DRV_RENESAS_RTCA3 + tristate "Renesas RTCA-3 RTC" + depends on ARCH_RENESAS + help + If you say yes here you get support for the Renesas RTCA-3 RTC + available on the Renesas RZ/G3S SoC. + + This driver can also be built as a module, if so, the module + will be called "rtc-rtca3". + comment "HID Sensor RTC drivers" config RTC_DRV_HID_SENSOR_TIME @@ -2070,4 +2091,16 @@ config RTC_DRV_SSD202D This driver can also be built as a module, if so, the module will be called "rtc-ssd20xd". +config RTC_DRV_AMLOGIC_A4 + tristate "Amlogic RTC" + depends on ARCH_MESON || COMPILE_TEST + select REGMAP_MMIO + default y + help + If you say yes here you get support for the RTC block on the + Amlogic A113L2(A4) and A113X2(A5) SoCs. + + This driver can also be built as a module. If so, the module + will be called "rtc-amlogic-a4". + endif # RTC_CLASS diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index f62340ecc5348dafe7ff47514e105af93e7c8bf4..489b4ab07068c758db7ce6dbd5eadfd966963081 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -21,11 +21,13 @@ obj-$(CONFIG_RTC_LIB_KUNIT_TEST) += lib_test.o obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o +obj-$(CONFIG_RTC_DRV_88PM886) += rtc-88pm886.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o obj-$(CONFIG_RTC_DRV_ABEOZ9) += rtc-ab-eoz9.o obj-$(CONFIG_RTC_DRV_ABX80X) += rtc-abx80x.o obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o +obj-$(CONFIG_RTC_DRV_AMLOGIC_A4) += rtc-amlogic-a4.o obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o @@ -158,13 +160,14 @@ obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o obj-$(CONFIG_RTC_DRV_RX8111) += rtc-rx8111.o obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o obj-$(CONFIG_RTC_DRV_RZN1) += rtc-rzn1.o +obj-$(CONFIG_RTC_DRV_RENESAS_RTCA3) += rtc-renesas-rtca3.o obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o obj-$(CONFIG_RTC_DRV_SD2405AL) += rtc-sd2405al.o -obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o +obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index cca650b2e0b94dfe77b13d4fd92447c8d695f9e2..aaf76406cd7d7d2cfd5479fc1fc892fcb5efbb6b 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -904,13 +904,18 @@ void rtc_timer_do_work(struct work_struct *work) struct timerqueue_node *next; ktime_t now; struct rtc_time tm; + int err; struct rtc_device *rtc = container_of(work, struct rtc_device, irqwork); mutex_lock(&rtc->ops_lock); again: - __rtc_read_time(rtc, &tm); + err = __rtc_read_time(rtc, &tm); + if (err) { + mutex_unlock(&rtc->ops_lock); + return; + } now = rtc_tm_to_ktime(tm); while ((next = timerqueue_getnext(&rtc->timerqueue))) { if (next->expires > now) diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c index f40cc06b097973a0116b53887798110cdcb81bed..5c39cf252392de52d86015b75d44193a7f1e2a2c 100644 --- a/drivers/rtc/rtc-88pm80x.c +++ b/drivers/rtc/rtc-88pm80x.c @@ -329,7 +329,7 @@ static struct platform_driver pm80x_rtc_driver = { .pm = &pm80x_rtc_pm_ops, }, .probe = pm80x_rtc_probe, - .remove_new = pm80x_rtc_remove, + .remove = pm80x_rtc_remove, }; module_platform_driver(pm80x_rtc_driver); diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 0f124ed5b3e56b8c63ebd11de2fdf50195250781..814230d6184271fba205d96489b5e73016d8ba15 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -371,7 +371,7 @@ static struct platform_driver pm860x_rtc_driver = { .pm = &pm860x_rtc_pm_ops, }, .probe = pm860x_rtc_probe, - .remove_new = pm860x_rtc_remove, + .remove = pm860x_rtc_remove, }; module_platform_driver(pm860x_rtc_driver); diff --git a/drivers/rtc/rtc-88pm886.c b/drivers/rtc/rtc-88pm886.c new file mode 100644 index 0000000000000000000000000000000000000000..57e9b0a66eed4ecbb053e83f273d157664badc02 --- /dev/null +++ b/drivers/rtc/rtc-88pm886.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include + +#include + +/* + * Time is calculated as the sum of a 32-bit read-only advancing counter and a + * writeable constant offset stored in the chip's spare registers. + */ + +static int pm886_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct regmap *regmap = dev_get_drvdata(dev); + u32 time; + u32 buf; + int ret; + + ret = regmap_bulk_read(regmap, PM886_REG_RTC_SPARE1, &buf, 4); + if (ret) + return ret; + time = buf; + + ret = regmap_bulk_read(regmap, PM886_REG_RTC_CNT1, &buf, 4); + if (ret) + return ret; + time += buf; + + rtc_time64_to_tm(time, tm); + + return 0; +} + +static int pm886_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct regmap *regmap = dev_get_drvdata(dev); + u32 buf; + int ret; + + ret = regmap_bulk_read(regmap, PM886_REG_RTC_CNT1, &buf, 4); + if (ret) + return ret; + + buf = rtc_tm_to_time64(tm) - buf; + + return regmap_bulk_write(regmap, PM886_REG_RTC_SPARE1, &buf, 4); +} + +static const struct rtc_class_ops pm886_rtc_ops = { + .read_time = pm886_rtc_read_time, + .set_time = pm886_rtc_set_time, +}; + +static int pm886_rtc_probe(struct platform_device *pdev) +{ + struct pm886_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct rtc_device *rtc; + int ret; + + platform_set_drvdata(pdev, chip->regmap); + + rtc = devm_rtc_allocate_device(dev); + if (IS_ERR(rtc)) + return dev_err_probe(dev, PTR_ERR(rtc), + "Failed to allocate RTC device\n"); + + rtc->ops = &pm886_rtc_ops; + rtc->range_max = U32_MAX; + + ret = devm_rtc_register_device(rtc); + if (ret) + return dev_err_probe(dev, ret, "Failed to register RTC device\n"); + + return 0; +} + +static const struct platform_device_id pm886_rtc_id_table[] = { + { "88pm886-rtc", }, + { } +}; +MODULE_DEVICE_TABLE(platform, pm886_rtc_id_table); + +static struct platform_driver pm886_rtc_driver = { + .driver = { + .name = "88pm886-rtc", + }, + .probe = pm886_rtc_probe, + .id_table = pm886_rtc_id_table, +}; +module_platform_driver(pm886_rtc_driver); + +MODULE_DESCRIPTION("Marvell 88PM886 RTC driver"); +MODULE_AUTHOR("Karel Balej "); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c index 02f7d0711287723a480fdf7d079ba2ea5e59ce61..d2b60487d4623e529c1e7adcd0d233af8b6c14df 100644 --- a/drivers/rtc/rtc-ab-eoz9.c +++ b/drivers/rtc/rtc-ab-eoz9.c @@ -64,7 +64,7 @@ #define ABEOZ9_BIT_ALARM_MIN GENMASK(6, 0) #define ABEOZ9_REG_ALARM_HOURS 0x12 #define ABEOZ9_BIT_ALARM_HOURS_PM BIT(5) -#define ABEOZ9_BIT_ALARM_HOURS GENMASK(4, 0) +#define ABEOZ9_BIT_ALARM_HOURS GENMASK(5, 0) #define ABEOZ9_REG_ALARM_DAYS 0x13 #define ABEOZ9_BIT_ALARM_DAYS GENMASK(5, 0) #define ABEOZ9_REG_ALARM_WEEKDAYS 0x14 @@ -231,8 +231,6 @@ static int abeoz9_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) alarm->time.tm_sec = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_SEC, regs[0])); alarm->time.tm_min = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_MIN, regs[1])); alarm->time.tm_hour = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_HOURS, regs[2])); - if (FIELD_GET(ABEOZ9_BIT_ALARM_HOURS_PM, regs[2])) - alarm->time.tm_hour += 12; alarm->time.tm_mday = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_DAYS, regs[3])); @@ -396,13 +394,6 @@ static int abeoz9z3_temp_read(struct device *dev, if (ret < 0) return ret; - if ((val & ABEOZ9_REG_CTRL_STATUS_V1F) || - (val & ABEOZ9_REG_CTRL_STATUS_V2F)) { - dev_err(dev, - "thermometer might be disabled due to low voltage\n"); - return -EINVAL; - } - switch (attr) { case hwmon_temp_input: ret = regmap_read(regmap, ABEOZ9_REG_REG_TEMP, &val); diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 75bb2ac9005c26c8737ce87ca89b8235e5d1f52c..2dcda96f4a8ef727514c751322b84d8d2b382b75 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -403,7 +403,7 @@ static struct platform_driver ab8500_rtc_driver = { .name = "ab8500-rtc", }, .probe = ab8500_rtc_probe, - .remove_new = ab8500_rtc_remove, + .remove = ab8500_rtc_remove, .id_table = ab85xx_rtc_ids, }; diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index 1298962402ff47c388ea8fea6c1baf7b1a986d49..3fee27914ba805388bd45e8399c3c06ab44514e7 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -39,7 +39,7 @@ #define ABX8XX_REG_STATUS 0x0f #define ABX8XX_STATUS_AF BIT(2) #define ABX8XX_STATUS_BLF BIT(4) -#define ABX8XX_STATUS_WDT BIT(6) +#define ABX8XX_STATUS_WDT BIT(5) #define ABX8XX_REG_CTRL1 0x10 #define ABX8XX_CTRL_WRITE BIT(0) diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index fa642bba3cee008c9d4fe4abe2cc37aebe2eb41c..33626311fa781b5ce90dcc472f948dc933bbc897 100644 --- a/drivers/rtc/rtc-ac100.c +++ b/drivers/rtc/rtc-ac100.c @@ -628,7 +628,7 @@ MODULE_DEVICE_TABLE(of, ac100_rtc_match); static struct platform_driver ac100_rtc_driver = { .probe = ac100_rtc_probe, - .remove_new = ac100_rtc_remove, + .remove = ac100_rtc_remove, .driver = { .name = "ac100-rtc", .of_match_table = of_match_ptr(ac100_rtc_match), diff --git a/drivers/rtc/rtc-amlogic-a4.c b/drivers/rtc/rtc-amlogic-a4.c new file mode 100644 index 0000000000000000000000000000000000000000..2278b4c98a711feba81798eebbd43944a252b89d --- /dev/null +++ b/drivers/rtc/rtc-amlogic-a4.c @@ -0,0 +1,465 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2024 Amlogic, Inc. All rights reserved + * Author: Yiting Deng + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* rtc oscillator rate */ +#define OSC_32K 32768 +#define OSC_24M 24000000 + +#define RTC_CTRL (0x0 << 2) /* Control RTC */ +#define RTC_ALRM0_EN BIT(0) +#define RTC_OSC_SEL BIT(8) +#define RTC_ENABLE BIT(12) + +#define RTC_COUNTER_REG (0x1 << 2) /* Program RTC counter initial value */ + +#define RTC_ALARM0_REG (0x2 << 2) /* Program RTC alarm0 value */ + +#define RTC_SEC_ADJUST_REG (0x6 << 2) /* Control second-based timing adjustment */ +#define RTC_MATCH_COUNTER GENMASK(18, 0) +#define RTC_SEC_ADJUST_CTRL GENMASK(20, 19) +#define RTC_ADJ_VALID BIT(23) + +#define RTC_INT_MASK (0x8 << 2) /* RTC interrupt mask */ +#define RTC_ALRM0_IRQ_MSK BIT(0) + +#define RTC_INT_CLR (0x9 << 2) /* Clear RTC interrupt */ +#define RTC_ALRM0_IRQ_CLR BIT(0) + +#define RTC_OSCIN_CTRL0 (0xa << 2) /* Control RTC clk from 24M */ +#define RTC_OSCIN_CTRL1 (0xb << 2) /* Control RTC clk from 24M */ +#define RTC_OSCIN_IN_EN BIT(31) +#define RTC_OSCIN_OUT_CFG GENMASK(29, 28) +#define RTC_OSCIN_OUT_N0M0 GENMASK(11, 0) +#define RTC_OSCIN_OUT_N1M1 GENMASK(23, 12) + +#define RTC_INT_STATUS (0xc << 2) /* RTC interrupt status */ +#define RTC_ALRM0_IRQ_STATUS BIT(0) + +#define RTC_REAL_TIME (0xd << 2) /* RTC time value */ + +#define RTC_OSCIN_OUT_32K_N0 0x2dc +#define RTC_OSCIN_OUT_32K_N1 0x2db +#define RTC_OSCIN_OUT_32K_M0 0x1 +#define RTC_OSCIN_OUT_32K_M1 0x2 + +#define RTC_SWALLOW_SECOND 0x2 +#define RTC_INSERT_SECOND 0x3 + +struct aml_rtc_config { + bool gray_stored; +}; + +struct aml_rtc_data { + struct regmap *map; + struct rtc_device *rtc_dev; + int irq; + struct clk *rtc_clk; + struct clk *sys_clk; + int rtc_enabled; + const struct aml_rtc_config *config; +}; + +static const struct regmap_config aml_rtc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = RTC_REAL_TIME, +}; + +static inline u32 gray_to_binary(u32 gray) +{ + u32 bcd = gray; + int size = sizeof(bcd) * 8; + int i; + + for (i = 0; (1 << i) < size; i++) + bcd ^= bcd >> (1 << i); + + return bcd; +} + +static inline u32 binary_to_gray(u32 bcd) +{ + return bcd ^ (bcd >> 1); +} + +static int aml_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + u32 time_sec; + + /* if RTC disabled, read time failed */ + if (!rtc->rtc_enabled) + return -EINVAL; + + regmap_read(rtc->map, RTC_REAL_TIME, &time_sec); + if (rtc->config->gray_stored) + time_sec = gray_to_binary(time_sec); + rtc_time64_to_tm(time_sec, tm); + dev_dbg(dev, "%s: read time = %us\n", __func__, time_sec); + + return 0; +} + +static int aml_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + u32 time_sec; + + /* if RTC disabled, first enable it */ + if (!rtc->rtc_enabled) { + regmap_write_bits(rtc->map, RTC_CTRL, RTC_ENABLE, RTC_ENABLE); + usleep_range(100, 200); + rtc->rtc_enabled = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ENABLE); + if (!rtc->rtc_enabled) + return -EINVAL; + } + + time_sec = rtc_tm_to_time64(tm); + if (rtc->config->gray_stored) + time_sec = binary_to_gray(time_sec); + regmap_write(rtc->map, RTC_COUNTER_REG, time_sec); + dev_dbg(dev, "%s: set time = %us\n", __func__, time_sec); + + return 0; +} + +static int aml_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + time64_t alarm_sec; + + /* if RTC disabled, set alarm failed */ + if (!rtc->rtc_enabled) + return -EINVAL; + + regmap_update_bits(rtc->map, RTC_CTRL, + RTC_ALRM0_EN, RTC_ALRM0_EN); + regmap_update_bits(rtc->map, RTC_INT_MASK, + RTC_ALRM0_IRQ_MSK, 0); + + alarm_sec = rtc_tm_to_time64(&alarm->time); + if (rtc->config->gray_stored) + alarm_sec = binary_to_gray(alarm_sec); + regmap_write(rtc->map, RTC_ALARM0_REG, alarm_sec); + + dev_dbg(dev, "%s: alarm->enabled=%d alarm_set=%llds\n", __func__, + alarm->enabled, alarm_sec); + + return 0; +} + +static int aml_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + u32 alarm_sec; + int alarm_enable; + int alarm_mask; + + /* if RTC disabled, read alarm failed */ + if (!rtc->rtc_enabled) + return -EINVAL; + + regmap_read(rtc->map, RTC_ALARM0_REG, &alarm_sec); + if (rtc->config->gray_stored) + alarm_sec = gray_to_binary(alarm_sec); + rtc_time64_to_tm(alarm_sec, &alarm->time); + + alarm_enable = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ALRM0_EN); + alarm_mask = regmap_test_bits(rtc->map, RTC_INT_MASK, RTC_ALRM0_IRQ_MSK); + alarm->enabled = (alarm_enable && !alarm_mask) ? 1 : 0; + dev_dbg(dev, "%s: alarm->enabled=%d alarm=%us\n", __func__, + alarm->enabled, alarm_sec); + + return 0; +} + +static int aml_rtc_read_offset(struct device *dev, long *offset) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + u32 reg_val; + long val; + int sign, match_counter, enable; + + /* if RTC disabled, read offset failed */ + if (!rtc->rtc_enabled) + return -EINVAL; + + regmap_read(rtc->map, RTC_SEC_ADJUST_REG, ®_val); + enable = FIELD_GET(RTC_ADJ_VALID, reg_val); + if (!enable) { + val = 0; + } else { + sign = FIELD_GET(RTC_SEC_ADJUST_CTRL, reg_val); + match_counter = FIELD_GET(RTC_MATCH_COUNTER, reg_val); + val = 1000000000 / (match_counter + 1); + if (sign == RTC_SWALLOW_SECOND) + val = -val; + } + *offset = val; + + return 0; +} + +static int aml_rtc_set_offset(struct device *dev, long offset) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + int sign = 0; + int match_counter = 0; + int enable = 0; + u32 reg_val; + + /* if RTC disabled, set offset failed */ + if (!rtc->rtc_enabled) + return -EINVAL; + + if (offset) { + enable = 1; + sign = offset < 0 ? RTC_SWALLOW_SECOND : RTC_INSERT_SECOND; + match_counter = 1000000000 / abs(offset) - 1; + if (match_counter < 0 || match_counter > RTC_MATCH_COUNTER) + return -EINVAL; + } + + reg_val = FIELD_PREP(RTC_ADJ_VALID, enable) | + FIELD_PREP(RTC_SEC_ADJUST_CTRL, sign) | + FIELD_PREP(RTC_MATCH_COUNTER, match_counter); + regmap_write(rtc->map, RTC_SEC_ADJUST_REG, reg_val); + + return 0; +} + +static int aml_rtc_alarm_enable(struct device *dev, unsigned int enabled) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + + if (enabled) { + regmap_update_bits(rtc->map, RTC_CTRL, + RTC_ALRM0_EN, RTC_ALRM0_EN); + regmap_update_bits(rtc->map, RTC_INT_MASK, + RTC_ALRM0_IRQ_MSK, 0); + } else { + regmap_update_bits(rtc->map, RTC_INT_MASK, + RTC_ALRM0_IRQ_MSK, RTC_ALRM0_IRQ_MSK); + regmap_update_bits(rtc->map, RTC_CTRL, + RTC_ALRM0_EN, 0); + } + + return 0; +} + +static const struct rtc_class_ops aml_rtc_ops = { + .read_time = aml_rtc_read_time, + .set_time = aml_rtc_set_time, + .read_alarm = aml_rtc_read_alarm, + .set_alarm = aml_rtc_set_alarm, + .alarm_irq_enable = aml_rtc_alarm_enable, + .read_offset = aml_rtc_read_offset, + .set_offset = aml_rtc_set_offset, +}; + +static irqreturn_t aml_rtc_handler(int irq, void *data) +{ + struct aml_rtc_data *rtc = (struct aml_rtc_data *)data; + + regmap_write(rtc->map, RTC_ALARM0_REG, 0); + regmap_write(rtc->map, RTC_INT_CLR, RTC_ALRM0_IRQ_STATUS); + + rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); + + return IRQ_HANDLED; +} + +static void aml_rtc_init(struct aml_rtc_data *rtc) +{ + u32 reg_val = 0; + + rtc->rtc_enabled = regmap_test_bits(rtc->map, RTC_CTRL, RTC_ENABLE); + if (!rtc->rtc_enabled) { + if (clk_get_rate(rtc->rtc_clk) == OSC_24M) { + /* select 24M oscillator */ + regmap_write_bits(rtc->map, RTC_CTRL, RTC_OSC_SEL, RTC_OSC_SEL); + + /* + * Set RTC oscillator to freq_out to freq_in/((N0*M0+N1*M1)/(M0+M1)) + * Enable clock_in gate of oscillator 24MHz + * Set N0 to 733, N1 to 732 + */ + reg_val = FIELD_PREP(RTC_OSCIN_IN_EN, 1) + | FIELD_PREP(RTC_OSCIN_OUT_CFG, 1) + | FIELD_PREP(RTC_OSCIN_OUT_N0M0, RTC_OSCIN_OUT_32K_N0) + | FIELD_PREP(RTC_OSCIN_OUT_N1M1, RTC_OSCIN_OUT_32K_N1); + regmap_write_bits(rtc->map, RTC_OSCIN_CTRL0, RTC_OSCIN_IN_EN + | RTC_OSCIN_OUT_CFG | RTC_OSCIN_OUT_N0M0 + | RTC_OSCIN_OUT_N1M1, reg_val); + + /* Set M0 to 2, M1 to 3, so freq_out = 32768 Hz*/ + reg_val = FIELD_PREP(RTC_OSCIN_OUT_N0M0, RTC_OSCIN_OUT_32K_M0) + | FIELD_PREP(RTC_OSCIN_OUT_N1M1, RTC_OSCIN_OUT_32K_M1); + regmap_write_bits(rtc->map, RTC_OSCIN_CTRL1, RTC_OSCIN_OUT_N0M0 + | RTC_OSCIN_OUT_N1M1, reg_val); + } else { + /* select 32K oscillator */ + regmap_write_bits(rtc->map, RTC_CTRL, RTC_OSC_SEL, 0); + } + } + regmap_write_bits(rtc->map, RTC_INT_MASK, + RTC_ALRM0_IRQ_MSK, RTC_ALRM0_IRQ_MSK); + regmap_write_bits(rtc->map, RTC_CTRL, RTC_ALRM0_EN, 0); +} + +static int aml_rtc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct aml_rtc_data *rtc; + void __iomem *base; + int ret = 0; + + rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + rtc->config = of_device_get_match_data(dev); + if (!rtc->config) + return -ENODEV; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(dev, PTR_ERR(base), "resource ioremap failed\n"); + + rtc->map = devm_regmap_init_mmio(dev, base, &aml_rtc_regmap_config); + if (IS_ERR(rtc->map)) + return dev_err_probe(dev, PTR_ERR(rtc->map), "regmap init failed\n"); + + rtc->irq = platform_get_irq(pdev, 0); + if (rtc->irq < 0) + return rtc->irq; + + rtc->rtc_clk = devm_clk_get(dev, "osc"); + if (IS_ERR(rtc->rtc_clk)) + return dev_err_probe(dev, PTR_ERR(rtc->rtc_clk), + "failed to find rtc clock\n"); + if (clk_get_rate(rtc->rtc_clk) != OSC_32K && clk_get_rate(rtc->rtc_clk) != OSC_24M) + return dev_err_probe(dev, -EINVAL, "Invalid clock configuration\n"); + + rtc->sys_clk = devm_clk_get_enabled(dev, "sys"); + if (IS_ERR(rtc->sys_clk)) + return dev_err_probe(dev, PTR_ERR(rtc->sys_clk), + "failed to get_enable rtc sys clk\n"); + aml_rtc_init(rtc); + + device_init_wakeup(dev, 1); + platform_set_drvdata(pdev, rtc); + + rtc->rtc_dev = devm_rtc_allocate_device(dev); + if (IS_ERR(rtc->rtc_dev)) { + ret = PTR_ERR(rtc->rtc_dev); + goto err_clk; + } + + ret = devm_request_irq(dev, rtc->irq, aml_rtc_handler, + IRQF_ONESHOT, "aml-rtc alarm", rtc); + if (ret) { + dev_err_probe(dev, ret, "IRQ%d request failed, ret = %d\n", + rtc->irq, ret); + goto err_clk; + } + + rtc->rtc_dev->ops = &aml_rtc_ops; + rtc->rtc_dev->range_min = 0; + rtc->rtc_dev->range_max = U32_MAX; + + ret = devm_rtc_register_device(rtc->rtc_dev); + if (ret) { + dev_err_probe(&pdev->dev, ret, "Failed to register RTC device: %d\n", ret); + goto err_clk; + } + + return 0; +err_clk: + clk_disable_unprepare(rtc->sys_clk); + device_init_wakeup(dev, 0); + + return ret; +} + +#ifdef CONFIG_PM_SLEEP +static int aml_rtc_suspend(struct device *dev) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(rtc->irq); + + return 0; +} + +static int aml_rtc_resume(struct device *dev) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(rtc->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(aml_rtc_pm_ops, + aml_rtc_suspend, aml_rtc_resume); + +static void aml_rtc_remove(struct platform_device *pdev) +{ + struct aml_rtc_data *rtc = dev_get_drvdata(&pdev->dev); + + clk_disable_unprepare(rtc->sys_clk); + device_init_wakeup(&pdev->dev, 0); +} + +static const struct aml_rtc_config a5_rtc_config = { +}; + +static const struct aml_rtc_config a4_rtc_config = { + .gray_stored = true, +}; + +static const struct of_device_id aml_rtc_device_id[] = { + { + .compatible = "amlogic,a4-rtc", + .data = &a4_rtc_config, + }, + { + .compatible = "amlogic,a5-rtc", + .data = &a5_rtc_config, + }, + { } +}; +MODULE_DEVICE_TABLE(of, aml_rtc_device_id); + +static struct platform_driver aml_rtc_driver = { + .probe = aml_rtc_probe, + .remove = aml_rtc_remove, + .driver = { + .name = "aml-rtc", + .pm = &aml_rtc_pm_ops, + .of_match_table = aml_rtc_device_id, + }, +}; + +module_platform_driver(aml_rtc_driver); +MODULE_DESCRIPTION("Amlogic RTC driver"); +MODULE_AUTHOR("Yiting Deng "); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-asm9260.c b/drivers/rtc/rtc-asm9260.c index a83b47e0d8f5328e3231d81bbe58131413ab304d..705470ae84280f8ba3b7ed5c06a778857799e8a1 100644 --- a/drivers/rtc/rtc-asm9260.c +++ b/drivers/rtc/rtc-asm9260.c @@ -325,7 +325,7 @@ MODULE_DEVICE_TABLE(of, asm9260_dt_ids); static struct platform_driver asm9260_rtc_driver = { .probe = asm9260_rtc_probe, - .remove_new = asm9260_rtc_remove, + .remove = asm9260_rtc_remove, .driver = { .name = "asm9260-rtc", .of_match_table = asm9260_dt_ids, diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index c16fe711a0d94f8abfe301f0b5d74901d182bed0..9b3898b8de7cf79cb0ec3e523f851b292b679290 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -640,7 +640,7 @@ static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume); * triggering a section mismatch warning. */ static struct platform_driver at91_rtc_driver __refdata = { - .remove_new = __exit_p(at91_rtc_remove), + .remove = __exit_p(at91_rtc_remove), .shutdown = at91_rtc_shutdown, .driver = { .name = "at91_rtc", diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 993c0878fb66063cc72522046a5d09913dd6651f..15b21da2788f63e48876033d1e57d33da629c5b8 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -530,7 +530,7 @@ MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids); static struct platform_driver at91_rtc_driver = { .probe = at91_rtc_probe, - .remove_new = at91_rtc_remove, + .remove = at91_rtc_remove, .shutdown = at91_rtc_shutdown, .driver = { .name = "rtc-at91sam9", diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c index 1a65a4e0dc00350bcf86812d46f811fbc912956f..fb47c32ab5ff4f89fc1512bf1a9f8278f84dc958 100644 --- a/drivers/rtc/rtc-brcmstb-waketimer.c +++ b/drivers/rtc/rtc-brcmstb-waketimer.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -417,7 +416,7 @@ static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = { static struct platform_driver brcmstb_waketmr_driver = { .probe = brcmstb_waketmr_probe, - .remove_new = brcmstb_waketmr_remove, + .remove = brcmstb_waketmr_remove, .driver = { .name = "brcmstb-waketimer", .pm = &brcmstb_waketmr_pm_ops, diff --git a/drivers/rtc/rtc-cadence.c b/drivers/rtc/rtc-cadence.c index 4ca60b51983650f32c2edc4fb7ded99a7b51400a..bf2a9a1fdea7443b38e61be046ff8daf1f23303e 100644 --- a/drivers/rtc/rtc-cadence.c +++ b/drivers/rtc/rtc-cadence.c @@ -402,7 +402,7 @@ static struct platform_driver cdns_rtc_driver = { .pm = &cdns_rtc_pm_ops, }, .probe = cdns_rtc_probe, - .remove_new = cdns_rtc_remove, + .remove = cdns_rtc_remove, }; module_platform_driver(cdns_rtc_driver); diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 35dca2accbb8df737f0a15ba17d6e8a4b6dcd2dd..78f2ce12c75a77172c50956f32572e22078079fa 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -645,18 +645,17 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val, unsigned char *buf = val; off += NVRAM_OFFSET; - spin_lock_irq(&rtc_lock); - for (; count; count--, off++) { + for (; count; count--, off++, buf++) { + guard(spinlock_irq)(&rtc_lock); if (off < 128) - *buf++ = CMOS_READ(off); + *buf = CMOS_READ(off); else if (can_bank2) - *buf++ = cmos_read_bank2(off); + *buf = cmos_read_bank2(off); else - break; + return -EIO; } - spin_unlock_irq(&rtc_lock); - return count ? -EIO : 0; + return 0; } static int cmos_nvram_write(void *priv, unsigned int off, void *val, @@ -671,23 +670,23 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val, * NVRAM to update, updating checksums is also part of its job. */ off += NVRAM_OFFSET; - spin_lock_irq(&rtc_lock); - for (; count; count--, off++) { + for (; count; count--, off++, buf++) { /* don't trash RTC registers */ if (off == cmos->day_alrm || off == cmos->mon_alrm || off == cmos->century) - buf++; - else if (off < 128) - CMOS_WRITE(*buf++, off); + continue; + + guard(spinlock_irq)(&rtc_lock); + if (off < 128) + CMOS_WRITE(*buf, off); else if (can_bank2) - cmos_write_bank2(*buf++, off); + cmos_write_bank2(*buf, off); else - break; + return -EIO; } - spin_unlock_irq(&rtc_lock); - return count ? -EIO : 0; + return 0; } /*----------------------------------------------------------------*/ @@ -1528,7 +1527,7 @@ static void cmos_platform_shutdown(struct platform_device *pdev) MODULE_ALIAS("platform:rtc_cmos"); static struct platform_driver cmos_platform_driver = { - .remove_new = cmos_platform_remove, + .remove = cmos_platform_remove, .shutdown = cmos_platform_shutdown, .driver = { .name = driver_name, diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c index f57462c7b2c64f74a05c6d5644fd43e7d4a0c7bf..60a48c3ba3ca50211a39aa5c86018bf557aadcd8 100644 --- a/drivers/rtc/rtc-cros-ec.c +++ b/drivers/rtc/rtc-cros-ec.c @@ -401,7 +401,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_rtc_id); static struct platform_driver cros_ec_rtc_driver = { .probe = cros_ec_rtc_probe, - .remove_new = cros_ec_rtc_remove, + .remove = cros_ec_rtc_remove, .driver = { .name = DRV_NAME, .pm = &cros_ec_rtc_pm_ops, diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 04dbf35cf3b706e2ad8776a2347cfe4a964fcc12..38e25f63597ab7ca26aefa1a7d8bcb39272150c9 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -1354,7 +1354,7 @@ static struct platform_driver ds1685_rtc_driver = { .name = "rtc-ds1685", }, .probe = ds1685_rtc_probe, - .remove_new = ds1685_rtc_remove, + .remove = ds1685_rtc_remove, }; module_platform_driver(ds1685_rtc_driver); /* ----------------------------------------------------------------------- */ diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c index 8bfe7378f6533fdbf64725be78a77ad60b69e692..cb4a5d101f537e20a685bb022e6f6516b0df8271 100644 --- a/drivers/rtc/rtc-ftrtc010.c +++ b/drivers/rtc/rtc-ftrtc010.c @@ -214,7 +214,7 @@ static struct platform_driver ftrtc010_rtc_driver = { .of_match_table = ftrtc010_rtc_dt_match, }, .probe = ftrtc010_rtc_probe, - .remove_new = ftrtc010_rtc_remove, + .remove = ftrtc010_rtc_remove, }; module_platform_driver_probe(ftrtc010_rtc_driver, ftrtc010_rtc_probe); diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index b81cea505ee93fdc1eba7c1cfc8108f1dc5acc9e..6228d0b2486e9fb7f24ea27b5d45a7b26d849092 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c @@ -319,11 +319,11 @@ static struct platform_driver hid_time_platform_driver = { .name = KBUILD_MODNAME, }, .probe = hid_time_probe, - .remove_new = hid_time_remove, + .remove = hid_time_remove, }; module_platform_driver(hid_time_platform_driver); MODULE_DESCRIPTION("HID Sensor Time"); MODULE_AUTHOR("Alexander Holler "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(IIO_HID); +MODULE_IMPORT_NS("IIO_HID"); diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 284011c419db9722634d51f50eeb5979b6665ec1..ca4a0af95e8c5a21dd645fa5eba403381be52ea4 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -860,7 +860,7 @@ static struct platform_driver dryice_rtc_driver __refdata = { .name = "imxdi_rtc", .of_match_table = dryice_dt_ids, }, - .remove_new = __exit_p(dryice_rtc_remove), + .remove = __exit_p(dryice_rtc_remove), }; module_platform_driver_probe(dryice_rtc_driver, dryice_rtc_probe); diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 6fa9a68af9d9804180ac9f821c890f7bc68f1533..9b44839a7402c9ab7da634d95152c2520eb8552e 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -21,7 +21,7 @@ #include -/* ISL register offsets */ +/* RTC - Real time clock registers */ #define ISL12022_REG_SC 0x00 #define ISL12022_REG_MN 0x01 #define ISL12022_REG_HR 0x02 @@ -30,21 +30,36 @@ #define ISL12022_REG_YR 0x05 #define ISL12022_REG_DW 0x06 +/* CSR - Control and status registers */ #define ISL12022_REG_SR 0x07 #define ISL12022_REG_INT 0x08 - #define ISL12022_REG_PWR_VBAT 0x0a - #define ISL12022_REG_BETA 0x0d + +/* ALARM - Alarm registers */ +#define ISL12022_REG_SCA0 0x10 +#define ISL12022_REG_MNA0 0x11 +#define ISL12022_REG_HRA0 0x12 +#define ISL12022_REG_DTA0 0x13 +#define ISL12022_REG_MOA0 0x14 +#define ISL12022_REG_DWA0 0x15 +#define ISL12022_ALARM ISL12022_REG_SCA0 +#define ISL12022_ALARM_LEN (ISL12022_REG_DWA0 - ISL12022_REG_SCA0 + 1) + +/* TEMP - Temperature sensor registers */ #define ISL12022_REG_TEMP_L 0x28 /* ISL register bits */ #define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */ +#define ISL12022_SR_ALM (1 << 4) #define ISL12022_SR_LBAT85 (1 << 2) #define ISL12022_SR_LBAT75 (1 << 1) +#define ISL12022_INT_ARST (1 << 7) #define ISL12022_INT_WRTC (1 << 6) +#define ISL12022_INT_IM (1 << 5) +#define ISL12022_INT_FOBATB (1 << 4) #define ISL12022_INT_FO_MASK GENMASK(3, 0) #define ISL12022_INT_FO_OFF 0x0 #define ISL12022_INT_FO_32K 0x1 @@ -52,8 +67,19 @@ #define ISL12022_REG_VB85_MASK GENMASK(5, 3) #define ISL12022_REG_VB75_MASK GENMASK(2, 0) +#define ISL12022_ALARM_ENABLE (1 << 7) /* for all ALARM registers */ + #define ISL12022_BETA_TSE (1 << 7) +static struct i2c_driver isl12022_driver; + +struct isl12022 { + struct rtc_device *rtc; + struct regmap *regmap; + int irq; + bool irq_enabled; +}; + static umode_t isl12022_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel) @@ -116,7 +142,8 @@ static const struct hwmon_chip_info isl12022_hwmon_chip_info = { static void isl12022_hwmon_register(struct device *dev) { - struct regmap *regmap = dev_get_drvdata(dev); + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; struct device *hwmon; int ret; @@ -143,8 +170,9 @@ static void isl12022_hwmon_register(struct device *dev) */ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct regmap *regmap = dev_get_drvdata(dev); - uint8_t buf[ISL12022_REG_INT + 1]; + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; + u8 buf[ISL12022_REG_INT + 1]; int ret; ret = regmap_bulk_read(regmap, ISL12022_REG_SC, buf, sizeof(buf)); @@ -178,9 +206,10 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm) static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct regmap *regmap = dev_get_drvdata(dev); + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; int ret; - uint8_t buf[ISL12022_REG_DW + 1]; + u8 buf[ISL12022_REG_DW + 1]; dev_dbg(dev, "%s: %ptR\n", __func__, tm); @@ -208,9 +237,198 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm) return regmap_bulk_write(regmap, ISL12022_REG_SC, buf, sizeof(buf)); } +static int isl12022_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct rtc_time *tm = &alarm->time; + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; + u8 buf[ISL12022_ALARM_LEN]; + unsigned int i, yr; + int ret; + + ret = regmap_bulk_read(regmap, ISL12022_ALARM, buf, sizeof(buf)); + if (ret) { + dev_dbg(dev, "%s: reading ALARM registers failed\n", + __func__); + return ret; + } + + /* The alarm doesn't store the year so get it from the rtc section */ + ret = regmap_read(regmap, ISL12022_REG_YR, &yr); + if (ret) { + dev_dbg(dev, "%s: reading YR register failed\n", __func__); + return ret; + } + + dev_dbg(dev, + "%s: sc=%02x, mn=%02x, hr=%02x, dt=%02x, mo=%02x, dw=%02x yr=%u\n", + __func__, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], yr); + + tm->tm_sec = bcd2bin(buf[ISL12022_REG_SCA0 - ISL12022_ALARM] & 0x7F); + tm->tm_min = bcd2bin(buf[ISL12022_REG_MNA0 - ISL12022_ALARM] & 0x7F); + tm->tm_hour = bcd2bin(buf[ISL12022_REG_HRA0 - ISL12022_ALARM] & 0x3F); + tm->tm_mday = bcd2bin(buf[ISL12022_REG_DTA0 - ISL12022_ALARM] & 0x3F); + tm->tm_mon = bcd2bin(buf[ISL12022_REG_MOA0 - ISL12022_ALARM] & 0x1F) - 1; + tm->tm_wday = buf[ISL12022_REG_DWA0 - ISL12022_ALARM] & 0x07; + tm->tm_year = bcd2bin(yr) + 100; + + for (i = 0; i < ISL12022_ALARM_LEN; i++) { + if (buf[i] & ISL12022_ALARM_ENABLE) { + alarm->enabled = 1; + break; + } + } + + dev_dbg(dev, "%s: %ptR\n", __func__, tm); + + return 0; +} + +static int isl12022_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct rtc_time *alarm_tm = &alarm->time; + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; + u8 regs[ISL12022_ALARM_LEN] = { 0, }; + struct rtc_time rtc_tm; + int ret, enable, dw; + + ret = isl12022_rtc_read_time(dev, &rtc_tm); + if (ret) + return ret; + + /* If the alarm time is before the current time disable the alarm */ + if (!alarm->enabled || rtc_tm_sub(alarm_tm, &rtc_tm) <= 0) + enable = 0; + else + enable = ISL12022_ALARM_ENABLE; + + /* + * Set non-matching day of the week to safeguard against early false + * matching while setting all the alarm registers (this rtc lacks a + * general alarm/irq enable/disable bit). + */ + ret = regmap_read(regmap, ISL12022_REG_DW, &dw); + if (ret) { + dev_dbg(dev, "%s: reading DW failed\n", __func__); + return ret; + } + /* ~4 days into the future should be enough to avoid match */ + dw = ((dw + 4) % 7) | ISL12022_ALARM_ENABLE; + ret = regmap_write(regmap, ISL12022_REG_DWA0, dw); + if (ret) { + dev_dbg(dev, "%s: writing DWA0 failed\n", __func__); + return ret; + } + + /* Program the alarm and enable it for each setting */ + regs[ISL12022_REG_SCA0 - ISL12022_ALARM] = bin2bcd(alarm_tm->tm_sec) | enable; + regs[ISL12022_REG_MNA0 - ISL12022_ALARM] = bin2bcd(alarm_tm->tm_min) | enable; + regs[ISL12022_REG_HRA0 - ISL12022_ALARM] = bin2bcd(alarm_tm->tm_hour) | enable; + regs[ISL12022_REG_DTA0 - ISL12022_ALARM] = bin2bcd(alarm_tm->tm_mday) | enable; + regs[ISL12022_REG_MOA0 - ISL12022_ALARM] = bin2bcd(alarm_tm->tm_mon + 1) | enable; + regs[ISL12022_REG_DWA0 - ISL12022_ALARM] = bin2bcd(alarm_tm->tm_wday & 7) | enable; + + /* write ALARM registers */ + ret = regmap_bulk_write(regmap, ISL12022_ALARM, ®s, sizeof(regs)); + if (ret) { + dev_dbg(dev, "%s: writing ALARM registers failed\n", __func__); + return ret; + } + + return 0; +} + +static irqreturn_t isl12022_rtc_interrupt(int irq, void *data) +{ + struct isl12022 *isl12022 = data; + struct rtc_device *rtc = isl12022->rtc; + struct device *dev = &rtc->dev; + struct regmap *regmap = isl12022->regmap; + u32 val = 0; + unsigned long events = 0; + int ret; + + ret = regmap_read(regmap, ISL12022_REG_SR, &val); + if (ret) { + dev_dbg(dev, "%s: reading SR failed\n", __func__); + return IRQ_HANDLED; + } + + if (val & ISL12022_SR_ALM) + events |= RTC_IRQF | RTC_AF; + + if (events & RTC_AF) + dev_dbg(dev, "alarm!\n"); + + if (!events) + return IRQ_NONE; + + rtc_update_irq(rtc, 1, events); + return IRQ_HANDLED; +} + +static int isl12022_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct isl12022 *isl12022 = dev_get_drvdata(dev); + + /* Make sure enabled is 0 or 1 */ + enabled = !!enabled; + + if (isl12022->irq_enabled == enabled) + return 0; + + if (enabled) + enable_irq(isl12022->irq); + else + disable_irq(isl12022->irq); + + isl12022->irq_enabled = enabled; + + return 0; +} + +static int isl12022_setup_irq(struct device *dev, int irq) +{ + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; + unsigned int reg_mask, reg_val; + u8 buf[ISL12022_ALARM_LEN] = { 0, }; + int ret; + + /* Clear and disable all alarm registers */ + ret = regmap_bulk_write(regmap, ISL12022_ALARM, buf, sizeof(buf)); + if (ret) + return ret; + + /* + * Enable automatic reset of ALM bit and enable single event interrupt + * mode. + */ + reg_mask = ISL12022_INT_ARST | ISL12022_INT_IM | ISL12022_INT_FO_MASK; + reg_val = ISL12022_INT_ARST | ISL12022_INT_FO_OFF; + ret = regmap_write_bits(regmap, ISL12022_REG_INT, + reg_mask, reg_val); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, irq, NULL, + isl12022_rtc_interrupt, + IRQF_SHARED | IRQF_ONESHOT, + isl12022_driver.driver.name, + isl12022); + if (ret) + return dev_err_probe(dev, ret, "Unable to request irq %d\n", irq); + + isl12022->irq = irq; + return 0; +} + static int isl12022_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { - struct regmap *regmap = dev_get_drvdata(dev); + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; u32 user, val; int ret; @@ -238,6 +456,9 @@ static const struct rtc_class_ops isl12022_rtc_ops = { .ioctl = isl12022_rtc_ioctl, .read_time = isl12022_rtc_read_time, .set_time = isl12022_rtc_set_time, + .read_alarm = isl12022_rtc_read_alarm, + .set_alarm = isl12022_rtc_set_alarm, + .alarm_irq_enable = isl12022_rtc_alarm_irq_enable, }; static const struct regmap_config regmap_config = { @@ -248,7 +469,8 @@ static const struct regmap_config regmap_config = { static int isl12022_register_clock(struct device *dev) { - struct regmap *regmap = dev_get_drvdata(dev); + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; struct clk_hw *hw; int ret; @@ -288,7 +510,8 @@ static const u32 trip_levels[2][7] = { static void isl12022_set_trip_levels(struct device *dev) { - struct regmap *regmap = dev_get_drvdata(dev); + struct isl12022 *isl12022 = dev_get_drvdata(dev); + struct regmap *regmap = isl12022->regmap; u32 levels[2] = {0, 0}; int ret, i, j, x[2]; u8 val, mask; @@ -325,6 +548,7 @@ static void isl12022_set_trip_levels(struct device *dev) static int isl12022_probe(struct i2c_client *client) { + struct isl12022 *isl12022; struct rtc_device *rtc; struct regmap *regmap; int ret; @@ -332,13 +556,17 @@ static int isl12022_probe(struct i2c_client *client) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; + /* Allocate driver state */ + isl12022 = devm_kzalloc(&client->dev, sizeof(*isl12022), GFP_KERNEL); + if (!isl12022) + return -ENOMEM; + regmap = devm_regmap_init_i2c(client, ®map_config); - if (IS_ERR(regmap)) { - dev_err(&client->dev, "regmap allocation failed\n"); - return PTR_ERR(regmap); - } + if (IS_ERR(regmap)) + return dev_err_probe(&client->dev, PTR_ERR(regmap), "regmap allocation failed\n"); + isl12022->regmap = regmap; - dev_set_drvdata(&client->dev, regmap); + dev_set_drvdata(&client->dev, isl12022); ret = isl12022_register_clock(&client->dev); if (ret) @@ -350,11 +578,20 @@ static int isl12022_probe(struct i2c_client *client) rtc = devm_rtc_allocate_device(&client->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); + isl12022->rtc = rtc; rtc->ops = &isl12022_rtc_ops; rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; rtc->range_max = RTC_TIMESTAMP_END_2099; + if (client->irq > 0) { + ret = isl12022_setup_irq(&client->dev, client->irq); + if (ret) + return ret; + } else { + clear_bit(RTC_FEATURE_ALARM, rtc->features); + } + return devm_rtc_register_device(rtc); } diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c index e8ffc1ab90b02fbf6a383efaa79ea57cee4ae67b..8d713e563d7c0a70dbda435b65ddd4133c9123ab 100644 --- a/drivers/rtc/rtc-loongson.c +++ b/drivers/rtc/rtc-loongson.c @@ -381,7 +381,7 @@ MODULE_DEVICE_TABLE(acpi, loongson_rtc_acpi_match); static struct platform_driver loongson_rtc_driver = { .probe = loongson_rtc_probe, - .remove_new = loongson_rtc_remove, + .remove = loongson_rtc_remove, .driver = { .name = "loongson-rtc", .of_match_table = loongson_rtc_of_match, diff --git a/drivers/rtc/rtc-lpc24xx.c b/drivers/rtc/rtc-lpc24xx.c index df17c48ff086ee7228ce157f8bf54a356e8ad006..2dcdc77ff646c9d5578a8bb125cad9dd1d4cf1bb 100644 --- a/drivers/rtc/rtc-lpc24xx.c +++ b/drivers/rtc/rtc-lpc24xx.c @@ -285,7 +285,7 @@ MODULE_DEVICE_TABLE(of, lpc24xx_rtc_match); static struct platform_driver lpc24xx_rtc_driver = { .probe = lpc24xx_rtc_probe, - .remove_new = lpc24xx_rtc_remove, + .remove = lpc24xx_rtc_remove, .driver = { .name = "lpc24xx-rtc", .of_match_table = lpc24xx_rtc_match, diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 5d30ce8e13ca0368c69b50660ff669f8edad6d59..4e608bc8bbd369fd90bde059d92513428919c0d3 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -71,7 +71,7 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) /* Issue the READ command */ M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); - tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); + tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)) + pdata->yy_offset; /* tm_mon is 0-11 */ tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; tm->tm_mday = bcd2bin(M48T59_READ(M48T59_MDAY)); @@ -82,10 +82,6 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) dev_dbg(dev, "Century bit is enabled\n"); tm->tm_year += 100; /* one century */ } -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - tm->tm_year += 68; -#endif tm->tm_wday = bcd2bin(val & 0x07); tm->tm_hour = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F); @@ -106,12 +102,7 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) struct m48t59_private *m48t59 = dev_get_drvdata(dev); unsigned long flags; u8 val = 0; - int year = tm->tm_year; - -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - year -= 68; -#endif + int year = tm->tm_year - pdata->yy_offset; dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n", year + 1900, tm->tm_mon, tm->tm_mday, @@ -162,11 +153,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) /* Issue the READ command */ M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); - tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - tm->tm_year += 68; -#endif + tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)) + pdata->yy_offset; /* tm_mon is 0-11 */ tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; @@ -197,12 +184,7 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *tm = &alrm->time; u8 mday, hour, min, sec; unsigned long flags; - int year = tm->tm_year; - -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - year -= 68; -#endif + int year = tm->tm_year - pdata->yy_offset; /* If no irq, we don't support ALARM */ if (m48t59->irq == NO_IRQ) diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 35a6021d9ba4c2f940f2027ced9b4e429b1f9720..a8f4b645c09d2422ad04c3ff3196fd20cbb05bf1 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -875,7 +875,7 @@ static struct platform_driver max77686_rtc_driver = { .pm = &max77686_rtc_pm_ops, }, .probe = max77686_rtc_probe, - .remove_new = max77686_rtc_remove, + .remove = max77686_rtc_remove, .id_table = rtc_id, }; diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 763a42f422eb27b3fe171ba4c38243da7d3ff6e4..e7b87130e6248d20eacb1ddf1887705a80b163c9 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -350,7 +350,7 @@ MODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable); static struct platform_driver mc13xxx_rtc_driver = { .id_table = mc13xxx_rtc_idtable, - .remove_new = mc13xxx_rtc_remove, + .remove = mc13xxx_rtc_remove, .driver = { .name = DRIVER_NAME, }, diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c index 651bf3c279c7462151096cf8565a56fffab9052d..dbd2d5835f002c746ff08e3535a1f01adaa67150 100644 --- a/drivers/rtc/rtc-mc146818-lib.c +++ b/drivers/rtc/rtc-mc146818-lib.c @@ -216,7 +216,7 @@ int mc146818_set_time(struct rtc_time *time) unsigned char save_control, save_freq_select; unsigned int yrs; #ifdef CONFIG_MACH_DECSTATION - unsigned int real_yrs, leap_yr; + unsigned int real_yrs; #endif unsigned char century = 0; @@ -232,8 +232,6 @@ int mc146818_set_time(struct rtc_time *time) #ifdef CONFIG_MACH_DECSTATION real_yrs = yrs; - leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) || - !((yrs + 1900) % 400)); yrs = 72; /* @@ -241,7 +239,7 @@ int mc146818_set_time(struct rtc_time *time) * for non-leap years, so that Feb, 29th is handled * correctly. */ - if (!leap_yr && mon < 3) { + if (!is_leap_year(real_yrs + 1900) && mon < 3) { real_yrs--; yrs = 73; } diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 71eafe4fbc72bd0fff7404d537492eac75a0cdc2..6003281316031c2c1d1a63f7bdb05d960c1e741c 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -398,7 +398,7 @@ static struct platform_driver mpc5121_rtc_driver = { .of_match_table = of_match_ptr(mpc5121_rtc_match), }, .probe = mpc5121_rtc_probe, - .remove_new = mpc5121_rtc_remove, + .remove = mpc5121_rtc_remove, }; module_platform_driver(mpc5121_rtc_driver); diff --git a/drivers/rtc/rtc-mpfs.c b/drivers/rtc/rtc-mpfs.c index 5b96a6d39210cff48c09ece297a80ccf5a208922..3892b0f9917fa7bc4f732cfe2c2b2f548ba7429f 100644 --- a/drivers/rtc/rtc-mpfs.c +++ b/drivers/rtc/rtc-mpfs.c @@ -288,7 +288,7 @@ MODULE_DEVICE_TABLE(of, mpfs_rtc_of_match); static struct platform_driver mpfs_rtc_driver = { .probe = mpfs_rtc_probe, - .remove_new = mpfs_rtc_remove, + .remove = mpfs_rtc_remove, .driver = { .name = "mpfs_rtc", .of_match_table = mpfs_rtc_of_match, diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c index 1617063669cc58a4314957a98a9832856229cadc..152699219a2b9e0aa1dff98c72133b63207fc468 100644 --- a/drivers/rtc/rtc-mt6397.c +++ b/drivers/rtc/rtc-mt6397.c @@ -75,6 +75,7 @@ static int __mtk_rtc_read_time(struct mt6397_rtc *rtc, tm->tm_min = data[RTC_OFFSET_MIN]; tm->tm_hour = data[RTC_OFFSET_HOUR]; tm->tm_mday = data[RTC_OFFSET_DOM]; + tm->tm_wday = data[RTC_OFFSET_DOW]; tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_TC_MTH_MASK; tm->tm_year = data[RTC_OFFSET_YEAR]; @@ -86,9 +87,8 @@ exit: static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) { - time64_t time; struct mt6397_rtc *rtc = dev_get_drvdata(dev); - int days, sec, ret; + int sec, ret; do { ret = __mtk_rtc_read_time(rtc, tm, &sec); @@ -96,21 +96,9 @@ static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) goto exit; } while (sec < tm->tm_sec); - /* HW register use 7 bits to store year data, minus - * RTC_MIN_YEAR_OFFSET before write year data to register, and plus - * RTC_MIN_YEAR_OFFSET back after read year from register - */ - tm->tm_year += RTC_MIN_YEAR_OFFSET; - - /* HW register start mon from one, but tm_mon start from zero. */ + /* HW register start mon/wday from one, but tm_mon/tm_wday start from zero. */ tm->tm_mon--; - time = rtc_tm_to_time64(tm); - - /* rtc_tm_to_time64 covert Gregorian date to seconds since - * 01-01-1970 00:00:00, and this date is Thursday. - */ - days = div_s64(time, 86400); - tm->tm_wday = (days + 4) % 7; + tm->tm_wday--; exit: return ret; @@ -122,13 +110,14 @@ static int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm) int ret; u16 data[RTC_OFFSET_COUNT]; - tm->tm_year -= RTC_MIN_YEAR_OFFSET; tm->tm_mon++; + tm->tm_wday++; data[RTC_OFFSET_SEC] = tm->tm_sec; data[RTC_OFFSET_MIN] = tm->tm_min; data[RTC_OFFSET_HOUR] = tm->tm_hour; data[RTC_OFFSET_DOM] = tm->tm_mday; + data[RTC_OFFSET_DOW] = tm->tm_wday; data[RTC_OFFSET_MTH] = tm->tm_mon; data[RTC_OFFSET_YEAR] = tm->tm_year; @@ -178,7 +167,6 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK; tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK; - tm->tm_year += RTC_MIN_YEAR_OFFSET; tm->tm_mon--; return 0; @@ -194,7 +182,6 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) int ret; u16 data[RTC_OFFSET_COUNT]; - tm->tm_year -= RTC_MIN_YEAR_OFFSET; tm->tm_mon++; mutex_lock(&rtc->lock); @@ -302,6 +289,10 @@ static int mtk_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); rtc->rtc_dev->ops = &mtk_rtc_ops; + rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900; + rtc->rtc_dev->range_max = mktime64(2027, 12, 31, 23, 59, 59); + rtc->rtc_dev->start_secs = mktime64(1968, 1, 2, 0, 0, 0); + rtc->rtc_dev->set_start_time = true; return devm_rtc_register_device(rtc->rtc_dev); } diff --git a/drivers/rtc/rtc-mt7622.c b/drivers/rtc/rtc-mt7622.c index 094c649fc137f20929b356bf2209c57fdd842c99..4cf0cbb31a313d48e13b04abf3b441481bf8a59d 100644 --- a/drivers/rtc/rtc-mt7622.c +++ b/drivers/rtc/rtc-mt7622.c @@ -394,7 +394,7 @@ static SIMPLE_DEV_PM_OPS(mtk_rtc_pm_ops, mtk_rtc_suspend, mtk_rtc_resume); static struct platform_driver mtk_rtc_driver = { .probe = mtk_rtc_probe, - .remove_new = mtk_rtc_remove, + .remove = mtk_rtc_remove, .driver = { .name = MTK_RTC_DEV, .of_match_table = mtk_rtc_match, diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index db31da56bfa74d0851f51a08d7b9175dba2468a4..51029c53624418d6c1c78f340b36060fd2660a68 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -308,7 +308,7 @@ MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table); * triggering a section mismatch warning. */ static struct platform_driver mv_rtc_driver __refdata = { - .remove_new = __exit_p(mv_rtc_remove), + .remove = __exit_p(mv_rtc_remove), .driver = { .name = "rtc-mv", .of_match_table = of_match_ptr(rtc_mv_of_match_table), diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c index 6934bce4b29fd56239fee3055ac9dbacfa012c10..13c041bb79f160a1b348cb4a5ba124cc467aa616 100644 --- a/drivers/rtc/rtc-mxc_v2.c +++ b/drivers/rtc/rtc-mxc_v2.c @@ -381,7 +381,7 @@ static struct platform_driver mxc_rtc_driver = { .of_match_table = mxc_ids, }, .probe = mxc_rtc_probe, - .remove_new = mxc_rtc_remove, + .remove = mxc_rtc_remove, }; module_platform_driver(mxc_rtc_driver); diff --git a/drivers/rtc/rtc-nxp-bbnsm.c b/drivers/rtc/rtc-nxp-bbnsm.c index acbfbeb8b0700708464867d3395f890dd77271ed..fa3b0328c7a255ff8a902a58d61a4b0e59eac493 100644 --- a/drivers/rtc/rtc-nxp-bbnsm.c +++ b/drivers/rtc/rtc-nxp-bbnsm.c @@ -197,13 +197,28 @@ static int bbnsm_rtc_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "failed to request irq %d: %d\n", bbnsm->irq, ret); - return ret; + goto err; } bbnsm->rtc->ops = &bbnsm_rtc_ops; bbnsm->rtc->range_max = U32_MAX; - return devm_rtc_register_device(bbnsm->rtc); + ret = devm_rtc_register_device(bbnsm->rtc); + if (ret) + goto err; + + return 0; + +err: + dev_pm_clear_wake_irq(&pdev->dev); + device_init_wakeup(&pdev->dev, false); + return ret; +} + +static void bbnsm_rtc_remove(struct platform_device *pdev) +{ + dev_pm_clear_wake_irq(&pdev->dev); + device_init_wakeup(&pdev->dev, false); } static const struct of_device_id bbnsm_dt_ids[] = { @@ -218,6 +233,7 @@ static struct platform_driver bbnsm_rtc_driver = { .of_match_table = bbnsm_dt_ids, }, .probe = bbnsm_rtc_probe, + .remove = bbnsm_rtc_remove, }; module_platform_driver(bbnsm_rtc_driver); diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index e6b2a9c15b542eeed37a80885ea967e87e3fa30e..c123778e2d9bcc47bde3eb00a0b80adff790a501 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -1014,7 +1014,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev) static struct platform_driver omap_rtc_driver = { .probe = omap_rtc_probe, - .remove_new = omap_rtc_remove, + .remove = omap_rtc_remove, .shutdown = omap_rtc_shutdown, .driver = { .name = "omap_rtc", diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c index 6971e47c6021eea935c2a8a811e03e6ec8b95802..7256a88b490c98bf501e67ef1257c7b3418618ca 100644 --- a/drivers/rtc/rtc-palmas.c +++ b/drivers/rtc/rtc-palmas.c @@ -346,7 +346,7 @@ MODULE_DEVICE_TABLE(of, of_palmas_rtc_match); static struct platform_driver palmas_rtc_driver = { .probe = palmas_rtc_probe, - .remove_new = palmas_rtc_remove, + .remove = palmas_rtc_remove, .driver = { .name = "palmas-rtc", .pm = &palmas_rtc_pm_ops, diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index 23edd11aa40c5529aa1d4b69f06ad9946f3b31ad..c019c4d91c7d77cda82add8810030965e44262f4 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c @@ -273,7 +273,7 @@ static struct platform_driver pcf50633_rtc_driver = { .name = "pcf50633-rtc", }, .probe = pcf50633_rtc_probe, - .remove_new = pcf50633_rtc_remove, + .remove = pcf50633_rtc_remove, }; module_platform_driver(pcf50633_rtc_driver); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 647d52f1f5c5e8a736efa7275a178d1cb0f4785f..5a084d426e58d09cfedf0809695a96a27627c420 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -11,14 +11,15 @@ * https://www.nxp.com/docs/en/data-sheet/PCF8563.pdf */ +#include #include +#include #include -#include -#include -#include #include #include -#include +#include +#include +#include #define PCF8563_REG_ST1 0x00 /* status */ #define PCF8563_REG_ST2 0x01 @@ -77,64 +78,18 @@ struct pcf8563 { */ int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ - struct i2c_client *client; + struct regmap *regmap; #ifdef CONFIG_COMMON_CLK struct clk_hw clkout_hw; #endif }; -static int pcf8563_read_block_data(struct i2c_client *client, unsigned char reg, - unsigned char length, unsigned char *buf) -{ - struct i2c_msg msgs[] = { - {/* setup read ptr */ - .addr = client->addr, - .len = 1, - .buf = ®, - }, - { - .addr = client->addr, - .flags = I2C_M_RD, - .len = length, - .buf = buf - }, - }; - - if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __func__); - return -EIO; - } - - return 0; -} - -static int pcf8563_write_block_data(struct i2c_client *client, - unsigned char reg, unsigned char length, - unsigned char *buf) -{ - int i, err; - - for (i = 0; i < length; i++) { - unsigned char data[2] = { reg + i, buf[i] }; - - err = i2c_master_send(client, data, sizeof(data)); - if (err != sizeof(data)) { - dev_err(&client->dev, - "%s: err=%d addr=%02x, data=%02x\n", - __func__, err, data[0], data[1]); - return -EIO; - } - } - - return 0; -} - -static int pcf8563_set_alarm_mode(struct i2c_client *client, bool on) +static int pcf8563_set_alarm_mode(struct pcf8563 *pcf8563, bool on) { - unsigned char buf; + u32 buf; int err; - err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, &buf); + err = regmap_read(pcf8563->regmap, PCF8563_REG_ST2, &buf); if (err < 0) return err; @@ -145,23 +100,17 @@ static int pcf8563_set_alarm_mode(struct i2c_client *client, bool on) buf &= ~(PCF8563_BIT_AF | PCF8563_BITS_ST2_N); - err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf); - if (err < 0) { - dev_err(&client->dev, "%s: write error\n", __func__); - return -EIO; - } - - return 0; + return regmap_write(pcf8563->regmap, PCF8563_REG_ST2, buf); } -static int pcf8563_get_alarm_mode(struct i2c_client *client, unsigned char *en, +static int pcf8563_get_alarm_mode(struct pcf8563 *pcf8563, unsigned char *en, unsigned char *pen) { - unsigned char buf; + u32 buf; int err; - err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, &buf); - if (err) + err = regmap_read(pcf8563->regmap, PCF8563_REG_ST2, &buf); + if (err < 0) return err; if (en) @@ -174,17 +123,17 @@ static int pcf8563_get_alarm_mode(struct i2c_client *client, unsigned char *en, static irqreturn_t pcf8563_irq(int irq, void *dev_id) { - struct pcf8563 *pcf8563 = i2c_get_clientdata(dev_id); - int err; + struct pcf8563 *pcf8563 = dev_id; char pending; + int err; - err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending); + err = pcf8563_get_alarm_mode(pcf8563, NULL, &pending); if (err) return IRQ_NONE; if (pending) { rtc_update_irq(pcf8563->rtc, 1, RTC_IRQF | RTC_AF); - pcf8563_set_alarm_mode(pcf8563->client, 1); + pcf8563_set_alarm_mode(pcf8563, 1); return IRQ_HANDLED; } @@ -197,22 +146,22 @@ static irqreturn_t pcf8563_irq(int irq, void *dev_id) */ static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct i2c_client *client = to_i2c_client(dev); - struct pcf8563 *pcf8563 = i2c_get_clientdata(client); + struct pcf8563 *pcf8563 = dev_get_drvdata(dev); unsigned char buf[9]; int err; - err = pcf8563_read_block_data(client, PCF8563_REG_ST1, 9, buf); - if (err) + err = regmap_bulk_read(pcf8563->regmap, PCF8563_REG_ST1, buf, + sizeof(buf)); + if (err < 0) return err; if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { - dev_err(&client->dev, + dev_err(dev, "low voltage detected, date/time is not reliable.\n"); return -EINVAL; } - dev_dbg(&client->dev, + dev_dbg(dev, "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " "mday=%02x, wday=%02x, mon=%02x, year=%02x\n", __func__, @@ -220,7 +169,6 @@ static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) buf[4], buf[5], buf[6], buf[7], buf[8]); - tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F); tm->tm_min = bcd2bin(buf[PCF8563_REG_MN] & 0x7F); tm->tm_hour = bcd2bin(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */ @@ -232,7 +180,7 @@ static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ? (tm->tm_year >= 100) : (tm->tm_year < 100); - dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " + dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " "mday=%d, mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, @@ -243,11 +191,10 @@ static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct i2c_client *client = to_i2c_client(dev); - struct pcf8563 *pcf8563 = i2c_get_clientdata(client); + struct pcf8563 *pcf8563 = dev_get_drvdata(dev); unsigned char buf[9]; - dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " + dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, " "mday=%d, mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, @@ -270,22 +217,24 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; - return pcf8563_write_block_data(client, PCF8563_REG_SC, - 9 - PCF8563_REG_SC, buf + PCF8563_REG_SC); + return regmap_bulk_write(pcf8563->regmap, PCF8563_REG_SC, + buf + PCF8563_REG_SC, + sizeof(buf) - PCF8563_REG_SC); } static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { - struct i2c_client *client = to_i2c_client(dev); + struct pcf8563 *pcf8563 = dev_get_drvdata(dev); int ret; switch (cmd) { case RTC_VL_READ: - ret = i2c_smbus_read_byte_data(client, PCF8563_REG_SC); + ret = regmap_test_bits(pcf8563->regmap, PCF8563_REG_SC, + PCF8563_SC_LV); if (ret < 0) return ret; - return put_user(ret & PCF8563_SC_LV ? RTC_VL_DATA_INVALID : 0, + return put_user(ret ? RTC_VL_DATA_INVALID : 0, (unsigned int __user *)arg); default: return -ENOIOCTLCMD; @@ -294,15 +243,16 @@ static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) { - struct i2c_client *client = to_i2c_client(dev); + struct pcf8563 *pcf8563 = dev_get_drvdata(dev); unsigned char buf[4]; int err; - err = pcf8563_read_block_data(client, PCF8563_REG_AMN, 4, buf); - if (err) + err = regmap_bulk_read(pcf8563->regmap, PCF8563_REG_AMN, buf, + sizeof(buf)); + if (err < 0) return err; - dev_dbg(&client->dev, + dev_dbg(dev, "%s: raw data is min=%02x, hr=%02x, mday=%02x, wday=%02x\n", __func__, buf[0], buf[1], buf[2], buf[3]); @@ -312,11 +262,11 @@ static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) tm->time.tm_mday = bcd2bin(buf[2] & 0x3F); tm->time.tm_wday = bcd2bin(buf[3] & 0x7); - err = pcf8563_get_alarm_mode(client, &tm->enabled, &tm->pending); + err = pcf8563_get_alarm_mode(pcf8563, &tm->enabled, &tm->pending); if (err < 0) return err; - dev_dbg(&client->dev, "%s: tm is mins=%d, hours=%d, mday=%d, wday=%d," + dev_dbg(dev, "%s: tm is mins=%d, hours=%d, mday=%d, wday=%d," " enabled=%d, pending=%d\n", __func__, tm->time.tm_min, tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_wday, tm->enabled, tm->pending); @@ -326,7 +276,7 @@ static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) { - struct i2c_client *client = to_i2c_client(dev); + struct pcf8563 *pcf8563 = dev_get_drvdata(dev); unsigned char buf[4]; int err; @@ -335,17 +285,20 @@ static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) buf[2] = bin2bcd(tm->time.tm_mday); buf[3] = tm->time.tm_wday & 0x07; - err = pcf8563_write_block_data(client, PCF8563_REG_AMN, 4, buf); + err = regmap_bulk_write(pcf8563->regmap, PCF8563_REG_SC, buf, + sizeof(buf)); if (err) return err; - return pcf8563_set_alarm_mode(client, !!tm->enabled); + return pcf8563_set_alarm_mode(pcf8563, !!tm->enabled); } static int pcf8563_irq_enable(struct device *dev, unsigned int enabled) { + struct pcf8563 *pcf8563 = dev_get_drvdata(dev); + dev_dbg(dev, "%s: en=%d\n", __func__, enabled); - return pcf8563_set_alarm_mode(to_i2c_client(dev), !!enabled); + return pcf8563_set_alarm_mode(pcf8563, !!enabled); } #ifdef CONFIG_COMMON_CLK @@ -366,10 +319,10 @@ static unsigned long pcf8563_clkout_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct pcf8563 *pcf8563 = clkout_hw_to_pcf8563(hw); - struct i2c_client *client = pcf8563->client; - unsigned char buf; - int ret = pcf8563_read_block_data(client, PCF8563_REG_CLKO, 1, &buf); + u32 buf; + int ret; + ret = regmap_read(pcf8563->regmap, PCF8563_REG_CLKO, &buf); if (ret < 0) return 0; @@ -393,11 +346,10 @@ static int pcf8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct pcf8563 *pcf8563 = clkout_hw_to_pcf8563(hw); - struct i2c_client *client = pcf8563->client; - unsigned char buf; - int ret = pcf8563_read_block_data(client, PCF8563_REG_CLKO, 1, &buf); - int i; + int i, ret; + u32 buf; + ret = regmap_read(pcf8563->regmap, PCF8563_REG_CLKO, &buf); if (ret < 0) return ret; @@ -405,10 +357,10 @@ static int pcf8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate, if (clkout_rates[i] == rate) { buf &= ~PCF8563_REG_CLKO_F_MASK; buf |= i; - ret = pcf8563_write_block_data(client, - PCF8563_REG_CLKO, 1, - &buf); - return ret; + return regmap_update_bits(pcf8563->regmap, + PCF8563_REG_CLKO, + PCF8563_REG_CLKO_F_MASK, + buf); } return -EINVAL; @@ -417,10 +369,10 @@ static int pcf8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate, static int pcf8563_clkout_control(struct clk_hw *hw, bool enable) { struct pcf8563 *pcf8563 = clkout_hw_to_pcf8563(hw); - struct i2c_client *client = pcf8563->client; - unsigned char buf; - int ret = pcf8563_read_block_data(client, PCF8563_REG_CLKO, 1, &buf); + u32 buf; + int ret; + ret = regmap_read(pcf8563->regmap, PCF8563_REG_CLKO, &buf); if (ret < 0) return ret; @@ -429,8 +381,8 @@ static int pcf8563_clkout_control(struct clk_hw *hw, bool enable) else buf &= ~PCF8563_REG_CLKO_FE; - ret = pcf8563_write_block_data(client, PCF8563_REG_CLKO, 1, &buf); - return ret; + return regmap_update_bits(pcf8563->regmap, PCF8563_REG_CLKO, + PCF8563_REG_CLKO_FE, buf); } static int pcf8563_clkout_prepare(struct clk_hw *hw) @@ -446,10 +398,10 @@ static void pcf8563_clkout_unprepare(struct clk_hw *hw) static int pcf8563_clkout_is_prepared(struct clk_hw *hw) { struct pcf8563 *pcf8563 = clkout_hw_to_pcf8563(hw); - struct i2c_client *client = pcf8563->client; - unsigned char buf; - int ret = pcf8563_read_block_data(client, PCF8563_REG_CLKO, 1, &buf); + u32 buf; + int ret; + ret = regmap_read(pcf8563->regmap, PCF8563_REG_CLKO, &buf); if (ret < 0) return ret; @@ -467,16 +419,14 @@ static const struct clk_ops pcf8563_clkout_ops = { static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563) { - struct i2c_client *client = pcf8563->client; - struct device_node *node = client->dev.of_node; - struct clk *clk; + struct device_node *node = pcf8563->rtc->dev.of_node; struct clk_init_data init; + struct clk *clk; int ret; - unsigned char buf; /* disable the clkout output */ - buf = 0; - ret = pcf8563_write_block_data(client, PCF8563_REG_CLKO, 1, &buf); + ret = regmap_clear_bits(pcf8563->regmap, PCF8563_REG_CLKO, + PCF8563_REG_CLKO_FE); if (ret < 0) return ERR_PTR(ret); @@ -491,7 +441,7 @@ static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563) of_property_read_string(node, "clock-output-names", &init.name); /* register the clock */ - clk = devm_clk_register(&client->dev, &pcf8563->clkout_hw); + clk = devm_clk_register(&pcf8563->rtc->dev, &pcf8563->clkout_hw); if (!IS_ERR(clk)) of_clk_add_provider(node, of_clk_src_simple_get, clk); @@ -509,11 +459,16 @@ static const struct rtc_class_ops pcf8563_rtc_ops = { .alarm_irq_enable = pcf8563_irq_enable, }; +static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xF, +}; + static int pcf8563_probe(struct i2c_client *client) { struct pcf8563 *pcf8563; int err; - unsigned char buf; dev_dbg(&client->dev, "%s\n", __func__); @@ -525,20 +480,23 @@ static int pcf8563_probe(struct i2c_client *client) if (!pcf8563) return -ENOMEM; + pcf8563->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(pcf8563->regmap)) + return PTR_ERR(pcf8563->regmap); + i2c_set_clientdata(client, pcf8563); - pcf8563->client = client; + device_set_wakeup_capable(&client->dev, 1); /* Set timer to lowest frequency to save power (ref Haoyu datasheet) */ - buf = PCF8563_TMRC_1_60; - err = pcf8563_write_block_data(client, PCF8563_REG_TMRC, 1, &buf); + err = regmap_set_bits(pcf8563->regmap, PCF8563_REG_TMRC, + PCF8563_TMRC_1_60); if (err < 0) { dev_err(&client->dev, "%s: write error\n", __func__); return err; } /* Clear flags and disable interrupts */ - buf = 0; - err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf); + err = regmap_write(pcf8563->regmap, PCF8563_REG_ST2, 0); if (err < 0) { dev_err(&client->dev, "%s: write error\n", __func__); return err; diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c index 4f85e0c3d75729f2d54ed062a587e516d421278f..bed3c27e665f32d0cc5becbaf2ad489bff9c74c2 100644 --- a/drivers/rtc/rtc-pic32.c +++ b/drivers/rtc/rtc-pic32.c @@ -371,7 +371,7 @@ MODULE_DEVICE_TABLE(of, pic32_rtc_dt_ids); static struct platform_driver pic32_rtc_driver = { .probe = pic32_rtc_probe, - .remove_new = pic32_rtc_remove, + .remove = pic32_rtc_remove, .driver = { .name = "pic32-rtc", .of_match_table = of_match_ptr(pic32_rtc_dt_ids), diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index c32fba550c8e0aba82aa1940465fcf672474536c..2f32187ecc8d3276a451a317ab83446b7b04ecc8 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -537,7 +537,7 @@ static void pm8xxx_remove(struct platform_device *pdev) static struct platform_driver pm8xxx_rtc_driver = { .probe = pm8xxx_rtc_probe, - .remove_new = pm8xxx_remove, + .remove = pm8xxx_remove, .driver = { .name = "rtc-pm8xxx", .of_match_table = pm8xxx_id_table, diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index cdb39fc4cab52c7349f010632f0a88e2713e9c7f..34d8545c8e155a4496a2ef47bfa32109581d8aa3 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -409,7 +409,7 @@ static SIMPLE_DEV_PM_OPS(pxa_rtc_pm_ops, pxa_rtc_suspend, pxa_rtc_resume); * triggering a section mismatch warning. */ static struct platform_driver pxa_rtc_driver __refdata = { - .remove_new = __exit_p(pxa_rtc_remove), + .remove = __exit_p(pxa_rtc_remove), .driver = { .name = "pxa-rtc", .of_match_table = of_match_ptr(pxa_rtc_dt_ids), diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c index 115c46f862f95bfa04d189473a864672df18ddd1..eecb49bab56ad52f9cdd9eeef35c20881019abab 100644 --- a/drivers/rtc/rtc-rc5t583.c +++ b/drivers/rtc/rtc-rc5t583.c @@ -298,7 +298,7 @@ static SIMPLE_DEV_PM_OPS(rc5t583_rtc_pm_ops, rc5t583_rtc_suspend, static struct platform_driver rc5t583_rtc_driver = { .probe = rc5t583_rtc_probe, - .remove_new = rc5t583_rtc_remove, + .remove = rc5t583_rtc_remove, .driver = { .name = "rtc-rc5t583", .pm = &rc5t583_rtc_pm_ops, diff --git a/drivers/rtc/rtc-renesas-rtca3.c b/drivers/rtc/rtc-renesas-rtca3.c new file mode 100644 index 0000000000000000000000000000000000000000..d127933bfc8adc4f98ed96f35da8482c8fa2ac75 --- /dev/null +++ b/drivers/rtc/rtc-renesas-rtca3.c @@ -0,0 +1,900 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * On-Chip RTC Support available on RZ/G3S SoC + * + * Copyright (C) 2024 Renesas Electronics Corp. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Counter registers. */ +#define RTCA3_RSECCNT 0x2 +#define RTCA3_RSECCNT_SEC GENMASK(6, 0) +#define RTCA3_RMINCNT 0x4 +#define RTCA3_RMINCNT_MIN GENMASK(6, 0) +#define RTCA3_RHRCNT 0x6 +#define RTCA3_RHRCNT_HR GENMASK(5, 0) +#define RTCA3_RHRCNT_PM BIT(6) +#define RTCA3_RWKCNT 0x8 +#define RTCA3_RWKCNT_WK GENMASK(2, 0) +#define RTCA3_RDAYCNT 0xa +#define RTCA3_RDAYCNT_DAY GENMASK(5, 0) +#define RTCA3_RMONCNT 0xc +#define RTCA3_RMONCNT_MONTH GENMASK(4, 0) +#define RTCA3_RYRCNT 0xe +#define RTCA3_RYRCNT_YEAR GENMASK(7, 0) + +/* Alarm registers. */ +#define RTCA3_RSECAR 0x10 +#define RTCA3_RSECAR_SEC GENMASK(6, 0) +#define RTCA3_RMINAR 0x12 +#define RTCA3_RMINAR_MIN GENMASK(6, 0) +#define RTCA3_RHRAR 0x14 +#define RTCA3_RHRAR_HR GENMASK(5, 0) +#define RTCA3_RHRAR_PM BIT(6) +#define RTCA3_RWKAR 0x16 +#define RTCA3_RWKAR_DAYW GENMASK(2, 0) +#define RTCA3_RDAYAR 0x18 +#define RTCA3_RDAYAR_DATE GENMASK(5, 0) +#define RTCA3_RMONAR 0x1a +#define RTCA3_RMONAR_MON GENMASK(4, 0) +#define RTCA3_RYRAR 0x1c +#define RTCA3_RYRAR_YR GENMASK(7, 0) +#define RTCA3_RYRAREN 0x1e + +/* Alarm enable bit (for all alarm registers). */ +#define RTCA3_AR_ENB BIT(7) + +/* Control registers. */ +#define RTCA3_RCR1 0x22 +#define RTCA3_RCR1_AIE BIT(0) +#define RTCA3_RCR1_CIE BIT(1) +#define RTCA3_RCR1_PIE BIT(2) +#define RTCA3_RCR1_PES GENMASK(7, 4) +#define RTCA3_RCR1_PES_1_64_SEC 0x8 +#define RTCA3_RCR2 0x24 +#define RTCA3_RCR2_START BIT(0) +#define RTCA3_RCR2_RESET BIT(1) +#define RTCA3_RCR2_AADJE BIT(4) +#define RTCA3_RCR2_ADJP BIT(5) +#define RTCA3_RCR2_HR24 BIT(6) +#define RTCA3_RCR2_CNTMD BIT(7) +#define RTCA3_RSR 0x20 +#define RTCA3_RSR_AF BIT(0) +#define RTCA3_RSR_CF BIT(1) +#define RTCA3_RSR_PF BIT(2) +#define RTCA3_RADJ 0x2e +#define RTCA3_RADJ_ADJ GENMASK(5, 0) +#define RTCA3_RADJ_ADJ_MAX 0x3f +#define RTCA3_RADJ_PMADJ GENMASK(7, 6) +#define RTCA3_RADJ_PMADJ_NONE 0 +#define RTCA3_RADJ_PMADJ_ADD 1 +#define RTCA3_RADJ_PMADJ_SUB 2 + +/* Polling operation timeouts. */ +#define RTCA3_DEFAULT_TIMEOUT_US 150 +#define RTCA3_IRQSET_TIMEOUT_US 5000 +#define RTCA3_START_TIMEOUT_US 150000 +#define RTCA3_RESET_TIMEOUT_US 200000 + +/** + * enum rtca3_alrm_set_step - RTCA3 alarm set steps + * @RTCA3_ALRM_SSTEP_DONE: alarm setup done step + * @RTCA3_ALRM_SSTEP_IRQ: two 1/64 periodic IRQs were generated step + * @RTCA3_ALRM_SSTEP_INIT: alarm setup initialization step + */ +enum rtca3_alrm_set_step { + RTCA3_ALRM_SSTEP_DONE = 0, + RTCA3_ALRM_SSTEP_IRQ = 1, + RTCA3_ALRM_SSTEP_INIT = 3, +}; + +/** + * struct rtca3_ppb_per_cycle - PPB per cycle + * @ten_sec: PPB per cycle in 10 seconds adjutment mode + * @sixty_sec: PPB per cycle in 60 seconds adjustment mode + */ +struct rtca3_ppb_per_cycle { + int ten_sec; + int sixty_sec; +}; + +/** + * struct rtca3_priv - RTCA3 private data structure + * @base: base address + * @rtc_dev: RTC device + * @rstc: reset control + * @set_alarm_completion: alarm setup completion + * @alrm_sstep: alarm setup step (see enum rtca3_alrm_set_step) + * @lock: device lock + * @ppb: ppb per cycle for each the available adjustment modes + * @wakeup_irq: wakeup IRQ + */ +struct rtca3_priv { + void __iomem *base; + struct rtc_device *rtc_dev; + struct reset_control *rstc; + struct completion set_alarm_completion; + atomic_t alrm_sstep; + spinlock_t lock; + struct rtca3_ppb_per_cycle ppb; + int wakeup_irq; +}; + +static void rtca3_byte_update_bits(struct rtca3_priv *priv, u8 off, u8 mask, u8 val) +{ + u8 tmp; + + tmp = readb(priv->base + off); + tmp &= ~mask; + tmp |= (val & mask); + writeb(tmp, priv->base + off); +} + +static u8 rtca3_alarm_handler_helper(struct rtca3_priv *priv) +{ + u8 val, pending; + + val = readb(priv->base + RTCA3_RSR); + pending = val & RTCA3_RSR_AF; + writeb(val & ~pending, priv->base + RTCA3_RSR); + + if (pending) + rtc_update_irq(priv->rtc_dev, 1, RTC_AF | RTC_IRQF); + + return pending; +} + +static irqreturn_t rtca3_alarm_handler(int irq, void *dev_id) +{ + struct rtca3_priv *priv = dev_id; + u8 pending; + + guard(spinlock)(&priv->lock); + + pending = rtca3_alarm_handler_helper(priv); + + return IRQ_RETVAL(pending); +} + +static irqreturn_t rtca3_periodic_handler(int irq, void *dev_id) +{ + struct rtca3_priv *priv = dev_id; + u8 val, pending; + + guard(spinlock)(&priv->lock); + + val = readb(priv->base + RTCA3_RSR); + pending = val & RTCA3_RSR_PF; + + if (pending) { + writeb(val & ~pending, priv->base + RTCA3_RSR); + + if (atomic_read(&priv->alrm_sstep) > RTCA3_ALRM_SSTEP_IRQ) { + /* Alarm setup in progress. */ + atomic_dec(&priv->alrm_sstep); + + if (atomic_read(&priv->alrm_sstep) == RTCA3_ALRM_SSTEP_IRQ) { + /* + * We got 2 * 1/64 periodic interrupts. Disable + * interrupt and let alarm setup continue. + */ + rtca3_byte_update_bits(priv, RTCA3_RCR1, + RTCA3_RCR1_PIE, 0); + readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, val, + !(val & RTCA3_RCR1_PIE), + 10, RTCA3_DEFAULT_TIMEOUT_US); + complete(&priv->set_alarm_completion); + } + } + } + + return IRQ_RETVAL(pending); +} + +static void rtca3_prepare_cntalrm_regs_for_read(struct rtca3_priv *priv, bool cnt) +{ + /* Offset b/w time and alarm registers. */ + u8 offset = cnt ? 0 : 0xe; + + /* + * According to HW manual (section 22.6.4. Notes on writing to and + * reading from registers) after writing to count registers, alarm + * registers, year alarm enable register, bits RCR2.AADJE, AADJP, + * and HR24 register, we need to do 3 empty reads before being + * able to fetch the registers content. + */ + for (u8 i = 0; i < 3; i++) { + readb(priv->base + RTCA3_RSECCNT + offset); + readb(priv->base + RTCA3_RMINCNT + offset); + readb(priv->base + RTCA3_RHRCNT + offset); + readb(priv->base + RTCA3_RWKCNT + offset); + readb(priv->base + RTCA3_RDAYCNT + offset); + readw(priv->base + RTCA3_RYRCNT + offset); + if (!cnt) + readb(priv->base + RTCA3_RYRAREN); + } +} + +static int rtca3_read_time(struct device *dev, struct rtc_time *tm) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + u8 sec, min, hour, wday, mday, month, tmp; + u8 trials = 0; + u32 year100; + u16 year; + + guard(spinlock_irqsave)(&priv->lock); + + tmp = readb(priv->base + RTCA3_RCR2); + if (!(tmp & RTCA3_RCR2_START)) + return -EINVAL; + + do { + /* Clear carry interrupt. */ + rtca3_byte_update_bits(priv, RTCA3_RSR, RTCA3_RSR_CF, 0); + + /* Read counters. */ + sec = readb(priv->base + RTCA3_RSECCNT); + min = readb(priv->base + RTCA3_RMINCNT); + hour = readb(priv->base + RTCA3_RHRCNT); + wday = readb(priv->base + RTCA3_RWKCNT); + mday = readb(priv->base + RTCA3_RDAYCNT); + month = readb(priv->base + RTCA3_RMONCNT); + year = readw(priv->base + RTCA3_RYRCNT); + + tmp = readb(priv->base + RTCA3_RSR); + + /* + * We cannot generate carries due to reading 64Hz counter as + * the driver doesn't implement carry, thus, carries will be + * generated once per seconds. Add a timeout of 5 trials here + * to avoid infinite loop, if any. + */ + } while ((tmp & RTCA3_RSR_CF) && ++trials < 5); + + if (trials >= 5) + return -ETIMEDOUT; + + tm->tm_sec = bcd2bin(FIELD_GET(RTCA3_RSECCNT_SEC, sec)); + tm->tm_min = bcd2bin(FIELD_GET(RTCA3_RMINCNT_MIN, min)); + tm->tm_hour = bcd2bin(FIELD_GET(RTCA3_RHRCNT_HR, hour)); + tm->tm_wday = bcd2bin(FIELD_GET(RTCA3_RWKCNT_WK, wday)); + tm->tm_mday = bcd2bin(FIELD_GET(RTCA3_RDAYCNT_DAY, mday)); + tm->tm_mon = bcd2bin(FIELD_GET(RTCA3_RMONCNT_MONTH, month)) - 1; + year = FIELD_GET(RTCA3_RYRCNT_YEAR, year); + year100 = bcd2bin((year == 0x99) ? 0x19 : 0x20); + tm->tm_year = (year100 * 100 + bcd2bin(year)) - 1900; + + return 0; +} + +static int rtca3_set_time(struct device *dev, struct rtc_time *tm) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + u8 rcr2, tmp; + int ret; + + guard(spinlock_irqsave)(&priv->lock); + + /* Stop the RTC. */ + rcr2 = readb(priv->base + RTCA3_RCR2); + writeb(rcr2 & ~RTCA3_RCR2_START, priv->base + RTCA3_RCR2); + ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp, + !(tmp & RTCA3_RCR2_START), + 10, RTCA3_DEFAULT_TIMEOUT_US); + if (ret) + return ret; + + /* Update time. */ + writeb(bin2bcd(tm->tm_sec), priv->base + RTCA3_RSECCNT); + writeb(bin2bcd(tm->tm_min), priv->base + RTCA3_RMINCNT); + writeb(bin2bcd(tm->tm_hour), priv->base + RTCA3_RHRCNT); + writeb(bin2bcd(tm->tm_wday), priv->base + RTCA3_RWKCNT); + writeb(bin2bcd(tm->tm_mday), priv->base + RTCA3_RDAYCNT); + writeb(bin2bcd(tm->tm_mon + 1), priv->base + RTCA3_RMONCNT); + writew(bin2bcd(tm->tm_year % 100), priv->base + RTCA3_RYRCNT); + + /* Make sure we can read back the counters. */ + rtca3_prepare_cntalrm_regs_for_read(priv, true); + + /* Start RTC. */ + writeb(rcr2 | RTCA3_RCR2_START, priv->base + RTCA3_RCR2); + return readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp, + (tmp & RTCA3_RCR2_START), + 10, RTCA3_DEFAULT_TIMEOUT_US); +} + +static int rtca3_alarm_irq_set_helper(struct rtca3_priv *priv, + u8 interrupts, + unsigned int enabled) +{ + u8 tmp, val; + + if (enabled) { + /* + * AIE, CIE, PIE bit indexes in RSR corresponds with + * those on RCR1. Same interrupts mask can be used. + */ + rtca3_byte_update_bits(priv, RTCA3_RSR, interrupts, 0); + val = interrupts; + } else { + val = 0; + } + + rtca3_byte_update_bits(priv, RTCA3_RCR1, interrupts, val); + return readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, + ((tmp & interrupts) == val), + 10, RTCA3_IRQSET_TIMEOUT_US); +} + +static int rtca3_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + + guard(spinlock_irqsave)(&priv->lock); + + return rtca3_alarm_irq_set_helper(priv, RTCA3_RCR1_AIE, enabled); +} + +static int rtca3_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + u8 sec, min, hour, wday, mday, month; + struct rtc_time *tm = &wkalrm->time; + u32 year100; + u16 year; + + guard(spinlock_irqsave)(&priv->lock); + + sec = readb(priv->base + RTCA3_RSECAR); + min = readb(priv->base + RTCA3_RMINAR); + hour = readb(priv->base + RTCA3_RHRAR); + wday = readb(priv->base + RTCA3_RWKAR); + mday = readb(priv->base + RTCA3_RDAYAR); + month = readb(priv->base + RTCA3_RMONAR); + year = readw(priv->base + RTCA3_RYRAR); + + tm->tm_sec = bcd2bin(FIELD_GET(RTCA3_RSECAR_SEC, sec)); + tm->tm_min = bcd2bin(FIELD_GET(RTCA3_RMINAR_MIN, min)); + tm->tm_hour = bcd2bin(FIELD_GET(RTCA3_RHRAR_HR, hour)); + tm->tm_wday = bcd2bin(FIELD_GET(RTCA3_RWKAR_DAYW, wday)); + tm->tm_mday = bcd2bin(FIELD_GET(RTCA3_RDAYAR_DATE, mday)); + tm->tm_mon = bcd2bin(FIELD_GET(RTCA3_RMONAR_MON, month)) - 1; + year = FIELD_GET(RTCA3_RYRAR_YR, year); + year100 = bcd2bin((year == 0x99) ? 0x19 : 0x20); + tm->tm_year = (year100 * 100 + bcd2bin(year)) - 1900; + + wkalrm->enabled = !!(readb(priv->base + RTCA3_RCR1) & RTCA3_RCR1_AIE); + + return 0; +} + +static int rtca3_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + struct rtc_time *tm = &wkalrm->time; + u8 rcr1, tmp; + int ret; + + scoped_guard(spinlock_irqsave, &priv->lock) { + tmp = readb(priv->base + RTCA3_RCR2); + if (!(tmp & RTCA3_RCR2_START)) + return -EPERM; + + /* Disable AIE to prevent false interrupts. */ + rcr1 = readb(priv->base + RTCA3_RCR1); + rcr1 &= ~RTCA3_RCR1_AIE; + writeb(rcr1, priv->base + RTCA3_RCR1); + ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, + !(tmp & RTCA3_RCR1_AIE), + 10, RTCA3_DEFAULT_TIMEOUT_US); + if (ret) + return ret; + + /* Set the time and enable the alarm. */ + writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_sec), priv->base + RTCA3_RSECAR); + writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_min), priv->base + RTCA3_RMINAR); + writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_hour), priv->base + RTCA3_RHRAR); + writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_wday), priv->base + RTCA3_RWKAR); + writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_mday), priv->base + RTCA3_RDAYAR); + writeb(RTCA3_AR_ENB | bin2bcd(tm->tm_mon + 1), priv->base + RTCA3_RMONAR); + + writew(bin2bcd(tm->tm_year % 100), priv->base + RTCA3_RYRAR); + writeb(RTCA3_AR_ENB, priv->base + RTCA3_RYRAREN); + + /* Make sure we can read back the counters. */ + rtca3_prepare_cntalrm_regs_for_read(priv, false); + + /* Need to wait for 2 * 1/64 periodic interrupts to be generated. */ + atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_INIT); + reinit_completion(&priv->set_alarm_completion); + + /* Enable periodic interrupt. */ + rcr1 |= RTCA3_RCR1_PIE; + writeb(rcr1, priv->base + RTCA3_RCR1); + ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, + (tmp & RTCA3_RCR1_PIE), + 10, RTCA3_IRQSET_TIMEOUT_US); + } + + if (ret) + goto setup_failed; + + /* Wait for the 2 * 1/64 periodic interrupts. */ + ret = wait_for_completion_interruptible_timeout(&priv->set_alarm_completion, + msecs_to_jiffies(500)); + if (ret <= 0) { + ret = -ETIMEDOUT; + goto setup_failed; + } + + scoped_guard(spinlock_irqsave, &priv->lock) { + ret = rtca3_alarm_irq_set_helper(priv, RTCA3_RCR1_AIE, wkalrm->enabled); + atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE); + } + + return ret; + +setup_failed: + scoped_guard(spinlock_irqsave, &priv->lock) { + /* + * Disable PIE to avoid interrupt storm in case HW needed more than + * specified timeout for setup. + */ + writeb(rcr1 & ~RTCA3_RCR1_PIE, priv->base + RTCA3_RCR1); + readb_poll_timeout_atomic(priv->base + RTCA3_RCR1, tmp, !(tmp & ~RTCA3_RCR1_PIE), + 10, RTCA3_DEFAULT_TIMEOUT_US); + atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE); + } + + return ret; +} + +static int rtca3_read_offset(struct device *dev, long *offset) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + u8 val, radj, cycles; + u32 ppb_per_cycle; + + scoped_guard(spinlock_irqsave, &priv->lock) { + radj = readb(priv->base + RTCA3_RADJ); + val = readb(priv->base + RTCA3_RCR2); + } + + cycles = FIELD_GET(RTCA3_RADJ_ADJ, radj); + + if (!cycles) { + *offset = 0; + return 0; + } + + if (val & RTCA3_RCR2_ADJP) + ppb_per_cycle = priv->ppb.ten_sec; + else + ppb_per_cycle = priv->ppb.sixty_sec; + + *offset = cycles * ppb_per_cycle; + val = FIELD_GET(RTCA3_RADJ_PMADJ, radj); + if (val == RTCA3_RADJ_PMADJ_SUB) + *offset = -(*offset); + + return 0; +} + +static int rtca3_set_offset(struct device *dev, long offset) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + int cycles, cycles10, cycles60; + u8 radj, adjp, tmp; + int ret; + + /* + * Automatic time error adjustment could be set at intervals of 10 + * or 60 seconds. + */ + cycles10 = DIV_ROUND_CLOSEST(offset, priv->ppb.ten_sec); + cycles60 = DIV_ROUND_CLOSEST(offset, priv->ppb.sixty_sec); + + /* We can set b/w 1 and 63 clock cycles. */ + if (cycles60 >= -RTCA3_RADJ_ADJ_MAX && + cycles60 <= RTCA3_RADJ_ADJ_MAX) { + cycles = cycles60; + adjp = 0; + } else if (cycles10 >= -RTCA3_RADJ_ADJ_MAX && + cycles10 <= RTCA3_RADJ_ADJ_MAX) { + cycles = cycles10; + adjp = RTCA3_RCR2_ADJP; + } else { + return -ERANGE; + } + + radj = FIELD_PREP(RTCA3_RADJ_ADJ, abs(cycles)); + if (!cycles) + radj |= FIELD_PREP(RTCA3_RADJ_PMADJ, RTCA3_RADJ_PMADJ_NONE); + else if (cycles > 0) + radj |= FIELD_PREP(RTCA3_RADJ_PMADJ, RTCA3_RADJ_PMADJ_ADD); + else + radj |= FIELD_PREP(RTCA3_RADJ_PMADJ, RTCA3_RADJ_PMADJ_SUB); + + guard(spinlock_irqsave)(&priv->lock); + + tmp = readb(priv->base + RTCA3_RCR2); + + if ((tmp & RTCA3_RCR2_ADJP) != adjp) { + /* RADJ.PMADJ need to be set to zero before setting RCR2.ADJP. */ + writeb(0, priv->base + RTCA3_RADJ); + ret = readb_poll_timeout_atomic(priv->base + RTCA3_RADJ, tmp, !tmp, + 10, RTCA3_DEFAULT_TIMEOUT_US); + if (ret) + return ret; + + rtca3_byte_update_bits(priv, RTCA3_RCR2, RTCA3_RCR2_ADJP, adjp); + ret = readb_poll_timeout_atomic(priv->base + RTCA3_RCR2, tmp, + ((tmp & RTCA3_RCR2_ADJP) == adjp), + 10, RTCA3_DEFAULT_TIMEOUT_US); + if (ret) + return ret; + } + + writeb(radj, priv->base + RTCA3_RADJ); + return readb_poll_timeout_atomic(priv->base + RTCA3_RADJ, tmp, (tmp == radj), + 10, RTCA3_DEFAULT_TIMEOUT_US); +} + +static const struct rtc_class_ops rtca3_ops = { + .read_time = rtca3_read_time, + .set_time = rtca3_set_time, + .read_alarm = rtca3_read_alarm, + .set_alarm = rtca3_set_alarm, + .alarm_irq_enable = rtca3_alarm_irq_enable, + .set_offset = rtca3_set_offset, + .read_offset = rtca3_read_offset, +}; + +static int rtca3_initial_setup(struct clk *clk, struct rtca3_priv *priv) +{ + unsigned long osc32k_rate; + u8 val, tmp, mask; + u32 sleep_us; + int ret; + + osc32k_rate = clk_get_rate(clk); + if (!osc32k_rate) + return -EINVAL; + + sleep_us = DIV_ROUND_UP_ULL(1000000ULL, osc32k_rate) * 6; + + priv->ppb.ten_sec = DIV_ROUND_CLOSEST_ULL(1000000000ULL, (osc32k_rate * 10)); + priv->ppb.sixty_sec = DIV_ROUND_CLOSEST_ULL(1000000000ULL, (osc32k_rate * 60)); + + /* + * According to HW manual (section 22.4.2. Clock and count mode setting procedure) + * we need to wait at least 6 cycles of the 32KHz clock after clock was enabled. + */ + usleep_range(sleep_us, sleep_us + 10); + + /* Disable all interrupts. */ + mask = RTCA3_RCR1_AIE | RTCA3_RCR1_CIE | RTCA3_RCR1_PIE; + ret = rtca3_alarm_irq_set_helper(priv, mask, 0); + if (ret) + return ret; + + mask = RTCA3_RCR2_START | RTCA3_RCR2_HR24; + val = readb(priv->base + RTCA3_RCR2); + /* Nothing to do if already started in 24 hours and calendar count mode. */ + if ((val & mask) == mask) + return 0; + + /* Reconfigure the RTC in 24 hours and calendar count mode. */ + mask = RTCA3_RCR2_START | RTCA3_RCR2_CNTMD; + writeb(0, priv->base + RTCA3_RCR2); + ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask), + 10, RTCA3_DEFAULT_TIMEOUT_US); + if (ret) + return ret; + + /* + * Set 24 hours mode. According to HW manual (section 22.3.19. RTC Control + * Register 2) this needs to be done separate from stop operation. + */ + mask = RTCA3_RCR2_HR24; + val = RTCA3_RCR2_HR24; + writeb(val, priv->base + RTCA3_RCR2); + ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, (tmp & mask), + 10, RTCA3_DEFAULT_TIMEOUT_US); + if (ret) + return ret; + + /* Execute reset. */ + mask = RTCA3_RCR2_RESET; + writeb(val | RTCA3_RCR2_RESET, priv->base + RTCA3_RCR2); + ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, !(tmp & mask), + 10, RTCA3_RESET_TIMEOUT_US); + if (ret) + return ret; + + /* + * According to HW manual (section 22.6.3. Notes on writing to and reading + * from registers) after reset we need to wait 6 clock cycles before + * writing to RTC registers. + */ + usleep_range(sleep_us, sleep_us + 10); + + /* Set no adjustment. */ + writeb(0, priv->base + RTCA3_RADJ); + ret = readb_poll_timeout(priv->base + RTCA3_RADJ, tmp, !tmp, 10, + RTCA3_DEFAULT_TIMEOUT_US); + + /* Start the RTC and enable automatic time error adjustment. */ + mask = RTCA3_RCR2_START | RTCA3_RCR2_AADJE; + val |= RTCA3_RCR2_START | RTCA3_RCR2_AADJE; + writeb(val, priv->base + RTCA3_RCR2); + ret = readb_poll_timeout(priv->base + RTCA3_RCR2, tmp, ((tmp & mask) == mask), + 10, RTCA3_START_TIMEOUT_US); + if (ret) + return ret; + + /* + * According to HW manual (section 22.6.4. Notes on writing to and reading + * from registers) we need to wait 1/128 seconds while the clock is operating + * (RCR2.START bit = 1) to be able to read the counters after a return from + * reset. + */ + usleep_range(8000, 9000); + + /* Set period interrupt to 1/64 seconds. It is necessary for alarm setup. */ + val = FIELD_PREP(RTCA3_RCR1_PES, RTCA3_RCR1_PES_1_64_SEC); + rtca3_byte_update_bits(priv, RTCA3_RCR1, RTCA3_RCR1_PES, val); + return readb_poll_timeout(priv->base + RTCA3_RCR1, tmp, ((tmp & RTCA3_RCR1_PES) == val), + 10, RTCA3_DEFAULT_TIMEOUT_US); +} + +static int rtca3_request_irqs(struct platform_device *pdev, struct rtca3_priv *priv) +{ + struct device *dev = &pdev->dev; + int ret, irq; + + irq = platform_get_irq_byname(pdev, "alarm"); + if (irq < 0) + return dev_err_probe(dev, irq, "Failed to get alarm IRQ!\n"); + + ret = devm_request_irq(dev, irq, rtca3_alarm_handler, 0, "rtca3-alarm", priv); + if (ret) + return dev_err_probe(dev, ret, "Failed to request alarm IRQ!\n"); + priv->wakeup_irq = irq; + + irq = platform_get_irq_byname(pdev, "period"); + if (irq < 0) + return dev_err_probe(dev, irq, "Failed to get period IRQ!\n"); + + ret = devm_request_irq(dev, irq, rtca3_periodic_handler, 0, "rtca3-period", priv); + if (ret) + return dev_err_probe(dev, ret, "Failed to request period IRQ!\n"); + + /* + * Driver doesn't implement carry handler. Just get the IRQ here + * for backward compatibility, in case carry support will be added later. + */ + irq = platform_get_irq_byname(pdev, "carry"); + if (irq < 0) + return dev_err_probe(dev, irq, "Failed to get carry IRQ!\n"); + + return 0; +} + +static void rtca3_action(void *data) +{ + struct device *dev = data; + struct rtca3_priv *priv = dev_get_drvdata(dev); + int ret; + + ret = reset_control_assert(priv->rstc); + if (ret) + dev_err(dev, "Failed to de-assert reset!"); + + ret = pm_runtime_put_sync(dev); + if (ret < 0) + dev_err(dev, "Failed to runtime suspend!"); +} + +static int rtca3_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rtca3_priv *priv; + struct clk *clk; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + priv->rstc = devm_reset_control_get_shared(dev, NULL); + if (IS_ERR(priv->rstc)) + return PTR_ERR(priv->rstc); + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + + ret = reset_control_deassert(priv->rstc); + if (ret) { + pm_runtime_put_sync(dev); + return ret; + } + + dev_set_drvdata(dev, priv); + ret = devm_add_action_or_reset(dev, rtca3_action, dev); + if (ret) + return ret; + + /* + * This must be an always-on clock to keep the RTC running even after + * driver is unbinded. + */ + clk = devm_clk_get_enabled(dev, "counter"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + spin_lock_init(&priv->lock); + atomic_set(&priv->alrm_sstep, RTCA3_ALRM_SSTEP_DONE); + init_completion(&priv->set_alarm_completion); + + ret = rtca3_initial_setup(clk, priv); + if (ret) + return dev_err_probe(dev, ret, "Failed to setup the RTC!\n"); + + ret = rtca3_request_irqs(pdev, priv); + if (ret) + return ret; + + device_init_wakeup(&pdev->dev, 1); + + priv->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(priv->rtc_dev)) + return PTR_ERR(priv->rtc_dev); + + priv->rtc_dev->ops = &rtca3_ops; + priv->rtc_dev->max_user_freq = 256; + priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; + priv->rtc_dev->range_max = RTC_TIMESTAMP_END_2099; + + return devm_rtc_register_device(priv->rtc_dev); +} + +static void rtca3_remove(struct platform_device *pdev) +{ + struct rtca3_priv *priv = platform_get_drvdata(pdev); + + guard(spinlock_irqsave)(&priv->lock); + + /* + * Disable alarm, periodic interrupts. The RTC device cannot + * power up the system. + */ + rtca3_alarm_irq_set_helper(priv, RTCA3_RCR1_AIE | RTCA3_RCR1_PIE, 0); +} + +static int rtca3_suspend(struct device *dev) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + + if (!device_may_wakeup(dev)) + return 0; + + /* Alarm setup in progress. */ + if (atomic_read(&priv->alrm_sstep) != RTCA3_ALRM_SSTEP_DONE) + return -EBUSY; + + enable_irq_wake(priv->wakeup_irq); + + return 0; +} + +static int rtca3_clean_alarm(struct rtca3_priv *priv) +{ + struct rtc_device *rtc_dev = priv->rtc_dev; + time64_t alarm_time, now; + struct rtc_wkalrm alarm; + struct rtc_time tm; + u8 pending; + int ret; + + ret = rtc_read_alarm(rtc_dev, &alarm); + if (ret) + return ret; + + if (!alarm.enabled) + return 0; + + ret = rtc_read_time(rtc_dev, &tm); + if (ret) + return ret; + + alarm_time = rtc_tm_to_time64(&alarm.time); + now = rtc_tm_to_time64(&tm); + if (alarm_time >= now) + return 0; + + /* + * Heuristically, it has been determined that when returning from deep + * sleep state the RTCA3_RSR.AF is zero even though the alarm expired. + * Call again the rtc_update_irq() if alarm helper detects this. + */ + + guard(spinlock_irqsave)(&priv->lock); + + pending = rtca3_alarm_handler_helper(priv); + if (!pending) + rtc_update_irq(priv->rtc_dev, 1, RTC_AF | RTC_IRQF); + + return 0; +} + +static int rtca3_resume(struct device *dev) +{ + struct rtca3_priv *priv = dev_get_drvdata(dev); + + if (!device_may_wakeup(dev)) + return 0; + + disable_irq_wake(priv->wakeup_irq); + + /* + * According to the HW manual (section 22.6.4 Notes on writing to + * and reading from registers) we need to wait 1/128 seconds while + * RCR2.START = 1 to be able to read the counters after a return from low + * power consumption state. + */ + mdelay(8); + + /* + * The alarm cannot wake the system from deep sleep states. In case + * we return from deep sleep states and the alarm expired we need + * to disable it to avoid failures when setting another alarm. + */ + return rtca3_clean_alarm(priv); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(rtca3_pm_ops, rtca3_suspend, rtca3_resume); + +static const struct of_device_id rtca3_of_match[] = { + { .compatible = "renesas,rz-rtca3", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rtca3_of_match); + +static struct platform_driver rtca3_platform_driver = { + .driver = { + .name = "rtc-rtca3", + .pm = pm_ptr(&rtca3_pm_ops), + .of_match_table = rtca3_of_match, + }, + .probe = rtca3_probe, + .remove = rtca3_remove, +}; +module_platform_driver(rtca3_platform_driver); + +MODULE_DESCRIPTION("Renesas RTCA-3 RTC driver"); +MODULE_AUTHOR("Claudiu Beznea "); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-rtd119x.c b/drivers/rtc/rtc-rtd119x.c index 29662dfd56fef9cb5f47e6427d227daccaf4b79b..85a138db81d78a132fc754cb8448b8b94c61e8c2 100644 --- a/drivers/rtc/rtc-rtd119x.c +++ b/drivers/rtc/rtc-rtd119x.c @@ -228,7 +228,7 @@ static void rtd119x_rtc_remove(struct platform_device *pdev) static struct platform_driver rtd119x_rtc_driver = { .probe = rtd119x_rtc_probe, - .remove_new = rtd119x_rtc_remove, + .remove = rtd119x_rtc_remove, .driver = { .name = "rtd1295-rtc", .of_match_table = rtd119x_rtc_dt_ids, diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c index 2f001c59c61d54610a147bb2e7d1b24c26894e36..868d1b1eb0f42e8cdf2895033c24f0d2690587ca 100644 --- a/drivers/rtc/rtc-rv3028.c +++ b/drivers/rtc/rtc-rv3028.c @@ -120,8 +120,9 @@ static ssize_t timestamp0_show(struct device *dev, { struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); struct rtc_time tm; - int ret, count; + unsigned int count; u8 date[6]; + int ret; ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); if (ret) @@ -156,7 +157,8 @@ static ssize_t timestamp0_count_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); - int ret, count; + unsigned int count; + int ret; ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); if (ret) diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c index 56ebbd4d04814715c61ae1144220446d1fa403d7..cb220807d925b1955b8e5a0f554d29b58230e58f 100644 --- a/drivers/rtc/rtc-rzn1.c +++ b/drivers/rtc/rtc-rzn1.c @@ -7,7 +7,7 @@ * - 2022 Schneider Electric * * Authors: - * - Michel Pollet , + * - Michel Pollet * - Miquel Raynal */ @@ -35,13 +35,13 @@ #define RZN1_RTC_CTL2_WUST BIT(5) #define RZN1_RTC_CTL2_STOPPED (RZN1_RTC_CTL2_WAIT | RZN1_RTC_CTL2_WST) -#define RZN1_RTC_SEC 0x14 -#define RZN1_RTC_MIN 0x18 -#define RZN1_RTC_HOUR 0x1c -#define RZN1_RTC_WEEK 0x20 -#define RZN1_RTC_DAY 0x24 -#define RZN1_RTC_MONTH 0x28 -#define RZN1_RTC_YEAR 0x2c +#define RZN1_RTC_TIME 0x30 +#define RZN1_RTC_TIME_MIN_SHIFT 8 +#define RZN1_RTC_TIME_HOUR_SHIFT 16 +#define RZN1_RTC_CAL 0x34 +#define RZN1_RTC_CAL_DAY_SHIFT 8 +#define RZN1_RTC_CAL_MON_SHIFT 16 +#define RZN1_RTC_CAL_YEAR_SHIFT 24 #define RZN1_RTC_SUBU 0x38 #define RZN1_RTC_SUBU_DEV BIT(7) @@ -52,12 +52,8 @@ #define RZN1_RTC_ALW 0x48 #define RZN1_RTC_SECC 0x4c -#define RZN1_RTC_MINC 0x50 -#define RZN1_RTC_HOURC 0x54 -#define RZN1_RTC_WEEKC 0x58 -#define RZN1_RTC_DAYC 0x5c -#define RZN1_RTC_MONTHC 0x60 -#define RZN1_RTC_YEARC 0x64 +#define RZN1_RTC_TIMEC 0x68 +#define RZN1_RTC_CALC 0x6c struct rzn1_rtc { struct rtc_device *rtcdev; @@ -66,26 +62,18 @@ struct rzn1_rtc { static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm) { - tm->tm_sec = readl(rtc->base + RZN1_RTC_SECC); - tm->tm_min = readl(rtc->base + RZN1_RTC_MINC); - tm->tm_hour = readl(rtc->base + RZN1_RTC_HOURC); - tm->tm_wday = readl(rtc->base + RZN1_RTC_WEEKC); - tm->tm_mday = readl(rtc->base + RZN1_RTC_DAYC); - tm->tm_mon = readl(rtc->base + RZN1_RTC_MONTHC); - tm->tm_year = readl(rtc->base + RZN1_RTC_YEARC); -} - -static unsigned int rzn1_rtc_tm_to_wday(struct rtc_time *tm) -{ - time64_t time; - unsigned int days; - u32 secs; + u32 val; - time = rtc_tm_to_time64(tm); - days = div_s64_rem(time, 86400, &secs); + val = readl(rtc->base + RZN1_RTC_TIMEC); + tm->tm_sec = bcd2bin(val); + tm->tm_min = bcd2bin(val >> RZN1_RTC_TIME_MIN_SHIFT); + tm->tm_hour = bcd2bin(val >> RZN1_RTC_TIME_HOUR_SHIFT); - /* day of the week, 1970-01-01 was a Thursday */ - return (days + 4) % 7; + val = readl(rtc->base + RZN1_RTC_CALC); + tm->tm_wday = val & 0x0f; + tm->tm_mday = bcd2bin(val >> RZN1_RTC_CAL_DAY_SHIFT); + tm->tm_mon = bcd2bin(val >> RZN1_RTC_CAL_MON_SHIFT) - 1; + tm->tm_year = bcd2bin(val >> RZN1_RTC_CAL_YEAR_SHIFT) + 100; } static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -103,17 +91,9 @@ static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm) rzn1_rtc_get_time_snapshot(rtc, tm); secs = readl(rtc->base + RZN1_RTC_SECC); - if (tm->tm_sec != secs) + if (tm->tm_sec != bcd2bin(secs)) rzn1_rtc_get_time_snapshot(rtc, tm); - tm->tm_sec = bcd2bin(tm->tm_sec); - tm->tm_min = bcd2bin(tm->tm_min); - tm->tm_hour = bcd2bin(tm->tm_hour); - tm->tm_wday = bcd2bin(tm->tm_wday); - tm->tm_mday = bcd2bin(tm->tm_mday); - tm->tm_mon = bcd2bin(tm->tm_mon); - tm->tm_year = bcd2bin(tm->tm_year); - return 0; } @@ -123,14 +103,6 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm) u32 val; int ret; - tm->tm_sec = bin2bcd(tm->tm_sec); - tm->tm_min = bin2bcd(tm->tm_min); - tm->tm_hour = bin2bcd(tm->tm_hour); - tm->tm_wday = bin2bcd(rzn1_rtc_tm_to_wday(tm)); - tm->tm_mday = bin2bcd(tm->tm_mday); - tm->tm_mon = bin2bcd(tm->tm_mon); - tm->tm_year = bin2bcd(tm->tm_year); - val = readl(rtc->base + RZN1_RTC_CTL2); if (!(val & RZN1_RTC_CTL2_STOPPED)) { /* Hold the counter if it was counting up */ @@ -144,13 +116,17 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm) return ret; } - writel(tm->tm_sec, rtc->base + RZN1_RTC_SEC); - writel(tm->tm_min, rtc->base + RZN1_RTC_MIN); - writel(tm->tm_hour, rtc->base + RZN1_RTC_HOUR); - writel(tm->tm_wday, rtc->base + RZN1_RTC_WEEK); - writel(tm->tm_mday, rtc->base + RZN1_RTC_DAY); - writel(tm->tm_mon, rtc->base + RZN1_RTC_MONTH); - writel(tm->tm_year, rtc->base + RZN1_RTC_YEAR); + val = bin2bcd(tm->tm_sec); + val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT; + val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT; + writel(val, rtc->base + RZN1_RTC_TIME); + + val = tm->tm_wday; + val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT; + val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT; + val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT; + writel(val, rtc->base + RZN1_RTC_CAL); + writel(0, rtc->base + RZN1_RTC_CTL2); return 0; @@ -405,7 +381,7 @@ MODULE_DEVICE_TABLE(of, rzn1_rtc_of_match); static struct platform_driver rzn1_rtc_driver = { .probe = rzn1_rtc_probe, - .remove_new = rzn1_rtc_remove, + .remove = rzn1_rtc_remove, .driver = { .name = "rzn1-rtc", .of_match_table = rzn1_rtc_of_match, @@ -413,7 +389,7 @@ static struct platform_driver rzn1_rtc_driver = { }; module_platform_driver(rzn1_rtc_driver); -MODULE_AUTHOR("Michel Pollet "); MODULE_AUTHOR("Miquel Raynal dev, rtc->irq, st_rtc_handler, 0, - pdev->name, rtc); + ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler, + IRQF_NO_AUTOEN, pdev->name, rtc); if (ret) { dev_err(&pdev->dev, "Failed to request irq %i\n", rtc->irq); return ret; } enable_irq_wake(rtc->irq); - disable_irq(rtc->irq); rtc->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(rtc->clk)) diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 3e4f2ee22b0bc81e24ba0029fafd8be5a0b2049b..9f1a019ec8afa57245c6d40d378ec50fdcd64deb 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -1287,7 +1287,7 @@ static const struct dev_pm_ops stm32_rtc_pm_ops = { static struct platform_driver stm32_rtc_driver = { .probe = stm32_rtc_probe, - .remove_new = stm32_rtc_remove, + .remove = stm32_rtc_remove, .driver = { .name = DRIVER_NAME, .pm = &stm32_rtc_pm_ops, diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 7566d0a44af82aab2647a644a94464511ea42aea..7afcd14aeee56251dd93e7c0ca88c0f7e0b4fc02 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -403,7 +403,7 @@ MODULE_DEVICE_TABLE(of, rtc_dt_ids); static struct platform_driver stmp3xxx_rtcdrv = { .probe = stmp3xxx_rtc_probe, - .remove_new = stmp3xxx_rtc_remove, + .remove = stmp3xxx_rtc_remove, .driver = { .name = "stmp3xxx-rtc", .pm = &stmp3xxx_rtc_pm_ops, diff --git a/drivers/rtc/rtc-sunplus.c b/drivers/rtc/rtc-sunplus.c index 20c7e97c2fc81523356dd0cb23d2fde02cd48be0..9b1ce0e8ba27e6f4c78925b46bc13363974632fa 100644 --- a/drivers/rtc/rtc-sunplus.c +++ b/drivers/rtc/rtc-sunplus.c @@ -344,7 +344,7 @@ static SIMPLE_DEV_PM_OPS(sp_rtc_pm_ops, sp_rtc_suspend, sp_rtc_resume); static struct platform_driver sp_rtc_driver = { .probe = sp_rtc_probe, - .remove_new = sp_rtc_remove, + .remove = sp_rtc_remove, .driver = { .name = "sp7021-rtc", .of_match_table = sp_rtc_of_match, diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 441e0a66b215b796db12357691f2205fd695f124..79a3102c83549ab38a006247d16a3d20acb47f60 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -399,7 +399,7 @@ static void tegra_rtc_shutdown(struct platform_device *pdev) static struct platform_driver tegra_rtc_driver = { .probe = tegra_rtc_probe, - .remove_new = tegra_rtc_remove, + .remove = tegra_rtc_remove, .shutdown = tegra_rtc_shutdown, .driver = { .name = "tegra_rtc", diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 20faf08c254cc04c48c70a85101330616ef79133..e796729fc817c1bd99f4c70b714a346fc1a795d2 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -317,7 +317,7 @@ static struct platform_driver tps6586x_rtc_driver = { .pm = &tps6586x_pm_ops, }, .probe = tps6586x_rtc_probe, - .remove_new = tps6586x_rtc_remove, + .remove = tps6586x_rtc_remove, }; module_platform_driver(tps6586x_rtc_driver); diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 4e24c12004f1651a03b9073c2743637efa2f7537..794429182b34802c1e5ca9752db45429733e202d 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -673,7 +673,7 @@ MODULE_DEVICE_TABLE(of, twl_rtc_of_match); static struct platform_driver twl4030rtc_driver = { .probe = twl_rtc_probe, - .remove_new = twl_rtc_remove, + .remove = twl_rtc_remove, .shutdown = twl_rtc_shutdown, .driver = { .name = "twl_rtc", diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index ccfa76513a2ca8fb4b6d36facb122a1a83eac300..c8b568498016f22d1a8576d2c66daffb2f21ce2f 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -251,7 +251,7 @@ MODULE_DEVICE_TABLE(of, wmt_dt_ids); static struct platform_driver vt8500_rtc_driver = { .probe = vt8500_rtc_probe, - .remove_new = vt8500_rtc_remove, + .remove = vt8500_rtc_remove, .driver = { .name = "vt8500-rtc", .of_match_table = wmt_dt_ids, diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index 3c773cff2b3930775eba6b3604855a88f34d079d..6797eb4d2e493eb124a62a0239a7d1990c446f19 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c @@ -459,7 +459,7 @@ static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend, static struct platform_driver wm8350_rtc_driver = { .probe = wm8350_rtc_probe, - .remove_new = wm8350_rtc_remove, + .remove = wm8350_rtc_remove, .driver = { .name = "wm8350-rtc", .pm = &wm8350_rtc_pm_ops, diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c index f78efc9760c0e9c7ae5ef4c6526365b9ea5f8599..0813ea1a03c273b191498cea2094d16dd31be726 100644 --- a/drivers/rtc/rtc-xgene.c +++ b/drivers/rtc/rtc-xgene.c @@ -263,7 +263,7 @@ MODULE_DEVICE_TABLE(of, xgene_rtc_of_match); static struct platform_driver xgene_rtc_driver = { .probe = xgene_rtc_probe, - .remove_new = xgene_rtc_remove, + .remove = xgene_rtc_remove, .driver = { .name = "xgene-rtc", .pm = &xgene_rtc_pm_ops, diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index 08ed171bdab43a832c09abc1ed1edcdbac99615c..af1abb69d1e324c2eef89e95caac6847091a94a4 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -382,7 +382,7 @@ MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match); static struct platform_driver xlnx_rtc_driver = { .probe = xlnx_rtc_probe, - .remove_new = xlnx_rtc_remove, + .remove = xlnx_rtc_remove, .driver = { .name = KBUILD_MODNAME, .pm = &xlnx_rtc_pm_ops, diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index dcb3c32f027af6748448600bad51864f6ba5d9a1..c763c50d1454676f223e8b29a92f5fb45ddd7932 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -803,7 +803,6 @@ static struct attribute *con3215_drv_attrs[] = { static struct attribute_group con3215_drv_attr_group = { .attrs = con3215_drv_attrs, - NULL, }; static const struct attribute_group *con3215_drv_attr_groups[] = { diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index e14638936de6b8773a43aec14b04df94f26e6357..26e1ea1940ecb5a88f98dce9e8eda198c0d27018 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -453,7 +453,7 @@ static void ap_tasklet_fn(unsigned long dummy) * important that no requests on any AP get lost. */ if (ap_irq_flag) - xchg(ap_airq.lsi_ptr, 0); + WRITE_ONCE(*ap_airq.lsi_ptr, 0); spin_lock_bh(&ap_queues_lock); hash_for_each(ap_queues, bkt, aq, hnode) { diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 8c0b40d8eb39ecc411d7c2bcb78f83812737e03a..a52c2690933fd57c45f145bc0738b387f95226bd 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -360,10 +360,26 @@ static int vfio_ap_validate_nib(struct kvm_vcpu *vcpu, dma_addr_t *nib) return 0; } -static int ensure_nib_shared(unsigned long addr, struct gmap *gmap) +/** + * ensure_nib_shared() - Ensure the address of the NIB is secure and shared + * @addr: the physical (absolute) address of the NIB + * + * This function checks whether the NIB page, which has been pinned with + * vfio_pin_pages(), is a shared page belonging to a secure guest. + * + * It will call uv_pin_shared() on it; if the page was already pinned shared + * (i.e. if the NIB belongs to a secure guest and is shared), then 0 + * (success) is returned. If the NIB was not shared, vfio_pin_pages() had + * exported it and now it does not belong to the secure guest anymore. In + * that case, an error is returned. + * + * Context: the NIB (at physical address @addr) has to be pinned with + * vfio_pin_pages() before calling this function. + * + * Return: 0 in case of success, otherwise an error < 0. + */ +static int ensure_nib_shared(unsigned long addr) { - int ret; - /* * The nib has to be located in shared storage since guest and * host access it. vfio_pin_pages() will do a pin shared and @@ -374,12 +390,7 @@ static int ensure_nib_shared(unsigned long addr, struct gmap *gmap) * * If the page is already pinned shared the UV will return a success. */ - ret = uv_pin_shared(addr); - if (ret) { - /* vfio_pin_pages() likely exported the page so let's re-import */ - gmap_convert_to_secure(gmap, addr); - } - return ret; + return uv_pin_shared(addr); } /** @@ -425,6 +436,7 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q, return status; } + /* The pin will probably be successful even if the NIB was not shared */ ret = vfio_pin_pages(&q->matrix_mdev->vdev, nib, 1, IOMMU_READ | IOMMU_WRITE, &h_page); switch (ret) { @@ -447,7 +459,7 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q, /* NIB in non-shared storage is a rc 6 for PV guests */ if (kvm_s390_pv_cpu_is_protected(vcpu) && - ensure_nib_shared(h_nib & PAGE_MASK, kvm->arch.gmap)) { + ensure_nib_shared(h_nib & PAGE_MASK)) { vfio_unpin_pages(&q->matrix_mdev->vdev, nib, 1); status.response_code = AP_RESPONSE_INVALID_ADDRESS; return status; diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index d7fcde692f46aed39c028ec452acae0a6690cb0b..90e71ce4bab86889b621fdd2d91d52369a04b01d 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -413,7 +413,7 @@ static struct platform_driver bbc_i2c_driver = { .of_match_table = bbc_i2c_match, }, .probe = bbc_i2c_probe, - .remove_new = bbc_i2c_remove, + .remove = bbc_i2c_remove, }; module_platform_driver(bbc_i2c_driver); diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 521cf8affe65a1b4ff100c51b41e87ba79859157..e94222b3523cdc83beb1be5ee2a0d3cfca357af4 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -261,7 +261,7 @@ static struct platform_driver d7s_driver = { .of_match_table = d7s_match, }, .probe = d7s_probe, - .remove_new = d7s_remove, + .remove = d7s_remove, }; module_platform_driver(d7s_driver); diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index b543e9bcc785906092cdac2fa012599baf23b3d1..81918aa6710992f8bbd20d31013d62d1944e092e 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1125,7 +1125,7 @@ static struct platform_driver envctrl_driver = { .of_match_table = envctrl_match, }, .probe = envctrl_probe, - .remove_new = envctrl_remove, + .remove = envctrl_remove, }; module_platform_driver(envctrl_driver); diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index ddd449dfda31a67f41c3deba7307fc2f9cf89f0c..6524a4a1910956aa3804226f5f95c7bdc34da99f 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -206,7 +206,7 @@ static struct platform_driver flash_driver = { .of_match_table = flash_match, }, .probe = flash_probe, - .remove_new = flash_remove, + .remove = flash_remove, }; module_platform_driver(flash_driver); diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 8bbed7a7afb77f6b1e9e6853955aff9a03a500c3..e3dec78f51e9d7bd462e47b6e47430f6b0711bbc 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -424,7 +424,7 @@ static struct platform_driver uctrl_driver = { .of_match_table = uctrl_match, }, .probe = uctrl_probe, - .remove_new = uctrl_remove, + .remove = uctrl_remove, }; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 32f94db6d6bf5d2bd289c1a121da7ffc6a7cb2ff..f3a1ecb42128a2b221ca5c362e041eb59dba0f20 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1274,7 +1274,7 @@ static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj, } static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj, - struct bin_attribute *attr, int i) + const struct bin_attribute *attr, int i) { struct device *dev = kobj_to_dev(kobj); struct scsi_device *sdev = to_scsi_device(dev); diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 74350b5871dc8ecf627c6539170872741831436e..ea571eeb307878079e9a015aef4f93a3201920cd 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -209,7 +209,6 @@ int __init register_intc_controller(struct intc_desc *desc) goto err0; INIT_LIST_HEAD(&d->list); - list_add_tail(&d->list, &intc_list); raw_spin_lock_init(&d->lock); INIT_RADIX_TREE(&d->tree, GFP_ATOMIC); @@ -369,6 +368,7 @@ int __init register_intc_controller(struct intc_desc *desc) d->skip_suspend = desc->skip_syscore_suspend; + list_add_tail(&d->list, &intc_list); nr_intc_controllers++; return 0; diff --git a/drivers/slimbus/qcom-ctrl.c b/drivers/slimbus/qcom-ctrl.c index e25f9bdd9b2337428d7414d4228f806a7c2ed036..ab344f7472f254078660df952444fe44a321df51 100644 --- a/drivers/slimbus/qcom-ctrl.c +++ b/drivers/slimbus/qcom-ctrl.c @@ -722,7 +722,7 @@ MODULE_DEVICE_TABLE(of, qcom_slim_dt_match); static struct platform_driver qcom_slim_driver = { .probe = qcom_slim_probe, - .remove_new = qcom_slim_remove, + .remove = 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 1ac8e2912fd1cee1e28410d4f8e82d1534923fd1..4fb66986cc22e02463329f89ac7a57f5f71db4ec 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1743,7 +1743,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_new = qcom_slim_ngd_ctrl_remove, + .remove = qcom_slim_ngd_ctrl_remove, .driver = { .name = "qcom,slim-ngd-ctrl", .of_match_table = qcom_slim_ngd_dt_match, @@ -1752,7 +1752,7 @@ static struct platform_driver qcom_slim_ngd_ctrl_driver = { static struct platform_driver qcom_slim_ngd_driver = { .probe = qcom_slim_ngd_probe, - .remove_new = qcom_slim_ngd_remove, + .remove = qcom_slim_ngd_remove, .driver = { .name = QCOM_SLIM_NGD_DRV_NAME, .pm = &qcom_slim_ngd_dev_pm_ops, diff --git a/drivers/soundwire/amd_init.c b/drivers/soundwire/amd_init.c index d11b60efda33fe3f79172c7788aa0df6c48b3b0d..643e94524fe6da7e84cfd3117b0a6df1493ffb02 100644 --- a/drivers/soundwire/amd_init.c +++ b/drivers/soundwire/amd_init.c @@ -173,7 +173,7 @@ int sdw_amd_probe(struct sdw_amd_res *res, struct sdw_amd_ctx **sdw_ctx) return sdw_amd_startup(*sdw_ctx); } -EXPORT_SYMBOL_NS(sdw_amd_probe, SOUNDWIRE_AMD_INIT); +EXPORT_SYMBOL_NS(sdw_amd_probe, "SOUNDWIRE_AMD_INIT"); void sdw_amd_exit(struct sdw_amd_ctx *ctx) { @@ -181,7 +181,7 @@ void sdw_amd_exit(struct sdw_amd_ctx *ctx) kfree(ctx->peripherals); kfree(ctx); } -EXPORT_SYMBOL_NS(sdw_amd_exit, SOUNDWIRE_AMD_INIT); +EXPORT_SYMBOL_NS(sdw_amd_exit, "SOUNDWIRE_AMD_INIT"); int sdw_amd_get_slave_info(struct sdw_amd_ctx *ctx) { @@ -224,7 +224,7 @@ int sdw_amd_get_slave_info(struct sdw_amd_ctx *ctx) } return 0; } -EXPORT_SYMBOL_NS(sdw_amd_get_slave_info, SOUNDWIRE_AMD_INIT); +EXPORT_SYMBOL_NS(sdw_amd_get_slave_info, "SOUNDWIRE_AMD_INIT"); MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); MODULE_DESCRIPTION("AMD SoundWire Init Library"); diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 5a4bfaef65fb2e6bc4228d2f7ed9a82e9ad75360..96a7f9709720bb2a75b73079023d802d02d66f49 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -1221,7 +1221,7 @@ static const struct dev_pm_ops amd_pm = { static struct platform_driver amd_sdw_driver = { .probe = &amd_sdw_manager_probe, - .remove_new = &amd_sdw_manager_remove, + .remove = &amd_sdw_manager_remove, .driver = { .name = "amd_sdw_manager", .pm = &amd_pm, diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 421da0f86fad68d856e24f86370631f50f6d821f..9db78f3d761522e385681235b692265b312094f8 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1111,4 +1111,4 @@ const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = { .sync_go = intel_shim_sync_go, .sync_check_cmdsync_unlocked = intel_check_cmdsync_unlocked, }; -EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, SOUNDWIRE_INTEL); +EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, "SOUNDWIRE_INTEL"); diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index a005b63582e94d99210e18d2f90fcfe5a87bef40..e305c6258ca967c95e81ffb9df2afafc9f60287d 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -754,6 +754,6 @@ const struct sdw_intel_hw_ops sdw_intel_lnl_hw_ops = { .program_sdi = intel_program_sdi, }; -EXPORT_SYMBOL_NS(sdw_intel_lnl_hw_ops, SOUNDWIRE_INTEL); +EXPORT_SYMBOL_NS(sdw_intel_lnl_hw_ops, "SOUNDWIRE_INTEL"); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c index 12e7a98f319f8c870037f28916204110a2a91181..5f53666514a45a4f0869ab8022208edeb09a29ee 100644 --- a/drivers/soundwire/intel_init.c +++ b/drivers/soundwire/intel_init.c @@ -149,7 +149,7 @@ irqreturn_t sdw_intel_thread(int irq, void *dev_id) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT); +EXPORT_SYMBOL_NS(sdw_intel_thread, "SOUNDWIRE_INTEL_INIT"); static struct sdw_intel_ctx *sdw_intel_probe_controller(struct sdw_intel_res *res) @@ -334,7 +334,7 @@ struct sdw_intel_ctx { return sdw_intel_probe_controller(res); } -EXPORT_SYMBOL_NS(sdw_intel_probe, SOUNDWIRE_INTEL_INIT); +EXPORT_SYMBOL_NS(sdw_intel_probe, "SOUNDWIRE_INTEL_INIT"); /** * sdw_intel_startup() - SoundWire Intel startup @@ -347,7 +347,7 @@ int sdw_intel_startup(struct sdw_intel_ctx *ctx) { return sdw_intel_startup_controller(ctx); } -EXPORT_SYMBOL_NS(sdw_intel_startup, SOUNDWIRE_INTEL_INIT); +EXPORT_SYMBOL_NS(sdw_intel_startup, "SOUNDWIRE_INTEL_INIT"); /** * sdw_intel_exit() - SoundWire Intel exit * @ctx: SoundWire context allocated in the probe @@ -374,7 +374,7 @@ void sdw_intel_exit(struct sdw_intel_ctx *ctx) kfree(ctx->ldev); kfree(ctx); } -EXPORT_SYMBOL_NS(sdw_intel_exit, SOUNDWIRE_INTEL_INIT); +EXPORT_SYMBOL_NS(sdw_intel_exit, "SOUNDWIRE_INTEL_INIT"); void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx) { @@ -397,7 +397,7 @@ void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx) intel_link_process_wakeen_event(&ldev->auxdev); } } -EXPORT_SYMBOL_NS(sdw_intel_process_wakeen_event, SOUNDWIRE_INTEL_INIT); +EXPORT_SYMBOL_NS(sdw_intel_process_wakeen_event, "SOUNDWIRE_INTEL_INIT"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Intel Soundwire Init Library"); diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 2b403b14066c1611e69a07859d0f10d699c26399..e00c5ac496a6859c58354e02d5e4c6c31642e272 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -1779,7 +1779,7 @@ MODULE_DEVICE_TABLE(of, qcom_swrm_of_match); static struct platform_driver qcom_swrm_driver = { .probe = &qcom_swrm_probe, - .remove_new = qcom_swrm_remove, + .remove = qcom_swrm_remove, .driver = { .name = "qcom-soundwire", .of_match_table = qcom_swrm_of_match, diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c index 97cf8bcca04742cb0aa51ba30dbfc535a34a00f3..4869b073b11c2f3b658992f50c78dd78a2330833 100644 --- a/drivers/soundwire/slave.c +++ b/drivers/soundwire/slave.c @@ -272,4 +272,4 @@ int sdw_of_find_slaves(struct sdw_bus *bus) return 0; } -MODULE_IMPORT_NS(SND_SOC_SDCA); +MODULE_IMPORT_NS("SND_SOC_SDCA"); diff --git a/drivers/spi/spi-cs42l43.c b/drivers/spi/spi-cs42l43.c index d0b55a26c31b937f4dcc139735d924e3ed87b04b..ceefc253c54904b51a12ff112988d1dfbeed39c1 100644 --- a/drivers/spi/spi-cs42l43.c +++ b/drivers/spi/spi-cs42l43.c @@ -462,7 +462,7 @@ static struct platform_driver cs42l43_spi_driver = { }; module_platform_driver(cs42l43_spi_driver); -MODULE_IMPORT_NS(GPIO_SWNODE); +MODULE_IMPORT_NS("GPIO_SWNODE"); MODULE_DESCRIPTION("CS42L43 SPI Driver"); MODULE_AUTHOR("Lucas Tanure "); MODULE_AUTHOR("Maciej Strozek "); diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c index abe6410f0e99233d2966dc41363dbd50984ad191..4a5be813efa75e3606b5dd546f0678ed68794d6e 100644 --- a/drivers/spi/spi-dw-bt1.c +++ b/drivers/spi/spi-dw-bt1.c @@ -328,4 +328,4 @@ module_platform_driver(dw_spi_bt1_driver); MODULE_AUTHOR("Serge Semin "); MODULE_DESCRIPTION("Baikal-T1 System Boot SPI Controller driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SPI_DW_CORE); +MODULE_IMPORT_NS("SPI_DW_CORE"); diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 431788dd848cea1d854affe0d1fb971f680824a1..ea517af9435fa14bd347f51a2f05295517abe22b 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -104,7 +104,7 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable) else dw_writel(dws, DW_SPI_SER, 0); } -EXPORT_SYMBOL_NS_GPL(dw_spi_set_cs, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_set_cs, "SPI_DW_CORE"); /* Return the max entries we can fill into tx fifo */ static inline u32 dw_spi_tx_max(struct dw_spi *dws) @@ -208,7 +208,7 @@ int dw_spi_check_status(struct dw_spi *dws, bool raw) return ret; } -EXPORT_SYMBOL_NS_GPL(dw_spi_check_status, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_check_status, "SPI_DW_CORE"); static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) { @@ -351,7 +351,7 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, dws->cur_rx_sample_dly = chip->rx_sample_dly; } } -EXPORT_SYMBOL_NS_GPL(dw_spi_update_config, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_update_config, "SPI_DW_CORE"); static void dw_spi_irq_setup(struct dw_spi *dws) { @@ -982,7 +982,7 @@ err_free_host: spi_controller_put(host); return ret; } -EXPORT_SYMBOL_NS_GPL(dw_spi_add_host, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_add_host, "SPI_DW_CORE"); void dw_spi_remove_host(struct dw_spi *dws) { @@ -997,7 +997,7 @@ void dw_spi_remove_host(struct dw_spi *dws) free_irq(dws->irq, dws->host); } -EXPORT_SYMBOL_NS_GPL(dw_spi_remove_host, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_remove_host, "SPI_DW_CORE"); int dw_spi_suspend_host(struct dw_spi *dws) { @@ -1010,14 +1010,14 @@ int dw_spi_suspend_host(struct dw_spi *dws) dw_spi_shutdown_chip(dws); return 0; } -EXPORT_SYMBOL_NS_GPL(dw_spi_suspend_host, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_suspend_host, "SPI_DW_CORE"); int dw_spi_resume_host(struct dw_spi *dws) { dw_spi_hw_init(&dws->host->dev, dws); return spi_controller_resume(dws->host); } -EXPORT_SYMBOL_NS_GPL(dw_spi_resume_host, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_resume_host, "SPI_DW_CORE"); MODULE_AUTHOR("Feng Tang "); MODULE_DESCRIPTION("Driver for DesignWare SPI controller core"); diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c index f4c209e5f52baa2c453b353ac515f4950726d627..b5bed02b7e5006d399697384c958137649786f1a 100644 --- a/drivers/spi/spi-dw-dma.c +++ b/drivers/spi/spi-dw-dma.c @@ -693,7 +693,7 @@ void dw_spi_dma_setup_mfld(struct dw_spi *dws) { dws->dma_ops = &dw_spi_dma_mfld_ops; } -EXPORT_SYMBOL_NS_GPL(dw_spi_dma_setup_mfld, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_dma_setup_mfld, "SPI_DW_CORE"); static const struct dw_spi_dma_ops dw_spi_dma_generic_ops = { .dma_init = dw_spi_dma_init_generic, @@ -708,4 +708,4 @@ void dw_spi_dma_setup_generic(struct dw_spi *dws) { dws->dma_ops = &dw_spi_dma_generic_ops; } -EXPORT_SYMBOL_NS_GPL(dw_spi_dma_setup_generic, SPI_DW_CORE); +EXPORT_SYMBOL_NS_GPL(dw_spi_dma_setup_generic, "SPI_DW_CORE"); diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 863040cf5db76ef38cfdec777d651bea014256ae..f0f576fac77afed6ca2ddc0d31e37bc76462c736 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -445,4 +445,4 @@ module_platform_driver(dw_spi_mmio_driver); MODULE_AUTHOR("Jean-Hugues Deschenes "); MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SPI_DW_CORE); +MODULE_IMPORT_NS("SPI_DW_CORE"); diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 6b8cc26e06f8879bec11fcc0cf592f8eaffacfdb..b32d6648a32ea251028d2b4ad422941867c71519 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -211,4 +211,4 @@ module_pci_driver(dw_spi_pci_driver); MODULE_AUTHOR("Feng Tang "); MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SPI_DW_CORE); +MODULE_IMPORT_NS("SPI_DW_CORE"); diff --git a/drivers/spi/spi-ljca.c b/drivers/spi/spi-ljca.c index 1cc1422ddba0b6bdae4c01c6c76237ede5e77199..2cab79ad2b98f27c60b66825665a6122dce0f00e 100644 --- a/drivers/spi/spi-ljca.c +++ b/drivers/spi/spi-ljca.c @@ -294,4 +294,4 @@ MODULE_AUTHOR("Zhifeng Wang "); MODULE_AUTHOR("Lixu Zhang "); MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-SPI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LJCA); +MODULE_IMPORT_NS("LJCA"); diff --git a/drivers/spi/spi-loongson-core.c b/drivers/spi/spi-loongson-core.c index f97800b6fd65361bd45bad8ebf9f18ce43a8fa44..4fec226456d1bb1bcba68a5da3db8be8c7c26042 100644 --- a/drivers/spi/spi-loongson-core.c +++ b/drivers/spi/spi-loongson-core.c @@ -227,7 +227,7 @@ int loongson_spi_init_controller(struct device *dev, void __iomem *regs) return devm_spi_register_controller(dev, controller); } -EXPORT_SYMBOL_NS_GPL(loongson_spi_init_controller, SPI_LOONGSON_CORE); +EXPORT_SYMBOL_NS_GPL(loongson_spi_init_controller, "SPI_LOONGSON_CORE"); static int __maybe_unused loongson_spi_suspend(struct device *dev) { @@ -273,7 +273,7 @@ const struct dev_pm_ops loongson_spi_dev_pm_ops = { .suspend = loongson_spi_suspend, .resume = loongson_spi_resume, }; -EXPORT_SYMBOL_NS_GPL(loongson_spi_dev_pm_ops, SPI_LOONGSON_CORE); +EXPORT_SYMBOL_NS_GPL(loongson_spi_dev_pm_ops, "SPI_LOONGSON_CORE"); MODULE_DESCRIPTION("Loongson SPI core driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-loongson-pci.c b/drivers/spi/spi-loongson-pci.c index 892cf1eba1cfe9bf41580c2418a17ce69ef01c18..cbcde153260e778613f6ca57e9028dcfaf2c01ec 100644 --- a/drivers/spi/spi-loongson-pci.c +++ b/drivers/spi/spi-loongson-pci.c @@ -51,4 +51,4 @@ module_pci_driver(loongson_spi_pci_driver); MODULE_DESCRIPTION("Loongson spi pci driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SPI_LOONGSON_CORE); +MODULE_IMPORT_NS("SPI_LOONGSON_CORE"); diff --git a/drivers/spi/spi-loongson-plat.c b/drivers/spi/spi-loongson-plat.c index c066e5f5891e9a424e525559b8e765aee867f172..64a7270f9a642ac0729d4f1e29a2ed985ec90a4e 100644 --- a/drivers/spi/spi-loongson-plat.c +++ b/drivers/spi/spi-loongson-plat.c @@ -44,4 +44,4 @@ module_platform_driver(loongson_spi_plat_driver); MODULE_DESCRIPTION("Loongson spi platform driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SPI_LOONGSON_CORE); +MODULE_IMPORT_NS("SPI_LOONGSON_CORE"); diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index e51c1b49228323d8aabea6a376aa483859c42dc9..cae77ac1852061d82df0c95f9de27ccbd5f7b622 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -346,5 +346,5 @@ module_pci_driver(pxa2xx_spi_pci_driver); MODULE_DESCRIPTION("CE4100/LPSS PCI-SPI glue code for PXA's driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SPI_PXA2xx); +MODULE_IMPORT_NS("SPI_PXA2xx"); MODULE_AUTHOR("Sebastian Andrzej Siewior "); diff --git a/drivers/spi/spi-pxa2xx-platform.c b/drivers/spi/spi-pxa2xx-platform.c index b88b7de7a005008b6d6059a7ca7eaa1053a47890..45e159e75a521fac5ee951c1b3be24dad8cb2cdf 100644 --- a/drivers/spi/spi-pxa2xx-platform.c +++ b/drivers/spi/spi-pxa2xx-platform.c @@ -225,6 +225,6 @@ module_exit(pxa2xx_spi_exit); MODULE_AUTHOR("Stephen Street"); MODULE_DESCRIPTION("PXA2xx SSP SPI Controller platform driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SPI_PXA2xx); +MODULE_IMPORT_NS("SPI_PXA2xx"); MODULE_ALIAS("platform:pxa2xx-spi"); MODULE_SOFTDEP("pre: dw_dmac"); diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index bf1f34b0ffc8ebdc1fde387334c73178ccab4ffb..903d761452725cf18e926393c31442823a188a67 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1468,7 +1468,7 @@ out_error_dma_irq_alloc: return status; } -EXPORT_SYMBOL_NS_GPL(pxa2xx_spi_probe, SPI_PXA2xx); +EXPORT_SYMBOL_NS_GPL(pxa2xx_spi_probe, "SPI_PXA2xx"); void pxa2xx_spi_remove(struct device *dev) { @@ -1488,7 +1488,7 @@ void pxa2xx_spi_remove(struct device *dev) /* Release IRQ */ free_irq(ssp->irq, drv_data); } -EXPORT_SYMBOL_NS_GPL(pxa2xx_spi_remove, SPI_PXA2xx); +EXPORT_SYMBOL_NS_GPL(pxa2xx_spi_remove, "SPI_PXA2xx"); static int pxa2xx_spi_suspend(struct device *dev) { diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c index 5079442f8ea1664e467aac50441be11fffffe6bc..160d36f7d238e7eb4122091a53b779c18e9d91a4 100644 --- a/drivers/spmi/spmi-mtk-pmif.c +++ b/drivers/spmi/spmi-mtk-pmif.c @@ -545,7 +545,7 @@ static struct platform_driver mtk_spmi_driver = { .of_match_table = mtk_spmi_match_table, }, .probe = mtk_spmi_probe, - .remove_new = mtk_spmi_remove, + .remove = mtk_spmi_remove, }; module_platform_driver(mtk_spmi_driver); diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 9ba9495fcc4bae401fa054f7da244d35f1c120ca..5c058db2182186e0e131a3f9605704c3a8375489 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -1763,14 +1763,13 @@ static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb, { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; - struct device_node *child; int ret; /* legacy mode doesn't provide child node for the bus */ if (of_device_is_compatible(node, "qcom,spmi-pmic-arb")) return spmi_pmic_arb_bus_init(pdev, node, pmic_arb); - for_each_available_child_of_node(node, child) { + for_each_available_child_of_node_scoped(node, child) { if (of_node_name_eq(child, "spmi")) { ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb); if (ret) @@ -1882,7 +1881,7 @@ MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table); static struct platform_driver spmi_pmic_arb_driver = { .probe = spmi_pmic_arb_probe, - .remove_new = spmi_pmic_arb_remove, + .remove = spmi_pmic_arb_remove, .driver = { .name = "spmi_pmic_arb", .of_match_table = spmi_pmic_arb_match_table, diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index fcdd559a8acfd7841b1b134a73705f4e4157d859..075e775d3868b3449922a25df1f79dec5a83a42d 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -24,20 +24,10 @@ menuconfig STAGING if STAGING -source "drivers/staging/olpc_dcon/Kconfig" - source "drivers/staging/rtl8723bs/Kconfig" -source "drivers/staging/rtl8712/Kconfig" - -source "drivers/staging/rts5208/Kconfig" - source "drivers/staging/octeon/Kconfig" -source "drivers/staging/vt6655/Kconfig" - -source "drivers/staging/vt6656/Kconfig" - source "drivers/staging/iio/Kconfig" source "drivers/staging/sm750fb/Kconfig" @@ -46,8 +36,6 @@ source "drivers/staging/nvec/Kconfig" source "drivers/staging/media/Kconfig" -source "drivers/staging/gdm724x/Kconfig" - source "drivers/staging/fbtft/Kconfig" source "drivers/staging/most/Kconfig" @@ -58,8 +46,8 @@ source "drivers/staging/vc04_services/Kconfig" source "drivers/staging/axis-fifo/Kconfig" -source "drivers/staging/fieldbus/Kconfig" - source "drivers/staging/vme_user/Kconfig" +source "drivers/staging/gpib/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 4a84c4848664a439399cc8accd0d94fb74c39289..e681e403509ce271d388a5b0e70b296c41474f40 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -2,21 +2,15 @@ # Makefile for staging directory obj-y += media/ -obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ -obj-$(CONFIG_R8712U) += rtl8712/ -obj-$(CONFIG_RTS5208) += rts5208/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ -obj-$(CONFIG_VT6655) += vt6655/ -obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme_user/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_SM750) += sm750fb/ obj-$(CONFIG_MFD_NVEC) += nvec/ -obj-$(CONFIG_LTE_GDM724X) += gdm724x/ obj-$(CONFIG_FB_TFT) += fbtft/ obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ -obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ +obj-$(CONFIG_GPIB) += gpib/ diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index 1bbb9a6db5979aff0ed1a17ed2aa955e2bfbf487..7540c20090c78b817c1fb825a2fe340912e4b9a4 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -919,7 +919,7 @@ static struct platform_driver axis_fifo_driver = { .of_match_table = axis_fifo_of_match, }, .probe = axis_fifo_probe, - .remove_new = axis_fifo_remove, + .remove = axis_fifo_remove, }; static int __init axis_fifo_init(void) diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index 3e00a26a29d5c346734ec3189380a1c66bf89f80..317be17b95c1672404fc6aecda24d0a1f563685d 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -330,7 +330,7 @@ static struct platform_driver fbtft_driver_platform_driver = { \ .of_match_table = dt_ids, \ }, \ .probe = fbtft_driver_probe_pdev, \ - .remove_new = fbtft_driver_remove_pdev, \ + .remove = fbtft_driver_remove_pdev, \ }; \ \ static int __init fbtft_driver_module_init(void) \ diff --git a/drivers/staging/fieldbus/Documentation/ABI/fieldbus-dev-cdev b/drivers/staging/fieldbus/Documentation/ABI/fieldbus-dev-cdev deleted file mode 100644 index 45f631ea32a60c9cc60baed6e6cbd4c0dc8019e5..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/Documentation/ABI/fieldbus-dev-cdev +++ /dev/null @@ -1,31 +0,0 @@ -What: /dev/fieldbus_devX -Date: December 2018 -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - The cdev interface to drivers for Fieldbus Device Memory - (aka. Process Memory). - - The following file operations are supported: - - open(2) - Create an I/O context associated with the file descriptor. - - read(2) - Read from Process Memory's "read area". - Clears POLLERR | POLLPRI from the file descriptor. - - write(2) - Write to Process Memory's "write area". - - poll(2), select(2), epoll_wait(2) etc. - When a "Process Memory Read Area Changed" event occurs, - POLLERR | POLLPRI will be set on the file descriptor. - Note that POLLIN | POLLOUT events are always set, because the - process memory area is always readable and writable. - - close(2) - Free up the I/O context that was associated - with the file descriptor. - -Users: TBD diff --git a/drivers/staging/fieldbus/Documentation/ABI/sysfs-class-fieldbus-dev b/drivers/staging/fieldbus/Documentation/ABI/sysfs-class-fieldbus-dev deleted file mode 100644 index 439f14d33c3bfb90c001a6093af13224a353999b..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/Documentation/ABI/sysfs-class-fieldbus-dev +++ /dev/null @@ -1,62 +0,0 @@ -What: /sys/class/fieldbus_dev/fieldbus_devX/card_name -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - Human-readable name of the Fieldbus Device. - -What: /sys/class/fieldbus_dev/fieldbus_devX/fieldbus_type -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - The type of fieldbus implemented by this device. - Possible values: - 'unknown' - 'profinet' - -What: /sys/class/fieldbus_dev/fieldbus_devX/fieldbus_id -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - The unique fieldbus id associated with this device. - The exact format of this id is fieldbus type dependent, e.g. - a mac address for profinet. - -What: /sys/class/fieldbus_dev/fieldbus_devX/read_area_size -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - The size, in bytes, of the Process Memory read area. - Note: this area is accessible by reading from the associated - character device (/dev/fieldbus_devX). - -What: /sys/class/fieldbus_dev/fieldbus_devX/write_area_size -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - The size, in bytes, of the Process Memory write area. - Note: this area is accessible by writing to the associated - character device (/dev/fieldbus_devX) - -What: /sys/class/fieldbus_dev/fieldbus_devX/online -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - Whether the fieldbus is online or offline. - Possible values: - '1' meaning 'online' - '0' meaning 'offline' - Note: an uevent is generated when this property changes. - -What: /sys/class/fieldbus_dev/fieldbus_devX/enabled -KernelVersion: 5.1 (staging) -Contact: Sven Van Asbroeck -Description: - Whether the device is enabled (power on) or - disabled (power off). - Possible values: - '1' meaning enabled - '0' meaning disabled - Normally a r/o property, but optionally r/w: - Writing '1' enables the device (power on) with default - settings. - Writing '0' disables the card (power off). diff --git a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt deleted file mode 100644 index f34a95611645bd5d889384dfa547a4a47bd1b36d..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt +++ /dev/null @@ -1,71 +0,0 @@ -* Arcx Anybus-S controller - -This chip communicates with the SoC over a parallel bus. It is -expected that its Device Tree node is specified as the child of a node -corresponding to the parallel bus used for communication. - -Required properties: --------------------- - - - compatible : The following chip-specific string: - "arcx,anybus-controller" - - - reg : three areas: - index 0: bus memory area where the cpld registers are located. - index 1: bus memory area of the first host's dual-port ram. - index 2: bus memory area of the second host's dual-port ram. - - - reset-gpios : the GPIO pin connected to the reset line of the controller. - - - interrupts : two interrupts: - index 0: interrupt connected to the first host - index 1: interrupt connected to the second host - Generic interrupt client node bindings are described in - interrupt-controller/interrupts.txt - -Optional: use of subnodes -------------------------- - -The card connected to a host may need additional properties. These can be -specified in subnodes to the controller node. - -The subnodes are identified by the standard 'reg' property. Which information -exactly can be specified depends on the bindings for the function driver -for the subnode. - -Required controller node properties when using subnodes: -- #address-cells: should be one. -- #size-cells: should be zero. - -Required subnode properties: -- reg: Must contain the host index of the card this subnode describes: - <0> for the first host on the controller - <1> for the second host on the controller - Note that only a single card can be plugged into a host, so the host - index uniquely describes the card location. - -Example of usage: ------------------ - -This example places the bridge on top of the i.MX WEIM parallel bus, see: -Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml - -&weim { - controller@0,0 { - compatible = "arcx,anybus-controller"; - reg = <0 0 0x100>, <0 0x400000 0x800>, <1 0x400000 0x800>; - reset-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; - interrupt-parent = <&gpio1>; - interrupts = <1 IRQ_TYPE_LEVEL_LOW>, <5 IRQ_TYPE_LEVEL_LOW>; - /* fsl,weim-cs-timing is a i.MX WEIM bus specific property */ - fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100 - 0x00000000 0xa0000240 0x00000000>; - /* optional subnode for a card plugged into the first host */ - #address-cells = <1>; - #size-cells = <0>; - card@0 { - reg = <0>; - /* card specific properties go here */ - }; - }; -}; diff --git a/drivers/staging/fieldbus/Documentation/fieldbus_dev.txt b/drivers/staging/fieldbus/Documentation/fieldbus_dev.txt deleted file mode 100644 index 89fb8e14676f998224d02aeea7e400285374b6a9..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/Documentation/fieldbus_dev.txt +++ /dev/null @@ -1,66 +0,0 @@ - Fieldbus-Device Subsystem - ============================================ - -Part 0 - What is a Fieldbus Device ? ------------------------------------- - -Fieldbus is the name of a family of industrial computer network protocols used -for real-time distributed control, standardized as IEC 61158. - -A complex automated industrial system -- such as manufacturing assembly line -- -usually needs a distributed control system -- an organized hierarchy of -controller systems -- to function. In this hierarchy, there is usually a -Human Machine Interface (HMI) at the top, where an operator can monitor or -operate the system. This is typically linked to a middle layer of programmable -logic controllers (PLC) via a non-time-critical communications system -(e.g. Ethernet). At the bottom of the control chain is the fieldbus that links -the PLCs to the components that actually do the work, such as sensors, -actuators, electric motors, console lights, switches, valves and contactors. - -(Source: Wikipedia) - -A "Fieldbus Device" is such an actuator, motor, console light, switch, ... -controlled via the Fieldbus by a PLC aka "Fieldbus Controller". - -Communication between PLC and device typically happens via process data memory, -separated into input and output areas. The Fieldbus then cyclically transfers -the PLC's output area to the device's input area, and vice versa. - -Part I - Why do we need this subsystem? ---------------------------------------- - -Fieldbus device (client) adapters are commercially available. They allow data -exchange with a PLC aka "Fieldbus Controller" via process data memory. - -They are typically used when a Linux device wants to expose itself as an -actuator, motor, console light, switch, etc. over the fieldbus. - -The purpose of this subsystem is: -a) present a general, standardized, extensible API/ABI to userspace; and -b) present a convenient interface to drivers. - -Part II - How can drivers use the subsystem? --------------------------------------------- - -Any driver that wants to register as a Fieldbus Device should allocate and -populate a 'struct fieldbus_dev' (from include/linux/fieldbus_dev.h). -Registration then happens by calling fieldbus_dev_register(). - -Part III - How can userspace use the subsystem? ------------------------------------------------ - -Fieldbus protocols and adapters are diverse and varied. However, they share -a limited few common behaviours and properties. This allows us to define -a simple interface consisting of a character device and a set of sysfs files: - -See: -drivers/staging/fieldbus/Documentation/ABI/sysfs-class-fieldbus-dev -drivers/staging/fieldbus/Documentation/ABI/fieldbus-dev-cdev - -Note that this simple interface does not provide a way to modify adapter -configuration settings. It is therefore useful only for adapters that get their -configuration settings some other way, e.g. non-volatile memory on the adapter, -through the network, ... - -At a later phase, this simple interface can easily co-exist with a future -(netlink-based ?) configuration settings interface. diff --git a/drivers/staging/fieldbus/Kconfig b/drivers/staging/fieldbus/Kconfig deleted file mode 100644 index b0b865acccfbc0177780d01fc2a3c6806b3301b1..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -menuconfig FIELDBUS_DEV - tristate "Fieldbus Device Support" - help - Support for Fieldbus Device Adapters. - - Fieldbus device (client) adapters allow data exchange with a PLC aka. - "Fieldbus Controller" over a fieldbus (Profinet, FLNet, etc.) - - They are typically used when a Linux device wants to expose itself - as an actuator, motor, console light, switch, etc. over the fieldbus. - - This framework is designed to provide a generic interface to Fieldbus - Devices from both the Linux Kernel and the userspace. - - If unsure, say no. - -source "drivers/staging/fieldbus/anybuss/Kconfig" - diff --git a/drivers/staging/fieldbus/Makefile b/drivers/staging/fieldbus/Makefile deleted file mode 100644 index bdf645d41344d6cccb8c0795a084565b4c70c7f1..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for fieldbus_dev drivers. -# - -obj-$(CONFIG_FIELDBUS_DEV) += fieldbus_dev.o anybuss/ -fieldbus_dev-y := dev_core.o diff --git a/drivers/staging/fieldbus/TODO b/drivers/staging/fieldbus/TODO deleted file mode 100644 index 6d6626af4ec7de4b09620239fc443c50723a2776..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/TODO +++ /dev/null @@ -1,5 +0,0 @@ -TODO: --Get more people/drivers to use the Fieldbus userspace ABI. It requires - verification/sign-off by multiple users. - -Contact: Sven Van Asbroeck diff --git a/drivers/staging/fieldbus/anybuss/Kconfig b/drivers/staging/fieldbus/anybuss/Kconfig deleted file mode 100644 index 635a0a7b7dd29b66a010a7d767ea946b6ac865ab..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/anybuss/Kconfig +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config HMS_ANYBUSS_BUS - tristate "HMS Anybus-S Bus Support" - select REGMAP - depends on OF && FIELDBUS_DEV - help - Driver for the HMS Industrial Networks Anybus-S bus. - You can attach a single Anybus-S compatible card to it, which - typically provides fieldbus and industrial ethernet - functionality. - -if HMS_ANYBUSS_BUS - -config ARCX_ANYBUS_CONTROLLER - tristate "Arcx Anybus-S Controller" - depends on OF && GPIOLIB && HAS_IOMEM && REGULATOR - select REGMAP_MMIO - help - Select this to get support for the Arcx Anybus controller. - It connects to the SoC via a parallel memory bus, and - embeds up to two Anybus-S buses (slots). - There is also a CAN power readout, unrelated to the Anybus, - modelled as a regulator. - -config HMS_PROFINET - tristate "HMS Profinet IRT Controller (Anybus-S)" - depends on FIELDBUS_DEV && HMS_ANYBUSS_BUS - help - If you say yes here you get support for the HMS Industrial - Networks Profinet IRT Controller. - - It will be registered with the kernel as a fieldbus_dev, - so userspace can interact with it via the fieldbus_dev userspace - interface(s). - - This driver can also be built as a module. If so, the module - will be called hms-profinet. - - If unsure, say N. - -endif diff --git a/drivers/staging/fieldbus/anybuss/Makefile b/drivers/staging/fieldbus/anybuss/Makefile deleted file mode 100644 index 3ad3dcc6be56bd68a4624237cd4b739e1c630640..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/anybuss/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for anybuss drivers. -# - -obj-$(CONFIG_HMS_ANYBUSS_BUS) += anybuss_core.o -anybuss_core-y += host.o - -obj-$(CONFIG_ARCX_ANYBUS_CONTROLLER) += arcx-anybus.o -obj-$(CONFIG_HMS_PROFINET) += hms-profinet.o diff --git a/drivers/staging/fieldbus/anybuss/anybuss-client.h b/drivers/staging/fieldbus/anybuss/anybuss-client.h deleted file mode 100644 index c21c4bebfb845763d9f12eb4ad8a8311197fcf33..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/anybuss/anybuss-client.h +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Anybus-S client adapter definitions - * - * Copyright 2018 Arcx Inc - */ - -#ifndef __LINUX_ANYBUSS_CLIENT_H__ -#define __LINUX_ANYBUSS_CLIENT_H__ - -#include -#include -#include - -/* move to when taking this out of staging */ -#include "../fieldbus_dev.h" - -struct anybuss_host; - -struct anybuss_client { - struct device dev; - struct anybuss_host *host; - __be16 anybus_id; - /* - * these can be optionally set by the client to receive event - * notifications from the host. - */ - void (*on_area_updated)(struct anybuss_client *client); - void (*on_online_changed)(struct anybuss_client *client, bool online); -}; - -struct anybuss_client_driver { - struct device_driver driver; - int (*probe)(struct anybuss_client *adev); - void (*remove)(struct anybuss_client *adev); - u16 anybus_id; -}; - -int anybuss_client_driver_register(struct anybuss_client_driver *drv); -void anybuss_client_driver_unregister(struct anybuss_client_driver *drv); - -static inline struct anybuss_client *to_anybuss_client(struct device *dev) -{ - return container_of(dev, struct anybuss_client, dev); -} - -#define to_anybuss_client_driver(__drv) container_of_const(__drv, struct anybuss_client_driver, driver) - -static inline void * -anybuss_get_drvdata(const struct anybuss_client *client) -{ - return dev_get_drvdata(&client->dev); -} - -static inline void -anybuss_set_drvdata(struct anybuss_client *client, void *data) -{ - dev_set_drvdata(&client->dev, data); -} - -int anybuss_set_power(struct anybuss_client *client, bool power_on); - -struct anybuss_memcfg { - u16 input_io; - u16 input_dpram; - u16 input_total; - - u16 output_io; - u16 output_dpram; - u16 output_total; - - enum fieldbus_dev_offl_mode offl_mode; -}; - -int anybuss_start_init(struct anybuss_client *client, - const struct anybuss_memcfg *cfg); -int anybuss_finish_init(struct anybuss_client *client); -int anybuss_read_fbctrl(struct anybuss_client *client, u16 addr, - void *buf, size_t count); -int anybuss_send_msg(struct anybuss_client *client, u16 cmd_num, - const void *buf, size_t count); -int anybuss_send_ext(struct anybuss_client *client, u16 cmd_num, - const void *buf, size_t count); -int anybuss_recv_msg(struct anybuss_client *client, u16 cmd_num, - void *buf, size_t count); - -/* these help clients make a struct file_operations */ -int anybuss_write_input(struct anybuss_client *client, - const char __user *buf, size_t size, - loff_t *offset); -int anybuss_read_output(struct anybuss_client *client, - char __user *buf, size_t size, - loff_t *offset); - -#endif /* __LINUX_ANYBUSS_CLIENT_H__ */ diff --git a/drivers/staging/fieldbus/anybuss/anybuss-controller.h b/drivers/staging/fieldbus/anybuss/anybuss-controller.h deleted file mode 100644 index 02fa0749043bd91270107d196488d690284b8f00..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/anybuss/anybuss-controller.h +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Anybus-S controller definitions - * - * Copyright 2018 Arcx Inc - */ - -#ifndef __LINUX_ANYBUSS_CONTROLLER_H__ -#define __LINUX_ANYBUSS_CONTROLLER_H__ - -#include -#include - -/* - * To instantiate an Anybus-S host, a controller should provide the following: - * - a reset function which resets the attached card; - * - a regmap which provides access to the attached card's dpram; - * - the irq of the attached card - */ -/** - * struct anybuss_ops - Controller resources to instantiate an Anybus-S host - * - * @reset: asserts/deasserts the anybus card's reset line. - * @regmap: provides access to the card's dual-port RAM area. - * @irq: number of the interrupt connected to the card's interrupt line. - * @host_idx: for multi-host controllers, the host index: - * 0 for the first host on the controller, 1 for the second, etc. - */ -struct anybuss_ops { - void (*reset)(struct device *dev, bool assert); - struct regmap *regmap; - int irq; - int host_idx; -}; - -struct anybuss_host; - -struct anybuss_host * __must_check -anybuss_host_common_probe(struct device *dev, - const struct anybuss_ops *ops); -void anybuss_host_common_remove(struct anybuss_host *host); - -struct anybuss_host * __must_check -devm_anybuss_host_common_probe(struct device *dev, - const struct anybuss_ops *ops); - -#endif /* __LINUX_ANYBUSS_CONTROLLER_H__ */ diff --git a/drivers/staging/fieldbus/anybuss/arcx-anybus.c b/drivers/staging/fieldbus/anybuss/arcx-anybus.c deleted file mode 100644 index fcd3e3722ae017f7714e7bac786e48b48eb2b33c..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/anybuss/arcx-anybus.c +++ /dev/null @@ -1,379 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Arcx Anybus-S Controller driver - * - * Copyright (C) 2018 Arcx Inc - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* move to when taking this out of staging */ -#include "anybuss-controller.h" - -#define CPLD_STATUS1 0x80 -#define CPLD_CONTROL 0x80 -#define CPLD_CONTROL_CRST 0x40 -#define CPLD_CONTROL_RST1 0x04 -#define CPLD_CONTROL_RST2 0x80 -#define CPLD_STATUS1_AB 0x02 -#define CPLD_STATUS1_CAN_POWER 0x01 -#define CPLD_DESIGN_LO 0x81 -#define CPLD_DESIGN_HI 0x82 -#define CPLD_CAP 0x83 -#define CPLD_CAP_COMPAT 0x01 -#define CPLD_CAP_SEP_RESETS 0x02 - -struct controller_priv { - struct device *class_dev; - bool common_reset; - struct gpio_desc *reset_gpiod; - void __iomem *cpld_base; - struct mutex ctrl_lock; /* protects CONTROL register */ - u8 control_reg; - char version[3]; - u16 design_no; -}; - -static void do_reset(struct controller_priv *cd, u8 rst_bit, bool reset) -{ - mutex_lock(&cd->ctrl_lock); - /* - * CPLD_CONTROL is write-only, so cache its value in - * cd->control_reg - */ - if (reset) - cd->control_reg &= ~rst_bit; - else - cd->control_reg |= rst_bit; - writeb(cd->control_reg, cd->cpld_base + CPLD_CONTROL); - /* - * h/w work-around: - * the hardware is 'too fast', so a reset followed by an immediate - * not-reset will _not_ change the anybus reset line in any way, - * losing the reset. to prevent this from happening, introduce - * a minimum reset duration. - * Verified minimum safe duration required using a scope - * on 14-June-2018: 100 us. - */ - if (reset) - usleep_range(100, 200); - mutex_unlock(&cd->ctrl_lock); -} - -static int anybuss_reset(struct controller_priv *cd, - unsigned long id, bool reset) -{ - if (id >= 2) - return -EINVAL; - if (cd->common_reset) - do_reset(cd, CPLD_CONTROL_CRST, reset); - else - do_reset(cd, id ? CPLD_CONTROL_RST2 : CPLD_CONTROL_RST1, reset); - return 0; -} - -static void export_reset_0(struct device *dev, bool assert) -{ - struct controller_priv *cd = dev_get_drvdata(dev); - - anybuss_reset(cd, 0, assert); -} - -static void export_reset_1(struct device *dev, bool assert) -{ - struct controller_priv *cd = dev_get_drvdata(dev); - - anybuss_reset(cd, 1, assert); -} - -/* - * parallel bus limitation: - * - * the anybus is 8-bit wide. we can't assume that the hardware will translate - * word accesses on the parallel bus to multiple byte-accesses on the anybus. - * - * the imx WEIM bus does not provide this type of translation. - * - * to be safe, we will limit parallel bus accesses to a single byte - * at a time for now. - */ - -static const struct regmap_config arcx_regmap_cfg = { - .reg_bits = 16, - .val_bits = 8, - .max_register = 0x7ff, - .use_single_read = true, - .use_single_write = true, - /* - * single-byte parallel bus accesses are atomic, so don't - * require any synchronization. - */ - .disable_locking = true, -}; - -static struct regmap *create_parallel_regmap(struct platform_device *pdev, - int idx) -{ - void __iomem *base; - struct device *dev = &pdev->dev; - - base = devm_platform_ioremap_resource(pdev, idx + 1); - if (IS_ERR(base)) - return ERR_CAST(base); - return devm_regmap_init_mmio(dev, base, &arcx_regmap_cfg); -} - -static struct anybuss_host * -create_anybus_host(struct platform_device *pdev, int idx) -{ - struct anybuss_ops ops = {}; - - switch (idx) { - case 0: - ops.reset = export_reset_0; - break; - case 1: - ops.reset = export_reset_1; - break; - default: - return ERR_PTR(-EINVAL); - } - ops.host_idx = idx; - ops.regmap = create_parallel_regmap(pdev, idx); - if (IS_ERR(ops.regmap)) - return ERR_CAST(ops.regmap); - ops.irq = platform_get_irq(pdev, idx); - if (ops.irq < 0) - return ERR_PTR(ops.irq); - return devm_anybuss_host_common_probe(&pdev->dev, &ops); -} - -static ssize_t version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct controller_priv *cd = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", cd->version); -} -static DEVICE_ATTR_RO(version); - -static ssize_t design_number_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct controller_priv *cd = dev_get_drvdata(dev); - - return sprintf(buf, "%d\n", cd->design_no); -} -static DEVICE_ATTR_RO(design_number); - -static struct attribute *controller_attributes[] = { - &dev_attr_version.attr, - &dev_attr_design_number.attr, - NULL, -}; - -static const struct attribute_group controller_attribute_group = { - .attrs = controller_attributes, -}; - -static const struct attribute_group *controller_attribute_groups[] = { - &controller_attribute_group, - NULL, -}; - -static void controller_device_release(struct device *dev) -{ - kfree(dev); -} - -static int can_power_is_enabled(struct regulator_dev *rdev) -{ - struct controller_priv *cd = rdev_get_drvdata(rdev); - - return !(readb(cd->cpld_base + CPLD_STATUS1) & CPLD_STATUS1_CAN_POWER); -} - -static const struct regulator_ops can_power_ops = { - .is_enabled = can_power_is_enabled, -}; - -static const struct regulator_desc can_power_desc = { - .name = "regulator-can-power", - .id = -1, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .ops = &can_power_ops, -}; - -static const struct class controller_class = { - .name = "arcx_anybus_controller", -}; - -static DEFINE_IDA(controller_index_ida); - -static int controller_probe(struct platform_device *pdev) -{ - struct controller_priv *cd; - struct device *dev = &pdev->dev; - struct regulator_config config = { }; - struct regulator_dev *regulator; - int err, id; - struct anybuss_host *host; - u8 status1, cap; - - cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL); - if (!cd) - return -ENOMEM; - dev_set_drvdata(dev, cd); - mutex_init(&cd->ctrl_lock); - cd->reset_gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(cd->reset_gpiod)) - return PTR_ERR(cd->reset_gpiod); - - /* CPLD control memory, sits at index 0 */ - cd->cpld_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(cd->cpld_base)) { - dev_err(dev, - "failed to map cpld base address\n"); - err = PTR_ERR(cd->cpld_base); - goto out_reset; - } - - /* identify cpld */ - status1 = readb(cd->cpld_base + CPLD_STATUS1); - cd->design_no = (readb(cd->cpld_base + CPLD_DESIGN_HI) << 8) | - readb(cd->cpld_base + CPLD_DESIGN_LO); - snprintf(cd->version, sizeof(cd->version), "%c%d", - 'A' + ((status1 >> 5) & 0x7), - (status1 >> 2) & 0x7); - dev_info(dev, "design number %d, revision %s\n", - cd->design_no, - cd->version); - cap = readb(cd->cpld_base + CPLD_CAP); - if (!(cap & CPLD_CAP_COMPAT)) { - dev_err(dev, "unsupported controller [cap=0x%02X]", cap); - err = -ENODEV; - goto out_reset; - } - - if (status1 & CPLD_STATUS1_AB) { - dev_info(dev, "has anybus-S slot(s)"); - cd->common_reset = !(cap & CPLD_CAP_SEP_RESETS); - dev_info(dev, "supports %s", cd->common_reset ? - "a common reset" : "separate resets"); - for (id = 0; id < 2; id++) { - host = create_anybus_host(pdev, id); - if (!IS_ERR(host)) - continue; - err = PTR_ERR(host); - /* -ENODEV is fine, it just means no card detected */ - if (err != -ENODEV) - goto out_reset; - } - } - - id = ida_alloc(&controller_index_ida, GFP_KERNEL); - if (id < 0) { - err = id; - goto out_reset; - } - /* export can power readout as a regulator */ - config.dev = dev; - config.driver_data = cd; - regulator = devm_regulator_register(dev, &can_power_desc, &config); - if (IS_ERR(regulator)) { - err = PTR_ERR(regulator); - goto out_ida; - } - /* make controller info visible to userspace */ - cd->class_dev = kzalloc(sizeof(*cd->class_dev), GFP_KERNEL); - if (!cd->class_dev) { - err = -ENOMEM; - goto out_ida; - } - cd->class_dev->class = &controller_class; - cd->class_dev->groups = controller_attribute_groups; - cd->class_dev->parent = dev; - cd->class_dev->id = id; - cd->class_dev->release = controller_device_release; - dev_set_name(cd->class_dev, "%d", cd->class_dev->id); - dev_set_drvdata(cd->class_dev, cd); - err = device_register(cd->class_dev); - if (err) - goto out_dev; - return 0; -out_dev: - put_device(cd->class_dev); -out_ida: - ida_free(&controller_index_ida, id); -out_reset: - gpiod_set_value_cansleep(cd->reset_gpiod, 1); - return err; -} - -static void controller_remove(struct platform_device *pdev) -{ - struct controller_priv *cd = platform_get_drvdata(pdev); - int id = cd->class_dev->id; - - device_unregister(cd->class_dev); - ida_free(&controller_index_ida, id); - gpiod_set_value_cansleep(cd->reset_gpiod, 1); -} - -static const struct of_device_id controller_of_match[] = { - { .compatible = "arcx,anybus-controller" }, - { } -}; - -MODULE_DEVICE_TABLE(of, controller_of_match); - -static struct platform_driver controller_driver = { - .probe = controller_probe, - .remove_new = controller_remove, - .driver = { - .name = "arcx-anybus-controller", - .of_match_table = controller_of_match, - }, -}; - -static int __init controller_init(void) -{ - int err; - - err = class_register(&controller_class); - if (err) - return err; - err = platform_driver_register(&controller_driver); - if (err) - class_unregister(&controller_class); - - return err; -} - -static void __exit controller_exit(void) -{ - platform_driver_unregister(&controller_driver); - class_unregister(&controller_class); - ida_destroy(&controller_index_ida); -} - -module_init(controller_init); -module_exit(controller_exit); - -MODULE_DESCRIPTION("Arcx Anybus-S Controller driver"); -MODULE_AUTHOR("Sven Van Asbroeck "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/fieldbus/anybuss/hms-profinet.c b/drivers/staging/fieldbus/anybuss/hms-profinet.c deleted file mode 100644 index e691736a53f178349db87b64dcca476a55f97a3f..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/anybuss/hms-profinet.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * HMS Profinet Client Driver - * - * Copyright (C) 2018 Arcx Inc - */ - -#include -#include -#include -#include - -/* move to when taking this out of staging */ -#include "../fieldbus_dev.h" - -/* move to when taking this out of staging */ -#include "anybuss-client.h" - -#define PROFI_DPRAM_SIZE 512 - -/* - * --------------------------------------------------------------- - * Anybus Profinet mailbox messages - definitions - * --------------------------------------------------------------- - * note that we're depending on the layout of these structures being - * exactly as advertised. - */ - -struct msg_mac_addr { - u8 addr[6]; -}; - -struct profi_priv { - struct fieldbus_dev fbdev; - struct anybuss_client *client; - struct mutex enable_lock; /* serializes card enable */ - bool power_on; -}; - -static ssize_t -profi_read_area(struct fieldbus_dev *fbdev, char __user *buf, size_t size, - loff_t *offset) -{ - struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev); - - return anybuss_read_output(priv->client, buf, size, offset); -} - -static ssize_t -profi_write_area(struct fieldbus_dev *fbdev, const char __user *buf, - size_t size, loff_t *offset) -{ - struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev); - - return anybuss_write_input(priv->client, buf, size, offset); -} - -static int profi_id_get(struct fieldbus_dev *fbdev, char *buf, - size_t max_size) -{ - struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev); - struct msg_mac_addr response; - int ret; - - ret = anybuss_recv_msg(priv->client, 0x0010, &response, - sizeof(response)); - if (ret < 0) - return ret; - return snprintf(buf, max_size, "%pM\n", response.addr); -} - -static bool profi_enable_get(struct fieldbus_dev *fbdev) -{ - struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev); - bool power_on; - - mutex_lock(&priv->enable_lock); - power_on = priv->power_on; - mutex_unlock(&priv->enable_lock); - - return power_on; -} - -static int __profi_enable(struct profi_priv *priv) -{ - int ret; - struct anybuss_client *client = priv->client; - /* Initialization Sequence, Generic Anybus Mode */ - const struct anybuss_memcfg mem_cfg = { - .input_io = 220, - .input_dpram = PROFI_DPRAM_SIZE, - .input_total = PROFI_DPRAM_SIZE, - .output_io = 220, - .output_dpram = PROFI_DPRAM_SIZE, - .output_total = PROFI_DPRAM_SIZE, - .offl_mode = FIELDBUS_DEV_OFFL_MODE_CLEAR, - }; - - /* - * switch anybus off then on, this ensures we can do a complete - * configuration cycle in case anybus was already on. - */ - anybuss_set_power(client, false); - ret = anybuss_set_power(client, true); - if (ret) - goto err; - ret = anybuss_start_init(client, &mem_cfg); - if (ret) - goto err; - ret = anybuss_finish_init(client); - if (ret) - goto err; - priv->power_on = true; - return 0; - -err: - anybuss_set_power(client, false); - priv->power_on = false; - return ret; -} - -static int __profi_disable(struct profi_priv *priv) -{ - struct anybuss_client *client = priv->client; - - anybuss_set_power(client, false); - priv->power_on = false; - return 0; -} - -static int profi_simple_enable(struct fieldbus_dev *fbdev, bool enable) -{ - int ret; - struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev); - - mutex_lock(&priv->enable_lock); - if (enable) - ret = __profi_enable(priv); - else - ret = __profi_disable(priv); - mutex_unlock(&priv->enable_lock); - - return ret; -} - -static void profi_on_area_updated(struct anybuss_client *client) -{ - struct profi_priv *priv = anybuss_get_drvdata(client); - - fieldbus_dev_area_updated(&priv->fbdev); -} - -static void profi_on_online_changed(struct anybuss_client *client, bool online) -{ - struct profi_priv *priv = anybuss_get_drvdata(client); - - fieldbus_dev_online_changed(&priv->fbdev, online); -} - -static int profinet_probe(struct anybuss_client *client) -{ - struct profi_priv *priv; - struct device *dev = &client->dev; - int err; - - client->on_area_updated = profi_on_area_updated; - client->on_online_changed = profi_on_online_changed; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - mutex_init(&priv->enable_lock); - priv->client = client; - priv->fbdev.read_area_sz = PROFI_DPRAM_SIZE; - priv->fbdev.write_area_sz = PROFI_DPRAM_SIZE; - priv->fbdev.card_name = "HMS Profinet IRT (Anybus-S)"; - priv->fbdev.fieldbus_type = FIELDBUS_DEV_TYPE_PROFINET; - priv->fbdev.read_area = profi_read_area; - priv->fbdev.write_area = profi_write_area; - priv->fbdev.fieldbus_id_get = profi_id_get; - priv->fbdev.enable_get = profi_enable_get; - priv->fbdev.simple_enable_set = profi_simple_enable; - priv->fbdev.parent = dev; - err = fieldbus_dev_register(&priv->fbdev); - if (err < 0) - return err; - dev_info(dev, "card detected, registered as %s", - dev_name(priv->fbdev.dev)); - anybuss_set_drvdata(client, priv); - - return 0; -} - -static void profinet_remove(struct anybuss_client *client) -{ - struct profi_priv *priv = anybuss_get_drvdata(client); - - fieldbus_dev_unregister(&priv->fbdev); -} - -static struct anybuss_client_driver profinet_driver = { - .probe = profinet_probe, - .remove = profinet_remove, - .driver = { - .name = "hms-profinet", - .owner = THIS_MODULE, - }, - .anybus_id = 0x0089, -}; - -static int __init profinet_init(void) -{ - return anybuss_client_driver_register(&profinet_driver); -} -module_init(profinet_init); - -static void __exit profinet_exit(void) -{ - return anybuss_client_driver_unregister(&profinet_driver); -} -module_exit(profinet_exit); - -MODULE_AUTHOR("Sven Van Asbroeck "); -MODULE_DESCRIPTION("HMS Profinet IRT Driver (Anybus-S)"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/fieldbus/anybuss/host.c b/drivers/staging/fieldbus/anybuss/host.c deleted file mode 100644 index 4f2b2fce92eec44f34620a344eb2d3165334cd65..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/anybuss/host.c +++ /dev/null @@ -1,1452 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * HMS Anybus-S Host Driver - * - * Copyright (C) 2018 Arcx Inc - */ - -/* - * Architecture Overview - * ===================== - * This driver (running on the CPU/SoC) and the Anybus-S card communicate - * by reading and writing data to/from the Anybus-S Dual-Port RAM (dpram). - * This is memory connected to both the SoC and Anybus-S card, which both sides - * can access freely and concurrently. - * - * Synchronization happens by means of two registers located in the dpram: - * IND_AB: written exclusively by the Anybus card; and - * IND_AP: written exclusively by this driver. - * - * Communication happens using one of the following mechanisms: - * 1. reserve, read/write, release dpram memory areas: - * using an IND_AB/IND_AP protocol, the driver is able to reserve certain - * memory areas. no dpram memory can be read or written except if reserved. - * (with a few limited exceptions) - * 2. send and receive data structures via a shared mailbox: - * using an IND_AB/IND_AP protocol, the driver and Anybus card are able to - * exchange commands and responses using a shared mailbox. - * 3. receive software interrupts: - * using an IND_AB/IND_AP protocol, the Anybus card is able to notify the - * driver of certain events such as: bus online/offline, data available. - * note that software interrupt event bits are located in a memory area - * which must be reserved before it can be accessed. - * - * The manual[1] is silent on whether these mechanisms can happen concurrently, - * or how they should be synchronized. However, section 13 (Driver Example) - * provides the following suggestion for developing a driver: - * a) an interrupt handler which updates global variables; - * b) a continuously-running task handling area requests (1 above) - * c) a continuously-running task handling mailbox requests (2 above) - * The example conspicuously leaves out software interrupts (3 above), which - * is the thorniest issue to get right (see below). - * - * The naive, straightforward way to implement this would be: - * - create an isr which updates shared variables; - * - create a work_struct which handles software interrupts on a queue; - * - create a function which does reserve/update/unlock in a loop; - * - create a function which does mailbox send/receive in a loop; - * - call the above functions from the driver's read/write/ioctl; - * - synchronize using mutexes/spinlocks: - * + only one area request at a time - * + only one mailbox request at a time - * + protect AB_IND, AB_IND against data hazards (e.g. read-after-write) - * - * Unfortunately, the presence of the software interrupt causes subtle yet - * considerable synchronization issues; especially problematic is the - * requirement to reserve/release the area which contains the status bits. - * - * The driver architecture presented here sidesteps these synchronization issues - * by accessing the dpram from a single kernel thread only. User-space throws - * "tasks" (i.e. 1, 2 above) into a task queue, waits for their completion, - * and the kernel thread runs them to completion. - * - * Each task has a task_function, which is called/run by the queue thread. - * That function communicates with the Anybus card, and returns either - * 0 (OK), a negative error code (error), or -EINPROGRESS (waiting). - * On OK or error, the queue thread completes and dequeues the task, - * which also releases the user space thread which may still be waiting for it. - * On -EINPROGRESS (waiting), the queue thread will leave the task on the queue, - * and revisit (call again) whenever an interrupt event comes in. - * - * Each task has a state machine, which is run by calling its task_function. - * It ensures that the task will go through its various stages over time, - * returning -EINPROGRESS if it wants to wait for an event to happen. - * - * Note that according to the manual's driver example, the following operations - * may run independent of each other: - * - area reserve/read/write/release (point 1 above) - * - mailbox operations (point 2 above) - * - switching power on/off - * - * To allow them to run independently, each operation class gets its own queue. - * - * Userspace processes A, B, C, D post tasks to the appropriate queue, - * and wait for task completion: - * - * process A B C D - * | | | | - * v v v v - * |<----- ======================================== - * | | | | - * | v v v-------<-------+ - * | +--------------------------------------+ | - * | | power q | mbox q | area q | | - * | |------------|------------|------------| | - * | | task | task | task | | - * | | task | task | task | | - * | | task wait | task wait | task wait | | - * | +--------------------------------------+ | - * | ^ ^ ^ | - * | | | | ^ - * | +--------------------------------------+ | - * | | queue thread | | - * | |--------------------------------------| | - * | | single-threaded: | | - * | | loop: | | - * v | for each queue: | | - * | | run task state machine | | - * | | if task waiting: | | - * | | leave on queue | | - * | | if task done: | | - * | | complete task, remove from q | | - * | | if software irq event bits set: | | - * | | notify userspace | | - * | | post clear event bits task------>|>-------+ - * | | wait for IND_AB changed event OR | - * | | task added event OR | - * | | timeout | - * | | end loop | - * | +--------------------------------------+ - * | + wake up + - * | +--------------------------------------+ - * | ^ ^ - * | | | - * +-------->------- | - * | - * +--------------------------------------+ - * | interrupt service routine | - * |--------------------------------------| - * | wake up queue thread on IND_AB change| - * +--------------------------------------+ - * - * Note that the Anybus interrupt is dual-purpose: - * - after a reset, triggered when the card becomes ready; - * - during normal operation, triggered when AB_IND changes. - * This is why the interrupt service routine doesn't just wake up the - * queue thread, but also completes the card_boot completion. - * - * [1] https://www.anybus.com/docs/librariesprovider7/default-document-library/ - * manuals-design-guides/hms-hmsi-27-275.pdf - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* move to when taking this out of staging */ -#include "anybuss-client.h" -#include "anybuss-controller.h" - -#define DPRAM_SIZE 0x800 -#define MAX_MBOX_MSG_SZ 0x0FF -#define TIMEOUT (HZ * 2) -#define MAX_DATA_AREA_SZ 0x200 -#define MAX_FBCTRL_AREA_SZ 0x1BE - -#define REG_BOOTLOADER_V 0x7C0 -#define REG_API_V 0x7C2 -#define REG_FIELDBUS_V 0x7C4 -#define REG_SERIAL_NO 0x7C6 -#define REG_FIELDBUS_TYPE 0x7CC -#define REG_MODULE_SW_V 0x7CE -#define REG_IND_AB 0x7FF -#define REG_IND_AP 0x7FE -#define REG_EVENT_CAUSE 0x7ED -#define MBOX_IN_AREA 0x400 -#define MBOX_OUT_AREA 0x520 -#define DATA_IN_AREA 0x000 -#define DATA_OUT_AREA 0x200 -#define FBCTRL_AREA 0x640 - -#define EVENT_CAUSE_DC 0x01 -#define EVENT_CAUSE_FBOF 0x02 -#define EVENT_CAUSE_FBON 0x04 - -#define IND_AB_UPDATED 0x08 -#define IND_AX_MIN 0x80 -#define IND_AX_MOUT 0x40 -#define IND_AX_IN 0x04 -#define IND_AX_OUT 0x02 -#define IND_AX_FBCTRL 0x01 -#define IND_AP_LOCK 0x08 -#define IND_AP_ACTION 0x10 -#define IND_AX_EVNT 0x20 -#define IND_AP_ABITS (IND_AX_IN | IND_AX_OUT | \ - IND_AX_FBCTRL | \ - IND_AP_ACTION | IND_AP_LOCK) - -#define INFO_TYPE_FB 0x0002 -#define INFO_TYPE_APP 0x0001 -#define INFO_COMMAND 0x4000 - -#define OP_MODE_FBFC 0x0002 -#define OP_MODE_FBS 0x0004 -#define OP_MODE_CD 0x0200 - -#define CMD_START_INIT 0x0001 -#define CMD_ANYBUS_INIT 0x0002 -#define CMD_END_INIT 0x0003 - -/* - * --------------------------------------------------------------- - * Anybus mailbox messages - definitions - * --------------------------------------------------------------- - * note that we're depending on the layout of these structures being - * exactly as advertised. - */ - -struct anybus_mbox_hdr { - __be16 id; - __be16 info; - __be16 cmd_num; - __be16 data_size; - __be16 frame_count; - __be16 frame_num; - __be16 offset_high; - __be16 offset_low; - __be16 extended[8]; -}; - -struct msg_anybus_init { - __be16 input_io_len; - __be16 input_dpram_len; - __be16 input_total_len; - __be16 output_io_len; - __be16 output_dpram_len; - __be16 output_total_len; - __be16 op_mode; - __be16 notif_config; - __be16 wd_val; -}; - -/* ------------- ref counted tasks ------------- */ - -struct ab_task; -typedef int (*ab_task_fn_t)(struct anybuss_host *cd, - struct ab_task *t); -typedef void (*ab_done_fn_t)(struct anybuss_host *cd); - -struct area_priv { - bool is_write; - u16 flags; - u16 addr; - size_t count; - u8 buf[MAX_DATA_AREA_SZ]; -}; - -struct mbox_priv { - struct anybus_mbox_hdr hdr; - size_t msg_out_sz; - size_t msg_in_sz; - u8 msg[MAX_MBOX_MSG_SZ]; -}; - -struct ab_task { - struct kmem_cache *cache; - struct kref refcount; - ab_task_fn_t task_fn; - ab_done_fn_t done_fn; - int result; - struct completion done; - unsigned long start_jiffies; - union { - struct area_priv area_pd; - struct mbox_priv mbox_pd; - }; -}; - -static struct ab_task *ab_task_create_get(struct kmem_cache *cache, - ab_task_fn_t task_fn) -{ - struct ab_task *t; - - t = kmem_cache_alloc(cache, GFP_KERNEL); - if (!t) - return NULL; - t->cache = cache; - kref_init(&t->refcount); - t->task_fn = task_fn; - t->done_fn = NULL; - t->result = 0; - init_completion(&t->done); - return t; -} - -static void __ab_task_destroy(struct kref *refcount) -{ - struct ab_task *t = container_of(refcount, struct ab_task, refcount); - struct kmem_cache *cache = t->cache; - - kmem_cache_free(cache, t); -} - -static void ab_task_put(struct ab_task *t) -{ - kref_put(&t->refcount, __ab_task_destroy); -} - -static struct ab_task *__ab_task_get(struct ab_task *t) -{ - kref_get(&t->refcount); - return t; -} - -static void __ab_task_finish(struct ab_task *t, struct anybuss_host *cd) -{ - if (t->done_fn) - t->done_fn(cd); - complete(&t->done); -} - -static void -ab_task_dequeue_finish_put(struct kfifo *q, struct anybuss_host *cd) -{ - int ret; - struct ab_task *t; - - ret = kfifo_out(q, &t, sizeof(t)); - WARN_ON(!ret); - __ab_task_finish(t, cd); - ab_task_put(t); -} - -static int -ab_task_enqueue(struct ab_task *t, struct kfifo *q, spinlock_t *slock, - wait_queue_head_t *wq) -{ - int ret; - - t->start_jiffies = jiffies; - __ab_task_get(t); - ret = kfifo_in_spinlocked(q, &t, sizeof(t), slock); - if (!ret) { - ab_task_put(t); - return -ENOMEM; - } - wake_up(wq); - return 0; -} - -static int -ab_task_enqueue_wait(struct ab_task *t, struct kfifo *q, spinlock_t *slock, - wait_queue_head_t *wq) -{ - int ret; - - ret = ab_task_enqueue(t, q, slock, wq); - if (ret) - return ret; - ret = wait_for_completion_interruptible(&t->done); - if (ret) - return ret; - return t->result; -} - -/* ------------------------ anybus hardware ------------------------ */ - -struct anybuss_host { - struct device *dev; - struct anybuss_client *client; - void (*reset)(struct device *dev, bool assert); - struct regmap *regmap; - int irq; - int host_idx; - struct task_struct *qthread; - wait_queue_head_t wq; - struct completion card_boot; - atomic_t ind_ab; - spinlock_t qlock; /* protects IN side of powerq, mboxq, areaq */ - struct kmem_cache *qcache; - struct kfifo qs[3]; - struct kfifo *powerq; - struct kfifo *mboxq; - struct kfifo *areaq; - bool power_on; - bool softint_pending; -}; - -static void reset_assert(struct anybuss_host *cd) -{ - cd->reset(cd->dev, true); -} - -static void reset_deassert(struct anybuss_host *cd) -{ - cd->reset(cd->dev, false); -} - -static int test_dpram(struct regmap *regmap) -{ - int i; - unsigned int val; - - for (i = 0; i < DPRAM_SIZE; i++) - regmap_write(regmap, i, (u8)i); - for (i = 0; i < DPRAM_SIZE; i++) { - regmap_read(regmap, i, &val); - if ((u8)val != (u8)i) - return -EIO; - } - return 0; -} - -static int read_ind_ab(struct regmap *regmap) -{ - unsigned long timeout = jiffies + HZ / 2; - unsigned int a, b, i = 0; - - while (time_before_eq(jiffies, timeout)) { - regmap_read(regmap, REG_IND_AB, &a); - regmap_read(regmap, REG_IND_AB, &b); - if (likely(a == b)) - return (int)a; - if (i < 10) { - cpu_relax(); - i++; - } else { - usleep_range(500, 1000); - } - } - WARN(1, "IND_AB register not stable"); - return -ETIMEDOUT; -} - -static int write_ind_ap(struct regmap *regmap, unsigned int ind_ap) -{ - unsigned long timeout = jiffies + HZ / 2; - unsigned int v, i = 0; - - while (time_before_eq(jiffies, timeout)) { - regmap_write(regmap, REG_IND_AP, ind_ap); - regmap_read(regmap, REG_IND_AP, &v); - if (likely(ind_ap == v)) - return 0; - if (i < 10) { - cpu_relax(); - i++; - } else { - usleep_range(500, 1000); - } - } - WARN(1, "IND_AP register not stable"); - return -ETIMEDOUT; -} - -static irqreturn_t irq_handler(int irq, void *data) -{ - struct anybuss_host *cd = data; - int ind_ab; - - /* - * irq handler needs exclusive access to the IND_AB register, - * because the act of reading the register acks the interrupt. - * - * store the register value in cd->ind_ab (an atomic_t), so that the - * queue thread is able to read it without causing an interrupt ack - * side-effect (and without spuriously acking an interrupt). - */ - ind_ab = read_ind_ab(cd->regmap); - if (ind_ab < 0) - return IRQ_NONE; - atomic_set(&cd->ind_ab, ind_ab); - complete(&cd->card_boot); - wake_up(&cd->wq); - return IRQ_HANDLED; -} - -/* ------------------------ power on/off tasks --------------------- */ - -static int task_fn_power_off(struct anybuss_host *cd, - struct ab_task *t) -{ - struct anybuss_client *client = cd->client; - - if (!cd->power_on) - return 0; - disable_irq(cd->irq); - reset_assert(cd); - atomic_set(&cd->ind_ab, IND_AB_UPDATED); - if (client->on_online_changed) - client->on_online_changed(client, false); - cd->power_on = false; - return 0; -} - -static int task_fn_power_on_2(struct anybuss_host *cd, - struct ab_task *t) -{ - if (completion_done(&cd->card_boot)) { - cd->power_on = true; - return 0; - } - if (time_after(jiffies, t->start_jiffies + TIMEOUT)) { - disable_irq(cd->irq); - reset_assert(cd); - dev_err(cd->dev, "power on timed out"); - return -ETIMEDOUT; - } - return -EINPROGRESS; -} - -static int task_fn_power_on(struct anybuss_host *cd, - struct ab_task *t) -{ - unsigned int dummy; - - if (cd->power_on) - return 0; - /* - * anybus docs: prevent false 'init done' interrupt by - * doing a dummy read of IND_AB register while in reset. - */ - regmap_read(cd->regmap, REG_IND_AB, &dummy); - reinit_completion(&cd->card_boot); - enable_irq(cd->irq); - reset_deassert(cd); - t->task_fn = task_fn_power_on_2; - return -EINPROGRESS; -} - -int anybuss_set_power(struct anybuss_client *client, bool power_on) -{ - struct anybuss_host *cd = client->host; - struct ab_task *t; - int err; - - t = ab_task_create_get(cd->qcache, power_on ? - task_fn_power_on : task_fn_power_off); - if (!t) - return -ENOMEM; - err = ab_task_enqueue_wait(t, cd->powerq, &cd->qlock, &cd->wq); - ab_task_put(t); - return err; -} -EXPORT_SYMBOL_GPL(anybuss_set_power); - -/* ---------------------------- area tasks ------------------------ */ - -static int task_fn_area_3(struct anybuss_host *cd, struct ab_task *t) -{ - struct area_priv *pd = &t->area_pd; - - if (!cd->power_on) - return -EIO; - if (atomic_read(&cd->ind_ab) & pd->flags) { - /* area not released yet */ - if (time_after(jiffies, t->start_jiffies + TIMEOUT)) - return -ETIMEDOUT; - return -EINPROGRESS; - } - return 0; -} - -static int task_fn_area_2(struct anybuss_host *cd, struct ab_task *t) -{ - struct area_priv *pd = &t->area_pd; - unsigned int ind_ap; - int ret; - - if (!cd->power_on) - return -EIO; - regmap_read(cd->regmap, REG_IND_AP, &ind_ap); - if (!(atomic_read(&cd->ind_ab) & pd->flags)) { - /* we don't own the area yet */ - if (time_after(jiffies, t->start_jiffies + TIMEOUT)) { - dev_warn(cd->dev, "timeout waiting for area"); - dump_stack(); - return -ETIMEDOUT; - } - return -EINPROGRESS; - } - /* we own the area, do what we're here to do */ - if (pd->is_write) - regmap_bulk_write(cd->regmap, pd->addr, pd->buf, - pd->count); - else - regmap_bulk_read(cd->regmap, pd->addr, pd->buf, - pd->count); - /* ask to release the area, must use unlocked release */ - ind_ap &= ~IND_AP_ABITS; - ind_ap |= pd->flags; - ret = write_ind_ap(cd->regmap, ind_ap); - if (ret) - return ret; - t->task_fn = task_fn_area_3; - return -EINPROGRESS; -} - -static int task_fn_area(struct anybuss_host *cd, struct ab_task *t) -{ - struct area_priv *pd = &t->area_pd; - unsigned int ind_ap; - int ret; - - if (!cd->power_on) - return -EIO; - regmap_read(cd->regmap, REG_IND_AP, &ind_ap); - /* ask to take the area */ - ind_ap &= ~IND_AP_ABITS; - ind_ap |= pd->flags | IND_AP_ACTION | IND_AP_LOCK; - ret = write_ind_ap(cd->regmap, ind_ap); - if (ret) - return ret; - t->task_fn = task_fn_area_2; - return -EINPROGRESS; -} - -static struct ab_task * -create_area_reader(struct kmem_cache *qcache, u16 flags, u16 addr, - size_t count) -{ - struct ab_task *t; - struct area_priv *ap; - - t = ab_task_create_get(qcache, task_fn_area); - if (!t) - return NULL; - ap = &t->area_pd; - ap->flags = flags; - ap->addr = addr; - ap->is_write = false; - ap->count = count; - return t; -} - -static struct ab_task * -create_area_writer(struct kmem_cache *qcache, u16 flags, u16 addr, - const void *buf, size_t count) -{ - struct ab_task *t; - struct area_priv *ap; - - t = ab_task_create_get(qcache, task_fn_area); - if (!t) - return NULL; - ap = &t->area_pd; - ap->flags = flags; - ap->addr = addr; - ap->is_write = true; - ap->count = count; - memcpy(ap->buf, buf, count); - return t; -} - -static struct ab_task * -create_area_user_writer(struct kmem_cache *qcache, u16 flags, u16 addr, - const void __user *buf, size_t count) -{ - struct ab_task *t; - struct area_priv *ap; - - t = ab_task_create_get(qcache, task_fn_area); - if (!t) - return ERR_PTR(-ENOMEM); - ap = &t->area_pd; - ap->flags = flags; - ap->addr = addr; - ap->is_write = true; - ap->count = count; - if (copy_from_user(ap->buf, buf, count)) { - ab_task_put(t); - return ERR_PTR(-EFAULT); - } - return t; -} - -static bool area_range_ok(u16 addr, size_t count, u16 area_start, - size_t area_sz) -{ - u16 area_end_ex = area_start + area_sz; - u16 addr_end_ex; - - if (addr < area_start) - return false; - if (addr >= area_end_ex) - return false; - addr_end_ex = addr + count; - if (addr_end_ex > area_end_ex) - return false; - return true; -} - -/* -------------------------- mailbox tasks ----------------------- */ - -static int task_fn_mbox_2(struct anybuss_host *cd, struct ab_task *t) -{ - struct mbox_priv *pd = &t->mbox_pd; - unsigned int ind_ap; - - if (!cd->power_on) - return -EIO; - regmap_read(cd->regmap, REG_IND_AP, &ind_ap); - if (((atomic_read(&cd->ind_ab) ^ ind_ap) & IND_AX_MOUT) == 0) { - /* output message not here */ - if (time_after(jiffies, t->start_jiffies + TIMEOUT)) - return -ETIMEDOUT; - return -EINPROGRESS; - } - /* grab the returned header and msg */ - regmap_bulk_read(cd->regmap, MBOX_OUT_AREA, &pd->hdr, - sizeof(pd->hdr)); - regmap_bulk_read(cd->regmap, MBOX_OUT_AREA + sizeof(pd->hdr), - pd->msg, pd->msg_in_sz); - /* tell anybus we've consumed the message */ - ind_ap ^= IND_AX_MOUT; - return write_ind_ap(cd->regmap, ind_ap); -} - -static int task_fn_mbox(struct anybuss_host *cd, struct ab_task *t) -{ - struct mbox_priv *pd = &t->mbox_pd; - unsigned int ind_ap; - int ret; - - if (!cd->power_on) - return -EIO; - regmap_read(cd->regmap, REG_IND_AP, &ind_ap); - if ((atomic_read(&cd->ind_ab) ^ ind_ap) & IND_AX_MIN) { - /* mbox input area busy */ - if (time_after(jiffies, t->start_jiffies + TIMEOUT)) - return -ETIMEDOUT; - return -EINPROGRESS; - } - /* write the header and msg to input area */ - regmap_bulk_write(cd->regmap, MBOX_IN_AREA, &pd->hdr, - sizeof(pd->hdr)); - regmap_bulk_write(cd->regmap, MBOX_IN_AREA + sizeof(pd->hdr), - pd->msg, pd->msg_out_sz); - /* tell anybus we gave it a message */ - ind_ap ^= IND_AX_MIN; - ret = write_ind_ap(cd->regmap, ind_ap); - if (ret) - return ret; - t->start_jiffies = jiffies; - t->task_fn = task_fn_mbox_2; - return -EINPROGRESS; -} - -static void log_invalid_other(struct device *dev, - struct anybus_mbox_hdr *hdr) -{ - size_t ext_offs = ARRAY_SIZE(hdr->extended) - 1; - u16 code = be16_to_cpu(hdr->extended[ext_offs]); - - dev_err(dev, " Invalid other: [0x%02X]", code); -} - -static const char * const EMSGS[] = { - "Invalid Message ID", - "Invalid Message Type", - "Invalid Command", - "Invalid Data Size", - "Message Header Malformed (offset 008h)", - "Message Header Malformed (offset 00Ah)", - "Message Header Malformed (offset 00Ch - 00Dh)", - "Invalid Address", - "Invalid Response", - "Flash Config Error", -}; - -static int mbox_cmd_err(struct device *dev, struct mbox_priv *mpriv) -{ - int i; - u8 ecode; - struct anybus_mbox_hdr *hdr = &mpriv->hdr; - u16 info = be16_to_cpu(hdr->info); - u8 *phdr = (u8 *)hdr; - u8 *pmsg = mpriv->msg; - - if (!(info & 0x8000)) - return 0; - ecode = (info >> 8) & 0x0F; - dev_err(dev, "mailbox command failed:"); - if (ecode == 0x0F) - log_invalid_other(dev, hdr); - else if (ecode < ARRAY_SIZE(EMSGS)) - dev_err(dev, " Error code: %s (0x%02X)", - EMSGS[ecode], ecode); - else - dev_err(dev, " Error code: 0x%02X\n", ecode); - dev_err(dev, "Failed command:"); - dev_err(dev, "Message Header:"); - for (i = 0; i < sizeof(mpriv->hdr); i += 2) - dev_err(dev, "%02X%02X", phdr[i], phdr[i + 1]); - dev_err(dev, "Message Data:"); - for (i = 0; i < mpriv->msg_in_sz; i += 2) - dev_err(dev, "%02X%02X", pmsg[i], pmsg[i + 1]); - dev_err(dev, "Stack dump:"); - dump_stack(); - return -EIO; -} - -static int _anybus_mbox_cmd(struct anybuss_host *cd, - u16 cmd_num, bool is_fb_cmd, - const void *msg_out, size_t msg_out_sz, - void *msg_in, size_t msg_in_sz, - const void *ext, size_t ext_sz) -{ - struct ab_task *t; - struct mbox_priv *pd; - struct anybus_mbox_hdr *h; - size_t msg_sz = max(msg_in_sz, msg_out_sz); - u16 info; - int err; - - if (msg_sz > MAX_MBOX_MSG_SZ) - return -EINVAL; - if (ext && ext_sz > sizeof(h->extended)) - return -EINVAL; - t = ab_task_create_get(cd->qcache, task_fn_mbox); - if (!t) - return -ENOMEM; - pd = &t->mbox_pd; - h = &pd->hdr; - info = is_fb_cmd ? INFO_TYPE_FB : INFO_TYPE_APP; - /* - * prevent uninitialized memory in the header from being sent - * across the anybus - */ - memset(h, 0, sizeof(*h)); - h->info = cpu_to_be16(info | INFO_COMMAND); - h->cmd_num = cpu_to_be16(cmd_num); - h->data_size = cpu_to_be16(msg_out_sz); - h->frame_count = cpu_to_be16(1); - h->frame_num = cpu_to_be16(1); - h->offset_high = cpu_to_be16(0); - h->offset_low = cpu_to_be16(0); - if (ext) - memcpy(h->extended, ext, ext_sz); - memcpy(pd->msg, msg_out, msg_out_sz); - pd->msg_out_sz = msg_out_sz; - pd->msg_in_sz = msg_in_sz; - err = ab_task_enqueue_wait(t, cd->powerq, &cd->qlock, &cd->wq); - if (err) - goto out; - /* - * mailbox mechanism worked ok, but maybe the mbox response - * contains an error ? - */ - err = mbox_cmd_err(cd->dev, pd); - if (err) - goto out; - memcpy(msg_in, pd->msg, msg_in_sz); -out: - ab_task_put(t); - return err; -} - -/* ------------------------ anybus queues ------------------------ */ - -static void process_q(struct anybuss_host *cd, struct kfifo *q) -{ - struct ab_task *t; - int ret; - - ret = kfifo_out_peek(q, &t, sizeof(t)); - if (!ret) - return; - t->result = t->task_fn(cd, t); - if (t->result != -EINPROGRESS) - ab_task_dequeue_finish_put(q, cd); -} - -static bool qs_have_work(struct kfifo *qs, size_t num) -{ - size_t i; - struct ab_task *t; - int ret; - - for (i = 0; i < num; i++, qs++) { - ret = kfifo_out_peek(qs, &t, sizeof(t)); - if (ret && (t->result != -EINPROGRESS)) - return true; - } - return false; -} - -static void process_qs(struct anybuss_host *cd) -{ - size_t i; - struct kfifo *qs = cd->qs; - size_t nqs = ARRAY_SIZE(cd->qs); - - for (i = 0; i < nqs; i++, qs++) - process_q(cd, qs); -} - -static void softint_ack(struct anybuss_host *cd) -{ - unsigned int ind_ap; - - cd->softint_pending = false; - if (!cd->power_on) - return; - regmap_read(cd->regmap, REG_IND_AP, &ind_ap); - ind_ap &= ~IND_AX_EVNT; - ind_ap |= atomic_read(&cd->ind_ab) & IND_AX_EVNT; - write_ind_ap(cd->regmap, ind_ap); -} - -static void process_softint(struct anybuss_host *cd) -{ - struct anybuss_client *client = cd->client; - static const u8 zero; - int ret; - unsigned int ind_ap, ev; - struct ab_task *t; - - if (!cd->power_on) - return; - if (cd->softint_pending) - return; - regmap_read(cd->regmap, REG_IND_AP, &ind_ap); - if (!((atomic_read(&cd->ind_ab) ^ ind_ap) & IND_AX_EVNT)) - return; - /* process software interrupt */ - regmap_read(cd->regmap, REG_EVENT_CAUSE, &ev); - if (ev & EVENT_CAUSE_FBON) { - if (client->on_online_changed) - client->on_online_changed(client, true); - dev_dbg(cd->dev, "Fieldbus ON"); - } - if (ev & EVENT_CAUSE_FBOF) { - if (client->on_online_changed) - client->on_online_changed(client, false); - dev_dbg(cd->dev, "Fieldbus OFF"); - } - if (ev & EVENT_CAUSE_DC) { - if (client->on_area_updated) - client->on_area_updated(client); - dev_dbg(cd->dev, "Fieldbus data changed"); - } - /* - * reset the event cause bits. - * this must be done while owning the fbctrl area, so we'll - * enqueue a task to do that. - */ - t = create_area_writer(cd->qcache, IND_AX_FBCTRL, - REG_EVENT_CAUSE, &zero, sizeof(zero)); - if (!t) { - ret = -ENOMEM; - goto out; - } - t->done_fn = softint_ack; - ret = ab_task_enqueue(t, cd->powerq, &cd->qlock, &cd->wq); - ab_task_put(t); - cd->softint_pending = true; -out: - WARN_ON(ret); - if (ret) - softint_ack(cd); -} - -static int qthread_fn(void *data) -{ - struct anybuss_host *cd = data; - struct kfifo *qs = cd->qs; - size_t nqs = ARRAY_SIZE(cd->qs); - unsigned int ind_ab; - - /* - * this kernel thread has exclusive access to the anybus's memory. - * only exception: the IND_AB register, which is accessed exclusively - * by the interrupt service routine (ISR). This thread must not touch - * the IND_AB register, but it does require access to its value. - * - * the interrupt service routine stores the register's value in - * cd->ind_ab (an atomic_t), where we may safely access it, with the - * understanding that it can be modified by the ISR at any time. - */ - - while (!kthread_should_stop()) { - /* - * make a local copy of IND_AB, so we can go around the loop - * again in case it changed while processing queues and softint. - */ - ind_ab = atomic_read(&cd->ind_ab); - process_qs(cd); - process_softint(cd); - wait_event_timeout(cd->wq, - (atomic_read(&cd->ind_ab) != ind_ab) || - qs_have_work(qs, nqs) || - kthread_should_stop(), - HZ); - /* - * time out so even 'stuck' tasks will run eventually, - * and can time out. - */ - } - - return 0; -} - -/* ------------------------ anybus exports ------------------------ */ - -int anybuss_start_init(struct anybuss_client *client, - const struct anybuss_memcfg *cfg) -{ - int ret; - u16 op_mode; - struct anybuss_host *cd = client->host; - struct msg_anybus_init msg = { - .input_io_len = cpu_to_be16(cfg->input_io), - .input_dpram_len = cpu_to_be16(cfg->input_dpram), - .input_total_len = cpu_to_be16(cfg->input_total), - .output_io_len = cpu_to_be16(cfg->output_io), - .output_dpram_len = cpu_to_be16(cfg->output_dpram), - .output_total_len = cpu_to_be16(cfg->output_total), - .notif_config = cpu_to_be16(0x000F), - .wd_val = cpu_to_be16(0), - }; - - switch (cfg->offl_mode) { - case FIELDBUS_DEV_OFFL_MODE_CLEAR: - op_mode = 0; - break; - case FIELDBUS_DEV_OFFL_MODE_FREEZE: - op_mode = OP_MODE_FBFC; - break; - case FIELDBUS_DEV_OFFL_MODE_SET: - op_mode = OP_MODE_FBS; - break; - default: - return -EINVAL; - } - msg.op_mode = cpu_to_be16(op_mode | OP_MODE_CD); - ret = _anybus_mbox_cmd(cd, CMD_START_INIT, false, NULL, 0, - NULL, 0, NULL, 0); - if (ret) - return ret; - return _anybus_mbox_cmd(cd, CMD_ANYBUS_INIT, false, - &msg, sizeof(msg), NULL, 0, NULL, 0); -} -EXPORT_SYMBOL_GPL(anybuss_start_init); - -int anybuss_finish_init(struct anybuss_client *client) -{ - struct anybuss_host *cd = client->host; - - return _anybus_mbox_cmd(cd, CMD_END_INIT, false, NULL, 0, - NULL, 0, NULL, 0); -} -EXPORT_SYMBOL_GPL(anybuss_finish_init); - -int anybuss_read_fbctrl(struct anybuss_client *client, u16 addr, - void *buf, size_t count) -{ - struct anybuss_host *cd = client->host; - struct ab_task *t; - int ret; - - if (count == 0) - return 0; - if (!area_range_ok(addr, count, FBCTRL_AREA, - MAX_FBCTRL_AREA_SZ)) - return -EFAULT; - t = create_area_reader(cd->qcache, IND_AX_FBCTRL, addr, count); - if (!t) - return -ENOMEM; - ret = ab_task_enqueue_wait(t, cd->powerq, &cd->qlock, &cd->wq); - if (ret) - goto out; - memcpy(buf, t->area_pd.buf, count); -out: - ab_task_put(t); - return ret; -} -EXPORT_SYMBOL_GPL(anybuss_read_fbctrl); - -int anybuss_write_input(struct anybuss_client *client, - const char __user *buf, size_t size, - loff_t *offset) -{ - ssize_t len = min_t(loff_t, MAX_DATA_AREA_SZ - *offset, size); - struct anybuss_host *cd = client->host; - struct ab_task *t; - int ret; - - if (len <= 0) - return 0; - t = create_area_user_writer(cd->qcache, IND_AX_IN, - DATA_IN_AREA + *offset, buf, len); - if (IS_ERR(t)) - return PTR_ERR(t); - ret = ab_task_enqueue_wait(t, cd->powerq, &cd->qlock, &cd->wq); - ab_task_put(t); - if (ret) - return ret; - /* success */ - *offset += len; - return len; -} -EXPORT_SYMBOL_GPL(anybuss_write_input); - -int anybuss_read_output(struct anybuss_client *client, - char __user *buf, size_t size, - loff_t *offset) -{ - ssize_t len = min_t(loff_t, MAX_DATA_AREA_SZ - *offset, size); - struct anybuss_host *cd = client->host; - struct ab_task *t; - int ret; - - if (len <= 0) - return 0; - t = create_area_reader(cd->qcache, IND_AX_OUT, - DATA_OUT_AREA + *offset, len); - if (!t) - return -ENOMEM; - ret = ab_task_enqueue_wait(t, cd->powerq, &cd->qlock, &cd->wq); - if (ret) - goto out; - if (copy_to_user(buf, t->area_pd.buf, len)) - ret = -EFAULT; -out: - ab_task_put(t); - if (ret) - return ret; - /* success */ - *offset += len; - return len; -} -EXPORT_SYMBOL_GPL(anybuss_read_output); - -int anybuss_send_msg(struct anybuss_client *client, u16 cmd_num, - const void *buf, size_t count) -{ - struct anybuss_host *cd = client->host; - - return _anybus_mbox_cmd(cd, cmd_num, true, buf, count, NULL, 0, - NULL, 0); -} -EXPORT_SYMBOL_GPL(anybuss_send_msg); - -int anybuss_send_ext(struct anybuss_client *client, u16 cmd_num, - const void *buf, size_t count) -{ - struct anybuss_host *cd = client->host; - - return _anybus_mbox_cmd(cd, cmd_num, true, NULL, 0, NULL, 0, - buf, count); -} -EXPORT_SYMBOL_GPL(anybuss_send_ext); - -int anybuss_recv_msg(struct anybuss_client *client, u16 cmd_num, - void *buf, size_t count) -{ - struct anybuss_host *cd = client->host; - - return _anybus_mbox_cmd(cd, cmd_num, true, NULL, 0, buf, count, - NULL, 0); -} -EXPORT_SYMBOL_GPL(anybuss_recv_msg); - -/* ------------------------ bus functions ------------------------ */ - -static int anybus_bus_match(struct device *dev, - const struct device_driver *drv) -{ - const struct anybuss_client_driver *adrv = - to_anybuss_client_driver(drv); - struct anybuss_client *adev = - to_anybuss_client(dev); - - return adrv->anybus_id == be16_to_cpu(adev->anybus_id); -} - -static int anybus_bus_probe(struct device *dev) -{ - struct anybuss_client_driver *adrv = - to_anybuss_client_driver(dev->driver); - struct anybuss_client *adev = - to_anybuss_client(dev); - - return adrv->probe(adev); -} - -static void anybus_bus_remove(struct device *dev) -{ - struct anybuss_client_driver *adrv = - to_anybuss_client_driver(dev->driver); - - if (adrv->remove) - adrv->remove(to_anybuss_client(dev)); -} - -static const struct bus_type anybus_bus = { - .name = "anybuss", - .match = anybus_bus_match, - .probe = anybus_bus_probe, - .remove = anybus_bus_remove, -}; - -int anybuss_client_driver_register(struct anybuss_client_driver *drv) -{ - if (!drv->probe) - return -ENODEV; - - drv->driver.bus = &anybus_bus; - return driver_register(&drv->driver); -} -EXPORT_SYMBOL_GPL(anybuss_client_driver_register); - -void anybuss_client_driver_unregister(struct anybuss_client_driver *drv) -{ - return driver_unregister(&drv->driver); -} -EXPORT_SYMBOL_GPL(anybuss_client_driver_unregister); - -static void client_device_release(struct device *dev) -{ - kfree(to_anybuss_client(dev)); -} - -static int taskq_alloc(struct device *dev, struct kfifo *q) -{ - void *buf; - size_t size = 64 * sizeof(struct ab_task *); - - buf = devm_kzalloc(dev, size, GFP_KERNEL); - if (!buf) - return -EIO; - return kfifo_init(q, buf, size); -} - -static int anybus_of_get_host_idx(struct device_node *np) -{ - const __be32 *host_idx; - - host_idx = of_get_address(np, 0, NULL, NULL); - if (!host_idx) - return -ENOENT; - return __be32_to_cpu(*host_idx); -} - -static struct device_node * -anybus_of_find_child_device(struct device *dev, int host_idx) -{ - struct device_node *node; - - if (!dev || !dev->of_node) - return NULL; - for_each_child_of_node(dev->of_node, node) { - if (anybus_of_get_host_idx(node) == host_idx) - return node; - } - return NULL; -} - -struct anybuss_host * __must_check -anybuss_host_common_probe(struct device *dev, - const struct anybuss_ops *ops) -{ - int ret, i; - u8 val[4]; - __be16 fieldbus_type; - struct anybuss_host *cd; - - cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL); - if (!cd) - return ERR_PTR(-ENOMEM); - cd->dev = dev; - cd->host_idx = ops->host_idx; - init_completion(&cd->card_boot); - init_waitqueue_head(&cd->wq); - for (i = 0; i < ARRAY_SIZE(cd->qs); i++) { - ret = taskq_alloc(dev, &cd->qs[i]); - if (ret) - return ERR_PTR(ret); - } - if (WARN_ON(ARRAY_SIZE(cd->qs) < 3)) - return ERR_PTR(-EINVAL); - cd->powerq = &cd->qs[0]; - cd->mboxq = &cd->qs[1]; - cd->areaq = &cd->qs[2]; - cd->reset = ops->reset; - if (!cd->reset) - return ERR_PTR(-EINVAL); - cd->regmap = ops->regmap; - if (!cd->regmap) - return ERR_PTR(-EINVAL); - spin_lock_init(&cd->qlock); - cd->qcache = kmem_cache_create(dev_name(dev), - sizeof(struct ab_task), 0, 0, NULL); - if (!cd->qcache) - return ERR_PTR(-ENOMEM); - cd->irq = ops->irq; - if (cd->irq <= 0) { - ret = -EINVAL; - goto err_qcache; - } - /* - * use a dpram test to check if a card is present, this is only - * possible while in reset. - */ - reset_assert(cd); - if (test_dpram(cd->regmap)) { - dev_err(dev, "no Anybus-S card in slot"); - ret = -ENODEV; - goto err_qcache; - } - ret = devm_request_threaded_irq(dev, cd->irq, NULL, irq_handler, - IRQF_ONESHOT, dev_name(dev), cd); - if (ret) { - dev_err(dev, "could not request irq"); - goto err_qcache; - } - /* - * startup sequence: - * a) perform dummy IND_AB read to prevent false 'init done' irq - * (already done by test_dpram() above) - * b) release reset - * c) wait for first interrupt - * d) interrupt came in: ready to go ! - */ - reset_deassert(cd); - if (!wait_for_completion_timeout(&cd->card_boot, TIMEOUT)) { - ret = -ETIMEDOUT; - goto err_reset; - } - /* - * according to the anybus docs, we're allowed to read these - * without handshaking / reserving the area - */ - dev_info(dev, "Anybus-S card detected"); - regmap_bulk_read(cd->regmap, REG_BOOTLOADER_V, val, 2); - dev_info(dev, "Bootloader version: %02X%02X", - val[0], val[1]); - regmap_bulk_read(cd->regmap, REG_API_V, val, 2); - dev_info(dev, "API version: %02X%02X", val[0], val[1]); - regmap_bulk_read(cd->regmap, REG_FIELDBUS_V, val, 2); - dev_info(dev, "Fieldbus version: %02X%02X", val[0], val[1]); - regmap_bulk_read(cd->regmap, REG_SERIAL_NO, val, 4); - dev_info(dev, "Serial number: %02X%02X%02X%02X", - val[0], val[1], val[2], val[3]); - add_device_randomness(&val, 4); - regmap_bulk_read(cd->regmap, REG_FIELDBUS_TYPE, &fieldbus_type, - sizeof(fieldbus_type)); - dev_info(dev, "Fieldbus type: %04X", be16_to_cpu(fieldbus_type)); - regmap_bulk_read(cd->regmap, REG_MODULE_SW_V, val, 2); - dev_info(dev, "Module SW version: %02X%02X", - val[0], val[1]); - /* put card back reset until a client driver releases it */ - disable_irq(cd->irq); - reset_assert(cd); - atomic_set(&cd->ind_ab, IND_AB_UPDATED); - /* fire up the queue thread */ - cd->qthread = kthread_run(qthread_fn, cd, dev_name(dev)); - if (IS_ERR(cd->qthread)) { - dev_err(dev, "could not create kthread"); - ret = PTR_ERR(cd->qthread); - goto err_reset; - } - /* - * now advertise that we've detected a client device (card). - * the bus infrastructure will match it to a client driver. - */ - cd->client = kzalloc(sizeof(*cd->client), GFP_KERNEL); - if (!cd->client) { - ret = -ENOMEM; - goto err_kthread; - } - cd->client->anybus_id = fieldbus_type; - cd->client->host = cd; - cd->client->dev.bus = &anybus_bus; - cd->client->dev.parent = dev; - cd->client->dev.release = client_device_release; - cd->client->dev.of_node = - anybus_of_find_child_device(dev, cd->host_idx); - dev_set_name(&cd->client->dev, "anybuss.card%d", cd->host_idx); - ret = device_register(&cd->client->dev); - if (ret) - goto err_device; - return cd; -err_device: - put_device(&cd->client->dev); -err_kthread: - kthread_stop(cd->qthread); -err_reset: - reset_assert(cd); -err_qcache: - kmem_cache_destroy(cd->qcache); - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(anybuss_host_common_probe); - -void anybuss_host_common_remove(struct anybuss_host *host) -{ - struct anybuss_host *cd = host; - - device_unregister(&cd->client->dev); - kthread_stop(cd->qthread); - reset_assert(cd); - kmem_cache_destroy(cd->qcache); -} -EXPORT_SYMBOL_GPL(anybuss_host_common_remove); - -static void host_release(void *res) -{ - anybuss_host_common_remove(res); -} - -struct anybuss_host * __must_check -devm_anybuss_host_common_probe(struct device *dev, - const struct anybuss_ops *ops) -{ - struct anybuss_host *host; - int ret; - - host = anybuss_host_common_probe(dev, ops); - if (IS_ERR(host)) - return host; - - ret = devm_add_action_or_reset(dev, host_release, host); - if (ret) - return ERR_PTR(ret); - - return host; -} -EXPORT_SYMBOL_GPL(devm_anybuss_host_common_probe); - -static int __init anybus_init(void) -{ - int ret; - - ret = bus_register(&anybus_bus); - if (ret) - pr_err("could not register Anybus-S bus: %d\n", ret); - return ret; -} -module_init(anybus_init); - -static void __exit anybus_exit(void) -{ - bus_unregister(&anybus_bus); -} -module_exit(anybus_exit); - -MODULE_DESCRIPTION("HMS Anybus-S Host Driver"); -MODULE_AUTHOR("Sven Van Asbroeck "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/fieldbus/dev_core.c b/drivers/staging/fieldbus/dev_core.c deleted file mode 100644 index 0053ebd91442de3ffa1e0fbabcb3f7152f27053e..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/dev_core.c +++ /dev/null @@ -1,344 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Fieldbus Device Driver Core - * - */ - -#include -#include -#include -#include -#include -#include -#include - -/* move to when taking this out of staging */ -#include "fieldbus_dev.h" - -/* Maximum number of fieldbus devices */ -#define MAX_FIELDBUSES 32 - -/* the dev_t structure to store the dynamically allocated fieldbus devices */ -static dev_t fieldbus_devt; -static DEFINE_IDA(fieldbus_ida); -static DEFINE_MUTEX(fieldbus_mtx); - -static ssize_t online_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - - return sysfs_emit(buf, "%d\n", !!fb->online); -} -static DEVICE_ATTR_RO(online); - -static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - - if (!fb->enable_get) - return -EINVAL; - return sysfs_emit(buf, "%d\n", !!fb->enable_get(fb)); -} - -static ssize_t enabled_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t n) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - bool value; - int ret; - - if (!fb->simple_enable_set) - return -ENOTSUPP; - ret = kstrtobool(buf, &value); - if (ret) - return ret; - ret = fb->simple_enable_set(fb, value); - if (ret < 0) - return ret; - return n; -} -static DEVICE_ATTR_RW(enabled); - -static ssize_t card_name_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - - /* card_name was provided by child driver. */ - return sysfs_emit(buf, "%s\n", fb->card_name); -} -static DEVICE_ATTR_RO(card_name); - -static ssize_t read_area_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - - return sysfs_emit(buf, "%zu\n", fb->read_area_sz); -} -static DEVICE_ATTR_RO(read_area_size); - -static ssize_t write_area_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - - return sysfs_emit(buf, "%zu\n", fb->write_area_sz); -} -static DEVICE_ATTR_RO(write_area_size); - -static ssize_t fieldbus_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - - return fb->fieldbus_id_get(fb, buf, PAGE_SIZE); -} -static DEVICE_ATTR_RO(fieldbus_id); - -static ssize_t fieldbus_type_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fieldbus_dev *fb = dev_get_drvdata(dev); - const char *t; - - switch (fb->fieldbus_type) { - case FIELDBUS_DEV_TYPE_PROFINET: - t = "profinet"; - break; - default: - t = "unknown"; - break; - } - - return sysfs_emit(buf, "%s\n", t); -} -static DEVICE_ATTR_RO(fieldbus_type); - -static struct attribute *fieldbus_attrs[] = { - &dev_attr_enabled.attr, - &dev_attr_card_name.attr, - &dev_attr_fieldbus_id.attr, - &dev_attr_read_area_size.attr, - &dev_attr_write_area_size.attr, - &dev_attr_online.attr, - &dev_attr_fieldbus_type.attr, - NULL, -}; - -static umode_t fieldbus_is_visible(struct kobject *kobj, struct attribute *attr, - int n) -{ - struct device *dev = kobj_to_dev(kobj); - struct fieldbus_dev *fb = dev_get_drvdata(dev); - umode_t mode = attr->mode; - - if (attr == &dev_attr_enabled.attr) { - mode = 0; - if (fb->enable_get) - mode |= 0444; - if (fb->simple_enable_set) - mode |= 0200; - } - - return mode; -} - -static const struct attribute_group fieldbus_group = { - .attrs = fieldbus_attrs, - .is_visible = fieldbus_is_visible, -}; -__ATTRIBUTE_GROUPS(fieldbus); - -static const struct class fieldbus_class = { - .name = "fieldbus_dev", - .dev_groups = fieldbus_groups, -}; - -struct fb_open_file { - struct fieldbus_dev *fbdev; - int dc_event; -}; - -static int fieldbus_open(struct inode *inode, struct file *filp) -{ - struct fb_open_file *of; - struct fieldbus_dev *fbdev = container_of(inode->i_cdev, - struct fieldbus_dev, - cdev); - - of = kzalloc(sizeof(*of), GFP_KERNEL); - if (!of) - return -ENOMEM; - of->fbdev = fbdev; - filp->private_data = of; - return 0; -} - -static int fieldbus_release(struct inode *node, struct file *filp) -{ - struct fb_open_file *of = filp->private_data; - - kfree(of); - return 0; -} - -static ssize_t fieldbus_read(struct file *filp, char __user *buf, size_t size, - loff_t *offset) -{ - struct fb_open_file *of = filp->private_data; - struct fieldbus_dev *fbdev = of->fbdev; - - of->dc_event = fbdev->dc_event; - return fbdev->read_area(fbdev, buf, size, offset); -} - -static ssize_t fieldbus_write(struct file *filp, const char __user *buf, - size_t size, loff_t *offset) -{ - struct fb_open_file *of = filp->private_data; - struct fieldbus_dev *fbdev = of->fbdev; - - return fbdev->write_area(fbdev, buf, size, offset); -} - -static __poll_t fieldbus_poll(struct file *filp, poll_table *wait) -{ - struct fb_open_file *of = filp->private_data; - struct fieldbus_dev *fbdev = of->fbdev; - __poll_t mask = EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM; - - poll_wait(filp, &fbdev->dc_wq, wait); - /* data changed ? */ - if (fbdev->dc_event != of->dc_event) - mask |= EPOLLPRI | EPOLLERR; - return mask; -} - -static const struct file_operations fieldbus_fops = { - .open = fieldbus_open, - .release = fieldbus_release, - .read = fieldbus_read, - .write = fieldbus_write, - .poll = fieldbus_poll, - .llseek = generic_file_llseek, - .owner = THIS_MODULE, -}; - -void fieldbus_dev_area_updated(struct fieldbus_dev *fb) -{ - fb->dc_event++; - wake_up_all(&fb->dc_wq); -} -EXPORT_SYMBOL_GPL(fieldbus_dev_area_updated); - -void fieldbus_dev_online_changed(struct fieldbus_dev *fb, bool online) -{ - fb->online = online; - kobject_uevent(&fb->dev->kobj, KOBJ_CHANGE); -} -EXPORT_SYMBOL_GPL(fieldbus_dev_online_changed); - -static void __fieldbus_dev_unregister(struct fieldbus_dev *fb) -{ - if (!fb) - return; - device_destroy(&fieldbus_class, fb->cdev.dev); - cdev_del(&fb->cdev); - ida_free(&fieldbus_ida, fb->id); -} - -void fieldbus_dev_unregister(struct fieldbus_dev *fb) -{ - mutex_lock(&fieldbus_mtx); - __fieldbus_dev_unregister(fb); - mutex_unlock(&fieldbus_mtx); -} -EXPORT_SYMBOL_GPL(fieldbus_dev_unregister); - -static int __fieldbus_dev_register(struct fieldbus_dev *fb) -{ - dev_t devno; - int err; - - if (!fb) - return -EINVAL; - if (!fb->read_area || !fb->write_area || !fb->fieldbus_id_get) - return -EINVAL; - fb->id = ida_alloc_max(&fieldbus_ida, MAX_FIELDBUSES - 1, GFP_KERNEL); - if (fb->id < 0) - return fb->id; - devno = MKDEV(MAJOR(fieldbus_devt), fb->id); - init_waitqueue_head(&fb->dc_wq); - cdev_init(&fb->cdev, &fieldbus_fops); - err = cdev_add(&fb->cdev, devno, 1); - if (err) { - pr_err("fieldbus_dev%d unable to add device %d:%d\n", - fb->id, MAJOR(fieldbus_devt), fb->id); - goto err_cdev; - } - fb->dev = device_create(&fieldbus_class, fb->parent, devno, fb, - "fieldbus_dev%d", fb->id); - if (IS_ERR(fb->dev)) { - err = PTR_ERR(fb->dev); - goto err_dev_create; - } - return 0; - -err_dev_create: - cdev_del(&fb->cdev); -err_cdev: - ida_free(&fieldbus_ida, fb->id); - return err; -} - -int fieldbus_dev_register(struct fieldbus_dev *fb) -{ - int err; - - mutex_lock(&fieldbus_mtx); - err = __fieldbus_dev_register(fb); - mutex_unlock(&fieldbus_mtx); - - return err; -} -EXPORT_SYMBOL_GPL(fieldbus_dev_register); - -static int __init fieldbus_init(void) -{ - int err; - - err = class_register(&fieldbus_class); - if (err < 0) { - pr_err("fieldbus_dev: could not register class\n"); - return err; - } - err = alloc_chrdev_region(&fieldbus_devt, 0, - MAX_FIELDBUSES, "fieldbus_dev"); - if (err < 0) { - pr_err("fieldbus_dev: unable to allocate char dev region\n"); - goto err_alloc; - } - return 0; - -err_alloc: - class_unregister(&fieldbus_class); - return err; -} - -static void __exit fieldbus_exit(void) -{ - unregister_chrdev_region(fieldbus_devt, MAX_FIELDBUSES); - class_unregister(&fieldbus_class); - ida_destroy(&fieldbus_ida); -} - -subsys_initcall(fieldbus_init); -module_exit(fieldbus_exit); - -MODULE_AUTHOR("Sven Van Asbroeck "); -MODULE_AUTHOR("Jonathan Stiles "); -MODULE_DESCRIPTION("Fieldbus Device Driver Core"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/fieldbus/fieldbus_dev.h b/drivers/staging/fieldbus/fieldbus_dev.h deleted file mode 100644 index 301dca3b8d71a72cd4bd3e47bd036187124b3866..0000000000000000000000000000000000000000 --- a/drivers/staging/fieldbus/fieldbus_dev.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Fieldbus Device Driver Core - * - */ - -#ifndef __FIELDBUS_DEV_H -#define __FIELDBUS_DEV_H - -#include -#include - -enum fieldbus_dev_type { - FIELDBUS_DEV_TYPE_UNKNOWN = 0, - FIELDBUS_DEV_TYPE_PROFINET, -}; - -enum fieldbus_dev_offl_mode { - FIELDBUS_DEV_OFFL_MODE_CLEAR = 0, - FIELDBUS_DEV_OFFL_MODE_FREEZE, - FIELDBUS_DEV_OFFL_MODE_SET -}; - -/** - * struct fieldbus_dev - Fieldbus device - * @read_area: [DRIVER] function to read the process data area of the - * device. same parameters/return values as - * the read function in struct file_operations - * @write_area: [DRIVER] function to write to the process data area of - * the device. same parameters/return values as - * the write function in struct file_operations - * @write_area_sz [DRIVER] size of the writable process data area - * @read_area_sz [DRIVER] size of the readable process data area - * @card_name [DRIVER] name of the card, e.g. "ACME Inc. profinet" - * @fieldbus_type [DRIVER] fieldbus type of this device, e.g. - * FIELDBUS_DEV_TYPE_PROFINET - * @enable_get [DRIVER] function which returns true if the card - * is enabled, false otherwise - * @fieldbus_id_get [DRIVER] function to retrieve the unique fieldbus id - * by which this device can be identified; - * return value follows the snprintf convention - * @simple_enable_set [DRIVER] (optional) function to enable the device - * according to its default settings - * @parent [DRIVER] (optional) the device's parent device - */ -struct fieldbus_dev { - ssize_t (*read_area)(struct fieldbus_dev *fbdev, char __user *buf, - size_t size, loff_t *offset); - ssize_t (*write_area)(struct fieldbus_dev *fbdev, - const char __user *buf, size_t size, - loff_t *offset); - size_t write_area_sz, read_area_sz; - const char *card_name; - enum fieldbus_dev_type fieldbus_type; - bool (*enable_get)(struct fieldbus_dev *fbdev); - int (*fieldbus_id_get)(struct fieldbus_dev *fbdev, char *buf, - size_t max_size); - int (*simple_enable_set)(struct fieldbus_dev *fbdev, bool enable); - struct device *parent; - - /* private data */ - int id; - struct cdev cdev; - struct device *dev; - int dc_event; - wait_queue_head_t dc_wq; - bool online; -}; - -#if IS_ENABLED(CONFIG_FIELDBUS_DEV) - -/** - * fieldbus_dev_unregister() - * - unregister a previously registered fieldbus device - * @fb: Device structure previously registered - **/ -void fieldbus_dev_unregister(struct fieldbus_dev *fb); - -/** - * fieldbus_dev_register() - * - register a device with the fieldbus device subsystem - * @fb: Device structure filled by the device driver - **/ -int __must_check fieldbus_dev_register(struct fieldbus_dev *fb); - -/** - * fieldbus_dev_area_updated() - * - notify the subsystem that an external fieldbus controller updated - * the process data area - * @fb: Device structure - **/ -void fieldbus_dev_area_updated(struct fieldbus_dev *fb); - -/** - * fieldbus_dev_online_changed() - * - notify the subsystem that the fieldbus online status changed - * @fb: Device structure - **/ -void fieldbus_dev_online_changed(struct fieldbus_dev *fb, bool online); - -#else /* IS_ENABLED(CONFIG_FIELDBUS_DEV) */ - -static inline void fieldbus_dev_unregister(struct fieldbus_dev *fb) {} -static inline int __must_check fieldbus_dev_register(struct fieldbus_dev *fb) -{ - return -ENOTSUPP; -} - -static inline void fieldbus_dev_area_updated(struct fieldbus_dev *fb) {} -static inline void fieldbus_dev_online_changed(struct fieldbus_dev *fb, - bool online) {} - -#endif /* IS_ENABLED(CONFIG_FIELDBUS_DEV) */ -#endif /* __FIELDBUS_DEV_H */ diff --git a/drivers/staging/gdm724x/Kconfig b/drivers/staging/gdm724x/Kconfig deleted file mode 100644 index 1f403ecd9608b488b3677c82a8c1e896618bf252..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# GCT GDM724x LTE driver configuration -# - -config LTE_GDM724X - tristate "GCT GDM724x LTE support" - depends on NET && USB && TTY && m - help - This driver supports GCT GDM724x LTE chip based USB modem devices. - It exposes 4 network devices to be used per PDN and 2 tty devices to be - used for AT commands and DM monitoring applications. - The modules will be called gdmulte.ko and gdmtty.ko - - GCT-ATCx can be used for AT Commands - GCT-DMx can be used for LTE protocol monitoring diff --git a/drivers/staging/gdm724x/Makefile b/drivers/staging/gdm724x/Makefile deleted file mode 100644 index e61b95788c9fca0f925af2363701db2e08b32c57..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_LTE_GDM724X) := gdmulte.o -gdmulte-y += gdm_lte.o netlink_k.o -gdmulte-y += gdm_usb.o gdm_endian.o - -obj-$(CONFIG_LTE_GDM724X) += gdmtty.o -gdmtty-y := gdm_tty.o gdm_mux.o - diff --git a/drivers/staging/gdm724x/TODO b/drivers/staging/gdm724x/TODO deleted file mode 100644 index b2b571ecb063f740a332de328c187e38e3b9123a..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/TODO +++ /dev/null @@ -1,16 +0,0 @@ -TODO: -- Clean up coding style to meet kernel standard. (80 line limit, netdev_err) -- Remove test for host endian -- Remove confusing macros (endian, hci_send, sdu_send, rcv_with_cb) -- Fixes for every instances of function returning -1 -- Check for skb->len in gdm_lte_emulate_arp() -- Use ALIGN() macro for dummy_cnt in up_to_host() -- Error handling in init_usb() -- Explain reason for multiples of 512 bytes in alloc_tx_struct() -- Review use of atomic allocation for tx structs -- No error checking for alloc_tx_struct in do_tx() -- fix up static tty port allocation to be dynamic - -Patches to: - Jonathan Kim - Dean ahn diff --git a/drivers/staging/gdm724x/gdm_endian.c b/drivers/staging/gdm724x/gdm_endian.c deleted file mode 100644 index ae39e59daf7074585607e3ffa0069c4009cad798..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_endian.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#include -#include "gdm_endian.h" - -__dev16 gdm_cpu_to_dev16(u8 dev_ed, u16 x) -{ - if (dev_ed == ENDIANNESS_LITTLE) - return (__force __dev16)cpu_to_le16(x); - else - return (__force __dev16)cpu_to_be16(x); -} - -u16 gdm_dev16_to_cpu(u8 dev_ed, __dev16 x) -{ - if (dev_ed == ENDIANNESS_LITTLE) - return le16_to_cpu((__force __le16)x); - else - return be16_to_cpu((__force __be16)x); -} - -__dev32 gdm_cpu_to_dev32(u8 dev_ed, u32 x) -{ - if (dev_ed == ENDIANNESS_LITTLE) - return (__force __dev32)cpu_to_le32(x); - else - return (__force __dev32)cpu_to_be32(x); -} - -u32 gdm_dev32_to_cpu(u8 dev_ed, __dev32 x) -{ - if (dev_ed == ENDIANNESS_LITTLE) - return le32_to_cpu((__force __le32)x); - else - return be32_to_cpu((__force __be32)x); -} diff --git a/drivers/staging/gdm724x/gdm_endian.h b/drivers/staging/gdm724x/gdm_endian.h deleted file mode 100644 index f373dc3a19bf3e779ad41749cd0605d52ab874a3..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_endian.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef __GDM_ENDIAN_H__ -#define __GDM_ENDIAN_H__ - -#include - -/* - * For data in "device-endian" byte order (device endianness is model - * dependent). Analogous to __leXX or __beXX. - */ -typedef __u32 __bitwise __dev32; -typedef __u16 __bitwise __dev16; - -enum { - ENDIANNESS_MIN = 0, - ENDIANNESS_UNKNOWN, - ENDIANNESS_LITTLE, - ENDIANNESS_BIG, - ENDIANNESS_MIDDLE, - ENDIANNESS_MAX -}; - -__dev16 gdm_cpu_to_dev16(u8 dev_ed, u16 x); -u16 gdm_dev16_to_cpu(u8 dev_ed, __dev16 x); -__dev32 gdm_cpu_to_dev32(u8 dev_ed, u32 x); -u32 gdm_dev32_to_cpu(u8 dev_ed, __dev32 x); - -#endif /*__GDM_ENDIAN_H__*/ diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c deleted file mode 100644 index eb754b231429be1aed1ba06052a93e0b4af9f632..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_lte.c +++ /dev/null @@ -1,937 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gdm_lte.h" -#include "netlink_k.h" -#include "hci.h" -#include "hci_packet.h" -#include "gdm_endian.h" - -/* - * Netlink protocol number - */ -#define NETLINK_LTE 30 - -/* - * Default MTU Size - */ -#define DEFAULT_MTU_SIZE 1500 - -#define IP_VERSION_4 4 -#define IP_VERSION_6 6 - -static struct { - int ref_cnt; - struct sock *sock; -} lte_event; - -static const struct device_type wwan_type = { - .name = "wwan", -}; - -static int gdm_lte_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; -} - -static int gdm_lte_close(struct net_device *dev) -{ - netif_stop_queue(dev); - return 0; -} - -static int gdm_lte_set_config(struct net_device *dev, struct ifmap *map) -{ - if (dev->flags & IFF_UP) - return -EBUSY; - return 0; -} - -static void tx_complete(void *arg) -{ - struct nic *nic = arg; - - if (netif_queue_stopped(nic->netdev)) - netif_wake_queue(nic->netdev); -} - -static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type) -{ - int ret, len; - - len = skb->len + ETH_HLEN; - ret = netif_rx(skb); - if (ret == NET_RX_DROP) { - nic->stats.rx_dropped++; - } else { - nic->stats.rx_packets++; - nic->stats.rx_bytes += len; - } - - return 0; -} - -static int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type) -{ - struct nic *nic = netdev_priv(skb_in->dev); - struct sk_buff *skb_out; - struct ethhdr eth; - struct vlan_ethhdr vlan_eth; - struct arphdr *arp_in; - struct arphdr *arp_out; - struct arpdata { - u8 ar_sha[ETH_ALEN]; - u8 ar_sip[4]; - u8 ar_tha[ETH_ALEN]; - u8 ar_tip[4]; - }; - struct arpdata *arp_data_in; - struct arpdata *arp_data_out; - u8 arp_temp[60]; - void *mac_header_data; - u32 mac_header_len; - - /* Check for skb->len, discard if empty */ - if (skb_in->len == 0) - return -ENODATA; - - /* Format the mac header so that it can be put to skb */ - if (ntohs(((struct ethhdr *)skb_in->data)->h_proto) == ETH_P_8021Q) { - memcpy(&vlan_eth, skb_in->data, sizeof(struct vlan_ethhdr)); - mac_header_data = &vlan_eth; - mac_header_len = VLAN_ETH_HLEN; - } else { - memcpy(ð, skb_in->data, sizeof(struct ethhdr)); - mac_header_data = ð - mac_header_len = ETH_HLEN; - } - - /* Get the pointer of the original request */ - arp_in = (struct arphdr *)(skb_in->data + mac_header_len); - arp_data_in = (struct arpdata *)(skb_in->data + mac_header_len + - sizeof(struct arphdr)); - - /* Get the pointer of the outgoing response */ - arp_out = (struct arphdr *)arp_temp; - arp_data_out = (struct arpdata *)(arp_temp + sizeof(struct arphdr)); - - /* Copy the arp header */ - memcpy(arp_out, arp_in, sizeof(struct arphdr)); - arp_out->ar_op = htons(ARPOP_REPLY); - - /* Copy the arp payload: based on 2 bytes of mac and fill the IP */ - arp_data_out->ar_sha[0] = arp_data_in->ar_sha[0]; - arp_data_out->ar_sha[1] = arp_data_in->ar_sha[1]; - memcpy(&arp_data_out->ar_sha[2], &arp_data_in->ar_tip[0], 4); - memcpy(&arp_data_out->ar_sip[0], &arp_data_in->ar_tip[0], 4); - memcpy(&arp_data_out->ar_tha[0], &arp_data_in->ar_sha[0], 6); - memcpy(&arp_data_out->ar_tip[0], &arp_data_in->ar_sip[0], 4); - - /* Fill the destination mac with source mac of the received packet */ - memcpy(mac_header_data, mac_header_data + ETH_ALEN, ETH_ALEN); - /* Fill the source mac with nic's source mac */ - memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); - - /* Alloc skb and reserve align */ - skb_out = dev_alloc_skb(skb_in->len); - if (!skb_out) - return -ENOMEM; - skb_reserve(skb_out, NET_IP_ALIGN); - - skb_put_data(skb_out, mac_header_data, mac_header_len); - skb_put_data(skb_out, arp_out, sizeof(struct arphdr)); - skb_put_data(skb_out, arp_data_out, sizeof(struct arpdata)); - - skb_out->protocol = ((struct ethhdr *)mac_header_data)->h_proto; - skb_out->dev = skb_in->dev; - skb_reset_mac_header(skb_out); - skb_pull(skb_out, ETH_HLEN); - - gdm_lte_rx(skb_out, nic, nic_type); - - return 0; -} - -static __sum16 icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len) -{ - unsigned short *w; - __wsum sum = 0; - int i; - u16 pa; - - union { - struct { - u8 ph_src[16]; - u8 ph_dst[16]; - u32 ph_len; - u8 ph_zero[3]; - u8 ph_nxt; - } ph __packed; - u16 pa[20]; - } pseudo_header; - - memset(&pseudo_header, 0, sizeof(pseudo_header)); - memcpy(&pseudo_header.ph.ph_src, &ipv6->saddr.in6_u.u6_addr8, 16); - memcpy(&pseudo_header.ph.ph_dst, &ipv6->daddr.in6_u.u6_addr8, 16); - pseudo_header.ph.ph_len = be16_to_cpu(ipv6->payload_len); - pseudo_header.ph.ph_nxt = ipv6->nexthdr; - - for (i = 0; i < ARRAY_SIZE(pseudo_header.pa); i++) { - pa = pseudo_header.pa[i]; - sum = csum_add(sum, csum_unfold((__force __sum16)pa)); - } - - w = ptr; - while (len > 1) { - sum = csum_add(sum, csum_unfold((__force __sum16)*w++)); - len -= 2; - } - - return csum_fold(sum); -} - -static int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type) -{ - struct nic *nic = netdev_priv(skb_in->dev); - struct sk_buff *skb_out; - struct ethhdr eth; - struct vlan_ethhdr vlan_eth; - struct neighbour_advertisement { - u8 target_address[16]; - u8 type; - u8 length; - u8 link_layer_address[6]; - }; - struct neighbour_advertisement na; - struct neighbour_solicitation { - u8 target_address[16]; - }; - struct neighbour_solicitation *ns; - struct ipv6hdr *ipv6_in; - struct ipv6hdr ipv6_out; - struct icmp6hdr *icmp6_in; - struct icmp6hdr icmp6_out; - - void *mac_header_data; - u32 mac_header_len; - - /* Format the mac header so that it can be put to skb */ - if (ntohs(((struct ethhdr *)skb_in->data)->h_proto) == ETH_P_8021Q) { - memcpy(&vlan_eth, skb_in->data, sizeof(struct vlan_ethhdr)); - if (ntohs(vlan_eth.h_vlan_encapsulated_proto) != ETH_P_IPV6) - return -EPROTONOSUPPORT; - mac_header_data = &vlan_eth; - mac_header_len = VLAN_ETH_HLEN; - } else { - memcpy(ð, skb_in->data, sizeof(struct ethhdr)); - if (ntohs(eth.h_proto) != ETH_P_IPV6) - return -EPROTONOSUPPORT; - mac_header_data = ð - mac_header_len = ETH_HLEN; - } - - /* Check if this is IPv6 ICMP packet */ - ipv6_in = (struct ipv6hdr *)(skb_in->data + mac_header_len); - if (ipv6_in->version != 6 || ipv6_in->nexthdr != IPPROTO_ICMPV6) - return -EPROTONOSUPPORT; - - /* Check if this is NDP packet */ - icmp6_in = (struct icmp6hdr *)(skb_in->data + mac_header_len + - sizeof(struct ipv6hdr)); - if (icmp6_in->icmp6_type == NDISC_ROUTER_SOLICITATION) { /* Check RS */ - return -EPROTONOSUPPORT; - } else if (icmp6_in->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { - /* Check NS */ - u8 icmp_na[sizeof(struct icmp6hdr) + - sizeof(struct neighbour_advertisement)]; - u8 zero_addr8[16] = {0,}; - - if (memcmp(ipv6_in->saddr.in6_u.u6_addr8, zero_addr8, 16) == 0) - /* Duplicate Address Detection: Source IP is all zero */ - return 0; - - icmp6_out.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT; - icmp6_out.icmp6_code = 0; - icmp6_out.icmp6_cksum = 0; - /* R=0, S=1, O=1 */ - icmp6_out.icmp6_dataun.un_data32[0] = htonl(0x60000000); - - ns = (struct neighbour_solicitation *) - (skb_in->data + mac_header_len + - sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr)); - memcpy(&na.target_address, ns->target_address, 16); - na.type = 0x02; - na.length = 1; - na.link_layer_address[0] = 0x00; - na.link_layer_address[1] = 0x0a; - na.link_layer_address[2] = 0x3b; - na.link_layer_address[3] = 0xaf; - na.link_layer_address[4] = 0x63; - na.link_layer_address[5] = 0xc7; - - memcpy(&ipv6_out, ipv6_in, sizeof(struct ipv6hdr)); - memcpy(ipv6_out.saddr.in6_u.u6_addr8, &na.target_address, 16); - memcpy(ipv6_out.daddr.in6_u.u6_addr8, - ipv6_in->saddr.in6_u.u6_addr8, 16); - ipv6_out.payload_len = htons(sizeof(struct icmp6hdr) + - sizeof(struct neighbour_advertisement)); - - memcpy(icmp_na, &icmp6_out, sizeof(struct icmp6hdr)); - memcpy(icmp_na + sizeof(struct icmp6hdr), &na, - sizeof(struct neighbour_advertisement)); - - icmp6_out.icmp6_cksum = icmp6_checksum(&ipv6_out, - (u16 *)icmp_na, - sizeof(icmp_na)); - } else { - return -EINVAL; - } - - /* Fill the destination mac with source mac of the received packet */ - memcpy(mac_header_data, mac_header_data + ETH_ALEN, ETH_ALEN); - /* Fill the source mac with nic's source mac */ - memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); - - /* Alloc skb and reserve align */ - skb_out = dev_alloc_skb(skb_in->len); - if (!skb_out) - return -ENOMEM; - skb_reserve(skb_out, NET_IP_ALIGN); - - skb_put_data(skb_out, mac_header_data, mac_header_len); - skb_put_data(skb_out, &ipv6_out, sizeof(struct ipv6hdr)); - skb_put_data(skb_out, &icmp6_out, sizeof(struct icmp6hdr)); - skb_put_data(skb_out, &na, sizeof(struct neighbour_advertisement)); - - skb_out->protocol = ((struct ethhdr *)mac_header_data)->h_proto; - skb_out->dev = skb_in->dev; - skb_reset_mac_header(skb_out); - skb_pull(skb_out, ETH_HLEN); - - gdm_lte_rx(skb_out, nic, nic_type); - - return 0; -} - -static s32 gdm_lte_tx_nic_type(struct net_device *dev, struct sk_buff *skb) -{ - struct nic *nic = netdev_priv(dev); - struct ethhdr *eth; - struct vlan_ethhdr *vlan_eth; - struct iphdr *ip; - struct ipv6hdr *ipv6; - int mac_proto; - void *network_data; - u32 nic_type; - - /* NIC TYPE is based on the nic_id of this net_device */ - nic_type = 0x00000010 | nic->nic_id; - - /* Get ethernet protocol */ - eth = (struct ethhdr *)skb->data; - if (ntohs(eth->h_proto) == ETH_P_8021Q) { - vlan_eth = skb_vlan_eth_hdr(skb); - mac_proto = ntohs(vlan_eth->h_vlan_encapsulated_proto); - network_data = skb->data + VLAN_ETH_HLEN; - nic_type |= NIC_TYPE_F_VLAN; - } else { - mac_proto = ntohs(eth->h_proto); - network_data = skb->data + ETH_HLEN; - } - - /* Process packet for nic type */ - switch (mac_proto) { - case ETH_P_ARP: - nic_type |= NIC_TYPE_ARP; - break; - case ETH_P_IP: - nic_type |= NIC_TYPE_F_IPV4; - ip = network_data; - - /* Check DHCPv4 */ - if (ip->protocol == IPPROTO_UDP) { - struct udphdr *udp = - network_data + sizeof(struct iphdr); - if (ntohs(udp->dest) == 67 || ntohs(udp->dest) == 68) - nic_type |= NIC_TYPE_F_DHCP; - } - break; - case ETH_P_IPV6: - nic_type |= NIC_TYPE_F_IPV6; - ipv6 = network_data; - - if (ipv6->nexthdr == IPPROTO_ICMPV6) /* Check NDP request */ { - struct icmp6hdr *icmp6 = - network_data + sizeof(struct ipv6hdr); - if (icmp6->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) - nic_type |= NIC_TYPE_ICMPV6; - } else if (ipv6->nexthdr == IPPROTO_UDP) /* Check DHCPv6 */ { - struct udphdr *udp = - network_data + sizeof(struct ipv6hdr); - if (ntohs(udp->dest) == 546 || ntohs(udp->dest) == 547) - nic_type |= NIC_TYPE_F_DHCP; - } - break; - default: - break; - } - - return nic_type; -} - -static netdev_tx_t gdm_lte_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct nic *nic = netdev_priv(dev); - u32 nic_type; - void *data_buf; - int data_len; - int idx; - int ret = 0; - - nic_type = gdm_lte_tx_nic_type(dev, skb); - if (nic_type == 0) { - netdev_err(dev, "tx - invalid nic_type\n"); - return -EMEDIUMTYPE; - } - - if (nic_type & NIC_TYPE_ARP) { - if (gdm_lte_emulate_arp(skb, nic_type) == 0) { - dev_kfree_skb(skb); - return 0; - } - } - - if (nic_type & NIC_TYPE_ICMPV6) { - if (gdm_lte_emulate_ndp(skb, nic_type) == 0) { - dev_kfree_skb(skb); - return 0; - } - } - - /* - * Need byte shift (that is, remove VLAN tag) if there is one - * For the case of ARP, this breaks the offset as vlan_ethhdr+4 - * is treated as ethhdr However, it shouldn't be a problem as - * the response starts from arp_hdr and ethhdr is created by this - * driver based on the NIC mac - */ - if (nic_type & NIC_TYPE_F_VLAN) { - struct vlan_ethhdr *vlan_eth = skb_vlan_eth_hdr(skb); - - nic->vlan_id = ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK; - data_buf = skb->data + (VLAN_ETH_HLEN - ETH_HLEN); - data_len = skb->len - (VLAN_ETH_HLEN - ETH_HLEN); - } else { - nic->vlan_id = 0; - data_buf = skb->data; - data_len = skb->len; - } - - /* If it is a ICMPV6 packet, clear all the other bits : - * for backward compatibility with the firmware - */ - if (nic_type & NIC_TYPE_ICMPV6) - nic_type = NIC_TYPE_ICMPV6; - - /* If it is not a dhcp packet, clear all the flag bits : - * original NIC, otherwise the special flag (IPVX | DHCP) - */ - if (!(nic_type & NIC_TYPE_F_DHCP)) - nic_type &= NIC_TYPE_MASK; - - ret = sscanf(dev->name, "lte%d", &idx); - if (ret != 1) { - dev_kfree_skb(skb); - return -EINVAL; - } - - ret = nic->phy_dev->send_sdu_func(nic->phy_dev->priv_dev, - data_buf, data_len, - nic->pdn_table.dft_eps_id, 0, - tx_complete, nic, idx, - nic_type); - - if (ret == TX_NO_BUFFER || ret == TX_NO_SPC) { - netif_stop_queue(dev); - if (ret == TX_NO_BUFFER) - ret = 0; - else - ret = -ENOSPC; - } else if (ret == TX_NO_DEV) { - ret = -ENODEV; - } - - /* Updates tx stats */ - if (ret) { - nic->stats.tx_dropped++; - } else { - nic->stats.tx_packets++; - nic->stats.tx_bytes += data_len; - } - dev_kfree_skb(skb); - - return 0; -} - -static struct net_device_stats *gdm_lte_stats(struct net_device *dev) -{ - struct nic *nic = netdev_priv(dev); - - return &nic->stats; -} - -static int gdm_lte_event_send(struct net_device *dev, char *buf, int len) -{ - struct phy_dev *phy_dev = ((struct nic *)netdev_priv(dev))->phy_dev; - struct hci_packet *hci = (struct hci_packet *)buf; - int length; - int idx; - int ret; - - ret = sscanf(dev->name, "lte%d", &idx); - if (ret != 1) - return -EINVAL; - - length = gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev), - hci->len) + HCI_HEADER_SIZE; - return netlink_send(lte_event.sock, idx, 0, buf, length, dev); -} - -static void gdm_lte_event_rcv(struct net_device *dev, u16 type, - void *msg, int len) -{ - struct nic *nic = netdev_priv(dev); - - nic->phy_dev->send_hci_func(nic->phy_dev->priv_dev, msg, len, NULL, - NULL); -} - -int gdm_lte_event_init(void) -{ - if (lte_event.ref_cnt == 0) - lte_event.sock = netlink_init(NETLINK_LTE, gdm_lte_event_rcv); - - if (lte_event.sock) { - lte_event.ref_cnt++; - return 0; - } - - pr_err("event init failed\n"); - return -ENODATA; -} - -void gdm_lte_event_exit(void) -{ - if (lte_event.sock && --lte_event.ref_cnt == 0) { - sock_release(lte_event.sock->sk_socket); - lte_event.sock = NULL; - } -} - -static int find_dev_index(u32 nic_type) -{ - u8 index; - - index = (u8)(nic_type & 0x0000000f); - if (index >= MAX_NIC_TYPE) - return -EINVAL; - - return index; -} - -static void gdm_lte_netif_rx(struct net_device *dev, char *buf, - int len, int flagged_nic_type) -{ - u32 nic_type; - struct nic *nic; - struct sk_buff *skb; - struct ethhdr eth; - struct vlan_ethhdr vlan_eth; - void *mac_header_data; - u32 mac_header_len; - char ip_version = 0; - - nic_type = flagged_nic_type & NIC_TYPE_MASK; - nic = netdev_priv(dev); - - if (flagged_nic_type & NIC_TYPE_F_DHCP) { - /* Change the destination mac address - * with the one requested the IP - */ - if (flagged_nic_type & NIC_TYPE_F_IPV4) { - struct dhcp_packet { - u8 op; /* BOOTREQUEST or BOOTREPLY */ - u8 htype; /* hardware address type. - * 1 = 10mb ethernet - */ - u8 hlen; /* hardware address length */ - u8 hops; /* used by relay agents only */ - u32 xid; /* unique id */ - u16 secs; /* elapsed since client began - * acquisition/renewal - */ - u16 flags; /* only one flag so far: */ - #define BROADCAST_FLAG 0x8000 - /* "I need broadcast replies" */ - u32 ciaddr; /* client IP (if client is in - * BOUND, RENEW or REBINDING state) - */ - u32 yiaddr; /* 'your' (client) IP address */ - /* IP address of next server to use in - * bootstrap, returned in DHCPOFFER, - * DHCPACK by server - */ - u32 siaddr_nip; - u32 gateway_nip; /* relay agent IP address */ - u8 chaddr[16]; /* link-layer client hardware - * address (MAC) - */ - u8 sname[64]; /* server host name (ASCIZ) */ - u8 file[128]; /* boot file name (ASCIZ) */ - u32 cookie; /* fixed first four option - * bytes (99,130,83,99 dec) - */ - } __packed; - int offset = sizeof(struct iphdr) + - sizeof(struct udphdr) + - offsetof(struct dhcp_packet, chaddr); - if (offset + ETH_ALEN > len) - return; - ether_addr_copy(nic->dest_mac_addr, buf + offset); - } - } - - if (nic->vlan_id > 0) { - mac_header_data = (void *)&vlan_eth; - mac_header_len = VLAN_ETH_HLEN; - } else { - mac_header_data = (void *)ð - mac_header_len = ETH_HLEN; - } - - /* Format the data so that it can be put to skb */ - ether_addr_copy(mac_header_data, nic->dest_mac_addr); - memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); - - vlan_eth.h_vlan_TCI = htons(nic->vlan_id); - vlan_eth.h_vlan_proto = htons(ETH_P_8021Q); - - if (nic_type == NIC_TYPE_ARP) { - /* Should be response: Only happens because - * there was a request from the host - */ - eth.h_proto = htons(ETH_P_ARP); - vlan_eth.h_vlan_encapsulated_proto = htons(ETH_P_ARP); - } else { - ip_version = buf[0] >> 4; - if (ip_version == IP_VERSION_4) { - eth.h_proto = htons(ETH_P_IP); - vlan_eth.h_vlan_encapsulated_proto = htons(ETH_P_IP); - } else if (ip_version == IP_VERSION_6) { - eth.h_proto = htons(ETH_P_IPV6); - vlan_eth.h_vlan_encapsulated_proto = htons(ETH_P_IPV6); - } else { - netdev_err(dev, "Unknown IP version %d\n", ip_version); - return; - } - } - - /* Alloc skb and reserve align */ - skb = dev_alloc_skb(len + mac_header_len + NET_IP_ALIGN); - if (!skb) - return; - skb_reserve(skb, NET_IP_ALIGN); - - skb_put_data(skb, mac_header_data, mac_header_len); - skb_put_data(skb, buf, len); - - skb->protocol = ((struct ethhdr *)mac_header_data)->h_proto; - skb->dev = dev; - skb_reset_mac_header(skb); - skb_pull(skb, ETH_HLEN); - - gdm_lte_rx(skb, nic, nic_type); -} - -static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len) -{ - struct net_device *dev; - struct multi_sdu *multi_sdu = (struct multi_sdu *)buf; - struct sdu *sdu = NULL; - u8 endian = phy_dev->get_endian(phy_dev->priv_dev); - u8 *data = (u8 *)multi_sdu->data; - int copied; - u16 i = 0; - u16 num_packet; - u16 hci_len; - u16 cmd_evt; - u32 nic_type; - int index; - - num_packet = gdm_dev16_to_cpu(endian, multi_sdu->num_packet); - - for (i = 0; i < num_packet; i++) { - copied = data - multi_sdu->data; - if (len < copied + sizeof(*sdu)) { - pr_err("rx prevent buffer overflow"); - return; - } - - sdu = (struct sdu *)data; - - cmd_evt = gdm_dev16_to_cpu(endian, sdu->cmd_evt); - hci_len = gdm_dev16_to_cpu(endian, sdu->len); - nic_type = gdm_dev32_to_cpu(endian, sdu->nic_type); - - if (cmd_evt != LTE_RX_SDU) { - pr_err("rx sdu wrong hci %04x\n", cmd_evt); - return; - } - if (hci_len < 12 || - len < copied + sizeof(*sdu) + (hci_len - 12)) { - pr_err("rx sdu invalid len %d\n", hci_len); - return; - } - - index = find_dev_index(nic_type); - if (index < 0) { - pr_err("rx sdu invalid nic_type :%x\n", nic_type); - return; - } - dev = phy_dev->dev[index]; - gdm_lte_netif_rx(dev, (char *)sdu->data, - (int)(hci_len - 12), nic_type); - - data += ((hci_len + 3) & 0xfffc) + HCI_HEADER_SIZE; - } -} - -static void gdm_lte_pdn_table(struct net_device *dev, char *buf, int len) -{ - struct nic *nic = netdev_priv(dev); - struct hci_pdn_table_ind *pdn_table = (struct hci_pdn_table_ind *)buf; - u8 ed = nic->phy_dev->get_endian(nic->phy_dev->priv_dev); - - if (!pdn_table->activate) { - memset(&nic->pdn_table, 0x00, sizeof(struct pdn_table)); - netdev_info(dev, "pdn deactivated\n"); - - return; - } - - nic->pdn_table.activate = pdn_table->activate; - nic->pdn_table.dft_eps_id = gdm_dev32_to_cpu(ed, pdn_table->dft_eps_id); - nic->pdn_table.nic_type = gdm_dev32_to_cpu(ed, pdn_table->nic_type); - - netdev_info(dev, "pdn activated, nic_type=0x%x\n", - nic->pdn_table.nic_type); -} - -static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len) -{ - struct hci_packet *hci = (struct hci_packet *)buf; - struct hci_pdn_table_ind *pdn_table = (struct hci_pdn_table_ind *)buf; - struct sdu *sdu; - struct net_device *dev; - u8 endian = phy_dev->get_endian(phy_dev->priv_dev); - int ret = 0; - u16 cmd_evt; - u32 nic_type; - int index; - - if (!len) - return ret; - - cmd_evt = gdm_dev16_to_cpu(endian, hci->cmd_evt); - - dev = phy_dev->dev[0]; - if (!dev) - return 0; - - switch (cmd_evt) { - case LTE_RX_SDU: - sdu = (struct sdu *)hci->data; - nic_type = gdm_dev32_to_cpu(endian, sdu->nic_type); - index = find_dev_index(nic_type); - if (index < 0) - return index; - dev = phy_dev->dev[index]; - gdm_lte_netif_rx(dev, hci->data, len, nic_type); - break; - case LTE_RX_MULTI_SDU: - gdm_lte_multi_sdu_pkt(phy_dev, buf, len); - break; - case LTE_LINK_ON_OFF_INDICATION: - netdev_info(dev, "link %s\n", - ((struct hci_connect_ind *)buf)->connect - ? "on" : "off"); - break; - case LTE_PDN_TABLE_IND: - pdn_table = (struct hci_pdn_table_ind *)buf; - nic_type = gdm_dev32_to_cpu(endian, pdn_table->nic_type); - index = find_dev_index(nic_type); - if (index < 0) - return index; - dev = phy_dev->dev[index]; - gdm_lte_pdn_table(dev, buf, len); - fallthrough; - default: - ret = gdm_lte_event_send(dev, buf, len); - break; - } - - return ret; -} - -static int rx_complete(void *arg, void *data, int len, int context) -{ - struct phy_dev *phy_dev = arg; - - return gdm_lte_receive_pkt(phy_dev, data, len); -} - -void start_rx_proc(struct phy_dev *phy_dev) -{ - int i; - - for (i = 0; i < MAX_RX_SUBMIT_COUNT; i++) - phy_dev->rcv_func(phy_dev->priv_dev, - rx_complete, phy_dev, USB_COMPLETE); -} - -static const struct net_device_ops gdm_netdev_ops = { - .ndo_open = gdm_lte_open, - .ndo_stop = gdm_lte_close, - .ndo_set_config = gdm_lte_set_config, - .ndo_start_xmit = gdm_lte_tx, - .ndo_get_stats = gdm_lte_stats, -}; - -static u8 gdm_lte_macaddr[ETH_ALEN] = {0x00, 0x0a, 0x3b, 0x00, 0x00, 0x00}; - -static void form_mac_address(u8 *dev_addr, u8 *nic_src, u8 *nic_dest, - u8 *mac_address, u8 index) -{ - /* Form the dev_addr */ - if (!mac_address) - ether_addr_copy(dev_addr, gdm_lte_macaddr); - else - ether_addr_copy(dev_addr, mac_address); - - /* The last byte of the mac address - * should be less than or equal to 0xFC - */ - dev_addr[ETH_ALEN - 1] += index; - - /* Create random nic src and copy the first - * 3 bytes to be the same as dev_addr - */ - eth_random_addr(nic_src); - memcpy(nic_src, dev_addr, 3); - - /* Copy the nic_dest from dev_addr*/ - ether_addr_copy(nic_dest, dev_addr); -} - -static void validate_mac_address(u8 *mac_address) -{ - /* if zero address or multicast bit set, restore the default value */ - if (is_zero_ether_addr(mac_address) || (mac_address[0] & 0x01)) { - pr_err("MAC invalid, restoring default\n"); - memcpy(mac_address, gdm_lte_macaddr, 6); - } -} - -int register_lte_device(struct phy_dev *phy_dev, - struct device *dev, u8 *mac_address) -{ - struct nic *nic; - struct net_device *net; - char pdn_dev_name[16]; - u8 addr[ETH_ALEN]; - int ret = 0; - u8 index; - - validate_mac_address(mac_address); - - for (index = 0; index < MAX_NIC_TYPE; index++) { - /* Create device name lteXpdnX */ - sprintf(pdn_dev_name, "lte%%dpdn%d", index); - - /* Allocate netdev */ - net = alloc_netdev(sizeof(struct nic), pdn_dev_name, - NET_NAME_UNKNOWN, ether_setup); - if (!net) { - ret = -ENOMEM; - goto err; - } - net->netdev_ops = &gdm_netdev_ops; - net->flags &= ~IFF_MULTICAST; - net->mtu = DEFAULT_MTU_SIZE; - - nic = netdev_priv(net); - memset(nic, 0, sizeof(struct nic)); - nic->netdev = net; - nic->phy_dev = phy_dev; - nic->nic_id = index; - - form_mac_address(addr, - nic->src_mac_addr, - nic->dest_mac_addr, - mac_address, - index); - eth_hw_addr_set(net, addr); - - SET_NETDEV_DEV(net, dev); - SET_NETDEV_DEVTYPE(net, &wwan_type); - - ret = register_netdev(net); - if (ret) - goto err; - - netif_carrier_on(net); - - phy_dev->dev[index] = net; - } - - return 0; - -err: - unregister_lte_device(phy_dev); - - return ret; -} - -void unregister_lte_device(struct phy_dev *phy_dev) -{ - struct net_device *net; - int index; - - for (index = 0; index < MAX_NIC_TYPE; index++) { - net = phy_dev->dev[index]; - if (!net) - continue; - - unregister_netdev(net); - free_netdev(net); - } -} diff --git a/drivers/staging/gdm724x/gdm_lte.h b/drivers/staging/gdm724x/gdm_lte.h deleted file mode 100644 index f2143a6e0e990f1cef8c5f4ef14b90917931f4bc..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_lte.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_LTE_H_ -#define _GDM_LTE_H_ - -#include -#include - -#include "gdm_endian.h" - -#define MAX_NIC_TYPE 4 -#define MAX_RX_SUBMIT_COUNT 3 -#define DRIVER_VERSION "3.7.17.0" - -enum TX_ERROR_CODE { - TX_NO_ERROR = 0, - TX_NO_DEV, - TX_NO_SPC, - TX_NO_BUFFER, -}; - -enum CALLBACK_CONTEXT { - KERNEL_THREAD = 0, - USB_COMPLETE, -}; - -struct pdn_table { - u8 activate; - u32 dft_eps_id; - u32 nic_type; -} __packed; - -struct nic; - -struct phy_dev { - void *priv_dev; - struct net_device *dev[MAX_NIC_TYPE]; - int (*send_hci_func)(void *priv_dev, void *data, int len, - void (*cb)(void *cb_data), void *cb_data); - int (*send_sdu_func)(void *priv_dev, void *data, int len, - unsigned int dft_eps_id, unsigned int eps_id, - void (*cb)(void *cb_data), void *cb_data, - int dev_idx, int nic_type); - int (*rcv_func)(void *priv_dev, - int (*cb)(void *cb_data, void *data, int len, - int context), - void *cb_data, int context); - u8 (*get_endian)(void *priv_dev); -}; - -struct nic { - struct net_device *netdev; - struct phy_dev *phy_dev; - struct net_device_stats stats; - struct pdn_table pdn_table; - u8 dest_mac_addr[ETH_ALEN]; - u8 src_mac_addr[ETH_ALEN]; - u32 nic_id; - u16 vlan_id; -}; - -int gdm_lte_event_init(void); -void gdm_lte_event_exit(void); - -void start_rx_proc(struct phy_dev *phy_dev); -int register_lte_device(struct phy_dev *phy_dev, struct device *dev, - u8 *mac_address); -void unregister_lte_device(struct phy_dev *phy_dev); - -#endif /* _GDM_LTE_H_ */ diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c deleted file mode 100644 index 9b12619671a13ec4b2ecc140ed830aeeb182bc54..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_mux.c +++ /dev/null @@ -1,668 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gdm_mux.h" - -static u16 packet_type_for_tty_index[TTY_MAX_COUNT] = {0xF011, 0xF010}; - -#define USB_DEVICE_CDC_DATA(vid, pid) \ - .match_flags = \ - USB_DEVICE_ID_MATCH_DEVICE |\ - USB_DEVICE_ID_MATCH_INT_CLASS |\ - USB_DEVICE_ID_MATCH_INT_SUBCLASS,\ - .idVendor = vid,\ - .idProduct = pid,\ - .bInterfaceClass = USB_CLASS_COMM,\ - .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM - -static const struct usb_device_id id_table[] = { - { USB_DEVICE_CDC_DATA(0x1076, 0x8000) }, /* GCT GDM7240 */ - { USB_DEVICE_CDC_DATA(0x1076, 0x8f00) }, /* GCT GDM7243 */ - { USB_DEVICE_CDC_DATA(0x1076, 0x9000) }, /* GCT GDM7243 */ - { USB_DEVICE_CDC_DATA(0x1d74, 0x2300) }, /* LGIT Phoenix */ - {} -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static int packet_type_to_tty_index(u16 packet_type) -{ - int i; - - for (i = 0; i < TTY_MAX_COUNT; i++) { - if (packet_type_for_tty_index[i] == packet_type) - return i; - } - - return -1; -} - -static struct mux_tx *alloc_mux_tx(int len) -{ - struct mux_tx *t; - - t = kzalloc(sizeof(*t), GFP_ATOMIC); - if (!t) - return NULL; - - t->urb = usb_alloc_urb(0, GFP_ATOMIC); - t->buf = kmalloc(MUX_TX_MAX_SIZE, GFP_ATOMIC); - if (!t->urb || !t->buf) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - return NULL; - } - - return t; -} - -static void free_mux_tx(struct mux_tx *t) -{ - if (t) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - } -} - -static struct mux_rx *alloc_mux_rx(void) -{ - struct mux_rx *r; - - r = kzalloc(sizeof(*r), GFP_KERNEL); - if (!r) - return NULL; - - r->urb = usb_alloc_urb(0, GFP_KERNEL); - r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_KERNEL); - if (!r->urb || !r->buf) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - return NULL; - } - - return r; -} - -static void free_mux_rx(struct mux_rx *r) -{ - if (r) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - } -} - -static struct mux_rx *get_rx_struct(struct rx_cxt *rx) -{ - struct mux_rx *r; - unsigned long flags; - - spin_lock_irqsave(&rx->free_list_lock, flags); - - if (list_empty(&rx->rx_free_list)) { - spin_unlock_irqrestore(&rx->free_list_lock, flags); - return NULL; - } - - r = list_entry(rx->rx_free_list.prev, struct mux_rx, free_list); - list_del(&r->free_list); - - spin_unlock_irqrestore(&rx->free_list_lock, flags); - - return r; -} - -static void put_rx_struct(struct rx_cxt *rx, struct mux_rx *r) -{ - unsigned long flags; - - spin_lock_irqsave(&rx->free_list_lock, flags); - list_add_tail(&r->free_list, &rx->rx_free_list); - spin_unlock_irqrestore(&rx->free_list_lock, flags); -} - -static int up_to_host(struct mux_rx *r) -{ - struct mux_dev *mux_dev = r->mux_dev; - struct mux_pkt_header *mux_header; - unsigned int start_flag; - unsigned int payload_size; - unsigned short packet_type; - int total_len; - u32 packet_size_sum = r->offset; - int index; - int ret = TO_HOST_INVALID_PACKET; - int len = r->len; - - while (1) { - mux_header = (struct mux_pkt_header *)(r->buf + - packet_size_sum); - start_flag = __le32_to_cpu(mux_header->start_flag); - payload_size = __le32_to_cpu(mux_header->payload_size); - packet_type = __le16_to_cpu(mux_header->packet_type); - - if (start_flag != START_FLAG) { - pr_err("invalid START_FLAG %x\n", start_flag); - break; - } - - total_len = ALIGN(MUX_HEADER_SIZE + payload_size, 4); - - if (len - packet_size_sum < total_len) { - pr_err("invalid payload : %d %d %04x\n", - payload_size, len, packet_type); - break; - } - - index = packet_type_to_tty_index(packet_type); - if (index < 0) { - pr_err("invalid index %d\n", index); - break; - } - - ret = r->callback(mux_header->data, - payload_size, - index, - mux_dev->tty_dev, - RECV_PACKET_PROCESS_CONTINUE - ); - if (ret == TO_HOST_BUFFER_REQUEST_FAIL) { - r->offset += packet_size_sum; - break; - } - - packet_size_sum += total_len; - if (len - packet_size_sum <= MUX_HEADER_SIZE + 2) { - ret = r->callback(NULL, - 0, - index, - mux_dev->tty_dev, - RECV_PACKET_PROCESS_COMPLETE - ); - break; - } - } - - return ret; -} - -static void do_rx(struct work_struct *work) -{ - struct mux_dev *mux_dev = - container_of(work, struct mux_dev, work_rx.work); - struct mux_rx *r; - struct rx_cxt *rx = &mux_dev->rx; - unsigned long flags; - int ret = 0; - - while (1) { - spin_lock_irqsave(&rx->to_host_lock, flags); - if (list_empty(&rx->to_host_list)) { - spin_unlock_irqrestore(&rx->to_host_lock, flags); - break; - } - r = list_entry(rx->to_host_list.next, struct mux_rx, - to_host_list); - list_del(&r->to_host_list); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - - ret = up_to_host(r); - if (ret == TO_HOST_BUFFER_REQUEST_FAIL) - pr_err("failed to send mux data to host\n"); - else - put_rx_struct(rx, r); - } -} - -static void remove_rx_submit_list(struct mux_rx *r, struct rx_cxt *rx) -{ - unsigned long flags; - struct mux_rx *r_remove, *r_remove_next; - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_for_each_entry_safe(r_remove, r_remove_next, &rx->rx_submit_list, - rx_submit_list) { - if (r == r_remove) - list_del(&r->rx_submit_list); - } - spin_unlock_irqrestore(&rx->submit_list_lock, flags); -} - -static void gdm_mux_rcv_complete(struct urb *urb) -{ - struct mux_rx *r = urb->context; - struct mux_dev *mux_dev = r->mux_dev; - struct rx_cxt *rx = &mux_dev->rx; - unsigned long flags; - - remove_rx_submit_list(r, rx); - - if (urb->status) { - if (mux_dev->usb_state == PM_NORMAL) - dev_err(&urb->dev->dev, "%s: urb status error %d\n", - __func__, urb->status); - put_rx_struct(rx, r); - } else { - r->len = r->urb->actual_length; - spin_lock_irqsave(&rx->to_host_lock, flags); - list_add_tail(&r->to_host_list, &rx->to_host_list); - schedule_work(&mux_dev->work_rx.work); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - } -} - -static int gdm_mux_recv(void *priv_dev, - int (*cb)(void *data, int len, int tty_index, - struct tty_dev *tty_dev, int complete)) -{ - struct mux_dev *mux_dev = priv_dev; - struct usb_device *usbdev = mux_dev->usbdev; - struct mux_rx *r; - struct rx_cxt *rx = &mux_dev->rx; - unsigned long flags; - int ret; - - if (!usbdev) { - pr_err("device is disconnected\n"); - return -ENODEV; - } - - r = get_rx_struct(rx); - if (!r) { - pr_err("get_rx_struct fail\n"); - return -ENOMEM; - } - - r->offset = 0; - r->mux_dev = (void *)mux_dev; - r->callback = cb; - mux_dev->rx_cb = cb; - - usb_fill_bulk_urb(r->urb, - usbdev, - usb_rcvbulkpipe(usbdev, 0x86), - r->buf, - MUX_RX_MAX_SIZE, - gdm_mux_rcv_complete, - r); - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_add_tail(&r->rx_submit_list, &rx->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - ret = usb_submit_urb(r->urb, GFP_KERNEL); - - if (ret) { - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_del(&r->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - put_rx_struct(rx, r); - - pr_err("usb_submit_urb ret=%d\n", ret); - } - - usb_mark_last_busy(usbdev); - - return ret; -} - -static void gdm_mux_send_complete(struct urb *urb) -{ - struct mux_tx *t = urb->context; - - if (urb->status == -ECONNRESET) { - dev_info(&urb->dev->dev, "CONNRESET\n"); - free_mux_tx(t); - return; - } - - if (t->callback) - t->callback(t->cb_data); - - free_mux_tx(t); -} - -static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, - void (*cb)(void *data), void *cb_data) -{ - struct mux_dev *mux_dev = priv_dev; - struct usb_device *usbdev = mux_dev->usbdev; - struct mux_pkt_header *mux_header; - struct mux_tx *t = NULL; - static u32 seq_num = 1; - int total_len; - int ret; - unsigned long flags; - - if (mux_dev->usb_state == PM_SUSPEND) { - ret = usb_autopm_get_interface(mux_dev->intf); - if (!ret) - usb_autopm_put_interface(mux_dev->intf); - } - - spin_lock_irqsave(&mux_dev->write_lock, flags); - - total_len = ALIGN(MUX_HEADER_SIZE + len, 4); - - t = alloc_mux_tx(total_len); - if (!t) { - pr_err("alloc_mux_tx fail\n"); - spin_unlock_irqrestore(&mux_dev->write_lock, flags); - return -ENOMEM; - } - - mux_header = (struct mux_pkt_header *)t->buf; - mux_header->start_flag = __cpu_to_le32(START_FLAG); - mux_header->seq_num = __cpu_to_le32(seq_num++); - mux_header->payload_size = __cpu_to_le32((u32)len); - mux_header->packet_type = __cpu_to_le16(packet_type_for_tty_index[tty_index]); - - memcpy(t->buf + MUX_HEADER_SIZE, data, len); - memset(t->buf + MUX_HEADER_SIZE + len, 0, - total_len - MUX_HEADER_SIZE - len); - - t->len = total_len; - t->callback = cb; - t->cb_data = cb_data; - - usb_fill_bulk_urb(t->urb, - usbdev, - usb_sndbulkpipe(usbdev, 5), - t->buf, - total_len, - gdm_mux_send_complete, - t); - - ret = usb_submit_urb(t->urb, GFP_ATOMIC); - - spin_unlock_irqrestore(&mux_dev->write_lock, flags); - - if (ret) - pr_err("usb_submit_urb Error: %d\n", ret); - - usb_mark_last_busy(usbdev); - - return ret; -} - -static int gdm_mux_send_control(void *priv_dev, int request, int value, - void *buf, int len) -{ - struct mux_dev *mux_dev = priv_dev; - struct usb_device *usbdev = mux_dev->usbdev; - int ret; - - ret = usb_control_msg(usbdev, - usb_sndctrlpipe(usbdev, 0), - request, - USB_RT_ACM, - value, - 2, - buf, - len, - 5000 - ); - - if (ret < 0) - pr_err("usb_control_msg error: %d\n", ret); - - return min(ret, 0); -} - -static void release_usb(struct mux_dev *mux_dev) -{ - struct rx_cxt *rx = &mux_dev->rx; - struct mux_rx *r, *r_next; - unsigned long flags; - - cancel_delayed_work(&mux_dev->work_rx); - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_list_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - spin_lock_irqsave(&rx->free_list_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_free_list, free_list) { - list_del(&r->free_list); - free_mux_rx(r); - } - spin_unlock_irqrestore(&rx->free_list_lock, flags); - - spin_lock_irqsave(&rx->to_host_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list) { - if (r->mux_dev == (void *)mux_dev) { - list_del(&r->to_host_list); - free_mux_rx(r); - } - } - spin_unlock_irqrestore(&rx->to_host_lock, flags); -} - -static int init_usb(struct mux_dev *mux_dev) -{ - struct mux_rx *r; - struct rx_cxt *rx = &mux_dev->rx; - int ret = 0; - int i; - - spin_lock_init(&mux_dev->write_lock); - INIT_LIST_HEAD(&rx->to_host_list); - INIT_LIST_HEAD(&rx->rx_submit_list); - INIT_LIST_HEAD(&rx->rx_free_list); - spin_lock_init(&rx->to_host_lock); - spin_lock_init(&rx->submit_list_lock); - spin_lock_init(&rx->free_list_lock); - - for (i = 0; i < MAX_ISSUE_NUM * 2; i++) { - r = alloc_mux_rx(); - if (!r) { - ret = -ENOMEM; - break; - } - - list_add(&r->free_list, &rx->rx_free_list); - } - - INIT_DELAYED_WORK(&mux_dev->work_rx, do_rx); - - return ret; -} - -static int gdm_mux_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct mux_dev *mux_dev; - struct tty_dev *tty_dev; - u16 idVendor, idProduct; - int bInterfaceNumber; - int ret; - int i; - struct usb_device *usbdev = interface_to_usbdev(intf); - - bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber; - - idVendor = __le16_to_cpu(usbdev->descriptor.idVendor); - idProduct = __le16_to_cpu(usbdev->descriptor.idProduct); - - pr_info("mux vid = 0x%04x pid = 0x%04x\n", idVendor, idProduct); - - if (bInterfaceNumber != 2) - return -ENODEV; - - mux_dev = kzalloc(sizeof(*mux_dev), GFP_KERNEL); - if (!mux_dev) - return -ENOMEM; - - tty_dev = kzalloc(sizeof(*tty_dev), GFP_KERNEL); - if (!tty_dev) { - ret = -ENOMEM; - goto err_free_mux; - } - - mux_dev->usbdev = usbdev; - mux_dev->control_intf = intf; - - ret = init_usb(mux_dev); - if (ret) - goto err_free_usb; - - tty_dev->priv_dev = (void *)mux_dev; - tty_dev->send_func = gdm_mux_send; - tty_dev->recv_func = gdm_mux_recv; - tty_dev->send_control = gdm_mux_send_control; - - ret = register_lte_tty_device(tty_dev, &intf->dev); - if (ret) - goto err_unregister_tty; - - for (i = 0; i < TTY_MAX_COUNT; i++) - mux_dev->tty_dev = tty_dev; - - mux_dev->intf = intf; - mux_dev->usb_state = PM_NORMAL; - - usb_get_dev(usbdev); - usb_set_intfdata(intf, tty_dev); - - return 0; - -err_unregister_tty: - unregister_lte_tty_device(tty_dev); -err_free_usb: - release_usb(mux_dev); - kfree(tty_dev); -err_free_mux: - kfree(mux_dev); - - return ret; -} - -static void gdm_mux_disconnect(struct usb_interface *intf) -{ - struct tty_dev *tty_dev; - struct mux_dev *mux_dev; - struct usb_device *usbdev = interface_to_usbdev(intf); - - tty_dev = usb_get_intfdata(intf); - - mux_dev = tty_dev->priv_dev; - - release_usb(mux_dev); - unregister_lte_tty_device(tty_dev); - - kfree(mux_dev); - kfree(tty_dev); - - usb_put_dev(usbdev); -} - -static int gdm_mux_suspend(struct usb_interface *intf, pm_message_t pm_msg) -{ - struct tty_dev *tty_dev; - struct mux_dev *mux_dev; - struct rx_cxt *rx; - struct mux_rx *r, *r_next; - unsigned long flags; - - tty_dev = usb_get_intfdata(intf); - mux_dev = tty_dev->priv_dev; - rx = &mux_dev->rx; - - cancel_work_sync(&mux_dev->work_rx.work); - - if (mux_dev->usb_state != PM_NORMAL) { - dev_err(intf->usb_dev, "usb suspend - invalid state\n"); - return -1; - } - - mux_dev->usb_state = PM_SUSPEND; - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_list_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - return 0; -} - -static int gdm_mux_resume(struct usb_interface *intf) -{ - struct tty_dev *tty_dev; - struct mux_dev *mux_dev; - u8 i; - - tty_dev = usb_get_intfdata(intf); - mux_dev = tty_dev->priv_dev; - - if (mux_dev->usb_state != PM_SUSPEND) { - dev_err(intf->usb_dev, "usb resume - invalid state\n"); - return -1; - } - - mux_dev->usb_state = PM_NORMAL; - - for (i = 0; i < MAX_ISSUE_NUM; i++) - gdm_mux_recv(mux_dev, mux_dev->rx_cb); - - return 0; -} - -static struct usb_driver gdm_mux_driver = { - .name = "gdm_mux", - .probe = gdm_mux_probe, - .disconnect = gdm_mux_disconnect, - .id_table = id_table, - .supports_autosuspend = 1, - .suspend = gdm_mux_suspend, - .resume = gdm_mux_resume, - .reset_resume = gdm_mux_resume, -}; - -static int __init gdm_usb_mux_init(void) -{ - int ret; - - ret = register_lte_tty_driver(); - if (ret) - return ret; - - return usb_register(&gdm_mux_driver); -} - -static void __exit gdm_usb_mux_exit(void) -{ - usb_deregister(&gdm_mux_driver); - unregister_lte_tty_driver(); -} - -module_init(gdm_usb_mux_init); -module_exit(gdm_usb_mux_exit); - -MODULE_DESCRIPTION("GCT LTE TTY Device Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gdm724x/gdm_mux.h b/drivers/staging/gdm724x/gdm_mux.h deleted file mode 100644 index 87b8d921fdc822208df7508158d699c40bea1c42..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_mux.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_MUX_H_ -#define _GDM_MUX_H_ - -#include -#include -#include - -#include "gdm_tty.h" - -#define PM_NORMAL 0 -#define PM_SUSPEND 1 - -#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE) - -#define START_FLAG 0xA512485A -#define MUX_HEADER_SIZE 14 -#define MUX_TX_MAX_SIZE (1024 * 10) -#define MUX_RX_MAX_SIZE (1024 * 30) -#define AT_PKT_TYPE 0xF011 -#define DM_PKT_TYPE 0xF010 - -#define RETRY_TIMER 30 /* msec */ - -struct mux_pkt_header { - __le32 start_flag; - __le32 seq_num; - __le32 payload_size; - __le16 packet_type; - unsigned char data[]; -}; - -struct mux_tx { - struct urb *urb; - u8 *buf; - int len; - void (*callback)(void *cb_data); - void *cb_data; -}; - -struct mux_rx { - struct list_head free_list; - struct list_head rx_submit_list; - struct list_head to_host_list; - struct urb *urb; - u8 *buf; - void *mux_dev; - u32 offset; - u32 len; - int (*callback)(void *data, - int len, - int tty_index, - struct tty_dev *tty_dev, - int complete); -}; - -struct rx_cxt { - struct list_head to_host_list; - struct list_head rx_submit_list; - struct list_head rx_free_list; - spinlock_t to_host_lock; - spinlock_t submit_list_lock; - spinlock_t free_list_lock; -}; - -struct mux_dev { - struct usb_device *usbdev; - struct usb_interface *control_intf; - struct usb_interface *data_intf; - struct rx_cxt rx; - struct delayed_work work_rx; - struct usb_interface *intf; - int usb_state; - int (*rx_cb)(void *data, - int len, - int tty_index, - struct tty_dev *tty_dev, - int complete); - spinlock_t write_lock; - struct tty_dev *tty_dev; -}; - -#endif /* _GDM_MUX_H_ */ diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c deleted file mode 100644 index 15c246d3b1a3ebeb4b03c189c8d5611c32f84ed1..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_tty.c +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "gdm_tty.h" - -#define GDM_TTY_MAJOR 0 -#define GDM_TTY_MINOR 32 - -#define WRITE_SIZE 2048 - -#define MUX_TX_MAX_SIZE 2048 - -static inline bool gdm_tty_ready(struct gdm *gdm) -{ - return gdm && gdm->tty_dev && gdm->port.count; -} - -static struct tty_driver *gdm_driver[TTY_MAX_COUNT]; -static struct gdm *gdm_table[TTY_MAX_COUNT][GDM_TTY_MINOR]; -static DEFINE_MUTEX(gdm_table_lock); - -static const char *DRIVER_STRING[TTY_MAX_COUNT] = {"GCTATC", "GCTDM"}; -static char *DEVICE_STRING[TTY_MAX_COUNT] = {"GCT-ATC", "GCT-DM"}; - -static void gdm_port_destruct(struct tty_port *port) -{ - struct gdm *gdm = container_of(port, struct gdm, port); - - mutex_lock(&gdm_table_lock); - gdm_table[gdm->index][gdm->minor] = NULL; - mutex_unlock(&gdm_table_lock); - - kfree(gdm); -} - -static const struct tty_port_operations gdm_port_ops = { - .destruct = gdm_port_destruct, -}; - -static int gdm_tty_install(struct tty_driver *driver, struct tty_struct *tty) -{ - struct gdm *gdm = NULL; - int ret; - - ret = match_string(DRIVER_STRING, TTY_MAX_COUNT, - tty->driver->driver_name); - if (ret < 0) - return -ENODEV; - - mutex_lock(&gdm_table_lock); - gdm = gdm_table[ret][tty->index]; - if (!gdm) { - mutex_unlock(&gdm_table_lock); - return -ENODEV; - } - - tty_port_get(&gdm->port); - - ret = tty_standard_install(driver, tty); - if (ret) { - tty_port_put(&gdm->port); - mutex_unlock(&gdm_table_lock); - return ret; - } - - tty->driver_data = gdm; - mutex_unlock(&gdm_table_lock); - - return 0; -} - -static int gdm_tty_open(struct tty_struct *tty, struct file *filp) -{ - struct gdm *gdm = tty->driver_data; - - return tty_port_open(&gdm->port, tty, filp); -} - -static void gdm_tty_cleanup(struct tty_struct *tty) -{ - struct gdm *gdm = tty->driver_data; - - tty_port_put(&gdm->port); -} - -static void gdm_tty_hangup(struct tty_struct *tty) -{ - struct gdm *gdm = tty->driver_data; - - tty_port_hangup(&gdm->port); -} - -static void gdm_tty_close(struct tty_struct *tty, struct file *filp) -{ - struct gdm *gdm = tty->driver_data; - - tty_port_close(&gdm->port, tty, filp); -} - -static int gdm_tty_recv_complete(void *data, - int len, - int index, - struct tty_dev *tty_dev, - int complete) -{ - struct gdm *gdm = tty_dev->gdm[index]; - - if (!gdm_tty_ready(gdm)) { - if (complete == RECV_PACKET_PROCESS_COMPLETE) - gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev, - gdm_tty_recv_complete); - return TO_HOST_PORT_CLOSE; - } - - if (data && len) { - if (tty_buffer_request_room(&gdm->port, len) == len) { - tty_insert_flip_string(&gdm->port, data, len); - tty_flip_buffer_push(&gdm->port); - } else { - return TO_HOST_BUFFER_REQUEST_FAIL; - } - } - - if (complete == RECV_PACKET_PROCESS_COMPLETE) - gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev, - gdm_tty_recv_complete); - - return 0; -} - -static void gdm_tty_send_complete(void *arg) -{ - struct gdm *gdm = arg; - - if (!gdm_tty_ready(gdm)) - return; - - tty_port_tty_wakeup(&gdm->port); -} - -static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) -{ - struct gdm *gdm = tty->driver_data; - size_t remain = len; - size_t sent_len = 0; - - if (!gdm_tty_ready(gdm)) - return -ENODEV; - - while (remain) { - size_t sending_len = min_t(size_t, MUX_TX_MAX_SIZE, remain); - - gdm->tty_dev->send_func(gdm->tty_dev->priv_dev, - (void *)(buf + sent_len), - sending_len, - gdm->index, - gdm_tty_send_complete, - gdm); - sent_len += sending_len; - remain -= sending_len; - } - - return len; -} - -static unsigned int gdm_tty_write_room(struct tty_struct *tty) -{ - struct gdm *gdm = tty->driver_data; - - if (!gdm_tty_ready(gdm)) - return 0; - - return WRITE_SIZE; -} - -int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device) -{ - struct gdm *gdm; - int i; - int j; - - for (i = 0; i < TTY_MAX_COUNT; i++) { - gdm = kmalloc(sizeof(*gdm), GFP_KERNEL); - if (!gdm) - return -ENOMEM; - - mutex_lock(&gdm_table_lock); - for (j = 0; j < GDM_TTY_MINOR; j++) { - if (!gdm_table[i][j]) - break; - } - - if (j == GDM_TTY_MINOR) { - kfree(gdm); - mutex_unlock(&gdm_table_lock); - return -EINVAL; - } - - gdm_table[i][j] = gdm; - mutex_unlock(&gdm_table_lock); - - tty_dev->gdm[i] = gdm; - tty_port_init(&gdm->port); - - gdm->port.ops = &gdm_port_ops; - gdm->index = i; - gdm->minor = j; - gdm->tty_dev = tty_dev; - - tty_port_register_device(&gdm->port, gdm_driver[i], - gdm->minor, device); - } - - for (i = 0; i < MAX_ISSUE_NUM; i++) - gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev, - gdm_tty_recv_complete); - - return 0; -} - -void unregister_lte_tty_device(struct tty_dev *tty_dev) -{ - struct gdm *gdm; - struct tty_struct *tty; - int i; - - for (i = 0; i < TTY_MAX_COUNT; i++) { - gdm = tty_dev->gdm[i]; - if (!gdm) - continue; - - mutex_lock(&gdm_table_lock); - gdm_table[gdm->index][gdm->minor] = NULL; - mutex_unlock(&gdm_table_lock); - - tty = tty_port_tty_get(&gdm->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } - - tty_unregister_device(gdm_driver[i], gdm->minor); - tty_port_put(&gdm->port); - } -} - -static const struct tty_operations gdm_tty_ops = { - .install = gdm_tty_install, - .open = gdm_tty_open, - .close = gdm_tty_close, - .cleanup = gdm_tty_cleanup, - .hangup = gdm_tty_hangup, - .write = gdm_tty_write, - .write_room = gdm_tty_write_room, -}; - -int register_lte_tty_driver(void) -{ - struct tty_driver *tty_driver; - int i; - int ret; - - for (i = 0; i < TTY_MAX_COUNT; i++) { - tty_driver = tty_alloc_driver(GDM_TTY_MINOR, - TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); - if (IS_ERR(tty_driver)) - return PTR_ERR(tty_driver); - - tty_driver->owner = THIS_MODULE; - tty_driver->driver_name = DRIVER_STRING[i]; - tty_driver->name = DEVICE_STRING[i]; - tty_driver->major = GDM_TTY_MAJOR; - tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - tty_driver->subtype = SERIAL_TYPE_NORMAL; - tty_driver->init_termios = tty_std_termios; - tty_driver->init_termios.c_cflag = B9600 | CS8 | HUPCL | CLOCAL; - tty_driver->init_termios.c_lflag = ISIG | ICANON | IEXTEN; - tty_set_operations(tty_driver, &gdm_tty_ops); - - ret = tty_register_driver(tty_driver); - if (ret) { - tty_driver_kref_put(tty_driver); - return ret; - } - - gdm_driver[i] = tty_driver; - } - - return ret; -} - -void unregister_lte_tty_driver(void) -{ - struct tty_driver *tty_driver; - int i; - - for (i = 0; i < TTY_MAX_COUNT; i++) { - tty_driver = gdm_driver[i]; - if (tty_driver) { - tty_unregister_driver(tty_driver); - tty_driver_kref_put(tty_driver); - } - } -} - diff --git a/drivers/staging/gdm724x/gdm_tty.h b/drivers/staging/gdm724x/gdm_tty.h deleted file mode 100644 index afec97ced4769b2b16cd52017925604cf62ced67..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_tty.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_TTY_H_ -#define _GDM_TTY_H_ - -#include -#include - -#define TTY_MAX_COUNT 2 - -#define MAX_ISSUE_NUM 3 - -enum TO_HOST_RESULT { - TO_HOST_BUFFER_REQUEST_FAIL = 1, - TO_HOST_PORT_CLOSE = 2, - TO_HOST_INVALID_PACKET = 3, -}; - -enum RECV_PACKET_PROCESS { - RECV_PACKET_PROCESS_COMPLETE = 0, - RECV_PACKET_PROCESS_CONTINUE = 1, -}; - -struct gdm { - struct tty_dev *tty_dev; - struct tty_port port; - unsigned int index; - unsigned int minor; -}; - -struct tty_dev { - void *priv_dev; - int (*send_func)(void *priv_dev, - void *data, - int len, - int tty_index, - void (*cb)(void *cb_data), - void *cb_data); - int (*recv_func)(void *priv_dev, - int (*cb)(void *data, - int len, - int tty_index, - struct tty_dev *tty_dev, - int complete)); - int (*send_control)(void *priv_dev, - int request, - int value, - void *data, - int len); - struct gdm *gdm[2]; -}; - -int register_lte_tty_driver(void); -void unregister_lte_tty_driver(void); -int register_lte_tty_device(struct tty_dev *tty_dev, struct device *dev); -void unregister_lte_tty_device(struct tty_dev *tty_dev); - -#endif /* _GDM_USB_H_ */ - diff --git a/drivers/staging/gdm724x/gdm_usb.c b/drivers/staging/gdm724x/gdm_usb.c deleted file mode 100644 index 54bdb64f52e889962205b7d2ff287e4e3a14a1ad..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_usb.c +++ /dev/null @@ -1,1012 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gdm_usb.h" -#include "gdm_lte.h" -#include "hci.h" -#include "hci_packet.h" -#include "gdm_endian.h" - -#define USB_DEVICE_CDC_DATA(vid, pid) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_INT_CLASS | \ - USB_DEVICE_ID_MATCH_INT_SUBCLASS,\ - .idVendor = vid,\ - .idProduct = pid,\ - .bInterfaceClass = USB_CLASS_COMM,\ - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET - -#define USB_DEVICE_MASS_DATA(vid, pid) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_INT_INFO,\ - .idVendor = vid,\ - .idProduct = pid,\ - .bInterfaceSubClass = USB_SC_SCSI, \ - .bInterfaceClass = USB_CLASS_MASS_STORAGE,\ - .bInterfaceProtocol = USB_PR_BULK - -static const struct usb_device_id id_table[] = { - { USB_DEVICE_CDC_DATA(VID_GCT, PID_GDM7240) }, /* GCT GDM7240 */ - { USB_DEVICE_CDC_DATA(VID_GCT, PID_GDM7243) }, /* GCT GDM7243 */ - { } -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static void do_tx(struct work_struct *work); -static void do_rx(struct work_struct *work); - -static int gdm_usb_recv(void *priv_dev, - int (*cb)(void *cb_data, - void *data, int len, int context), - void *cb_data, - int context); - -static int request_mac_address(struct lte_udev *udev) -{ - struct hci_packet *hci; - struct usb_device *usbdev = udev->usbdev; - int actual; - int ret = -1; - - hci = kmalloc(struct_size(hci, data, 1), GFP_KERNEL); - if (!hci) - return -ENOMEM; - - hci->cmd_evt = gdm_cpu_to_dev16(udev->gdm_ed, LTE_GET_INFORMATION); - hci->len = gdm_cpu_to_dev16(udev->gdm_ed, 1); - hci->data[0] = MAC_ADDRESS; - - ret = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 2), hci, 5, - &actual, 1000); - - udev->request_mac_addr = 1; - kfree(hci); - - return ret; -} - -static struct usb_tx *alloc_tx_struct(int len) -{ - struct usb_tx *t = NULL; - int ret = 0; - - t = kzalloc(sizeof(*t), GFP_ATOMIC); - if (!t) { - ret = -ENOMEM; - goto out; - } - - t->urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!(len % 512)) - len++; - - t->buf = kmalloc(len, GFP_ATOMIC); - if (!t->urb || !t->buf) { - ret = -ENOMEM; - goto out; - } - -out: - if (ret < 0) { - if (t) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - } - return NULL; - } - - return t; -} - -static struct usb_tx_sdu *alloc_tx_sdu_struct(void) -{ - struct usb_tx_sdu *t_sdu; - - t_sdu = kzalloc(sizeof(*t_sdu), GFP_KERNEL); - if (!t_sdu) - return NULL; - - t_sdu->buf = kmalloc(SDU_BUF_SIZE, GFP_KERNEL); - if (!t_sdu->buf) { - kfree(t_sdu); - return NULL; - } - - return t_sdu; -} - -static void free_tx_struct(struct usb_tx *t) -{ - if (t) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - } -} - -static void free_tx_sdu_struct(struct usb_tx_sdu *t_sdu) -{ - if (t_sdu) { - kfree(t_sdu->buf); - kfree(t_sdu); - } -} - -static struct usb_tx_sdu *get_tx_sdu_struct(struct tx_cxt *tx, int *no_spc) -{ - struct usb_tx_sdu *t_sdu; - - if (list_empty(&tx->free_list)) - return NULL; - - t_sdu = list_entry(tx->free_list.next, struct usb_tx_sdu, list); - list_del(&t_sdu->list); - - tx->avail_count--; - - *no_spc = list_empty(&tx->free_list) ? 1 : 0; - - return t_sdu; -} - -static void put_tx_struct(struct tx_cxt *tx, struct usb_tx_sdu *t_sdu) -{ - list_add_tail(&t_sdu->list, &tx->free_list); - tx->avail_count++; -} - -static struct usb_rx *alloc_rx_struct(void) -{ - struct usb_rx *r = NULL; - int ret = 0; - - r = kmalloc(sizeof(*r), GFP_KERNEL); - if (!r) { - ret = -ENOMEM; - goto out; - } - - r->urb = usb_alloc_urb(0, GFP_KERNEL); - r->buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL); - if (!r->urb || !r->buf) { - ret = -ENOMEM; - goto out; - } -out: - - if (ret < 0) { - if (r) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - } - return NULL; - } - - return r; -} - -static void free_rx_struct(struct usb_rx *r) -{ - if (r) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - } -} - -static struct usb_rx *get_rx_struct(struct rx_cxt *rx, int *no_spc) -{ - struct usb_rx *r; - unsigned long flags; - - spin_lock_irqsave(&rx->rx_lock, flags); - - if (list_empty(&rx->free_list)) { - spin_unlock_irqrestore(&rx->rx_lock, flags); - return NULL; - } - - r = list_entry(rx->free_list.next, struct usb_rx, free_list); - list_del(&r->free_list); - - rx->avail_count--; - - *no_spc = list_empty(&rx->free_list) ? 1 : 0; - - spin_unlock_irqrestore(&rx->rx_lock, flags); - - return r; -} - -static void put_rx_struct(struct rx_cxt *rx, struct usb_rx *r) -{ - unsigned long flags; - - spin_lock_irqsave(&rx->rx_lock, flags); - - list_add_tail(&r->free_list, &rx->free_list); - rx->avail_count++; - - spin_unlock_irqrestore(&rx->rx_lock, flags); -} - -static void release_usb(struct lte_udev *udev) -{ - struct rx_cxt *rx = &udev->rx; - struct tx_cxt *tx = &udev->tx; - struct usb_tx *t, *t_next; - struct usb_rx *r, *r_next; - struct usb_tx_sdu *t_sdu, *t_sdu_next; - unsigned long flags; - - spin_lock_irqsave(&tx->lock, flags); - list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->sdu_list, list) { - list_del(&t_sdu->list); - free_tx_sdu_struct(t_sdu); - } - - list_for_each_entry_safe(t, t_next, &tx->hci_list, list) { - list_del(&t->list); - free_tx_struct(t); - } - - list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->free_list, list) { - list_del(&t_sdu->list); - free_tx_sdu_struct(t_sdu); - } - spin_unlock_irqrestore(&tx->lock, flags); - - spin_lock_irqsave(&rx->submit_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_lock, flags); - - spin_lock_irqsave(&rx->rx_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->free_list, free_list) { - list_del(&r->free_list); - free_rx_struct(r); - } - spin_unlock_irqrestore(&rx->rx_lock, flags); - - spin_lock_irqsave(&rx->to_host_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list) { - if (r->index == (void *)udev) { - list_del(&r->to_host_list); - free_rx_struct(r); - } - } - spin_unlock_irqrestore(&rx->to_host_lock, flags); -} - -static int init_usb(struct lte_udev *udev) -{ - int ret = 0; - int i; - struct tx_cxt *tx = &udev->tx; - struct rx_cxt *rx = &udev->rx; - struct usb_tx_sdu *t_sdu = NULL; - struct usb_rx *r = NULL; - - udev->send_complete = 1; - udev->tx_stop = 0; - udev->request_mac_addr = 0; - udev->usb_state = PM_NORMAL; - - INIT_LIST_HEAD(&tx->sdu_list); - INIT_LIST_HEAD(&tx->hci_list); - INIT_LIST_HEAD(&tx->free_list); - INIT_LIST_HEAD(&rx->rx_submit_list); - INIT_LIST_HEAD(&rx->free_list); - INIT_LIST_HEAD(&rx->to_host_list); - spin_lock_init(&tx->lock); - spin_lock_init(&rx->rx_lock); - spin_lock_init(&rx->submit_lock); - spin_lock_init(&rx->to_host_lock); - - tx->avail_count = 0; - rx->avail_count = 0; - - udev->rx_cb = NULL; - - for (i = 0; i < MAX_NUM_SDU_BUF; i++) { - t_sdu = alloc_tx_sdu_struct(); - if (!t_sdu) { - ret = -ENOMEM; - goto fail; - } - - list_add(&t_sdu->list, &tx->free_list); - tx->avail_count++; - } - - for (i = 0; i < MAX_RX_SUBMIT_COUNT * 2; i++) { - r = alloc_rx_struct(); - if (!r) { - ret = -ENOMEM; - goto fail; - } - - list_add(&r->free_list, &rx->free_list); - rx->avail_count++; - } - INIT_DELAYED_WORK(&udev->work_tx, do_tx); - INIT_DELAYED_WORK(&udev->work_rx, do_rx); - return 0; -fail: - release_usb(udev); - return ret; -} - -static int set_mac_address(u8 *data, void *arg) -{ - struct phy_dev *phy_dev = arg; - struct lte_udev *udev = phy_dev->priv_dev; - struct tlv *tlv = (struct tlv *)data; - u8 mac_address[ETH_ALEN] = {0, }; - - if (tlv->type == MAC_ADDRESS && udev->request_mac_addr) { - memcpy(mac_address, tlv->data, tlv->len); - - if (register_lte_device(phy_dev, - &udev->intf->dev, mac_address) < 0) - pr_err("register lte device failed\n"); - - udev->request_mac_addr = 0; - - return 1; - } - - return 0; -} - -static void do_rx(struct work_struct *work) -{ - struct lte_udev *udev = - container_of(work, struct lte_udev, work_rx.work); - struct rx_cxt *rx = &udev->rx; - struct usb_rx *r; - struct hci_packet *hci; - struct phy_dev *phy_dev; - u16 cmd_evt; - int ret; - unsigned long flags; - - while (1) { - spin_lock_irqsave(&rx->to_host_lock, flags); - if (list_empty(&rx->to_host_list)) { - spin_unlock_irqrestore(&rx->to_host_lock, flags); - break; - } - r = list_entry(rx->to_host_list.next, - struct usb_rx, to_host_list); - list_del(&r->to_host_list); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - - phy_dev = r->cb_data; - udev = phy_dev->priv_dev; - hci = (struct hci_packet *)r->buf; - cmd_evt = gdm_dev16_to_cpu(udev->gdm_ed, hci->cmd_evt); - - switch (cmd_evt) { - case LTE_GET_INFORMATION_RESULT: - if (set_mac_address(hci->data, r->cb_data) == 0) { - r->callback(r->cb_data, - r->buf, - r->urb->actual_length, - KERNEL_THREAD); - } - break; - - default: - if (r->callback) { - ret = r->callback(r->cb_data, - r->buf, - r->urb->actual_length, - KERNEL_THREAD); - - if (ret == -EAGAIN) - pr_err("failed to send received data\n"); - } - break; - } - - put_rx_struct(rx, r); - - gdm_usb_recv(udev, - r->callback, - r->cb_data, - USB_COMPLETE); - } -} - -static void remove_rx_submit_list(struct usb_rx *r, struct rx_cxt *rx) -{ - unsigned long flags; - struct usb_rx *r_remove, *r_remove_next; - - spin_lock_irqsave(&rx->submit_lock, flags); - list_for_each_entry_safe(r_remove, r_remove_next, - &rx->rx_submit_list, rx_submit_list) { - if (r == r_remove) { - list_del(&r->rx_submit_list); - break; - } - } - spin_unlock_irqrestore(&rx->submit_lock, flags); -} - -static void gdm_usb_rcv_complete(struct urb *urb) -{ - struct usb_rx *r = urb->context; - struct rx_cxt *rx = r->rx; - unsigned long flags; - struct lte_udev *udev = container_of(r->rx, struct lte_udev, rx); - struct usb_device *usbdev = udev->usbdev; - - remove_rx_submit_list(r, rx); - - if (!urb->status && r->callback) { - spin_lock_irqsave(&rx->to_host_lock, flags); - list_add_tail(&r->to_host_list, &rx->to_host_list); - schedule_work(&udev->work_rx.work); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - } else { - if (urb->status && udev->usb_state == PM_NORMAL) - dev_err(&urb->dev->dev, "%s: urb status error %d\n", - __func__, urb->status); - - put_rx_struct(rx, r); - } - - usb_mark_last_busy(usbdev); -} - -static int gdm_usb_recv(void *priv_dev, - int (*cb)(void *cb_data, - void *data, int len, int context), - void *cb_data, - int context) -{ - struct lte_udev *udev = priv_dev; - struct usb_device *usbdev = udev->usbdev; - struct rx_cxt *rx = &udev->rx; - struct usb_rx *r; - int no_spc; - int ret; - unsigned long flags; - - if (!udev->usbdev) { - pr_err("invalid device\n"); - return -ENODEV; - } - - r = get_rx_struct(rx, &no_spc); - if (!r) { - pr_err("Out of Memory\n"); - return -ENOMEM; - } - - udev->rx_cb = cb; - r->callback = cb; - r->cb_data = cb_data; - r->index = (void *)udev; - r->rx = rx; - - usb_fill_bulk_urb(r->urb, - usbdev, - usb_rcvbulkpipe(usbdev, 0x83), - r->buf, - RX_BUF_SIZE, - gdm_usb_rcv_complete, - r); - - spin_lock_irqsave(&rx->submit_lock, flags); - list_add_tail(&r->rx_submit_list, &rx->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_lock, flags); - - if (context == KERNEL_THREAD) - ret = usb_submit_urb(r->urb, GFP_KERNEL); - else - ret = usb_submit_urb(r->urb, GFP_ATOMIC); - - if (ret) { - spin_lock_irqsave(&rx->submit_lock, flags); - list_del(&r->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_lock, flags); - - pr_err("usb_submit_urb failed (%p)\n", r); - put_rx_struct(rx, r); - } - - return ret; -} - -static void gdm_usb_send_complete(struct urb *urb) -{ - struct usb_tx *t = urb->context; - struct tx_cxt *tx = t->tx; - struct lte_udev *udev = container_of(tx, struct lte_udev, tx); - unsigned long flags; - - if (urb->status == -ECONNRESET) { - dev_info(&urb->dev->dev, "CONNRESET\n"); - return; - } - - if (t->callback) - t->callback(t->cb_data); - - free_tx_struct(t); - - spin_lock_irqsave(&tx->lock, flags); - udev->send_complete = 1; - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); -} - -static int send_tx_packet(struct usb_device *usbdev, struct usb_tx *t, u32 len) -{ - int ret = 0; - - if (!(len % 512)) - len++; - - usb_fill_bulk_urb(t->urb, - usbdev, - usb_sndbulkpipe(usbdev, 2), - t->buf, - len, - gdm_usb_send_complete, - t); - - ret = usb_submit_urb(t->urb, GFP_ATOMIC); - - if (ret) - dev_err(&usbdev->dev, "usb_submit_urb failed: %d\n", - ret); - - usb_mark_last_busy(usbdev); - - return ret; -} - -static u32 packet_aggregation(struct lte_udev *udev, u8 *send_buf) -{ - struct tx_cxt *tx = &udev->tx; - struct usb_tx_sdu *t_sdu = NULL; - struct multi_sdu *multi_sdu = (struct multi_sdu *)send_buf; - u16 send_len = 0; - u16 num_packet = 0; - unsigned long flags; - - multi_sdu->cmd_evt = gdm_cpu_to_dev16(udev->gdm_ed, LTE_TX_MULTI_SDU); - - while (num_packet < MAX_PACKET_IN_MULTI_SDU) { - spin_lock_irqsave(&tx->lock, flags); - if (list_empty(&tx->sdu_list)) { - spin_unlock_irqrestore(&tx->lock, flags); - break; - } - - t_sdu = list_entry(tx->sdu_list.next, struct usb_tx_sdu, list); - if (send_len + t_sdu->len > MAX_SDU_SIZE) { - spin_unlock_irqrestore(&tx->lock, flags); - break; - } - - list_del(&t_sdu->list); - spin_unlock_irqrestore(&tx->lock, flags); - - memcpy(multi_sdu->data + send_len, t_sdu->buf, t_sdu->len); - - send_len += (t_sdu->len + 3) & 0xfffc; - num_packet++; - - if (tx->avail_count > 10) - t_sdu->callback(t_sdu->cb_data); - - spin_lock_irqsave(&tx->lock, flags); - put_tx_struct(tx, t_sdu); - spin_unlock_irqrestore(&tx->lock, flags); - } - - multi_sdu->len = gdm_cpu_to_dev16(udev->gdm_ed, send_len); - multi_sdu->num_packet = gdm_cpu_to_dev16(udev->gdm_ed, num_packet); - - return send_len + offsetof(struct multi_sdu, data); -} - -static void do_tx(struct work_struct *work) -{ - struct lte_udev *udev = - container_of(work, struct lte_udev, work_tx.work); - struct usb_device *usbdev = udev->usbdev; - struct tx_cxt *tx = &udev->tx; - struct usb_tx *t = NULL; - int is_send = 0; - u32 len = 0; - unsigned long flags; - - if (!usb_autopm_get_interface(udev->intf)) - usb_autopm_put_interface(udev->intf); - - if (udev->usb_state == PM_SUSPEND) - return; - - spin_lock_irqsave(&tx->lock, flags); - if (!udev->send_complete) { - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - udev->send_complete = 0; - - if (!list_empty(&tx->hci_list)) { - t = list_entry(tx->hci_list.next, struct usb_tx, list); - list_del(&t->list); - len = t->len; - t->is_sdu = 0; - is_send = 1; - } else if (!list_empty(&tx->sdu_list)) { - if (udev->tx_stop) { - udev->send_complete = 1; - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - - t = alloc_tx_struct(TX_BUF_SIZE); - if (!t) { - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - t->callback = NULL; - t->tx = tx; - t->is_sdu = 1; - is_send = 1; - } - - if (!is_send) { - udev->send_complete = 1; - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - spin_unlock_irqrestore(&tx->lock, flags); - - if (t->is_sdu) - len = packet_aggregation(udev, t->buf); - - if (send_tx_packet(usbdev, t, len)) { - pr_err("send_tx_packet failed\n"); - t->callback = NULL; - gdm_usb_send_complete(t->urb); - } -} - -#define SDU_PARAM_LEN 12 -static int gdm_usb_sdu_send(void *priv_dev, void *data, int len, - unsigned int dft_eps_ID, unsigned int eps_ID, - void (*cb)(void *data), void *cb_data, - int dev_idx, int nic_type) -{ - struct lte_udev *udev = priv_dev; - struct tx_cxt *tx = &udev->tx; - struct usb_tx_sdu *t_sdu; - struct sdu *sdu = NULL; - unsigned long flags; - int no_spc = 0; - u16 send_len; - - if (!udev->usbdev) { - pr_err("sdu send - invalid device\n"); - return TX_NO_DEV; - } - - spin_lock_irqsave(&tx->lock, flags); - t_sdu = get_tx_sdu_struct(tx, &no_spc); - spin_unlock_irqrestore(&tx->lock, flags); - - if (!t_sdu) { - pr_err("sdu send - free list empty\n"); - return TX_NO_SPC; - } - - sdu = (struct sdu *)t_sdu->buf; - sdu->cmd_evt = gdm_cpu_to_dev16(udev->gdm_ed, LTE_TX_SDU); - if (nic_type == NIC_TYPE_ARP) { - send_len = len + SDU_PARAM_LEN; - memcpy(sdu->data, data, len); - } else { - send_len = len - ETH_HLEN; - send_len += SDU_PARAM_LEN; - memcpy(sdu->data, data + ETH_HLEN, len - ETH_HLEN); - } - - sdu->len = gdm_cpu_to_dev16(udev->gdm_ed, send_len); - sdu->dft_eps_ID = gdm_cpu_to_dev32(udev->gdm_ed, dft_eps_ID); - sdu->bearer_ID = gdm_cpu_to_dev32(udev->gdm_ed, eps_ID); - sdu->nic_type = gdm_cpu_to_dev32(udev->gdm_ed, nic_type); - - t_sdu->len = send_len + HCI_HEADER_SIZE; - t_sdu->callback = cb; - t_sdu->cb_data = cb_data; - - spin_lock_irqsave(&tx->lock, flags); - list_add_tail(&t_sdu->list, &tx->sdu_list); - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); - - if (no_spc) - return TX_NO_BUFFER; - - return 0; -} - -static int gdm_usb_hci_send(void *priv_dev, void *data, int len, - void (*cb)(void *data), void *cb_data) -{ - struct lte_udev *udev = priv_dev; - struct tx_cxt *tx = &udev->tx; - struct usb_tx *t; - unsigned long flags; - - if (!udev->usbdev) { - pr_err("hci send - invalid device\n"); - return -ENODEV; - } - - t = alloc_tx_struct(len); - if (!t) { - pr_err("hci_send - out of memory\n"); - return -ENOMEM; - } - - memcpy(t->buf, data, len); - t->callback = cb; - t->cb_data = cb_data; - t->len = len; - t->tx = tx; - t->is_sdu = 0; - - spin_lock_irqsave(&tx->lock, flags); - list_add_tail(&t->list, &tx->hci_list); - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); - - return 0; -} - -static u8 gdm_usb_get_endian(void *priv_dev) -{ - struct lte_udev *udev = priv_dev; - - return udev->gdm_ed; -} - -static int gdm_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int ret = 0; - struct phy_dev *phy_dev = NULL; - struct lte_udev *udev = NULL; - u16 idVendor, idProduct; - int bInterfaceNumber; - struct usb_device *usbdev = interface_to_usbdev(intf); - - bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber; - idVendor = __le16_to_cpu(usbdev->descriptor.idVendor); - idProduct = __le16_to_cpu(usbdev->descriptor.idProduct); - - pr_info("net vid = 0x%04x pid = 0x%04x\n", idVendor, idProduct); - - if (bInterfaceNumber > NETWORK_INTERFACE) { - pr_info("not a network device\n"); - return -ENODEV; - } - - phy_dev = kzalloc(sizeof(*phy_dev), GFP_KERNEL); - if (!phy_dev) - return -ENOMEM; - - udev = kzalloc(sizeof(*udev), GFP_KERNEL); - if (!udev) { - ret = -ENOMEM; - goto err_udev; - } - - phy_dev->priv_dev = (void *)udev; - phy_dev->send_hci_func = gdm_usb_hci_send; - phy_dev->send_sdu_func = gdm_usb_sdu_send; - phy_dev->rcv_func = gdm_usb_recv; - phy_dev->get_endian = gdm_usb_get_endian; - - udev->usbdev = usbdev; - ret = init_usb(udev); - if (ret < 0) { - dev_err(intf->usb_dev, "init_usb func failed\n"); - goto err_init_usb; - } - udev->intf = intf; - - intf->needs_remote_wakeup = 1; - usb_enable_autosuspend(usbdev); - pm_runtime_set_autosuspend_delay(&usbdev->dev, AUTO_SUSPEND_TIMER); - - /* List up hosts with big endians, otherwise, - * defaults to little endian - */ - if (idProduct == PID_GDM7243) - udev->gdm_ed = ENDIANNESS_BIG; - else - udev->gdm_ed = ENDIANNESS_LITTLE; - - ret = request_mac_address(udev); - if (ret < 0) { - dev_err(intf->usb_dev, "request Mac address failed\n"); - goto err_mac_address; - } - - start_rx_proc(phy_dev); - usb_get_dev(usbdev); - usb_set_intfdata(intf, phy_dev); - - return 0; - -err_mac_address: - release_usb(udev); -err_init_usb: - kfree(udev); -err_udev: - kfree(phy_dev); - - return ret; -} - -static void gdm_usb_disconnect(struct usb_interface *intf) -{ - struct phy_dev *phy_dev; - struct lte_udev *udev; - struct usb_device *usbdev; - - usbdev = interface_to_usbdev(intf); - phy_dev = usb_get_intfdata(intf); - - udev = phy_dev->priv_dev; - unregister_lte_device(phy_dev); - - release_usb(udev); - - kfree(udev); - udev = NULL; - - kfree(phy_dev); - phy_dev = NULL; - - usb_put_dev(usbdev); -} - -static int gdm_usb_suspend(struct usb_interface *intf, pm_message_t pm_msg) -{ - struct phy_dev *phy_dev; - struct lte_udev *udev; - struct rx_cxt *rx; - struct usb_rx *r; - struct usb_rx *r_next; - unsigned long flags; - - phy_dev = usb_get_intfdata(intf); - udev = phy_dev->priv_dev; - rx = &udev->rx; - if (udev->usb_state != PM_NORMAL) { - dev_err(intf->usb_dev, "usb suspend - invalid state\n"); - return -1; - } - - udev->usb_state = PM_SUSPEND; - - spin_lock_irqsave(&rx->submit_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_lock, flags); - - cancel_work_sync(&udev->work_tx.work); - cancel_work_sync(&udev->work_rx.work); - - return 0; -} - -static int gdm_usb_resume(struct usb_interface *intf) -{ - struct phy_dev *phy_dev; - struct lte_udev *udev; - struct tx_cxt *tx; - struct rx_cxt *rx; - unsigned long flags; - int issue_count; - int i; - - phy_dev = usb_get_intfdata(intf); - udev = phy_dev->priv_dev; - rx = &udev->rx; - - if (udev->usb_state != PM_SUSPEND) { - dev_err(intf->usb_dev, "usb resume - invalid state\n"); - return -1; - } - udev->usb_state = PM_NORMAL; - - spin_lock_irqsave(&rx->rx_lock, flags); - issue_count = rx->avail_count - MAX_RX_SUBMIT_COUNT; - spin_unlock_irqrestore(&rx->rx_lock, flags); - - if (issue_count >= 0) { - for (i = 0; i < issue_count; i++) - gdm_usb_recv(phy_dev->priv_dev, - udev->rx_cb, - phy_dev, - USB_COMPLETE); - } - - tx = &udev->tx; - spin_lock_irqsave(&tx->lock, flags); - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); - - return 0; -} - -static struct usb_driver gdm_usb_lte_driver = { - .name = "gdm_lte", - .probe = gdm_usb_probe, - .disconnect = gdm_usb_disconnect, - .id_table = id_table, - .supports_autosuspend = 1, - .suspend = gdm_usb_suspend, - .resume = gdm_usb_resume, - .reset_resume = gdm_usb_resume, -}; - -static int __init gdm_usb_lte_init(void) -{ - if (gdm_lte_event_init() < 0) { - pr_err("error creating event\n"); - return -1; - } - - return usb_register(&gdm_usb_lte_driver); -} - -static void __exit gdm_usb_lte_exit(void) -{ - gdm_lte_event_exit(); - - usb_deregister(&gdm_usb_lte_driver); -} - -module_init(gdm_usb_lte_init); -module_exit(gdm_usb_lte_exit); - -MODULE_VERSION(DRIVER_VERSION); -MODULE_DESCRIPTION("GCT LTE USB Device Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gdm724x/gdm_usb.h b/drivers/staging/gdm724x/gdm_usb.h deleted file mode 100644 index db689b091c4fd40129e170ed52b27faef146a75e..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/gdm_usb.h +++ /dev/null @@ -1,99 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_USB_H_ -#define _GDM_USB_H_ - -#include -#include -#include -#include - -#include "gdm_endian.h" -#include "hci_packet.h" - -#define PM_NORMAL 0 -#define PM_SUSPEND 1 -#define AUTO_SUSPEND_TIMER 5000 /* ms */ - -#define RX_BUF_SIZE (1024 * 32) -#define TX_BUF_SIZE (1024 * 32) -#define SDU_BUF_SIZE 2048 -#define MAX_SDU_SIZE (1024 * 30) -#define MAX_PACKET_IN_MULTI_SDU 256 - -#define VID_GCT 0x1076 -#define PID_GDM7240 0x8000 -#define PID_GDM7243 0x9000 - -#define NETWORK_INTERFACE 1 -#define USB_SC_SCSI 0x06 -#define USB_PR_BULK 0x50 - -#define MAX_NUM_SDU_BUF 64 - -struct usb_tx { - struct list_head list; - struct urb *urb; - u8 *buf; - u32 len; - void (*callback)(void *cb_data); - void *cb_data; - struct tx_cxt *tx; - u8 is_sdu; -}; - -struct usb_tx_sdu { - struct list_head list; - u8 *buf; - u32 len; - void (*callback)(void *cb_data); - void *cb_data; -}; - -struct usb_rx { - struct list_head to_host_list; - struct list_head free_list; - struct list_head rx_submit_list; - struct rx_cxt *rx; - struct urb *urb; - u8 *buf; - int (*callback)(void *cb_data, void *data, int len, int context); - void *cb_data; - void *index; -}; - -struct tx_cxt { - struct list_head sdu_list; - struct list_head hci_list; - struct list_head free_list; - u32 avail_count; - spinlock_t lock; -}; - -struct rx_cxt { - struct list_head to_host_list; - struct list_head rx_submit_list; - struct list_head free_list; - u32 avail_count; - spinlock_t to_host_lock; - spinlock_t rx_lock; - spinlock_t submit_lock; -}; - -struct lte_udev { - struct usb_device *usbdev; - struct tx_cxt tx; - struct rx_cxt rx; - struct delayed_work work_tx; - struct delayed_work work_rx; - u8 gdm_ed; - u8 send_complete; - u8 tx_stop; - struct usb_interface *intf; - int (*rx_cb)(void *cb_data, void *data, int len, int context); - int usb_state; - u8 request_mac_addr; -}; - -#endif /* _GDM_USB_H_ */ diff --git a/drivers/staging/gdm724x/hci.h b/drivers/staging/gdm724x/hci.h deleted file mode 100644 index b30945daf3a539a43c70da0d02f18ae1e4338fdd..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/hci.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _HCI_H_ -#define _HCI_H_ - -#define LTE_GET_INFORMATION 0x3002 -#define LTE_GET_INFORMATION_RESULT 0xB003 - #define MAC_ADDRESS 0xA2 - -#define LTE_LINK_ON_OFF_INDICATION 0xB133 -#define LTE_PDN_TABLE_IND 0xB143 - -#define LTE_TX_SDU 0x3200 -#define LTE_RX_SDU 0xB201 -#define LTE_TX_MULTI_SDU 0x3202 -#define LTE_RX_MULTI_SDU 0xB203 - -#define LTE_DL_SDU_FLOW_CONTROL 0x3305 -#define LTE_UL_SDU_FLOW_CONTROL 0xB306 - -#define LTE_AT_CMD_TO_DEVICE 0x3307 -#define LTE_AT_CMD_FROM_DEVICE 0xB308 - -#define LTE_SDIO_DM_SEND_PKT 0x3312 -#define LTE_SDIO_DM_RECV_PKT 0xB313 - -#define LTE_NV_RESTORE_REQUEST 0xB30C -#define LTE_NV_RESTORE_RESPONSE 0x330D -#define LTE_NV_SAVE_REQUEST 0xB30E - #define NV_TYPE_LTE_INFO 0x00 - #define NV_TYPE_BOARD_CONFIG 0x01 - #define NV_TYPE_RF_CAL 0x02 - #define NV_TYPE_TEMP 0x03 - #define NV_TYPE_NET_INFO 0x04 - #define NV_TYPE_SAFETY_INFO 0x05 - #define NV_TYPE_CDMA_CAL 0x06 - #define NV_TYPE_VENDOR 0x07 - #define NV_TYPE_ALL 0xff -#define LTE_NV_SAVE_RESPONSE 0x330F - -#define LTE_AT_CMD_TO_DEVICE_EXT 0x3323 -#define LTE_AT_CMD_FROM_DEVICE_EXT 0xB324 - -#endif /* _HCI_H_ */ diff --git a/drivers/staging/gdm724x/hci_packet.h b/drivers/staging/gdm724x/hci_packet.h deleted file mode 100644 index 3bb01e94f3b576d1b093b7c2ef696dabdda38dc2..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/hci_packet.h +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _HCI_PACKET_H_ -#define _HCI_PACKET_H_ - -#define HCI_HEADER_SIZE 4 - -/* - * The NIC type definition: - * For backward compatibility, lower 16 bits used as they were. - * Lower 16 bit: NIC_TYPE values - * Uppoer 16 bit: NIC_TYPE Flags - */ -#define NIC_TYPE_NIC0 0x00000010 -#define NIC_TYPE_NIC1 0x00000011 -#define NIC_TYPE_NIC2 0x00000012 -#define NIC_TYPE_NIC3 0x00000013 -#define NIC_TYPE_ARP 0x00000100 -#define NIC_TYPE_ICMPV6 0x00000200 -#define NIC_TYPE_MASK 0x0000FFFF -#define NIC_TYPE_F_IPV4 0x00010000 -#define NIC_TYPE_F_IPV6 0x00020000 -#define NIC_TYPE_F_DHCP 0x00040000 -#define NIC_TYPE_F_NDP 0x00080000 -#define NIC_TYPE_F_VLAN 0x00100000 - -struct hci_packet { - __dev16 cmd_evt; - __dev16 len; - u8 data[]; -} __packed; - -struct tlv { - u8 type; - u8 len; - u8 *data[]; -} __packed; - -struct sdu_header { - __dev16 cmd_evt; - __dev16 len; - __dev32 dft_eps_id; - __dev32 bearer_ID; - __dev32 nic_type; -} __packed; - -struct sdu { - __dev16 cmd_evt; - __dev16 len; - __dev32 dft_eps_ID; - __dev32 bearer_ID; - __dev32 nic_type; - u8 data[]; -} __packed; - -struct multi_sdu { - __dev16 cmd_evt; - __dev16 len; - __dev16 num_packet; - __dev16 reserved; - u8 data[]; -} __packed; - -struct hci_pdn_table_ind { - __dev16 cmd_evt; - __dev16 len; - u8 activate; - __dev32 dft_eps_id; - __dev32 nic_type; - u8 pdn_type; - u8 ipv4_addr[4]; - u8 ipv6_intf_id[8]; -} __packed; - -struct hci_connect_ind { - __dev16 cmd_evt; - __dev16 len; - __dev32 connect; -} __packed; - -#endif /* _HCI_PACKET_H_ */ diff --git a/drivers/staging/gdm724x/netlink_k.c b/drivers/staging/gdm724x/netlink_k.c deleted file mode 100644 index 8f39cc5617aada5353f9e0a36f8bc818e8083b62..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/netlink_k.c +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include - -#include "netlink_k.h" - -static DEFINE_MUTEX(netlink_mutex); - -#define ND_MAX_GROUP 30 -#define ND_IFINDEX_LEN sizeof(int) -#define ND_NLMSG_SPACE(len) (NLMSG_SPACE(len) + ND_IFINDEX_LEN) -#define ND_NLMSG_DATA(nlh) ((void *)((char *)NLMSG_DATA(nlh) + \ - ND_IFINDEX_LEN)) -#define ND_NLMSG_S_LEN(len) ((len) + ND_IFINDEX_LEN) -#define ND_NLMSG_R_LEN(nlh) ((nlh)->nlmsg_len - ND_IFINDEX_LEN) -#define ND_NLMSG_IFIDX(nlh) NLMSG_DATA(nlh) -#define ND_MAX_MSG_LEN (1024 * 32) - -static void (*rcv_cb)(struct net_device *dev, u16 type, void *msg, int len); - -static void netlink_rcv_cb(struct sk_buff *skb) -{ - struct nlmsghdr *nlh; - struct net_device *dev; - u32 mlen; - void *msg; - int ifindex; - - if (!rcv_cb) { - pr_err("nl cb - unregistered\n"); - return; - } - - if (skb->len < NLMSG_HDRLEN) { - pr_err("nl cb - invalid skb length\n"); - return; - } - - nlh = (struct nlmsghdr *)skb->data; - - if (skb->len < nlh->nlmsg_len || nlh->nlmsg_len > ND_MAX_MSG_LEN) { - pr_err("nl cb - invalid length (%d,%d)\n", - skb->len, nlh->nlmsg_len); - return; - } - - memcpy(&ifindex, ND_NLMSG_IFIDX(nlh), ND_IFINDEX_LEN); - msg = ND_NLMSG_DATA(nlh); - mlen = ND_NLMSG_R_LEN(nlh); - - dev = dev_get_by_index(&init_net, ifindex); - if (dev) { - rcv_cb(dev, nlh->nlmsg_type, msg, mlen); - dev_put(dev); - } else { - pr_err("nl cb - dev (%d) not found\n", ifindex); - } -} - -static void netlink_rcv(struct sk_buff *skb) -{ - mutex_lock(&netlink_mutex); - netlink_rcv_cb(skb); - mutex_unlock(&netlink_mutex); -} - -struct sock *netlink_init(int unit, - void (*cb)(struct net_device *dev, u16 type, - void *msg, int len)) -{ - struct sock *sock; - struct netlink_kernel_cfg cfg = { - .input = netlink_rcv, - }; - - sock = netlink_kernel_create(&init_net, unit, &cfg); - - if (sock) - rcv_cb = cb; - - return sock; -} - -int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len, - struct net_device *dev) -{ - static u32 seq; - struct sk_buff *skb = NULL; - struct nlmsghdr *nlh; - int ret = 0; - - if (group > ND_MAX_GROUP) - return -EINVAL; - - if (!netlink_has_listeners(sock, group + 1)) - return -ESRCH; - - skb = alloc_skb(NLMSG_SPACE(len), GFP_ATOMIC); - if (!skb) - return -ENOMEM; - - seq++; - - nlh = nlmsg_put(skb, 0, seq, type, len, 0); - memcpy(NLMSG_DATA(nlh), msg, len); - NETLINK_CB(skb).portid = 0; - NETLINK_CB(skb).dst_group = 0; - - ret = netlink_broadcast(sock, skb, 0, group + 1, GFP_ATOMIC); - if (!ret) - return len; - - if (ret != -ESRCH) - netdev_err(dev, "nl broadcast g=%d, t=%d, l=%d, r=%d\n", - group, type, len, ret); - else if (netlink_has_listeners(sock, group + 1)) - return -EAGAIN; - - return ret; -} diff --git a/drivers/staging/gdm724x/netlink_k.h b/drivers/staging/gdm724x/netlink_k.h deleted file mode 100644 index d42eea9bea3ec5719be32dfbc5f0e614e2319535..0000000000000000000000000000000000000000 --- a/drivers/staging/gdm724x/netlink_k.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _NETLINK_K_H -#define _NETLINK_K_H - -#include -#include - -struct sock *netlink_init(int unit, - void (*cb)(struct net_device *dev, - u16 type, void *msg, int len)); -int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len, - struct net_device *dev); - -#endif /* _NETLINK_K_H_ */ diff --git a/drivers/staging/gpib/Kconfig b/drivers/staging/gpib/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..95308d15a55516de9118e7ae90a6103ee8c6c003 --- /dev/null +++ b/drivers/staging/gpib/Kconfig @@ -0,0 +1,251 @@ +# SPDX-License-Identifier: GPL-2.0 +menuconfig GPIB + tristate "Linux GPIB drivers" + help + Enable support for GPIB cards and dongles for Linux. GPIB + is the General Purpose Interface Bus which conforms to the + IEEE488 standard. + + This set of drivers can be used with the corresponding user + space library that can be found on Sourceforge under linux-gpib. + Select the drivers for your hardware from the list. + +if GPIB + +config GPIB_COMMON + tristate "GPIB core" + help + + Core common driver for all GPIB drivers. It provides the + interface for the userland library + + To compile this driver as a module, choose M here: the module will be + called gpib_common + +config GPIB_AGILENT_82350B + tristate "Agilent 8235xx PCI(e) adapters" + depends on PCI + select GPIB_COMMON + select GPIB_TMS9914 + help + Enable support for HP/Agilent/Keysight boards + 82350A + 82350B + 82351A + + To compile this driver as a module, choose M here: the module will be + called agilent_82350b. + +config GPIB_AGILENT_82357A + tristate "Agilent 82357a/b USB dongles" + select GPIB_COMMON + depends on USB + help + Enable support for Agilent/Keysight 82357x USB dongles. + + To compile this driver as a module, choose M here: the module will be + called agilent_82357a. + +config GPIB_CEC_PCI + tristate "CEC PCI board" + depends on PCI + depends on HAS_IOPORT + select GPIB_COMMON + select GPIB_NEC7210 + help + Enable support for Capital Equipment Corporation PCI-488 + and Keithly KPCI-488 boards. + + To compile this driver as a module, choose M here: the module will be + called cec_gpib. + +config GPIB_NI_PCI_ISA + tristate "NI PCI/ISA compatible boards" + depends on ISA_BUS || PCI || PCMCIA + select GPIB_COMMON + select GPIB_NEC7210 + help + Enable support for National Instruments boards based + on TNT4882 chips: + AT-GPIB (with NAT4882 chip) + AT-GPIB (with NEC7210 chip) + AT-GPIB/TNT + PCI-GPIB + PCIe-GPIB + PCI-GPIB+ + PCM-GPIB + PXI-GPIB + PCMCIA-GPIB + and Capital Equipment Corporation CEC-488 board. + + To compile this driver as a module, choose M here: the module will be + called tnt4882. + +config GPIB_CB7210 + tristate "Measurement Computing compatible boards" + depends on HAS_IOPORT + depends on ISA_BUS || PCI || PCMCIA + select GPIB_COMMON + select GPIB_NEC7210 + help + Enable support for Measurement Computing (Computer Boards): + CPCI_GPIB, ISA-GPIB, ISA-GPIB/LC, PCI-GPIB/1M, PCI-GPIB/300K and + PCMCIA-GPIB + Quancom PCIGPIB-1 with MC cb7210 chip + + To compile this driver as a module, choose M here: the module will be + +config GPIB_NI_USB + tristate "NI USB dongles" + select GPIB_COMMON + depends on USB + help + Enable support for National Instruments + GPIB-USB-B + GPIB-USB-HS + GPIB-USB-HS+ + Keithly + KUSB-488 + KUSB-488A + Measurement Computing (Computer Boards) + USB-488 + + To compile this driver as a module, choose M here: the module will be + called ni_usb. + +config GPIB_FLUKE + tristate "Fluke" + depends on OF + select GPIB_COMMON + select GPIB_NEC7210 + help + GPIB driver for Fluke based cda devices. + + To compile this driver as a module, choose M here: the module will be + called fluke_gpib + +config GPIB_FMH + tristate "FMH FPGA based devices" + select GPIB_COMMON + select GPIB_NEC7210 + depends on BROKEN + depends on OF && PCI + help + GPIB driver for fmhess FPGA based devices + + To compile this driver as a module, choose M here: the module will be + called fmh_gpib + +config GPIB_GPIO + tristate "RPi GPIO bitbang" + depends on ARCH_BCM2835 || COMPILE_TEST + select GPIB_COMMON + help + GPIB bitbang driver Raspberry Pi GPIO adapters + + To compile this driver as a module, choose M here: the module will be + called gpib_bitbang + +config GPIB_HP82335 + tristate "HP82335/HP27209" + depends on ISA_BUS + select GPIB_COMMON + select GPIB_TMS9914 + help + GPIB driver for HP82335 and HP27209 boards + + To compile this driver as a module, choose M here: the module will be + called hp82335 + + +config GPIB_HP82341 + tristate "HP82341x" + select GPIB_COMMON + select GPIB_TMS9914 + depends on BROKEN + depends on ISA_BUS || EISA + help + GPIB driver for HP82341 A/B/C/D boards + + To compile this driver as a module, choose M here: the module will be + called hp82341 + +config GPIB_INES + tristate "INES" + depends on PCI || ISA_BUS || PCMCIA + depends on HAS_IOPORT + select GPIB_COMMON + select GPIB_NEC7210 + help + GPIB driver for Ines compatible boards + Ines + GPIB-HS-NT + GPIB for Compact PCI + GPIB for PCI + GPIB for PCMCIA + GPIB PC/104 + Hameg + HO80-2 + Quancom + PCIGPIB-1 based on Ines iGPIB 72010 chip + + To compile this driver as a module, choose M here: the module will be + called ines_gpib + called cb7210. + +config GPIB_PCMCIA + bool "PCMCIA/Cardbus support for NI MC and Ines boards" + depends on PCCARD && (GPIB_NI_PCI_ISA || GPIB_CB7210 || GPIB_INES) + help + Enable PCMCIA/CArdbus support for National Instruments, + measurement computing boards and Ines boards. + +config GPIB_LPVO + tristate "LPVO DIY USB GPIB" + select GPIB_COMMON + depends on USB + help + Enable support for LPVO Self-made usb-gpib adapter + + To compile this driver as a module, choose M here: the module will be + called lpvo_usb_gpib + +config GPIB_PC2 + tristate "PC2 PC2a" + depends on ISA_BUS + depends on HAS_IOPORT + select GPIB_COMMON + select GPIB_NEC7210 + help + Enable support for pc2 and pc2a compatible adapters + Capital Equipment Corporation PC-488 + CONTEC GP-IB(PC) + Hameg HO80 + Iotech GP488B + Keithly MBC-488 + Measurement Computing ISA-GPIB-PCA2 + National Instruments PCII, PCIIa and PCII/IIa + + To compile this driver as a module, choose M here: the module will be + called pc2_gpib + + +config GPIB_TMS9914 + tristate + select GPIB_COMMON + help + Enable support for TMS 9914 chip. + + To compile this driver as a module, choose M here: the module will be + called tms9914 + +config GPIB_NEC7210 + tristate + select GPIB_COMMON + help + Enable support for NEC 7210 compatible chips. + + To compile this driver as a module, choose M here: the module will be + called nec7210 + +endif # GPIB diff --git a/drivers/staging/gpib/Makefile b/drivers/staging/gpib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d0e88f5c08444ddb477e26f40fa26dcdc20bcd92 --- /dev/null +++ b/drivers/staging/gpib/Makefile @@ -0,0 +1,20 @@ + +subdir-ccflags-y += -I$(src)/include -I$(src)/uapi + +obj-$(CONFIG_GPIB_AGILENT_82350B) += agilent_82350b/ +obj-$(CONFIG_GPIB_AGILENT_82357A) += agilent_82357a/ +obj-$(CONFIG_GPIB_CB7210) += cb7210/ +obj-$(CONFIG_GPIB_CEC_PCI) += cec/ +obj-$(CONFIG_GPIB_COMMON) += common/ +obj-$(CONFIG_GPIB_FLUKE) += eastwood/ +obj-$(CONFIG_GPIB_FMH) += fmh_gpib/ +obj-$(CONFIG_GPIB_GPIO) += gpio/ +obj-$(CONFIG_GPIB_HP82335) += hp_82335/ +obj-$(CONFIG_GPIB_HP82341) += hp_82341/ +obj-$(CONFIG_GPIB_INES) += ines/ +obj-$(CONFIG_GPIB_LPVO) += lpvo_usb_gpib/ +obj-$(CONFIG_GPIB_NEC7210) += nec7210/ +obj-$(CONFIG_GPIB_NI_USB) += ni_usb/ +obj-$(CONFIG_GPIB_PC2) += pc2/ +obj-$(CONFIG_GPIB_TMS9914) += tms9914/ +obj-$(CONFIG_GPIB_NI_PCI_ISA) += tnt4882/ diff --git a/drivers/staging/gpib/TODO b/drivers/staging/gpib/TODO new file mode 100644 index 0000000000000000000000000000000000000000..bf2c3974254872f0d5bce1f061ccf4b2680d78e3 --- /dev/null +++ b/drivers/staging/gpib/TODO @@ -0,0 +1,21 @@ +TODO: +- checkpatch.pl fixes +- fix device drivers that are broken ("depends on BROKEN" in Kconfig) +- tidy-up comments: + - there are some "//comments" and "// comments" scattered around + - sometimes they are misaligned + - sometimes "// comments" are interleaved with "/* comments */" + - multiline comments should start with initial almost-blank line: + /* + * Good + * multiline + * comment + */ + /* Bad + * multiline + * comment + */ +- resolve XXX notes where possible +- fix FIXME notes +- clean-up commented-out code +- fix typos diff --git a/drivers/staging/gpib/agilent_82350b/Makefile b/drivers/staging/gpib/agilent_82350b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d9236c92e04be45bab3c92c34c3af9bfcf3ec32d --- /dev/null +++ b/drivers/staging/gpib/agilent_82350b/Makefile @@ -0,0 +1,2 @@ + +obj-m += agilent_82350b.o diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c new file mode 100644 index 0000000000000000000000000000000000000000..53006d0cc79c5dd2200d2e7bcd48b978b88a5740 --- /dev/null +++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c @@ -0,0 +1,932 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2002, 2004 by Frank Mori Hess * + ***************************************************************************/ + +#include "agilent_82350b.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for Agilent 82350b"); + +int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + struct tms9914_priv *tms_priv = &a_priv->tms9914_priv; + int retval = 0; + unsigned short event_status; + int i, num_fifo_bytes; + //hardware doesn't support checking for end-of-string character when using fifo + if (tms_priv->eos_flags & REOS) { + //pr_info("ag-rd: using tms9914 read for REOS %x EOS %x\n",tms_priv->eos_flags, + // tms_priv->eos); + return tms9914_read(board, tms_priv, buffer, length, end, bytes_read); + } + + clear_bit(DEV_CLEAR_BN, &tms_priv->state); + + read_and_clear_event_status(board); + *end = 0; + *bytes_read = 0; + if (length == 0) + return 0; + //disable fifo for the moment + writeb(DIRECTION_GPIB_TO_HOST, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); + // handle corner case of board not in holdoff and one byte might slip in early + if (tms_priv->holdoff_active == 0 && length > 1) { + size_t num_bytes; + + retval = tms9914_read(board, tms_priv, buffer, 1, end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + dev_err(board->gpib_dev, "%s: tms9914_read failed retval=%i\n", + driver_name, retval); + if (retval < 0 || *end) + return retval; + ++buffer; + --length; + } + tms9914_set_holdoff_mode(tms_priv, TMS9914_HOLDOFF_EOI); + tms9914_release_holdoff(tms_priv); + i = 0; + num_fifo_bytes = length - 1; + write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BIIE, IMR0); // disable BI interrupts + while (i < num_fifo_bytes && *end == 0) { + int block_size; + int j; + int count; + + if (num_fifo_bytes - i < agilent_82350b_fifo_size) + block_size = num_fifo_bytes - i; + else + block_size = agilent_82350b_fifo_size; + set_transfer_counter(a_priv, block_size); + writeb(ENABLE_TI_TO_SRAM | DIRECTION_GPIB_TO_HOST, + a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); + if (agilent_82350b_fifo_is_halted(a_priv)) + writeb(RESTART_STREAM_BIT, a_priv->gpib_base + STREAM_STATUS_REG); + + clear_bit(READ_READY_BN, &tms_priv->state); + + retval = wait_event_interruptible(board->wait, + ((event_status = + read_and_clear_event_status(board)) & + (TERM_COUNT_STATUS_BIT | + BUFFER_END_STATUS_BIT)) || + test_bit(DEV_CLEAR_BN, &tms_priv->state) || + test_bit(TIMO_NUM, &board->status)); + if (retval) { + dev_dbg(board->gpib_dev, "%s: read wait interrupted\n", driver_name); + retval = -ERESTARTSYS; + break; + } + count = block_size - read_transfer_counter(a_priv); + for (j = 0; j < count && i < num_fifo_bytes; ++j) + buffer[i++] = readb(a_priv->sram_base + j); + if (event_status & BUFFER_END_STATUS_BIT) { + clear_bit(RECEIVED_END_BN, &tms_priv->state); + + tms_priv->holdoff_active = 1; + *end = 1; + } + if (test_bit(TIMO_NUM, &board->status)) { + dev_err(board->gpib_dev, "%s: read timed out\n", driver_name); + retval = -ETIMEDOUT; + break; + } + if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) { + dev_err(board->gpib_dev, "%s: device clear interrupted read\n", + driver_name); + retval = -EINTR; + break; + } + } + write_byte(tms_priv, tms_priv->imr0_bits, IMR0); // re-enable BI interrupts + *bytes_read += i; + buffer += i; + length -= i; + writeb(DIRECTION_GPIB_TO_HOST, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); + if (retval < 0) + return retval; + // read last bytes if we havn't received an END yet + if (*end == 0) { + size_t num_bytes; + // try to make sure we holdoff after last byte read + retval = tms9914_read(board, tms_priv, buffer, length, end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + return retval; + } + return 0; +} + +static int translate_wait_return_value(gpib_board_t *board, int retval) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + struct tms9914_priv *tms_priv = &a_priv->tms9914_priv; + + if (retval) { + dev_err(board->gpib_dev, "%s: write wait interrupted\n", driver_name); + return -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) { + dev_err(board->gpib_dev, "%s: write timed out\n", driver_name); + return -ETIMEDOUT; + } + if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) { + dev_err(board->gpib_dev, "%s: device clear interrupted write\n", driver_name); + return -EINTR; + } + return 0; +} + +int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + struct tms9914_priv *tms_priv = &a_priv->tms9914_priv; + int i, j; + unsigned short event_status; + int retval = 0; + int fifotransferlength = length; + int block_size = 0; + size_t num_bytes; + + *bytes_written = 0; + if (send_eoi) + --fifotransferlength; + + clear_bit(DEV_CLEAR_BN, &tms_priv->state); + + writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); + + event_status = read_and_clear_event_status(board); + + //pr_info("ag_ac_wr: event status 0x%x tms state 0x%lx\n", event_status, tms_priv->state); + +#ifdef EXPERIMENTAL + pr_info("ag_ac_wr: wait for previous BO to complete if any\n"); + retval = wait_event_interruptible(board->wait, + test_bit(DEV_CLEAR_BN, &tms_priv->state) || + test_bit(WRITE_READY_BN, &tms_priv->state) || + test_bit(TIMO_NUM, &board->status)); + retval = translate_wait_return_value(board, retval); + + if (retval) + return retval; +#endif + + //pr_info("ag_ac_wr: sending first byte\n"); + retval = agilent_82350b_write(board, buffer, 1, 0, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + + //pr_info("ag_ac_wr: %ld bytes eoi %d tms state 0x%lx\n",length, send_eoi, tms_priv->state); + + write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BOIE, IMR0); + for (i = 1; i < fifotransferlength;) { + clear_bit(WRITE_READY_BN, &tms_priv->state); + + if (fifotransferlength - i < agilent_82350b_fifo_size) + block_size = fifotransferlength - i; + else + block_size = agilent_82350b_fifo_size; + set_transfer_counter(a_priv, block_size); + for (j = 0; j < block_size; ++j, ++i) { + // load data into board's sram + writeb(buffer[i], a_priv->sram_base + j); + } + writeb(ENABLE_TI_TO_SRAM, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); + + //pr_info("ag_ac_wr: send block: %d bytes tms 0x%lx\n", block_size, + // tms_priv->state); + + if (agilent_82350b_fifo_is_halted(a_priv)) { + writeb(RESTART_STREAM_BIT, a_priv->gpib_base + STREAM_STATUS_REG); + // pr_info("ag_ac_wr: needed restart\n"); + } + + retval = wait_event_interruptible(board->wait, + ((event_status = + read_and_clear_event_status(board)) & + TERM_COUNT_STATUS_BIT) || + test_bit(DEV_CLEAR_BN, &tms_priv->state) || + test_bit(TIMO_NUM, &board->status)); + writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); + num_bytes = block_size - read_transfer_counter(a_priv); + //pr_info("ag_ac_wr: sent %ld bytes tms 0x%lx\n", num_bytes, tms_priv->state); + + *bytes_written += num_bytes; + retval = translate_wait_return_value(board, retval); + if (retval) + break; + } + write_byte(tms_priv, tms_priv->imr0_bits, IMR0); + if (retval) + return retval; + + if (send_eoi) { + //pr_info("ag_ac_wr: sending last byte with eoi byte no: %d\n", + // fifotransferlength+1); + + retval = agilent_82350b_write(board, buffer + fifotransferlength, 1, send_eoi, + &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + } + return 0; +} + +unsigned short read_and_clear_event_status(gpib_board_t *board) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + unsigned long flags; + unsigned short status; + + spin_lock_irqsave(&board->spinlock, flags); + status = a_priv->event_status_bits; + a_priv->event_status_bits = 0; + spin_unlock_irqrestore(&board->spinlock, flags); + return status; +} + +irqreturn_t agilent_82350b_interrupt(int irq, void *arg) + +{ + int tms9914_status1 = 0, tms9914_status2 = 0; + int event_status; + gpib_board_t *board = arg; + struct agilent_82350b_priv *a_priv = board->private_data; + unsigned long flags; + irqreturn_t retval = IRQ_NONE; + + spin_lock_irqsave(&board->spinlock, flags); + event_status = readb(a_priv->gpib_base + EVENT_STATUS_REG); + if (event_status & IRQ_STATUS_BIT) + retval = IRQ_HANDLED; + + if (event_status & TMS9914_IRQ_STATUS_BIT) { + tms9914_status1 = read_byte(&a_priv->tms9914_priv, ISR0); + tms9914_status2 = read_byte(&a_priv->tms9914_priv, ISR1); + tms9914_interrupt_have_status(board, &a_priv->tms9914_priv, tms9914_status1, + tms9914_status2); + } +//pr_info("event_status=0x%x s1 %x s2 %x\n", event_status,tms9914_status1,tms9914_status2); +//write-clear status bits + if (event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT)) { + writeb(event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT), + a_priv->gpib_base + EVENT_STATUS_REG); + a_priv->event_status_bits |= event_status; + wake_up_interruptible(&board->wait); + } + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +void agilent_82350b_detach(gpib_board_t *board); + +const char *driver_name = "agilent_82350b"; + +int read_transfer_counter(struct agilent_82350b_priv *a_priv) + +{ + int lo, mid, value; + + lo = readb(a_priv->gpib_base + XFER_COUNT_LO_REG); + mid = readb(a_priv->gpib_base + XFER_COUNT_MID_REG); + value = (lo & 0xff) | ((mid << 8) & 0x7f00); + value = ~(value - 1) & 0x7fff; + return value; +} + +void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count) + +{ + int complement = -count; + + writeb(complement & 0xff, a_priv->gpib_base + XFER_COUNT_LO_REG); + writeb((complement >> 8) & 0xff, a_priv->gpib_base + XFER_COUNT_MID_REG); + //I don't think the hi count reg is even used, but oh well + writeb((complement >> 16) & 0xf, a_priv->gpib_base + XFER_COUNT_HI_REG); +} + +// wrappers for interface functions +int agilent_82350b_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read); +} + +int agilent_82350b_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written); +} + +int agilent_82350b_command(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written); +} + +int agilent_82350b_take_control(gpib_board_t *board, int synchronous) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_take_control_workaround(board, &priv->tms9914_priv, synchronous); +} + +int agilent_82350b_go_to_standby(gpib_board_t *board) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_go_to_standby(board, &priv->tms9914_priv); +} + +void agilent_82350b_request_system_control(gpib_board_t *board, int request_control) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + + if (request_control) { + a_priv->card_mode_bits |= CM_SYSTEM_CONTROLLER_BIT; + if (a_priv->model != MODEL_82350A) + writeb(IC_SYSTEM_CONTROLLER_BIT, a_priv->gpib_base + INTERNAL_CONFIG_REG); + } else { + a_priv->card_mode_bits &= ~CM_SYSTEM_CONTROLLER_BIT; + if (a_priv->model != MODEL_82350A) + writeb(0, a_priv->gpib_base + INTERNAL_CONFIG_REG); + } + writeb(a_priv->card_mode_bits, a_priv->gpib_base + CARD_MODE_REG); + tms9914_request_system_control(board, &a_priv->tms9914_priv, request_control); +} + +void agilent_82350b_interface_clear(gpib_board_t *board, int assert) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + tms9914_interface_clear(board, &priv->tms9914_priv, assert); +} + +void agilent_82350b_remote_enable(gpib_board_t *board, int enable) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + tms9914_remote_enable(board, &priv->tms9914_priv, enable); +} + +int agilent_82350b_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits); +} + +void agilent_82350b_disable_eos(gpib_board_t *board) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + tms9914_disable_eos(board, &priv->tms9914_priv); +} + +unsigned int agilent_82350b_update_status(gpib_board_t *board, unsigned int clear_mask) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_update_status(board, &priv->tms9914_priv, clear_mask); +} + +int agilent_82350b_primary_address(gpib_board_t *board, unsigned int address) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_primary_address(board, &priv->tms9914_priv, address); +} + +int agilent_82350b_secondary_address(gpib_board_t *board, unsigned int address, int enable) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable); +} + +int agilent_82350b_parallel_poll(gpib_board_t *board, uint8_t *result) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_parallel_poll(board, &priv->tms9914_priv, result); +} + +void agilent_82350b_parallel_poll_configure(gpib_board_t *board, uint8_t config) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config); +} + +void agilent_82350b_parallel_poll_response(gpib_board_t *board, int ist) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist); +} + +void agilent_82350b_serial_poll_response(gpib_board_t *board, uint8_t status) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + tms9914_serial_poll_response(board, &priv->tms9914_priv, status); +} + +uint8_t agilent_82350b_serial_poll_status(gpib_board_t *board) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_serial_poll_status(board, &priv->tms9914_priv); +} + +int agilent_82350b_line_status(const gpib_board_t *board) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + return tms9914_line_status(board, &priv->tms9914_priv); +} + +unsigned int agilent_82350b_t1_delay(gpib_board_t *board, unsigned int nanosec) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + static const int nanosec_per_clock = 30; + unsigned int value; + + tms9914_t1_delay(board, &a_priv->tms9914_priv, nanosec); + + value = (nanosec + nanosec_per_clock - 1) / nanosec_per_clock; + if (value > 0xff) + value = 0xff; + writeb(value, a_priv->gpib_base + T1_DELAY_REG); + return value * nanosec_per_clock; +} + +void agilent_82350b_return_to_local(gpib_board_t *board) + +{ + struct agilent_82350b_priv *priv = board->private_data; + + tms9914_return_to_local(board, &priv->tms9914_priv); +} + +int agilent_82350b_allocate_private(gpib_board_t *board) + +{ + board->private_data = kzalloc(sizeof(struct agilent_82350b_priv), GFP_KERNEL); + if (!board->private_data) + return -ENOMEM; + return 0; +} + +void agilent_82350b_free_private(gpib_board_t *board) + +{ + kfree(board->private_data); + board->private_data = NULL; +} + +static int init_82350a_hardware(gpib_board_t *board, const gpib_board_config_t *config) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + static const unsigned int firmware_length = 5302; + unsigned int borg_status; + static const unsigned int timeout = 1000; + int i, j; + const char *firmware_data = config->init_data; + const unsigned int plx_cntrl_static_bits = PLX9050_WAITO_NOT_USER0_SELECT_BIT | + PLX9050_USER0_OUTPUT_BIT | + PLX9050_LLOCK_NOT_USER1_SELECT_BIT | + PLX9050_USER1_OUTPUT_BIT | + PLX9050_USER2_OUTPUT_BIT | + PLX9050_USER3_OUTPUT_BIT | + PLX9050_PCI_READ_MODE_BIT | + PLX9050_PCI_WRITE_MODE_BIT | + PLX9050_PCI_RETRY_DELAY_BITS(64) | + PLX9050_DIRECT_SLAVE_LOCK_ENABLE_BIT; + +// load borg data + borg_status = readb(a_priv->borg_base); + if ((borg_status & BORG_DONE_BIT)) + return 0; + // need to programme borg + if (!config->init_data || config->init_data_length != firmware_length) { + dev_err(board->gpib_dev, "%s: the 82350A board requires firmware after powering on.\n", + driver_name); + return -EIO; + } + dev_info(board->gpib_dev, "%s: Loading firmware...\n", driver_name); + + // tickle the borg + writel(plx_cntrl_static_bits | PLX9050_USER3_DATA_BIT, + a_priv->plx_base + PLX9050_CNTRL_REG); + usleep_range(1000, 2000); + writel(plx_cntrl_static_bits, a_priv->plx_base + PLX9050_CNTRL_REG); + usleep_range(1000, 2000); + writel(plx_cntrl_static_bits | PLX9050_USER3_DATA_BIT, + a_priv->plx_base + PLX9050_CNTRL_REG); + usleep_range(1000, 2000); + + for (i = 0; i < config->init_data_length; ++i) { + for (j = 0; j < timeout && (readb(a_priv->borg_base) & BORG_READY_BIT) == 0; ++j) { + if (need_resched()) + schedule(); + usleep_range(10, 20); + } + if (j == timeout) { + dev_err(board->gpib_dev, "%s: timed out loading firmware.\n", driver_name); + return -ETIMEDOUT; + } + writeb(firmware_data[i], a_priv->gpib_base + CONFIG_DATA_REG); + } + for (j = 0; j < timeout && (readb(a_priv->borg_base) & BORG_DONE_BIT) == 0; ++j) { + if (need_resched()) + schedule(); + usleep_range(10, 20); + } + if (j == timeout) { + dev_err(board->gpib_dev, "%s: timed out waiting for firmware load to complete.\n", + driver_name); + return -ETIMEDOUT; + } + dev_info(board->gpib_dev, "%s: ...done.\n", driver_name); + return 0; +} + +static int test_sram(gpib_board_t *board) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + unsigned int i; + const unsigned int sram_length = pci_resource_len(a_priv->pci_device, SRAM_82350A_REGION); + // test SRAM + const unsigned int byte_mask = 0xff; + + for (i = 0; i < sram_length; ++i) { + writeb(i & byte_mask, a_priv->sram_base + i); + if (need_resched()) + schedule(); + } + for (i = 0; i < sram_length; ++i) { + unsigned int read_value = readb(a_priv->sram_base + i); + + if ((i & byte_mask) != read_value) { + dev_err(board->gpib_dev, "%s: SRAM test failed at %d wanted %d got %d\n", + driver_name, i, (i & byte_mask), read_value); + return -EIO; + } + if (need_resched()) + schedule(); + } + dev_info(board->gpib_dev, "%s: SRAM test passed 0x%x bytes checked\n", + driver_name, sram_length); + return 0; +} + +static int agilent_82350b_generic_attach(gpib_board_t *board, const gpib_board_config_t *config, + int use_fifos) + +{ + struct agilent_82350b_priv *a_priv; + struct tms9914_priv *tms_priv; + int retval; + + board->status = 0; + + if (agilent_82350b_allocate_private(board)) + return -ENOMEM; + a_priv = board->private_data; + a_priv->using_fifos = use_fifos; + tms_priv = &a_priv->tms9914_priv; + tms_priv->read_byte = tms9914_iomem_read_byte; + tms_priv->write_byte = tms9914_iomem_write_byte; + tms_priv->offset = 1; + + // find board + a_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_AGILENT, + PCI_DEVICE_ID_82350B, NULL); + if (a_priv->pci_device) { + a_priv->model = MODEL_82350B; + dev_info(board->gpib_dev, "%s: Agilent 82350B board found\n", driver_name); + + } else { + a_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_AGILENT, + PCI_DEVICE_ID_82351A, NULL); + if (a_priv->pci_device) { + a_priv->model = MODEL_82351A; + dev_info(board->gpib_dev, "%s: Agilent 82351B board found\n", driver_name); + + } else { + a_priv->pci_device = gpib_pci_get_subsys(config, PCI_VENDOR_ID_PLX, + PCI_DEVICE_ID_PLX_9050, + PCI_VENDOR_ID_HP, + PCI_SUBDEVICE_ID_82350A, + a_priv->pci_device); + if (a_priv->pci_device) { + a_priv->model = MODEL_82350A; + dev_info(board->gpib_dev, "%s: HP/Agilent 82350A board found\n", + driver_name); + } else { + dev_err(board->gpib_dev, "%s: no 82350/82351 board found\n", + driver_name); + return -ENODEV; + } + } + } + if (pci_enable_device(a_priv->pci_device)) { + dev_err(board->gpib_dev, "%s: error enabling pci device\n", driver_name); + return -EIO; + } + if (pci_request_regions(a_priv->pci_device, driver_name)) + return -EIO; + switch (a_priv->model) { + case MODEL_82350A: + a_priv->plx_base = ioremap(pci_resource_start(a_priv->pci_device, PLX_MEM_REGION), + pci_resource_len(a_priv->pci_device, PLX_MEM_REGION)); + dev_dbg(board->gpib_dev, "%s: plx base address remapped to 0x%p\n", + driver_name, a_priv->plx_base); + a_priv->gpib_base = ioremap(pci_resource_start(a_priv->pci_device, + GPIB_82350A_REGION), + pci_resource_len(a_priv->pci_device, + GPIB_82350A_REGION)); + dev_dbg(board->gpib_dev, "%s: gpib base address remapped to 0x%p\n", + driver_name, a_priv->gpib_base); + tms_priv->iobase = a_priv->gpib_base + TMS9914_BASE_REG; + a_priv->sram_base = ioremap(pci_resource_start(a_priv->pci_device, + SRAM_82350A_REGION), + pci_resource_len(a_priv->pci_device, + SRAM_82350A_REGION)); + dev_dbg(board->gpib_dev, "%s: sram base address remapped to 0x%p\n", + driver_name, a_priv->sram_base); + a_priv->borg_base = ioremap(pci_resource_start(a_priv->pci_device, + BORG_82350A_REGION), + pci_resource_len(a_priv->pci_device, + BORG_82350A_REGION)); + dev_dbg(board->gpib_dev, "%s: borg base address remapped to 0x%p\n", + driver_name, a_priv->borg_base); + + retval = init_82350a_hardware(board, config); + if (retval < 0) + return retval; + break; + case MODEL_82350B: + case MODEL_82351A: + a_priv->gpib_base = ioremap(pci_resource_start(a_priv->pci_device, GPIB_REGION), + pci_resource_len(a_priv->pci_device, GPIB_REGION)); + dev_dbg(board->gpib_dev, "%s: gpib base address remapped to 0x%p\n", + driver_name, a_priv->gpib_base); + tms_priv->iobase = a_priv->gpib_base + TMS9914_BASE_REG; + a_priv->sram_base = ioremap(pci_resource_start(a_priv->pci_device, SRAM_REGION), + pci_resource_len(a_priv->pci_device, SRAM_REGION)); + dev_dbg(board->gpib_dev, "%s: sram base address remapped to 0x%p\n", + driver_name, a_priv->sram_base); + a_priv->misc_base = ioremap(pci_resource_start(a_priv->pci_device, MISC_REGION), + pci_resource_len(a_priv->pci_device, MISC_REGION)); + dev_dbg(board->gpib_dev, "%s: misc base address remapped to 0x%p\n", + driver_name, a_priv->misc_base); + break; + default: + pr_err("%s: invalid board\n", driver_name); + return -1; + } + + retval = test_sram(board); + if (retval < 0) + return retval; + + if (request_irq(a_priv->pci_device->irq, agilent_82350b_interrupt, + IRQF_SHARED, driver_name, board)) { + pr_err("%s: can't request IRQ %d\n", driver_name, a_priv->pci_device->irq); + return -EIO; + } + a_priv->irq = a_priv->pci_device->irq; + dev_dbg(board->gpib_dev, "%s: IRQ %d\n", driver_name, a_priv->irq); + + writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); + a_priv->card_mode_bits = ENABLE_PCI_IRQ_BIT; + writeb(a_priv->card_mode_bits, a_priv->gpib_base + CARD_MODE_REG); + + if (a_priv->model == MODEL_82350A) { + // enable PCI interrupts for 82350a + writel(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR2_POLARITY_BIT | + PLX9050_PCI_INTR_EN_BIT, + a_priv->plx_base + PLX9050_INTCSR_REG); + } + + if (use_fifos) { + writeb(ENABLE_BUFFER_END_EVENTS_BIT | ENABLE_TERM_COUNT_EVENTS_BIT, + a_priv->gpib_base + EVENT_ENABLE_REG); + writeb(ENABLE_TERM_COUNT_INTERRUPT_BIT | ENABLE_BUFFER_END_INTERRUPT_BIT | + ENABLE_TMS9914_INTERRUPTS_BIT, a_priv->gpib_base + INTERRUPT_ENABLE_REG); + //write-clear event status bits + writeb(BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT, + a_priv->gpib_base + EVENT_STATUS_REG); + } else { + writeb(0, a_priv->gpib_base + EVENT_ENABLE_REG); + writeb(ENABLE_TMS9914_INTERRUPTS_BIT, + a_priv->gpib_base + INTERRUPT_ENABLE_REG); + } + board->t1_nano_sec = agilent_82350b_t1_delay(board, 2000); + tms9914_board_reset(tms_priv); + + tms9914_online(board, tms_priv); + + return 0; +} + +int agilent_82350b_unaccel_attach(gpib_board_t *board, const gpib_board_config_t *config) + +{ + return agilent_82350b_generic_attach(board, config, 0); +} + +int agilent_82350b_accel_attach(gpib_board_t *board, const gpib_board_config_t *config) + +{ + return agilent_82350b_generic_attach(board, config, 1); +} + +void agilent_82350b_detach(gpib_board_t *board) + +{ + struct agilent_82350b_priv *a_priv = board->private_data; + struct tms9914_priv *tms_priv; + + if (a_priv) { + if (a_priv->plx_base) // disable interrupts + writel(0, a_priv->plx_base + PLX9050_INTCSR_REG); + + tms_priv = &a_priv->tms9914_priv; + if (a_priv->irq) + free_irq(a_priv->irq, board); + if (a_priv->gpib_base) { + tms9914_board_reset(tms_priv); + if (a_priv->misc_base) + iounmap((void *)a_priv->misc_base); + if (a_priv->borg_base) + iounmap((void *)a_priv->borg_base); + if (a_priv->sram_base) + iounmap((void *)a_priv->sram_base); + if (a_priv->gpib_base) + iounmap((void *)a_priv->gpib_base); + if (a_priv->plx_base) + iounmap((void *)a_priv->plx_base); + pci_release_regions(a_priv->pci_device); + } + if (a_priv->pci_device) + pci_dev_put(a_priv->pci_device); + } + agilent_82350b_free_private(board); +} + +gpib_interface_t agilent_82350b_unaccel_interface = { +name: "agilent_82350b_unaccel", +attach : agilent_82350b_unaccel_attach, +detach : agilent_82350b_detach, +read : agilent_82350b_read, +write : agilent_82350b_write, +command : agilent_82350b_command, +request_system_control : agilent_82350b_request_system_control, +take_control : agilent_82350b_take_control, +go_to_standby : agilent_82350b_go_to_standby, +interface_clear : agilent_82350b_interface_clear, +remote_enable : agilent_82350b_remote_enable, +enable_eos : agilent_82350b_enable_eos, +disable_eos : agilent_82350b_disable_eos, +parallel_poll : agilent_82350b_parallel_poll, +parallel_poll_configure : agilent_82350b_parallel_poll_configure, +parallel_poll_response : agilent_82350b_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : agilent_82350b_line_status, +update_status : agilent_82350b_update_status, +primary_address : agilent_82350b_primary_address, +secondary_address : agilent_82350b_secondary_address, +serial_poll_response : agilent_82350b_serial_poll_response, +t1_delay : agilent_82350b_t1_delay, +return_to_local : agilent_82350b_return_to_local, +}; + +gpib_interface_t agilent_82350b_interface = { +name: "agilent_82350b", +attach : agilent_82350b_accel_attach, +detach : agilent_82350b_detach, +read : agilent_82350b_accel_read, +write : agilent_82350b_accel_write, +command : agilent_82350b_command, +request_system_control : agilent_82350b_request_system_control, +take_control : agilent_82350b_take_control, +go_to_standby : agilent_82350b_go_to_standby, +interface_clear : agilent_82350b_interface_clear, +remote_enable : agilent_82350b_remote_enable, +enable_eos : agilent_82350b_enable_eos, +disable_eos : agilent_82350b_disable_eos, +parallel_poll : agilent_82350b_parallel_poll, +parallel_poll_configure : agilent_82350b_parallel_poll_configure, +parallel_poll_response : agilent_82350b_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : agilent_82350b_line_status, +update_status : agilent_82350b_update_status, +primary_address : agilent_82350b_primary_address, +secondary_address : agilent_82350b_secondary_address, +serial_poll_response : agilent_82350b_serial_poll_response, +t1_delay : agilent_82350b_t1_delay, +return_to_local : agilent_82350b_return_to_local, +}; + +static int agilent_82350b_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + +{ + return 0; +} + +static const struct pci_device_id agilent_82350b_pci_table[] = { + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_HP, + PCI_SUBDEVICE_ID_82350A, 0, 0, 0 }, + { PCI_VENDOR_ID_AGILENT, PCI_DEVICE_ID_82350B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_AGILENT, PCI_DEVICE_ID_82351A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, agilent_82350b_pci_table); + +static struct pci_driver agilent_82350b_pci_driver = { + .name = "agilent_82350b", + .id_table = agilent_82350b_pci_table, + .probe = &agilent_82350b_pci_probe +}; + +static int __init agilent_82350b_init_module(void) + +{ + int result; + + result = pci_register_driver(&agilent_82350b_pci_driver); + if (result) { + pr_err("agilent_82350b: pci_driver_register failed!\n"); + return result; + } + + gpib_register_driver(&agilent_82350b_unaccel_interface, THIS_MODULE); + gpib_register_driver(&agilent_82350b_interface, THIS_MODULE); + return 0; +} + +static void __exit agilent_82350b_exit_module(void) + +{ + gpib_unregister_driver(&agilent_82350b_interface); + gpib_unregister_driver(&agilent_82350b_unaccel_interface); + + pci_unregister_driver(&agilent_82350b_pci_driver); +} + +module_init(agilent_82350b_init_module); +module_exit(agilent_82350b_exit_module); diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.h b/drivers/staging/gpib/agilent_82350b/agilent_82350b.h new file mode 100644 index 0000000000000000000000000000000000000000..30683d67d170506910fc7934c2f38b20aa431781 --- /dev/null +++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.h @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002, 2004 by Frank Mori Hess * + ***************************************************************************/ + +#include "gpibP.h" +#include "plx9050.h" +#include "tms9914.h" + +enum pci_vendor_ids { + PCI_VENDOR_ID_AGILENT = 0x15bc, +}; + +enum pci_device_ids { + PCI_DEVICE_ID_82350B = 0x0b01, + PCI_DEVICE_ID_82351A = 0x1218 +}; + +enum pci_subdevice_ids { + PCI_SUBDEVICE_ID_82350A = 0x10b0, +}; + +enum pci_regions_82350a { + PLX_MEM_REGION = 0, + PLX_IO_REGION = 1, + GPIB_82350A_REGION = 2, + SRAM_82350A_REGION = 3, + BORG_82350A_REGION = 4 +}; + +enum pci_regions_82350b { + GPIB_REGION = 0, + SRAM_REGION = 1, + MISC_REGION = 2, +}; + +enum board_model { + MODEL_82350A, + MODEL_82350B, + MODEL_82351A +}; + +// struct which defines private_data for board +struct agilent_82350b_priv { + struct tms9914_priv tms9914_priv; + struct pci_dev *pci_device; + void *plx_base; //82350a only + void *gpib_base; + void *sram_base; + void *misc_base; + void *borg_base; + int irq; + unsigned short card_mode_bits; + unsigned short event_status_bits; + enum board_model model; + bool using_fifos; +}; + +// driver name +extern const char *driver_name; + +// interfaces +extern gpib_interface_t agilent_82350b_interface; +// init functions + +int agilent_82350b_unaccel_attach(gpib_board_t *board, const gpib_board_config_t *config); +int agilent_82350b_accel_attach(gpib_board_t *board, const gpib_board_config_t *config); + +// interface functions +int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read); +int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written); +int agilent_82350b_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read); +int agilent_82350b_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written); +int agilent_82350b_command(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written); +int agilent_82350b_take_control(gpib_board_t *board, int synchronous); +int agilent_82350b_go_to_standby(gpib_board_t *board); +void agilent_82350b_request_system_control(gpib_board_t *board, int request_control); +void agilent_82350b_interface_clear(gpib_board_t *board, int assert); +void agilent_82350b_remote_enable(gpib_board_t *board, int enable); +int agilent_82350b_enable_eos(gpib_board_t *board, uint8_t eos_byte, int + compare_8_bits); +void agilent_82350b_disable_eos(gpib_board_t *board); +unsigned int agilent_82350b_update_status(gpib_board_t *board, unsigned int clear_mask); +int agilent_82350b_primary_address(gpib_board_t *board, unsigned int address); +int agilent_82350b_secondary_address(gpib_board_t *board, unsigned int address, int + enable); +int agilent_82350b_parallel_poll(gpib_board_t *board, uint8_t *result); +void agilent_82350b_parallel_poll_configure(gpib_board_t *board, uint8_t config); +void agilent_82350b_parallel_poll_response(gpib_board_t *board, int ist); +void agilent_82350b_serial_poll_response(gpib_board_t *board, uint8_t status); +void agilent_82350b_return_to_local(gpib_board_t *board); +uint8_t agilent_82350b_serial_poll_status(gpib_board_t *board); +int agilent_82350b_line_status(const gpib_board_t *board); +unsigned int agilent_82350b_t1_delay(gpib_board_t *board, unsigned int nanosec); + +// interrupt service routines +irqreturn_t agilent_82350b_interrupt(int irq, void *arg); + +// utility functions +int agilent_82350b_allocate_private(gpib_board_t *board); +void agilent_82350b_free_private(gpib_board_t *board); +unsigned short read_and_clear_event_status(gpib_board_t *board); +int read_transfer_counter(struct agilent_82350b_priv *a_priv); +void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count); + +//registers +enum agilent_82350b_gpib_registers + +{ + CARD_MODE_REG = 0x1, + CONFIG_DATA_REG = 0x2, // 82350A specific + INTERRUPT_ENABLE_REG = 0x3, + EVENT_STATUS_REG = 0x4, + EVENT_ENABLE_REG = 0x5, + STREAM_STATUS_REG = 0x7, + DEBUG_RAM0_REG = 0x8, + DEBUG_RAM1_REG = 0x9, + DEBUG_RAM2_REG = 0xa, + DEBUG_RAM3_REG = 0xb, + XFER_COUNT_LO_REG = 0xc, + XFER_COUNT_MID_REG = 0xd, + XFER_COUNT_HI_REG = 0xe, + TMS9914_BASE_REG = 0x10, + INTERNAL_CONFIG_REG = 0x18, + IMR0_READ_REG = 0x19, //read + T1_DELAY_REG = 0x19, // write + IMR1_READ_REG = 0x1a, + ADR_READ_REG = 0x1b, + SPMR_READ_REG = 0x1c, + PPR_READ_REG = 0x1d, + CDOR_READ_REG = 0x1e, + SRAM_ACCESS_CONTROL_REG = 0x1f, +}; + +enum card_mode_bits + +{ + ACTIVE_CONTROLLER_BIT = 0x2, // read-only + CM_SYSTEM_CONTROLLER_BIT = 0x8, + ENABLE_BUS_MONITOR_BIT = 0x10, + ENABLE_PCI_IRQ_BIT = 0x20, +}; + +enum interrupt_enable_bits + +{ + ENABLE_TMS9914_INTERRUPTS_BIT = 0x1, + ENABLE_BUFFER_END_INTERRUPT_BIT = 0x10, + ENABLE_TERM_COUNT_INTERRUPT_BIT = 0x20, +}; + +enum event_enable_bits + +{ + ENABLE_BUFFER_END_EVENTS_BIT = 0x10, + ENABLE_TERM_COUNT_EVENTS_BIT = 0x20, +}; + +enum event_status_bits + +{ + TMS9914_IRQ_STATUS_BIT = 0x1, + IRQ_STATUS_BIT = 0x2, + BUFFER_END_STATUS_BIT = 0x10, // write-clear + TERM_COUNT_STATUS_BIT = 0x20, // write-clear +}; + +enum stream_status_bits + +{ + HALTED_STATUS_BIT = 0x1, //read + RESTART_STREAM_BIT = 0x1, //write +}; + +enum internal_config_bits + +{ + IC_SYSTEM_CONTROLLER_BIT = 0x80, +}; + +enum sram_access_control_bits + +{ + DIRECTION_GPIB_TO_HOST = 0x20, // transfer direction + ENABLE_TI_TO_SRAM = 0x40, // enable fifo + ENABLE_FAST_TALKER = 0x80 // added for 82350A (not used) +}; + +enum borg_bits + +{ + BORG_READY_BIT = 0x40, + BORG_DONE_BIT = 0x80 +}; + +static const int agilent_82350b_fifo_size = 0x8000; + +static inline int agilent_82350b_fifo_is_halted(struct agilent_82350b_priv *a_priv) + +{ + return readb(a_priv->gpib_base + STREAM_STATUS_REG) & HALTED_STATUS_BIT; +} + diff --git a/drivers/staging/gpib/agilent_82357a/Makefile b/drivers/staging/gpib/agilent_82357a/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4a1d940fce2b83508012274c9df6dad2d42844c6 --- /dev/null +++ b/drivers/staging/gpib/agilent_82357a/Makefile @@ -0,0 +1,4 @@ + +obj-m += agilent_82357a.o + + diff --git a/drivers/staging/gpib/agilent_82357a/agilent_82357a.c b/drivers/staging/gpib/agilent_82357a/agilent_82357a.c new file mode 100644 index 0000000000000000000000000000000000000000..bf05fb4a736b3f4b7f9b12e3cac4d1b53a6cd49c --- /dev/null +++ b/drivers/staging/gpib/agilent_82357a/agilent_82357a.c @@ -0,0 +1,1712 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * driver for Agilent 82357A/B usb to gpib adapters * + * copyright : (C) 2004 by Frank Mori Hess * + ***************************************************************************/ + +#define _GNU_SOURCE + +#include +#include +#include +#include "agilent_82357a.h" +#include "gpibP.h" +#include "tms9914.h" + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for Agilent 82357A/B usb adapters"); + +#define MAX_NUM_82357A_INTERFACES 128 +static struct usb_interface *agilent_82357a_driver_interfaces[MAX_NUM_82357A_INTERFACES]; +DEFINE_MUTEX(agilent_82357a_hotplug_lock); // protect board insertion and removal + +static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned int clear_mask); + +static int agilent_82357a_take_control_internal(gpib_board_t *board, int synchronous); + +static void agilent_82357a_bulk_complete(struct urb *urb) +{ + struct agilent_82357a_urb_ctx *context = urb->context; + + up(&context->complete); +} + +static void agilent_82357a_timeout_handler(struct timer_list *t) +{ + struct agilent_82357a_priv *a_priv = from_timer(a_priv, t, bulk_timer); + struct agilent_82357a_urb_ctx *context = &a_priv->context; + + context->timed_out = 1; + up(&context->complete); +} + +static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void *data, + int data_length, int *actual_data_length, + int timeout_msecs) +{ + struct usb_device *usb_dev; + int retval; + unsigned int out_pipe; + struct agilent_82357a_urb_ctx *context = &a_priv->context; + + *actual_data_length = 0; + retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock); + if (retval) + return retval; + if (!a_priv->bus_interface) { + mutex_unlock(&a_priv->bulk_alloc_lock); + return -ENODEV; + } + if (a_priv->bulk_urb) { + mutex_unlock(&a_priv->bulk_alloc_lock); + return -EAGAIN; + } + a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!a_priv->bulk_urb) { + mutex_unlock(&a_priv->bulk_alloc_lock); + return -ENOMEM; + } + usb_dev = interface_to_usbdev(a_priv->bus_interface); + out_pipe = usb_sndbulkpipe(usb_dev, a_priv->bulk_out_endpoint); + sema_init(&context->complete, 0); + context->timed_out = 0; + usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, out_pipe, data, data_length, + &agilent_82357a_bulk_complete, context); + + if (timeout_msecs) + mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs)); + + retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL); + if (retval) { + dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n", + __func__, retval); + mutex_unlock(&a_priv->bulk_alloc_lock); + goto cleanup; + } + mutex_unlock(&a_priv->bulk_alloc_lock); + if (down_interruptible(&context->complete)) { + dev_err(&usb_dev->dev, "%s: interrupted\n", __func__); + retval = -ERESTARTSYS; + goto cleanup; + } + if (context->timed_out) { + retval = -ETIMEDOUT; + } else { + retval = a_priv->bulk_urb->status; + *actual_data_length = a_priv->bulk_urb->actual_length; + } +cleanup: + if (timeout_msecs) { + if (timer_pending(&a_priv->bulk_timer)) + del_timer_sync(&a_priv->bulk_timer); + } + mutex_lock(&a_priv->bulk_alloc_lock); + if (a_priv->bulk_urb) { + usb_kill_urb(a_priv->bulk_urb); + usb_free_urb(a_priv->bulk_urb); + a_priv->bulk_urb = NULL; + } + mutex_unlock(&a_priv->bulk_alloc_lock); + return retval; +} + +static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, void *data, + int data_length, int *actual_data_length, + int timeout_msecs) +{ + struct usb_device *usb_dev; + int retval; + unsigned int in_pipe; + struct agilent_82357a_urb_ctx *context = &a_priv->context; + + *actual_data_length = 0; + retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock); + if (retval) + return retval; + if (!a_priv->bus_interface) { + mutex_unlock(&a_priv->bulk_alloc_lock); + return -ENODEV; + } + if (a_priv->bulk_urb) { + mutex_unlock(&a_priv->bulk_alloc_lock); + return -EAGAIN; + } + a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!a_priv->bulk_urb) { + mutex_unlock(&a_priv->bulk_alloc_lock); + return -ENOMEM; + } + usb_dev = interface_to_usbdev(a_priv->bus_interface); + in_pipe = usb_rcvbulkpipe(usb_dev, AGILENT_82357_BULK_IN_ENDPOINT); + sema_init(&context->complete, 0); + context->timed_out = 0; + usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, in_pipe, data, data_length, + &agilent_82357a_bulk_complete, context); + + if (timeout_msecs) + mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs)); + + retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL); + if (retval) { + dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n", + __func__, retval); + mutex_unlock(&a_priv->bulk_alloc_lock); + goto cleanup; + } + mutex_unlock(&a_priv->bulk_alloc_lock); + if (down_interruptible(&context->complete)) { + dev_err(&usb_dev->dev, "%s: interrupted\n", __func__); + retval = -ERESTARTSYS; + goto cleanup; + } + if (context->timed_out) { + retval = -ETIMEDOUT; + goto cleanup; + } + retval = a_priv->bulk_urb->status; + *actual_data_length = a_priv->bulk_urb->actual_length; +cleanup: + if (timeout_msecs) + del_timer_sync(&a_priv->bulk_timer); + + mutex_lock(&a_priv->bulk_alloc_lock); + if (a_priv->bulk_urb) { + usb_kill_urb(a_priv->bulk_urb); + usb_free_urb(a_priv->bulk_urb); + a_priv->bulk_urb = NULL; + } + mutex_unlock(&a_priv->bulk_alloc_lock); + return retval; +} + +static int agilent_82357a_receive_control_msg(struct agilent_82357a_priv *a_priv, __u8 request, + __u8 requesttype, __u16 value, __u16 index, + void *data, __u16 size, int timeout_msecs) +{ + struct usb_device *usb_dev; + int retval; + unsigned int in_pipe; + + retval = mutex_lock_interruptible(&a_priv->control_alloc_lock); + if (retval) + return retval; + if (!a_priv->bus_interface) { + mutex_unlock(&a_priv->control_alloc_lock); + return -ENODEV; + } + usb_dev = interface_to_usbdev(a_priv->bus_interface); + in_pipe = usb_rcvctrlpipe(usb_dev, AGILENT_82357_CONTROL_ENDPOINT); + retval = usb_control_msg(usb_dev, in_pipe, request, requesttype, value, index, data, + size, timeout_msecs); + mutex_unlock(&a_priv->control_alloc_lock); + return retval; +} + +static void agilent_82357a_dump_raw_block(const u8 *raw_data, int length) +{ + pr_info("hex block dump\n"); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 8, 1, raw_data, length, true); +} + +static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv, + const struct agilent_82357a_register_pairlet *writes, + int num_writes) +{ + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + int retval; + u8 *out_data, *in_data; + int out_data_length, in_data_length; + int bytes_written, bytes_read; + int i = 0; + int j; + static const int bytes_per_write = 2; + static const int header_length = 2; + static const int max_writes = 31; + + if (num_writes > max_writes) { + dev_err(&usb_dev->dev, "%s: bug! num_writes=%i too large\n", __func__, num_writes); + return -EIO; + } + out_data_length = num_writes * bytes_per_write + header_length; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + + out_data[i++] = DATA_PIPE_CMD_WR_REGS; + out_data[i++] = num_writes; + for (j = 0; j < num_writes; j++) { + out_data[i++] = writes[j].address; + out_data[i++] = writes[j].value; + } + if (i > out_data_length) + dev_err(&usb_dev->dev, "%s: bug! buffer overrun\n", __func__); + retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock); + if (retval) { + kfree(out_data); + return retval; + } + retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000); + kfree(out_data); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + mutex_unlock(&a_priv->bulk_transfer_lock); + return retval; + } + in_data_length = 0x20; + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&a_priv->bulk_transfer_lock); + return -ENOMEM; + } + retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length, + &bytes_read, 1000); + mutex_unlock(&a_priv->bulk_transfer_lock); + + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + agilent_82357a_dump_raw_block(in_data, bytes_read); + kfree(in_data); + return -EIO; + } + if (in_data[0] != (0xff & ~DATA_PIPE_CMD_WR_REGS)) { + dev_err(&usb_dev->dev, "%s: error, bulk command=0x%x != ~DATA_PIPE_CMD_WR_REGS\n", + __func__, in_data[0]); + return -EIO; + } + if (in_data[1]) { + dev_err(&usb_dev->dev, "%s: nonzero error code 0x%x in DATA_PIPE_CMD_WR_REGS response\n", + __func__, in_data[1]); + return -EIO; + } + kfree(in_data); + return 0; +} + +static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv, + struct agilent_82357a_register_pairlet *reads, + int num_reads, int blocking) +{ + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + int retval; + u8 *out_data, *in_data; + int out_data_length, in_data_length; + int bytes_written, bytes_read; + int i = 0; + int j; + static const int header_length = 2; + static const int max_reads = 62; + + if (num_reads > max_reads) + dev_err(&usb_dev->dev, "%s: bug! num_reads=%i too large\n", __func__, num_reads); + + out_data_length = num_reads + header_length; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + + out_data[i++] = DATA_PIPE_CMD_RD_REGS; + out_data[i++] = num_reads; + for (j = 0; j < num_reads; j++) + out_data[i++] = reads[j].address; + if (i > out_data_length) + dev_err(&usb_dev->dev, "%s: bug! buffer overrun\n", __func__); + if (blocking) { + retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock); + if (retval) { + kfree(out_data); + return retval; + } + } else { + retval = mutex_trylock(&a_priv->bulk_transfer_lock); + if (retval == 0) { + kfree(out_data); + return -EAGAIN; + } + } + retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000); + kfree(out_data); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + mutex_unlock(&a_priv->bulk_transfer_lock); + return retval; + } + in_data_length = 0x20; + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&a_priv->bulk_transfer_lock); + return -ENOMEM; + } + retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length, + &bytes_read, 10000); + mutex_unlock(&a_priv->bulk_transfer_lock); + + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + agilent_82357a_dump_raw_block(in_data, bytes_read); + kfree(in_data); + return -EIO; + } + i = 0; + if (in_data[i++] != (0xff & ~DATA_PIPE_CMD_RD_REGS)) { + dev_err(&usb_dev->dev, "%s: error, bulk command=0x%x != ~DATA_PIPE_CMD_RD_REGS\n", + __func__, in_data[0]); + return -EIO; + } + if (in_data[i++]) { + dev_err(&usb_dev->dev, "%s: nonzero error code 0x%x in DATA_PIPE_CMD_RD_REGS response\n", + __func__, in_data[1]); + return -EIO; + } + for (j = 0; j < num_reads; j++) + reads[j].value = in_data[i++]; + kfree(in_data); + return 0; +} + +static int agilent_82357a_abort(struct agilent_82357a_priv *a_priv, int flush) +{ + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + int retval = 0; + int receive_control_retval; + u16 wIndex = 0; + u8 *status_data; + static const unsigned int status_data_len = 2; + + status_data = kmalloc(status_data_len, GFP_KERNEL); + if (!status_data) + return -ENOMEM; + + if (flush) + wIndex |= XA_FLUSH; + receive_control_retval = agilent_82357a_receive_control_msg(a_priv, + agilent_82357a_control_request, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, XFER_ABORT, + wIndex, status_data, + status_data_len, 100); + if (receive_control_retval < 0) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_control_msg() returned %i\n", + __func__, receive_control_retval); + retval = -EIO; + goto cleanup; + } + if (status_data[0] != (~XFER_ABORT & 0xff)) { + dev_err(&usb_dev->dev, "%s: error, major code=0x%x != ~XFER_ABORT\n", + __func__, status_data[0]); + retval = -EIO; + goto cleanup; + } + switch (status_data[1]) { + case UGP_SUCCESS: + retval = 0; + break; + case UGP_ERR_FLUSHING: + if (flush) { + retval = 0; + break; + } + fallthrough; + case UGP_ERR_FLUSHING_ALREADY: + default: + dev_err(&usb_dev->dev, "%s: abort returned error code=0x%x\n", + __func__, status_data[1]); + retval = -EIO; + break; + } + +cleanup: + kfree(status_data); + return retval; +} + +// interface functions +int agilent_82357a_command(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written); + +static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *nbytes) +{ + int retval; + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + u8 *out_data, *in_data; + int out_data_length, in_data_length; + int bytes_written, bytes_read; + int i = 0; + u8 trailing_flags; + unsigned long start_jiffies = jiffies; + int msec_timeout; + + *nbytes = 0; + *end = 0; + out_data_length = 0x9; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + out_data[i++] = DATA_PIPE_CMD_READ; + out_data[i++] = 0; //primary address when ARF_NO_ADDR is not set + out_data[i++] = 0; //secondary address when ARF_NO_ADDR is not set + out_data[i] = ARF_NO_ADDRESS | ARF_END_ON_EOI; + if (a_priv->eos_mode & REOS) + out_data[i] |= ARF_END_ON_EOS_CHAR; + ++i; + out_data[i++] = length & 0xff; + out_data[i++] = (length >> 8) & 0xff; + out_data[i++] = (length >> 16) & 0xff; + out_data[i++] = (length >> 24) & 0xff; + out_data[i++] = a_priv->eos_char; + msec_timeout = (board->usec_timeout + 999) / 1000; + retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock); + if (retval) { + kfree(out_data); + return retval; + } + retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, msec_timeout); + kfree(out_data); + if (retval || bytes_written != i) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + mutex_unlock(&a_priv->bulk_transfer_lock); + if (retval < 0) + return retval; + return -EIO; + } + in_data_length = length + 1; + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&a_priv->bulk_transfer_lock); + return -ENOMEM; + } + if (board->usec_timeout != 0) + msec_timeout -= jiffies_to_msecs(jiffies - start_jiffies) - 1; + if (msec_timeout >= 0) { + retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length, + &bytes_read, msec_timeout); + } else { + retval = -ETIMEDOUT; + bytes_read = 0; + } + if (retval == -ETIMEDOUT) { + int extra_bytes_read; + int extra_bytes_retval; + + agilent_82357a_abort(a_priv, 1); + extra_bytes_retval = agilent_82357a_receive_bulk_msg(a_priv, in_data + bytes_read, + in_data_length - bytes_read, + &extra_bytes_read, 100); + bytes_read += extra_bytes_read; + if (extra_bytes_retval) { + dev_err(&usb_dev->dev, "%s: extra_bytes_retval=%i, bytes_read=%i\n", + __func__, extra_bytes_retval, bytes_read); + agilent_82357a_abort(a_priv, 0); + } + } else if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + agilent_82357a_abort(a_priv, 0); + } + mutex_unlock(&a_priv->bulk_transfer_lock); + if (bytes_read > length + 1) { + bytes_read = length + 1; + pr_warn("%s: bytes_read > length? truncating", __func__); + } + + if (bytes_read >= 1) { + memcpy(buffer, in_data, bytes_read - 1); + trailing_flags = in_data[bytes_read - 1]; + *nbytes = bytes_read - 1; + if (trailing_flags & (ATRF_EOI | ATRF_EOS)) + *end = 1; + } + kfree(in_data); + + /* Fix for a bug in 9914A that does not return the contents of ADSR + * when the board is in listener active state and ATN is not asserted. + * Set ATN here to obtain a valid board level ibsta + */ + agilent_82357a_take_control_internal(board, 0); + + //FIXME check trailing flags for error + return retval; +} + +static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_commands, int send_eoi, size_t *bytes_written) +{ + int retval; + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + u8 *out_data = NULL; + u8 *status_data = NULL; + int out_data_length; + int raw_bytes_written; + int i = 0, j; + int msec_timeout; + unsigned short bsr, adsr; + struct agilent_82357a_register_pairlet read_reg; + + *bytes_written = 0; + out_data_length = length + 0x8; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + out_data[i++] = DATA_PIPE_CMD_WRITE; + out_data[i++] = 0; // primary address when AWF_NO_ADDRESS is not set + out_data[i++] = 0; // secondary address when AWF_NO_ADDRESS is not set + out_data[i] = AWF_NO_ADDRESS | AWF_NO_FAST_TALKER_FIRST_BYTE; + if (send_commands) + out_data[i] |= AWF_ATN | AWF_NO_FAST_TALKER; + if (send_eoi) + out_data[i] |= AWF_SEND_EOI; + ++i; + out_data[i++] = length & 0xff; + out_data[i++] = (length >> 8) & 0xff; + out_data[i++] = (length >> 16) & 0xff; + out_data[i++] = (length >> 24) & 0xff; + for (j = 0; j < length; j++) + out_data[i++] = buffer[j]; + + clear_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags); + + msec_timeout = (board->usec_timeout + 999) / 1000; + retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock); + if (retval) { + kfree(out_data); + return retval; + } + retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &raw_bytes_written, + msec_timeout); + kfree(out_data); + if (retval || raw_bytes_written != i) { + agilent_82357a_abort(a_priv, 0); + dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, raw_bytes_written=%i, i=%i\n", + __func__, retval, raw_bytes_written, i); + mutex_unlock(&a_priv->bulk_transfer_lock); + if (retval < 0) + return retval; + return -EIO; + } + + retval = wait_event_interruptible(board->wait, + test_bit(AIF_WRITE_COMPLETE_BN, + &a_priv->interrupt_flags) || + test_bit(TIMO_NUM, &board->status)); + if (retval) { + dev_err(&usb_dev->dev, "%s: wait write complete interrupted\n", __func__); + agilent_82357a_abort(a_priv, 0); + mutex_unlock(&a_priv->bulk_transfer_lock); + return -ERESTARTSYS; + } + + if (test_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags) == 0) { + dev_dbg(&usb_dev->dev, "write timed out ibs %i, tmo %i\n", + test_bit(TIMO_NUM, &board->status), msec_timeout); + + agilent_82357a_abort(a_priv, 0); + + mutex_unlock(&a_priv->bulk_transfer_lock); + + read_reg.address = BSR; + retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n", + __func__); + return -ETIMEDOUT; + } + + bsr = read_reg.value; + dev_dbg(&usb_dev->dev, "write aborted bsr 0x%x\n", bsr); + + if (send_commands) {/* check for no listeners */ + if ((bsr & BSR_ATN_BIT) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) { + dev_dbg(&usb_dev->dev, "No listener on command\n"); + clear_bit(TIMO_NUM, &board->status); + return -ENOTCONN; // no listener on bus + } + } else { + read_reg.address = ADSR; + retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n", + __func__); + return -ETIMEDOUT; + } + adsr = read_reg.value; + if ((adsr & HR_TA) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) { + dev_dbg(&usb_dev->dev, "No listener on write\n"); + clear_bit(TIMO_NUM, &board->status); + return -ECOMM; + } + } + + return -ETIMEDOUT; + } + + status_data = kmalloc(STATUS_DATA_LEN, GFP_KERNEL); + if (!status_data) { + mutex_unlock(&a_priv->bulk_transfer_lock); + return -ENOMEM; + } + + retval = agilent_82357a_receive_control_msg(a_priv, agilent_82357a_control_request, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + XFER_STATUS, 0, status_data, STATUS_DATA_LEN, + 100); + mutex_unlock(&a_priv->bulk_transfer_lock); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_control_msg() returned %i\n", + __func__, retval); + kfree(status_data); + return -EIO; + } + *bytes_written = (u32)status_data[2]; + *bytes_written |= (u32)status_data[3] << 8; + *bytes_written |= (u32)status_data[4] << 16; + *bytes_written |= (u32)status_data[5] << 24; + + kfree(status_data); + return 0; +} + +static int agilent_82357a_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + return agilent_82357a_generic_write(board, buffer, length, 0, send_eoi, bytes_written); +} + +int agilent_82357a_command(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written) +{ + return agilent_82357a_generic_write(board, buffer, length, 1, 0, bytes_written); +} + +int agilent_82357a_take_control_internal(gpib_board_t *board, int synchronous) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet write; + int retval; + + write.address = AUXCR; + if (synchronous) + write.value = AUX_TCS; + else + write.value = AUX_TCA; + retval = agilent_82357a_write_registers(a_priv, &write, 1); + if (retval) + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + + return retval; +} + +static int agilent_82357a_take_control(gpib_board_t *board, int synchronous) +{ + const int timeout = 10; + int i; + +/* It looks like the 9914 does not handle tcs properly. + * See comment above tms9914_take_control_workaround() in + * drivers/gpib/tms9914/tms9914_aux.c + */ + if (synchronous) + return -ETIMEDOUT; + + agilent_82357a_take_control_internal(board, synchronous); + // busy wait until ATN is asserted + for (i = 0; i < timeout; ++i) { + agilent_82357a_update_status(board, 0); + if (test_bit(ATN_NUM, &board->status)) + break; + udelay(1); + } + if (i == timeout) + return -ETIMEDOUT; + return 0; +} + +static int agilent_82357a_go_to_standby(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet write; + int retval; + + write.address = AUXCR; + write.value = AUX_GTS; + retval = agilent_82357a_write_registers(a_priv, &write, 1); + if (retval) + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return 0; +} + +//FIXME should change prototype to return int +static void agilent_82357a_request_system_control(gpib_board_t *board, int request_control) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet writes[2]; + int retval; + int i = 0; + + /* 82357B needs bit to be set in 9914 AUXCR register */ + writes[i].address = AUXCR; + if (request_control) { + writes[i].value = AUX_RQC; + a_priv->hw_control_bits |= SYSTEM_CONTROLLER; + } else { + writes[i].value = AUX_RLC; + a_priv->is_cic = 0; + a_priv->hw_control_bits &= ~SYSTEM_CONTROLLER; + } + ++i; + writes[i].address = HW_CONTROL; + writes[i].value = a_priv->hw_control_bits; + ++i; + retval = agilent_82357a_write_registers(a_priv, writes, i); + if (retval) + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return;// retval; +} + +static void agilent_82357a_interface_clear(gpib_board_t *board, int assert) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet write; + int retval; + + write.address = AUXCR; + write.value = AUX_SIC; + if (assert) { + write.value |= AUX_CS; + a_priv->is_cic = 1; + } + retval = agilent_82357a_write_registers(a_priv, &write, 1); + if (retval) + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); +} + +static void agilent_82357a_remote_enable(gpib_board_t *board, int enable) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet write; + int retval; + + write.address = AUXCR; + write.value = AUX_SRE; + if (enable) + write.value |= AUX_CS; + retval = agilent_82357a_write_registers(a_priv, &write, 1); + if (retval) + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + a_priv->ren_state = enable; + return;// 0; +} + +static int agilent_82357a_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + + if (compare_8_bits == 0) { + pr_warn("%s: hardware only supports 8-bit EOS compare", __func__); + return -EOPNOTSUPP; + } + a_priv->eos_char = eos_byte; + a_priv->eos_mode = REOS | BIN; + return 0; +} + +static void agilent_82357a_disable_eos(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + + a_priv->eos_mode &= ~REOS; +} + +static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet address_status, bus_status; + int retval; + + board->status &= ~clear_mask; + if (a_priv->is_cic) + set_bit(CIC_NUM, &board->status); + else + clear_bit(CIC_NUM, &board->status); + address_status.address = ADSR; + retval = agilent_82357a_read_registers(a_priv, &address_status, 1, 0); + if (retval) { + if (retval != -EAGAIN) + dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n", + __func__); + return board->status; + } + // check for remote/local + if (address_status.value & HR_REM) + set_bit(REM_NUM, &board->status); + else + clear_bit(REM_NUM, &board->status); + // check for lockout + if (address_status.value & HR_LLO) + set_bit(LOK_NUM, &board->status); + else + clear_bit(LOK_NUM, &board->status); + // check for ATN + if (address_status.value & HR_ATN) + set_bit(ATN_NUM, &board->status); + else + clear_bit(ATN_NUM, &board->status); + // check for talker/listener addressed + if (address_status.value & HR_TA) + set_bit(TACS_NUM, &board->status); + else + clear_bit(TACS_NUM, &board->status); + if (address_status.value & HR_LA) + set_bit(LACS_NUM, &board->status); + else + clear_bit(LACS_NUM, &board->status); + + bus_status.address = BSR; + retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0); + if (retval) { + if (retval != -EAGAIN) + dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n", + __func__); + return board->status; + } + if (bus_status.value & BSR_SRQ_BIT) + set_bit(SRQI_NUM, &board->status); + else + clear_bit(SRQI_NUM, &board->status); + + return board->status; +} + +static int agilent_82357a_primary_address(gpib_board_t *board, unsigned int address) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet write; + int retval; + + // put primary address in address0 + write.address = ADR; + write.value = address & ADDRESS_MASK; + retval = agilent_82357a_write_registers(a_priv, &write, 1); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return retval; + } + return retval; +} + +static int agilent_82357a_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + if (enable) + pr_warn("%s: warning: assigning a secondary address not supported\n", __func__); + return -EOPNOTSUPP; +} + +static int agilent_82357a_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet writes[2]; + struct agilent_82357a_register_pairlet read; + int retval; + + // execute parallel poll + writes[0].address = AUXCR; + writes[0].value = AUX_CS | AUX_RPP; + writes[1].address = HW_CONTROL; + writes[1].value = a_priv->hw_control_bits & ~NOT_PARALLEL_POLL; + retval = agilent_82357a_write_registers(a_priv, writes, 2); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return retval; + } + udelay(2); //silly, since usb write will take way longer + read.address = CPTR; + retval = agilent_82357a_read_registers(a_priv, &read, 1, 1); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n", + __func__); + return retval; + } + *result = read.value; + // clear parallel poll state + writes[0].address = HW_CONTROL; + writes[0].value = a_priv->hw_control_bits | NOT_PARALLEL_POLL; + writes[1].address = AUXCR; + writes[1].value = AUX_RPP; + retval = agilent_82357a_write_registers(a_priv, writes, 2); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return retval; + } + return 0; +} + +static void agilent_82357a_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + //board can only be system controller + return;// 0; +} + +static void agilent_82357a_parallel_poll_response(gpib_board_t *board, int ist) +{ + //board can only be system controller + return;// 0; +} + +static void agilent_82357a_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + //board can only be system controller + return;// 0; +} + +static uint8_t agilent_82357a_serial_poll_status(gpib_board_t *board) +{ + //board can only be system controller + return 0; +} + +static void agilent_82357a_return_to_local(gpib_board_t *board) +{ + //board can only be system controller + return;// 0; +} + +static int agilent_82357a_line_status(const gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet bus_status; + int retval; + int status = ValidALL; + + bus_status.address = BSR; + retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0); + if (retval) { + if (retval != -EAGAIN) + dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n", + __func__); + return retval; + } + if (bus_status.value & BSR_REN_BIT) + status |= BusREN; + if (bus_status.value & BSR_IFC_BIT) + status |= BusIFC; + if (bus_status.value & BSR_SRQ_BIT) + status |= BusSRQ; + if (bus_status.value & BSR_EOI_BIT) + status |= BusEOI; + if (bus_status.value & BSR_NRFD_BIT) + status |= BusNRFD; + if (bus_status.value & BSR_NDAC_BIT) + status |= BusNDAC; + if (bus_status.value & BSR_DAV_BIT) + status |= BusDAV; + if (bus_status.value & BSR_ATN_BIT) + status |= BusATN; + return status; +} + +static unsigned short nanosec_to_fast_talker_bits(unsigned int *nanosec) +{ + static const int nanosec_per_bit = 21; + static const int max_value = 0x72; + static const int min_value = 0x11; + unsigned short bits; + + bits = (*nanosec + nanosec_per_bit / 2) / nanosec_per_bit; + if (bits < min_value) + bits = min_value; + if (bits > max_value) + bits = max_value; + *nanosec = bits * nanosec_per_bit; + return bits; +} + +static unsigned int agilent_82357a_t1_delay(gpib_board_t *board, unsigned int nanosec) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet write; + int retval; + + write.address = FAST_TALKER_T1; + write.value = nanosec_to_fast_talker_bits(&nanosec); + retval = agilent_82357a_write_registers(a_priv, &write, 1); + if (retval) + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return nanosec; +} + +static void agilent_82357a_interrupt_complete(struct urb *urb) +{ + gpib_board_t *board = urb->context; + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + int retval; + u8 *transfer_buffer = urb->transfer_buffer; + unsigned long interrupt_flags; + + switch (urb->status) { + /* success */ + case 0: + break; + /* unlinked, don't resubmit */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + return; + default: /* other error, resubmit */ + retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC); + if (retval) + dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__); + return; + } + + interrupt_flags = transfer_buffer[0]; + if (test_bit(AIF_READ_COMPLETE_BN, &interrupt_flags)) + set_bit(AIF_READ_COMPLETE_BN, &a_priv->interrupt_flags); + if (test_bit(AIF_WRITE_COMPLETE_BN, &interrupt_flags)) + set_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags); + if (test_bit(AIF_SRQ_BN, &interrupt_flags)) + set_bit(SRQI_NUM, &board->status); + + wake_up_interruptible(&board->wait); + + retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC); + if (retval) + dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__); +} + +static int agilent_82357a_setup_urbs(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev; + int int_pipe; + int retval; + + retval = mutex_lock_interruptible(&a_priv->interrupt_alloc_lock); + if (retval) + return retval; + if (!a_priv->bus_interface) { + retval = -ENODEV; + goto setup_exit; + } + + a_priv->interrupt_buffer = kmalloc(INTERRUPT_BUF_LEN, GFP_KERNEL); + if (!a_priv->interrupt_buffer) { + retval = -ENOMEM; + goto setup_exit; + } + a_priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!a_priv->interrupt_urb) { + retval = -ENOMEM; + goto setup_exit; + } + usb_dev = interface_to_usbdev(a_priv->bus_interface); + int_pipe = usb_rcvintpipe(usb_dev, a_priv->interrupt_in_endpoint); + usb_fill_int_urb(a_priv->interrupt_urb, usb_dev, int_pipe, a_priv->interrupt_buffer, + INTERRUPT_BUF_LEN, &agilent_82357a_interrupt_complete, board, 1); + retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL); + if (retval) { + usb_free_urb(a_priv->interrupt_urb); + a_priv->interrupt_urb = NULL; + dev_err(&usb_dev->dev, "%s: failed to submit first interrupt urb, retval=%i\n", + __func__, retval); + goto setup_exit; + } + mutex_unlock(&a_priv->interrupt_alloc_lock); + return 0; + +setup_exit: + kfree(a_priv->interrupt_buffer); + mutex_unlock(&a_priv->interrupt_alloc_lock); + return retval; +} + +#ifdef RESET_USB_CONFIG +static int agilent_82357a_reset_usb_configuration(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct usb_device *usb_dev; + int retval; + + if (!a_priv->bus_interface) + return -ENODEV; + usb_dev = interface_to_usbdev(a_priv->bus_interface); + retval = usb_reset_configuration(usb_dev); + if (retval) + dev_err(&usb_dev->dev, "%s: usb_reset_configuration() returned %i\n", + __func__, retval); + return retval; +} +#endif + +static void agilent_82357a_cleanup_urbs(struct agilent_82357a_priv *a_priv) +{ + if (a_priv && a_priv->bus_interface) { + if (a_priv->interrupt_urb) + usb_kill_urb(a_priv->interrupt_urb); + if (a_priv->bulk_urb) + usb_kill_urb(a_priv->bulk_urb); + } +}; + +static int agilent_82357a_allocate_private(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv; + + board->private_data = kmalloc(sizeof(struct agilent_82357a_priv), GFP_KERNEL); + if (!board->private_data) + return -ENOMEM; + a_priv = board->private_data; + memset(a_priv, 0, sizeof(struct agilent_82357a_priv)); + mutex_init(&a_priv->bulk_transfer_lock); + mutex_init(&a_priv->bulk_alloc_lock); + mutex_init(&a_priv->control_alloc_lock); + mutex_init(&a_priv->interrupt_alloc_lock); + return 0; +} + +static void agilent_82357a_free_private(struct agilent_82357a_priv *a_priv) +{ + usb_free_urb(a_priv->interrupt_urb); + kfree(a_priv->interrupt_buffer); + kfree(a_priv); +} + +static int agilent_82357a_init(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet hw_control; + struct agilent_82357a_register_pairlet writes[0x20]; + int retval; + int i; + unsigned int nanosec; + + i = 0; + writes[i].address = LED_CONTROL; + writes[i].value = FAIL_LED_ON; + ++i; + writes[i].address = RESET_TO_POWERUP; + writes[i].value = RESET_SPACEBALL; + ++i; + retval = agilent_82357a_write_registers(a_priv, writes, i); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return -EIO; + } + set_current_state(TASK_INTERRUPTIBLE); + if (schedule_timeout(usec_to_jiffies(2000))) + return -ERESTARTSYS; + i = 0; + writes[i].address = AUXCR; + writes[i].value = AUX_NBAF; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_HLDE; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_TON; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_LON; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_RSV2; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_INVAL; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_RPP; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_STDL; + ++i; + writes[i].address = AUXCR; + writes[i].value = AUX_VSTDL; + ++i; + writes[i].address = FAST_TALKER_T1; + nanosec = board->t1_nano_sec; + writes[i].value = nanosec_to_fast_talker_bits(&nanosec); + board->t1_nano_sec = nanosec; + ++i; + writes[i].address = ADR; + writes[i].value = board->pad & ADDRESS_MASK; + ++i; + writes[i].address = PPR; + writes[i].value = 0; + ++i; + writes[i].address = SPMR; + writes[i].value = 0; + ++i; + writes[i].address = PROTOCOL_CONTROL; + writes[i].value = WRITE_COMPLETE_INTERRUPT_EN; + ++i; + writes[i].address = IMR0; + writes[i].value = HR_BOIE | HR_BIIE; + ++i; + writes[i].address = IMR1; + writes[i].value = HR_SRQIE; + ++i; + // turn off reset state + writes[i].address = AUXCR; + writes[i].value = AUX_CHIP_RESET; + ++i; + writes[i].address = LED_CONTROL; + writes[i].value = FIRMWARE_LED_CONTROL; + ++i; + if (i > ARRAY_SIZE(writes)) { + dev_err(&usb_dev->dev, "%s: bug! writes[] overflow\n", __func__); + return -EFAULT; + } + retval = agilent_82357a_write_registers(a_priv, writes, i); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return -EIO; + } + hw_control.address = HW_CONTROL; + retval = agilent_82357a_read_registers(a_priv, &hw_control, 1, 1); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n", + __func__); + return -EIO; + } + a_priv->hw_control_bits = (hw_control.value & ~0x7) | NOT_TI_RESET | NOT_PARALLEL_POLL; + + return 0; +} + +static inline int agilent_82357a_device_match(struct usb_interface *interface, + const gpib_board_config_t *config) +{ + struct usb_device * const usbdev = interface_to_usbdev(interface); + + if (gpib_match_device_path(&interface->dev, config->device_path) == 0) + return 0; + if (config->serial_number && + strcmp(usbdev->serial, config->serial_number) != 0) + return 0; + + return 1; +} + +static int agilent_82357a_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + int retval; + int i; + unsigned int product_id; + struct agilent_82357a_priv *a_priv; + struct usb_device *usb_dev; + + if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock)) + return -ERESTARTSYS; + + retval = agilent_82357a_allocate_private(board); + if (retval < 0) { + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; + } + a_priv = board->private_data; + for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) { + if (agilent_82357a_driver_interfaces[i] && + !usb_get_intfdata(agilent_82357a_driver_interfaces[i]) && + agilent_82357a_device_match(agilent_82357a_driver_interfaces[i], config)) { + a_priv->bus_interface = agilent_82357a_driver_interfaces[i]; + usb_set_intfdata(agilent_82357a_driver_interfaces[i], board); + usb_dev = interface_to_usbdev(a_priv->bus_interface); + dev_info(&usb_dev->dev, + "bus %d dev num %d attached to gpib minor %d, agilent usb interface %i\n", + usb_dev->bus->busnum, usb_dev->devnum, board->minor, i); + break; + } + } + if (i == MAX_NUM_82357A_INTERFACES) { + mutex_unlock(&agilent_82357a_hotplug_lock); + pr_err("No Agilent 82357 gpib adapters found, have you loaded its firmware?\n"); + return -ENODEV; + } + product_id = le16_to_cpu(interface_to_usbdev(a_priv->bus_interface)->descriptor.idProduct); + switch (product_id) { + case USB_DEVICE_ID_AGILENT_82357A: + a_priv->bulk_out_endpoint = AGILENT_82357A_BULK_OUT_ENDPOINT; + a_priv->interrupt_in_endpoint = AGILENT_82357A_INTERRUPT_IN_ENDPOINT; + break; + case USB_DEVICE_ID_AGILENT_82357B: + a_priv->bulk_out_endpoint = AGILENT_82357B_BULK_OUT_ENDPOINT; + a_priv->interrupt_in_endpoint = AGILENT_82357B_INTERRUPT_IN_ENDPOINT; + break; + default: + dev_err(&usb_dev->dev, "bug, unhandled product_id in switch?\n"); + return -EIO; + } +#ifdef RESET_USB_CONFIG + retval = agilent_82357a_reset_usb_configuration(board); + if (retval < 0) { + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; + } +#endif + retval = agilent_82357a_setup_urbs(board); + if (retval < 0) { + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; + } + + timer_setup(&a_priv->bulk_timer, agilent_82357a_timeout_handler, 0); + + board->t1_nano_sec = 800; + + retval = agilent_82357a_init(board); + + if (retval < 0) { + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; + } + + dev_info(&usb_dev->dev, "%s: attached\n", __func__); + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; +} + +static int agilent_82357a_go_idle(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface); + struct agilent_82357a_register_pairlet writes[0x20]; + int retval; + int i; + + i = 0; + // turn on tms9914 reset state + writes[i].address = AUXCR; + writes[i].value = AUX_CS | AUX_CHIP_RESET; + ++i; + a_priv->hw_control_bits &= ~NOT_TI_RESET; + writes[i].address = HW_CONTROL; + writes[i].value = a_priv->hw_control_bits; + ++i; + writes[i].address = PROTOCOL_CONTROL; + writes[i].value = 0; + ++i; + writes[i].address = IMR0; + writes[i].value = 0; + ++i; + writes[i].address = IMR1; + writes[i].value = 0; + ++i; + writes[i].address = LED_CONTROL; + writes[i].value = 0; + ++i; + if (i > ARRAY_SIZE(writes)) { + dev_err(&usb_dev->dev, "%s: bug! writes[] overflow\n", __func__); + return -EFAULT; + } + retval = agilent_82357a_write_registers(a_priv, writes, i); + if (retval) { + dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n", + __func__); + return -EIO; + } + return 0; +} + +static void agilent_82357a_detach(gpib_board_t *board) +{ + struct agilent_82357a_priv *a_priv; + struct usb_device *usb_dev; + + mutex_lock(&agilent_82357a_hotplug_lock); + + a_priv = board->private_data; + usb_dev = interface_to_usbdev(a_priv->bus_interface); + if (a_priv) { + if (a_priv->bus_interface) { + agilent_82357a_go_idle(board); + usb_set_intfdata(a_priv->bus_interface, NULL); + } + mutex_lock(&a_priv->control_alloc_lock); + mutex_lock(&a_priv->bulk_alloc_lock); + mutex_lock(&a_priv->interrupt_alloc_lock); + agilent_82357a_cleanup_urbs(a_priv); + agilent_82357a_free_private(a_priv); + } + dev_info(&usb_dev->dev, "%s: detached\n", __func__); + mutex_unlock(&agilent_82357a_hotplug_lock); +} + +gpib_interface_t agilent_82357a_gpib_interface = { +name: "agilent_82357a", +attach : agilent_82357a_attach, +detach : agilent_82357a_detach, +read : agilent_82357a_read, +write : agilent_82357a_write, +command : agilent_82357a_command, +take_control : agilent_82357a_take_control, +go_to_standby : agilent_82357a_go_to_standby, +request_system_control : agilent_82357a_request_system_control, +interface_clear : agilent_82357a_interface_clear, +remote_enable : agilent_82357a_remote_enable, +enable_eos : agilent_82357a_enable_eos, +disable_eos : agilent_82357a_disable_eos, +parallel_poll : agilent_82357a_parallel_poll, +parallel_poll_configure : agilent_82357a_parallel_poll_configure, +parallel_poll_response : agilent_82357a_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : agilent_82357a_line_status, +update_status : agilent_82357a_update_status, +primary_address : agilent_82357a_primary_address, +secondary_address : agilent_82357a_secondary_address, +serial_poll_response : agilent_82357a_serial_poll_response, +serial_poll_status : agilent_82357a_serial_poll_status, +t1_delay : agilent_82357a_t1_delay, +return_to_local : agilent_82357a_return_to_local, +no_7_bit_eos : 1, +skip_check_for_command_acceptors : 1 +}; + +// Table with the USB-devices: just now only testing IDs +static struct usb_device_id agilent_82357a_driver_device_table[] = { + {USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357A)}, + {USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357B)}, + {} /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, agilent_82357a_driver_device_table); + +static int agilent_82357a_driver_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + int i; + char *path; + static const int path_length = 1024; + struct usb_device *usb_dev; + + if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock)) + return -ERESTARTSYS; + usb_dev = usb_get_dev(interface_to_usbdev(interface)); + for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) { + if (!agilent_82357a_driver_interfaces[i]) { + agilent_82357a_driver_interfaces[i] = interface; + usb_set_intfdata(interface, NULL); + dev_dbg(&usb_dev->dev, "set bus interface %i to address 0x%p\n", + i, interface); + break; + } + } + if (i == MAX_NUM_82357A_INTERFACES) { + usb_put_dev(usb_dev); + mutex_unlock(&agilent_82357a_hotplug_lock); + dev_err(&usb_dev->dev, "%s: out of space in agilent_82357a_driver_interfaces[]\n", + __func__); + return -1; + } + path = kmalloc(path_length, GFP_KERNEL); + if (!path) { + usb_put_dev(usb_dev); + mutex_unlock(&agilent_82357a_hotplug_lock); + return -ENOMEM; + } + usb_make_path(usb_dev, path, path_length); + dev_info(&usb_dev->dev, "probe succeeded for path: %s\n", path); + kfree(path); + mutex_unlock(&agilent_82357a_hotplug_lock); + return 0; +} + +static void agilent_82357a_driver_disconnect(struct usb_interface *interface) +{ + int i; + struct usb_device *usb_dev = interface_to_usbdev(interface); + + mutex_lock(&agilent_82357a_hotplug_lock); + + for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) { + if (agilent_82357a_driver_interfaces[i] == interface) { + gpib_board_t *board = usb_get_intfdata(interface); + + if (board) { + struct agilent_82357a_priv *a_priv = board->private_data; + + if (a_priv) { + mutex_lock(&a_priv->control_alloc_lock); + mutex_lock(&a_priv->bulk_alloc_lock); + mutex_lock(&a_priv->interrupt_alloc_lock); + agilent_82357a_cleanup_urbs(a_priv); + a_priv->bus_interface = NULL; + mutex_unlock(&a_priv->interrupt_alloc_lock); + mutex_unlock(&a_priv->bulk_alloc_lock); + mutex_unlock(&a_priv->control_alloc_lock); + } + } + dev_dbg(&usb_dev->dev, "nulled agilent_82357a_driver_interfaces[%i]\n", i); + agilent_82357a_driver_interfaces[i] = NULL; + break; + } + } + if (i == MAX_NUM_82357A_INTERFACES) + dev_err(&usb_dev->dev, "unable to find interface in agilent_82357a_driver_interfaces[]? bug?\n"); + usb_put_dev(usb_dev); + + mutex_unlock(&agilent_82357a_hotplug_lock); +} + +static int agilent_82357a_driver_suspend(struct usb_interface *interface, pm_message_t message) +{ + int i, retval; + struct usb_device *usb_dev = interface_to_usbdev(interface); + + mutex_lock(&agilent_82357a_hotplug_lock); + + for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) { + if (agilent_82357a_driver_interfaces[i] == interface) { + gpib_board_t *board = usb_get_intfdata(interface); + + if (board) { + struct agilent_82357a_priv *a_priv = board->private_data; + + if (a_priv) { + agilent_82357a_abort(a_priv, 0); + agilent_82357a_abort(a_priv, 0); + retval = agilent_82357a_go_idle(board); + if (retval) { + dev_err(&usb_dev->dev, "%s: failed to go idle, retval=%i\n", + __func__, retval); + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; + } + mutex_lock(&a_priv->interrupt_alloc_lock); + agilent_82357a_cleanup_urbs(a_priv); + mutex_unlock(&a_priv->interrupt_alloc_lock); + dev_info(&usb_dev->dev, + "bus %d dev num %d gpib minor %d, agilent usb interface %i suspended\n", + usb_dev->bus->busnum, usb_dev->devnum, + board->minor, i); + } + } + break; + } + } + + mutex_unlock(&agilent_82357a_hotplug_lock); + + return 0; +} + +static int agilent_82357a_driver_resume(struct usb_interface *interface) +{ + struct usb_device *usb_dev = interface_to_usbdev(interface); + gpib_board_t *board; + int i, retval; + + mutex_lock(&agilent_82357a_hotplug_lock); + + for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) { + if (agilent_82357a_driver_interfaces[i] == interface) { + board = usb_get_intfdata(interface); + if (board) + break; + } + } + if (i == MAX_NUM_82357A_INTERFACES) + goto resume_exit; + + struct agilent_82357a_priv *a_priv = board->private_data; + + if (a_priv) { + if (a_priv->interrupt_urb) { + mutex_lock(&a_priv->interrupt_alloc_lock); + retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL); + if (retval) { + dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb, retval=%i\n", + __func__, retval); + mutex_unlock(&a_priv->interrupt_alloc_lock); + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; + } + mutex_unlock(&a_priv->interrupt_alloc_lock); + } + retval = agilent_82357a_init(board); + if (retval < 0) { + mutex_unlock(&agilent_82357a_hotplug_lock); + return retval; + } + // set/unset system controller + agilent_82357a_request_system_control(board, board->master); + // toggle ifc if master + if (board->master) { + agilent_82357a_interface_clear(board, 1); + usleep_range(200, 250); + agilent_82357a_interface_clear(board, 0); + } + // assert/unassert REN + agilent_82357a_remote_enable(board, a_priv->ren_state); + + dev_info(&usb_dev->dev, + "bus %d dev num %d gpib minor %d, agilent usb interface %i resumed\n", + usb_dev->bus->busnum, usb_dev->devnum, board->minor, i); + } + +resume_exit: + mutex_unlock(&agilent_82357a_hotplug_lock); + + return 0; +} + +static struct usb_driver agilent_82357a_bus_driver = { + .name = "agilent_82357a_gpib", + .probe = agilent_82357a_driver_probe, + .disconnect = agilent_82357a_driver_disconnect, + .suspend = agilent_82357a_driver_suspend, + .resume = agilent_82357a_driver_resume, + .id_table = agilent_82357a_driver_device_table, +}; + +static int __init agilent_82357a_init_module(void) +{ + int i; + + pr_info("agilent_82357a_gpib driver loading"); + for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) + agilent_82357a_driver_interfaces[i] = NULL; + usb_register(&agilent_82357a_bus_driver); + gpib_register_driver(&agilent_82357a_gpib_interface, THIS_MODULE); + + return 0; +} + +static void __exit agilent_82357a_exit_module(void) +{ + pr_info("agilent_82357a_gpib driver unloading"); + gpib_unregister_driver(&agilent_82357a_gpib_interface); + usb_deregister(&agilent_82357a_bus_driver); +} + +module_init(agilent_82357a_init_module); +module_exit(agilent_82357a_exit_module); diff --git a/drivers/staging/gpib/agilent_82357a/agilent_82357a.h b/drivers/staging/gpib/agilent_82357a/agilent_82357a.h new file mode 100644 index 0000000000000000000000000000000000000000..cdbc3ec5d8bd07e7b23ed9388a9c0be590b631f0 --- /dev/null +++ b/drivers/staging/gpib/agilent_82357a/agilent_82357a.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2004 by Frank Mori Hess * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "gpibP.h" +#include "tms9914.h" + +enum usb_vendor_ids { + USB_VENDOR_ID_AGILENT = 0x0957 +}; + +enum usb_device_ids { + USB_DEVICE_ID_AGILENT_82357A = 0x0107, + USB_DEVICE_ID_AGILENT_82357A_PREINIT = 0x0007, // device id before firmware is loaded + USB_DEVICE_ID_AGILENT_82357B = 0x0718, // device id before firmware is loaded + USB_DEVICE_ID_AGILENT_82357B_PREINIT = 0x0518, // device id before firmware is loaded +}; + +enum endpoint_addresses { + AGILENT_82357_CONTROL_ENDPOINT = 0x0, + AGILENT_82357_BULK_IN_ENDPOINT = 0x2, + AGILENT_82357A_BULK_OUT_ENDPOINT = 0x4, + AGILENT_82357A_INTERRUPT_IN_ENDPOINT = 0x6, + AGILENT_82357B_BULK_OUT_ENDPOINT = 0x6, + AGILENT_82357B_INTERRUPT_IN_ENDPOINT = 0x8, +}; + +enum bulk_commands { + DATA_PIPE_CMD_WRITE = 0x1, + DATA_PIPE_CMD_READ = 0x3, + DATA_PIPE_CMD_WR_REGS = 0x4, + DATA_PIPE_CMD_RD_REGS = 0x5 +}; + +enum agilent_82357a_read_flags { + ARF_END_ON_EOI = 0x1, + ARF_NO_ADDRESS = 0x2, + ARF_END_ON_EOS_CHAR = 0x4, + ARF_SPOLL = 0x8 +}; + +enum agilent_82357a_trailing_read_flags { + ATRF_EOI = 0x1, + ATRF_ATN = 0x2, + ATRF_IFC = 0x4, + ATRF_EOS = 0x8, + ATRF_ABORT = 0x10, + ATRF_COUNT = 0x20, + ATRF_DEAD_BUS = 0x40, + ATRF_UNADDRESSED = 0x80 +}; + +enum agilent_82357a_write_flags { + AWF_SEND_EOI = 0x1, + AWF_NO_FAST_TALKER_FIRST_BYTE = 0x2, + AWF_NO_FAST_TALKER = 0x4, + AWF_NO_ADDRESS = 0x8, + AWF_ATN = 0x10, + AWF_SEPARATE_HEADER = 0x80 +}; + +enum agilent_82357a_interrupt_flag_bit_numbers { + AIF_SRQ_BN = 0, + AIF_WRITE_COMPLETE_BN = 1, + AIF_READ_COMPLETE_BN = 2, +}; + +enum agilent_82357_error_codes { + UGP_SUCCESS = 0, + UGP_ERR_INVALID_CMD = 1, + UGP_ERR_INVALID_PARAM = 2, + UGP_ERR_INVALID_REG = 3, + UGP_ERR_GPIB_READ = 4, + UGP_ERR_GPIB_WRITE = 5, + UGP_ERR_FLUSHING = 6, + UGP_ERR_FLUSHING_ALREADY = 7, + UGP_ERR_UNSUPPORTED = 8, + UGP_ERR_OTHER = 9 +}; + +enum agilent_82357_control_values { + XFER_ABORT = 0xa0, + XFER_STATUS = 0xb0, +}; + +enum xfer_status_bits { + XS_COMPLETED = 0x1, + XS_READ = 0x2, +}; + +enum xfer_status_completion_bits { + XSC_EOI = 0x1, + XSC_ATN = 0x2, + XSC_IFC = 0x4, + XSC_EOS = 0x8, + XSC_ABORT = 0x10, + XSC_COUNT = 0x20, + XSC_DEAD_BUS = 0x40, + XSC_BUS_NOT_ADDRESSED = 0x80 +}; + +enum xfer_abort_type { + XA_FLUSH = 0x1 +}; + +#define STATUS_DATA_LEN 8 +#define INTERRUPT_BUF_LEN 8 + +struct agilent_82357a_urb_ctx { + struct semaphore complete; + unsigned timed_out : 1; +}; + +// struct which defines local data for each 82357 device +struct agilent_82357a_priv { + struct usb_interface *bus_interface; + unsigned short eos_char; + unsigned short eos_mode; + unsigned short hw_control_bits; + unsigned long interrupt_flags; + struct urb *bulk_urb; + struct urb *interrupt_urb; + u8 *interrupt_buffer; + struct mutex bulk_transfer_lock; // bulk transfer lock + struct mutex bulk_alloc_lock; // bulk transfer allocation lock + struct mutex interrupt_alloc_lock; // interrupt allocation lock + struct mutex control_alloc_lock; // control message allocation lock + struct timer_list bulk_timer; + struct agilent_82357a_urb_ctx context; + unsigned int bulk_out_endpoint; + unsigned int interrupt_in_endpoint; + unsigned is_cic : 1; + unsigned ren_state : 1; +}; + +struct agilent_82357a_register_pairlet { + short address; + unsigned short value; +}; + +enum firmware_registers { + HW_CONTROL = 0xa, + LED_CONTROL = 0xb, + RESET_TO_POWERUP = 0xc, + PROTOCOL_CONTROL = 0xd, + FAST_TALKER_T1 = 0xe +}; + +enum hardware_control_bits { + NOT_TI_RESET = 0x1, + SYSTEM_CONTROLLER = 0x2, + NOT_PARALLEL_POLL = 0x4, + OSCILLATOR_5V_ON = 0x8, + OUTPUT_5V_ON = 0x20, + CPLD_3V_ON = 0x80, +}; + +enum led_control_bits { + FIRMWARE_LED_CONTROL = 0x1, + FAIL_LED_ON = 0x20, + READY_LED_ON = 0x40, + ACCESS_LED_ON = 0x80 +}; + +enum reset_to_powerup_bits { + RESET_SPACEBALL = 0x1, // wait 2 millisec after sending +}; + +enum protocol_control_bits { + WRITE_COMPLETE_INTERRUPT_EN = 0x1, +}; + +static const int agilent_82357a_control_request = 0x4; + diff --git a/drivers/staging/gpib/cb7210/Makefile b/drivers/staging/gpib/cb7210/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..22e0214fc17dcae470d4693856007e81d631ca42 --- /dev/null +++ b/drivers/staging/gpib/cb7210/Makefile @@ -0,0 +1,4 @@ +ccflags-$(CONFIG_GPIB_PCMCIA) := -DGPIB_PCMCIA +obj-m += cb7210.o + + diff --git a/drivers/staging/gpib/cb7210/cb7210.c b/drivers/staging/gpib/cb7210/cb7210.c new file mode 100644 index 0000000000000000000000000000000000000000..63df7f3eb3f3e73d9ba448fa9778b4a65214ac50 --- /dev/null +++ b/drivers/staging/gpib/cb7210/cb7210.c @@ -0,0 +1,1556 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * Measurement Computing boards using cb7210.2 and cbi488.2 chips + * copyright : (C) 2001, 2002 by Frank Mori Hess + ***************************************************************************/ + +#include "cb7210.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gpib_pci_ids.h" +#include "quancom_pci.h" + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver Measurement Computing boards using cb7210.2 and cbi488.2"); + +static inline int have_fifo_word(const struct cb7210_priv *cb_priv) +{ + if (((cb7210_read_byte(cb_priv, HS_STATUS)) & + (HS_RX_MSB_NOT_EMPTY | HS_RX_LSB_NOT_EMPTY)) == + (HS_RX_MSB_NOT_EMPTY | HS_RX_LSB_NOT_EMPTY)) + return 1; + else + return 0; +} + +static inline void input_fifo_enable(gpib_board_t *board, int enable) +{ + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + + if (enable) { + cb_priv->in_fifo_half_full = 0; + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + + cb7210_write_byte(cb_priv, HS_RX_ENABLE | HS_TX_ENABLE | HS_CLR_SRQ_INT | + HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT | cb_priv->hs_mode_bits, + HS_MODE); + + cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK; + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE); + + cb7210_write_byte(cb_priv, irq_bits(cb_priv->irq), HS_INT_LEVEL); + + cb_priv->hs_mode_bits |= HS_RX_ENABLE; + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE); + } else { + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + + cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK; + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, nec7210_iobase(cb_priv) + + HS_MODE); + + clear_bit(READ_READY_BN, &nec_priv->state); + } + + spin_unlock_irqrestore(&board->spinlock, flags); +} + +static int fifo_read(gpib_board_t *board, struct cb7210_priv *cb_priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + ssize_t retval = 0; + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + int hs_status; + u16 word; + unsigned long flags; + + *bytes_read = 0; + if (cb_priv->fifo_iobase == 0) { + pr_err("cb7210: fifo iobase is zero!\n"); + return -EIO; + } + *end = 0; + if (length <= cb7210_fifo_size) { + pr_err("cb7210: bug! %s with length < fifo size\n", __func__); + return -EINVAL; + } + + input_fifo_enable(board, 1); + + while (*bytes_read + cb7210_fifo_size < length) { + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI); + + if (wait_event_interruptible(board->wait, + (cb_priv->in_fifo_half_full && + have_fifo_word(cb_priv)) || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_warn("cb7210: fifo half full wait interrupted\n"); + retval = -ERESTARTSYS; + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + break; + } + + spin_lock_irqsave(&board->spinlock, flags); + + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + + while (have_fifo_word(cb_priv)) { + word = inw(cb_priv->fifo_iobase + DIR); + buffer[(*bytes_read)++] = word & 0xff; + buffer[(*bytes_read)++] = (word >> 8) & 0xff; + } + + cb_priv->in_fifo_half_full = 0; + + hs_status = cb7210_read_byte(cb_priv, HS_STATUS); + + spin_unlock_irqrestore(&board->spinlock, flags); + + if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) { + *end = 1; + break; + } + if (hs_status & HS_FIFO_FULL) + break; + if (test_bit(TIMO_NUM, &board->status)) { + retval = -ETIMEDOUT; + break; + } + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) { + retval = -EINTR; + break; + } + } + hs_status = cb7210_read_byte(cb_priv, HS_STATUS); + if (hs_status & HS_RX_LSB_NOT_EMPTY) { + word = inw(cb_priv->fifo_iobase + DIR); + buffer[(*bytes_read)++] = word & 0xff; + } + + input_fifo_enable(board, 0); + + if (wait_event_interruptible(board->wait, + test_bit(READ_READY_BN, &nec_priv->state) || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_warn("cb7210: fifo half full wait interrupted\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + if (test_bit(READ_READY_BN, &nec_priv->state)) { + nec7210_set_handshake_mode(board, nec_priv, HR_HLDA); + buffer[(*bytes_read)++] = nec7210_read_data_in(board, nec_priv, end); + } + + return retval; +} + +int cb7210_accel_read(gpib_board_t *board, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + ssize_t retval; + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + size_t num_bytes; + + *bytes_read = 0; + // deal with limitations of fifo + if (length < cb7210_fifo_size + 3 || (nec_priv->auxa_bits & HR_REOS)) + return cb7210_read(board, buffer, length, end, bytes_read); + *end = 0; + + nec7210_release_rfd_holdoff(board, nec_priv); + + if (wait_event_interruptible(board->wait, + test_bit(READ_READY_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_warn("cb7210: read ready wait interrupted\n"); + return -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + return -ETIMEDOUT; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) + return -EINTR; + + nec7210_set_handshake_mode(board, nec_priv, HR_HLDE); + buffer[(*bytes_read)++] = nec7210_read_data_in(board, nec_priv, end); + if (*end) + return 0; + + nec7210_release_rfd_holdoff(board, nec_priv); + + retval = fifo_read(board, cb_priv, &buffer[*bytes_read], length - *bytes_read - 1, + end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + return retval; + if (*end) + return 0; + + retval = cb7210_read(board, &buffer[*bytes_read], 1, end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + return retval; + + return 0; +} + +static int output_fifo_empty(const struct cb7210_priv *cb_priv) +{ + if ((cb7210_read_byte(cb_priv, HS_STATUS) & (HS_TX_MSB_NOT_EMPTY | HS_TX_LSB_NOT_EMPTY)) + == 0) + return 1; + else + return 0; +} + +static inline void output_fifo_enable(gpib_board_t *board, int enable) +{ + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + + if (enable) { + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO); + + cb7210_write_byte(cb_priv, HS_RX_ENABLE | HS_TX_ENABLE | HS_CLR_SRQ_INT | + HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT | cb_priv->hs_mode_bits, + HS_MODE); + + cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK; + cb_priv->hs_mode_bits |= HS_TX_ENABLE; + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE); + + cb7210_write_byte(cb_priv, irq_bits(cb_priv->irq), HS_INT_LEVEL); + + clear_bit(WRITE_READY_BN, &nec_priv->state); + + } else { + cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK; + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE); + + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0); + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, HR_DOIE); + } + + spin_unlock_irqrestore(&board->spinlock, flags); +} + +static int fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + size_t count = 0; + ssize_t retval = 0; + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + unsigned int num_bytes, i; + unsigned long flags; + + *bytes_written = 0; + if (cb_priv->fifo_iobase == 0) { + pr_err("cb7210: fifo iobase is zero!\n"); + return -EINVAL; + } + if (length == 0) + return 0; + + clear_bit(DEV_CLEAR_BN, &nec_priv->state); + clear_bit(BUS_ERROR_BN, &nec_priv->state); + + output_fifo_enable(board, 1); + + while (count < length) { + // wait until byte is ready to be sent + if (wait_event_interruptible(board->wait, + cb_priv->out_fifo_half_empty || + output_fifo_empty(cb_priv) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(BUS_ERROR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_warn("cb7210: fifo wait interrupted\n"); + retval = -ERESTARTSYS; + break; + } + if (test_bit(TIMO_NUM, &board->status) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(BUS_ERROR_BN, &nec_priv->state)) + break; + + if (output_fifo_empty(cb_priv)) + num_bytes = cb7210_fifo_size - cb7210_fifo_width; + else + num_bytes = cb7210_fifo_size / 2; + if (num_bytes + count > length) + num_bytes = length - count; + if (num_bytes % cb7210_fifo_width) { + pr_err("cb7210: bug! %s with odd number of bytes\n", __func__); + retval = -EINVAL; + break; + } + + spin_lock_irqsave(&board->spinlock, flags); + for (i = 0; i < num_bytes / cb7210_fifo_width; i++) { + u16 word; + + word = buffer[count++] & 0xff; + word |= (buffer[count++] << 8) & 0xff00; + outw(word, cb_priv->fifo_iobase + CDOR); + } + cb_priv->out_fifo_half_empty = 0; + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits | + HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT, HS_MODE); + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE); + spin_unlock_irqrestore(&board->spinlock, flags); + } + // wait last byte has been sent + if (wait_event_interruptible(board->wait, + output_fifo_empty(cb_priv) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(BUS_ERROR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_err("cb7210: wait for last byte interrupted\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_bit(BUS_ERROR_BN, &nec_priv->state)) + retval = -EIO; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + + output_fifo_enable(board, 0); + + *bytes_written = count; + return retval; +} + +int cb7210_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + unsigned long fast_chunk_size, leftover; + int retval; + size_t num_bytes; + + *bytes_written = 0; + if (length > cb7210_fifo_width) + fast_chunk_size = length - 1; + else + fast_chunk_size = 0; + fast_chunk_size -= fast_chunk_size % cb7210_fifo_width; + leftover = length - fast_chunk_size; + + retval = fifo_write(board, buffer, fast_chunk_size, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + + retval = nec7210_write(board, nec_priv, buffer + fast_chunk_size, leftover, + send_eoi, &num_bytes); + *bytes_written += num_bytes; + return retval; +} + +int cb7210_line_status(const gpib_board_t *board) +{ + int status = ValidALL; + int bsr_bits; + struct cb7210_priv *cb_priv; + struct nec7210_priv *nec_priv; + + cb_priv = board->private_data; + nec_priv = &cb_priv->nec7210_priv; + + bsr_bits = cb7210_paged_read_byte(cb_priv, BUS_STATUS, BUS_STATUS_PAGE); + + if ((bsr_bits & BSR_REN_BIT) == 0) + status |= BusREN; + if ((bsr_bits & BSR_IFC_BIT) == 0) + status |= BusIFC; + if ((bsr_bits & BSR_SRQ_BIT) == 0) + status |= BusSRQ; + if ((bsr_bits & BSR_EOI_BIT) == 0) + status |= BusEOI; + if ((bsr_bits & BSR_NRFD_BIT) == 0) + status |= BusNRFD; + if ((bsr_bits & BSR_NDAC_BIT) == 0) + status |= BusNDAC; + if ((bsr_bits & BSR_DAV_BIT) == 0) + status |= BusDAV; + if ((bsr_bits & BSR_ATN_BIT) == 0) + status |= BusATN; + + return status; +} + +unsigned int cb7210_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + unsigned int retval; + + retval = nec7210_t1_delay(board, nec_priv, nano_sec); + + if (nano_sec <= 350) { + write_byte(nec_priv, AUX_HI_SPEED, AUXMR); + retval = 350; + } else { + write_byte(nec_priv, AUX_LO_SPEED, AUXMR); + } + return retval; +} + +irqreturn_t cb7210_locked_internal_interrupt(gpib_board_t *board); + +/* + * GPIB interrupt service routines + */ + +irqreturn_t cb_pci_interrupt(int irq, void *arg) +{ + int bits; + gpib_board_t *board = arg; + struct cb7210_priv *priv = board->private_data; + + // first task check if this is really our interrupt in a shared irq environment + switch (priv->pci_chip) { + case PCI_CHIP_AMCC_S5933: + if ((inl(priv->amcc_iobase + INTCSR_REG) & + (INBOX_INTR_CS_BIT | INTR_ASSERTED_BIT)) == 0) + return IRQ_NONE; + + // read incoming mailbox to clear mailbox full flag + inl(priv->amcc_iobase + INCOMING_MAILBOX_REG(3)); + // clear amccs5933 interrupt + bits = INBOX_FULL_INTR_BIT | INBOX_BYTE_BITS(3) | + INBOX_SELECT_BITS(3) | INBOX_INTR_CS_BIT; + outl(bits, priv->amcc_iobase + INTCSR_REG); + break; + case PCI_CHIP_QUANCOM: + if ((inb(nec7210_iobase(priv) + QUANCOM_IRQ_CONTROL_STATUS_REG) & + QUANCOM_IRQ_ASSERTED_BIT)) + outb(QUANCOM_IRQ_ENABLE_BIT, nec7210_iobase(priv) + + QUANCOM_IRQ_CONTROL_STATUS_REG); + break; + default: + break; + } + return cb7210_locked_internal_interrupt(arg); +} + +irqreturn_t cb7210_internal_interrupt(gpib_board_t *board) +{ + int hs_status, status1, status2; + struct cb7210_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + int clear_bits; + + if ((priv->hs_mode_bits & HS_ENABLE_MASK)) { + status1 = 0; + hs_status = cb7210_read_byte(priv, HS_STATUS); + } else { + hs_status = 0; + status1 = read_byte(nec_priv, ISR1); + } + status2 = read_byte(nec_priv, ISR2); + nec7210_interrupt_have_status(board, nec_priv, status1, status2); + + dev_dbg(board->gpib_dev, "cb7210: status 0x%x, mode 0x%x\n", hs_status, priv->hs_mode_bits); + + clear_bits = 0; + + if (hs_status & HS_HALF_FULL) { + if (priv->hs_mode_bits & HS_TX_ENABLE) + priv->out_fifo_half_empty = 1; + else if (priv->hs_mode_bits & HS_RX_ENABLE) + priv->in_fifo_half_full = 1; + clear_bits |= HS_CLR_HF_INT; + } + + if (hs_status & HS_SRQ_INT) { + set_bit(SRQI_NUM, &board->status); + clear_bits |= HS_CLR_SRQ_INT; + } + + if ((hs_status & HS_EOI_INT)) { + clear_bits |= HS_CLR_EOI_EMPTY_INT; + set_bit(RECEIVED_END_BN, &nec_priv->state); + if ((nec_priv->auxa_bits & HR_HANDSHAKE_MASK) == HR_HLDE) + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + } + + if ((priv->hs_mode_bits & HS_TX_ENABLE) && + (hs_status & (HS_TX_MSB_NOT_EMPTY | HS_TX_LSB_NOT_EMPTY)) == 0) + clear_bits |= HS_CLR_EOI_EMPTY_INT; + + if (clear_bits) { + cb7210_write_byte(priv, priv->hs_mode_bits | clear_bits, HS_MODE); + cb7210_write_byte(priv, priv->hs_mode_bits, HS_MODE); + wake_up_interruptible(&board->wait); + } + + return IRQ_HANDLED; +} + +irqreturn_t cb7210_locked_internal_interrupt(gpib_board_t *board) +{ + unsigned long flags; + irqreturn_t retval; + + spin_lock_irqsave(&board->spinlock, flags); + retval = cb7210_internal_interrupt(board); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +irqreturn_t cb7210_interrupt(int irq, void *arg) +{ + return cb7210_internal_interrupt(arg); +} + +static int cb_pci_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int cb_isa_attach(gpib_board_t *board, const gpib_board_config_t *config); + +static void cb_pci_detach(gpib_board_t *board); +static void cb_isa_detach(gpib_board_t *board); + +// wrappers for interface functions +int cb7210_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); +} + +int cb7210_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); +} + +int cb7210_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); +} + +int cb7210_take_control(gpib_board_t *board, int synchronous) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_take_control(board, &priv->nec7210_priv, synchronous); +} + +int cb7210_go_to_standby(gpib_board_t *board) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_go_to_standby(board, &priv->nec7210_priv); +} + +void cb7210_request_system_control(gpib_board_t *board, int request_control) +{ + struct cb7210_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + + if (request_control) + priv->hs_mode_bits |= HS_SYS_CONTROL; + else + priv->hs_mode_bits &= ~HS_SYS_CONTROL; + + cb7210_write_byte(priv, priv->hs_mode_bits, HS_MODE); + nec7210_request_system_control(board, nec_priv, request_control); +} + +void cb7210_interface_clear(gpib_board_t *board, int assert) +{ + struct cb7210_priv *priv = board->private_data; + + nec7210_interface_clear(board, &priv->nec7210_priv, assert); +} + +void cb7210_remote_enable(gpib_board_t *board, int enable) +{ + struct cb7210_priv *priv = board->private_data; + + nec7210_remote_enable(board, &priv->nec7210_priv, enable); +} + +int cb7210_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); +} + +void cb7210_disable_eos(gpib_board_t *board) +{ + struct cb7210_priv *priv = board->private_data; + + nec7210_disable_eos(board, &priv->nec7210_priv); +} + +unsigned int cb7210_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); +} + +int cb7210_primary_address(gpib_board_t *board, unsigned int address) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_primary_address(board, &priv->nec7210_priv, address); +} + +int cb7210_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); +} + +int cb7210_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_parallel_poll(board, &priv->nec7210_priv, result); +} + +void cb7210_parallel_poll_configure(gpib_board_t *board, uint8_t configuration) +{ + struct cb7210_priv *priv = board->private_data; + + nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration); +} + +void cb7210_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct cb7210_priv *priv = board->private_data; + + nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); +} + +void cb7210_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct cb7210_priv *priv = board->private_data; + + nec7210_serial_poll_response(board, &priv->nec7210_priv, status); +} + +uint8_t cb7210_serial_poll_status(gpib_board_t *board) +{ + struct cb7210_priv *priv = board->private_data; + + return nec7210_serial_poll_status(board, &priv->nec7210_priv); +} + +void cb7210_return_to_local(gpib_board_t *board) +{ + struct cb7210_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + + write_byte(nec_priv, AUX_RTL2, AUXMR); + udelay(1); + write_byte(nec_priv, AUX_RTL, AUXMR); +} + +gpib_interface_t cb_pci_unaccel_interface = { +name: "cbi_pci_unaccel", +attach : cb_pci_attach, +detach : cb_pci_detach, +read : cb7210_read, +write : cb7210_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +gpib_interface_t cb_pci_accel_interface = { +name: "cbi_pci_accel", +attach : cb_pci_attach, +detach : cb_pci_detach, +read : cb7210_accel_read, +write : cb7210_accel_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +gpib_interface_t cb_pci_interface = { +name: "cbi_pci", +attach : cb_pci_attach, +detach : cb_pci_detach, +read : cb7210_accel_read, +write : cb7210_accel_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +gpib_interface_t cb_isa_unaccel_interface = { +name: "cbi_isa_unaccel", +attach : cb_isa_attach, +detach : cb_isa_detach, +read : cb7210_read, +write : cb7210_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +gpib_interface_t cb_isa_interface = { +name: "cbi_isa", +attach : cb_isa_attach, +detach : cb_isa_detach, +read : cb7210_accel_read, +write : cb7210_accel_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +gpib_interface_t cb_isa_accel_interface = { +name: "cbi_isa_accel", +attach : cb_isa_attach, +detach : cb_isa_detach, +read : cb7210_accel_read, +write : cb7210_accel_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +static int cb7210_allocate_private(gpib_board_t *board) +{ + struct cb7210_priv *priv; + + board->private_data = kmalloc(sizeof(struct cb7210_priv), GFP_KERNEL); + if (!board->private_data) + return -1; + priv = board->private_data; + memset(priv, 0, sizeof(struct cb7210_priv)); + init_nec7210_private(&priv->nec7210_priv); + return 0; +} + +void cb7210_generic_detach(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +// generic part of attach functions shared by all cb7210 boards +int cb7210_generic_attach(gpib_board_t *board) +{ + struct cb7210_priv *cb_priv; + struct nec7210_priv *nec_priv; + + board->status = 0; + + if (cb7210_allocate_private(board)) + return -ENOMEM; + cb_priv = board->private_data; + nec_priv = &cb_priv->nec7210_priv; + nec_priv->read_byte = nec7210_locking_ioport_read_byte; + nec_priv->write_byte = nec7210_locking_ioport_write_byte; + nec_priv->offset = cb7210_reg_offset; + nec_priv->type = CB7210; + return 0; +} + +int cb7210_init(struct cb7210_priv *cb_priv, gpib_board_t *board) +{ + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + + cb7210_write_byte(cb_priv, HS_RESET7210, HS_INT_LEVEL); + cb7210_write_byte(cb_priv, irq_bits(cb_priv->irq), HS_INT_LEVEL); + + nec7210_board_reset(nec_priv, board); + cb7210_write_byte(cb_priv, HS_TX_ENABLE | HS_RX_ENABLE | HS_CLR_SRQ_INT | + HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT, HS_MODE); + + cb_priv->hs_mode_bits = HS_HF_INT_EN; + cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE); + + write_byte(nec_priv, AUX_LO_SPEED, AUXMR); + /* set clock register for maximum (20 MHz) driving frequency + * ICR should be set to clock in megahertz (1-15) and to zero + * for clocks faster than 15 MHz (max 20MHz) + */ + write_byte(nec_priv, ICR | 0, AUXMR); + + if (cb_priv->pci_chip == PCI_CHIP_QUANCOM) { + /* change interrupt polarity */ + nec_priv->auxb_bits |= HR_INV; + write_byte(nec_priv, nec_priv->auxb_bits, AUXMR); + } + nec7210_board_online(nec_priv, board); + + /* poll so we can detect assertion of ATN */ + if (gpib_request_pseudo_irq(board, cb_pci_interrupt)) { + pr_err("pc2_gpib: failed to allocate pseudo_irq\n"); + return -1; + } + return 0; +} + +int cb_pci_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct cb7210_priv *cb_priv; + struct nec7210_priv *nec_priv; + int isr_flags = 0; + int bits; + int retval; + + retval = cb7210_generic_attach(board); + if (retval) + return retval; + + cb_priv = board->private_data; + nec_priv = &cb_priv->nec7210_priv; + + cb_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_CBOARDS, + PCI_DEVICE_ID_CBOARDS_PCI_GPIB, NULL); + if (cb_priv->pci_device) + cb_priv->pci_chip = PCI_CHIP_AMCC_S5933; + if (!cb_priv->pci_device) { + cb_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_CBOARDS, + PCI_DEVICE_ID_CBOARDS_CPCI_GPIB, NULL); + if (cb_priv->pci_device) + cb_priv->pci_chip = PCI_CHIP_AMCC_S5933; + } + if (!cb_priv->pci_device) { + cb_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_QUANCOM, + PCI_DEVICE_ID_QUANCOM_GPIB, NULL); + if (cb_priv->pci_device) { + cb_priv->pci_chip = PCI_CHIP_QUANCOM; + nec_priv->offset = 4; + } + } + if (!cb_priv->pci_device) { + pr_warn("cb7210: no supported boards found.\n"); + return -1; + } + + if (pci_enable_device(cb_priv->pci_device)) { + pr_err("cb7210: error enabling pci device\n"); + return -1; + } + + if (pci_request_regions(cb_priv->pci_device, "cb7210")) + return -1; + switch (cb_priv->pci_chip) { + case PCI_CHIP_AMCC_S5933: + cb_priv->amcc_iobase = pci_resource_start(cb_priv->pci_device, 0); + nec_priv->iobase = (void *)(pci_resource_start(cb_priv->pci_device, 1)); + cb_priv->fifo_iobase = pci_resource_start(cb_priv->pci_device, 2); + break; + case PCI_CHIP_QUANCOM: + nec_priv->iobase = (void *)(pci_resource_start(cb_priv->pci_device, 0)); + cb_priv->fifo_iobase = (unsigned long)nec_priv->iobase; + break; + default: + pr_err("cb7210: bug! unhandled pci_chip=%i\n", cb_priv->pci_chip); + return -EIO; + } + isr_flags |= IRQF_SHARED; + if (request_irq(cb_priv->pci_device->irq, cb_pci_interrupt, isr_flags, "cb7210", board)) { + pr_err("cb7210: can't request IRQ %d\n", cb_priv->pci_device->irq); + return -1; + } + cb_priv->irq = cb_priv->pci_device->irq; + + switch (cb_priv->pci_chip) { + case PCI_CHIP_AMCC_S5933: + // make sure mailbox flags are clear + inl(cb_priv->amcc_iobase + INCOMING_MAILBOX_REG(3)); + // enable interrupts on amccs5933 chip + bits = INBOX_FULL_INTR_BIT | INBOX_BYTE_BITS(3) | INBOX_SELECT_BITS(3) | + INBOX_INTR_CS_BIT; + outl(bits, cb_priv->amcc_iobase + INTCSR_REG); + break; + default: + break; + } + return cb7210_init(cb_priv, board); +} + +void cb_pci_detach(gpib_board_t *board) +{ + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (cb_priv) { + gpib_free_pseudo_irq(board); + nec_priv = &cb_priv->nec7210_priv; + if (cb_priv->irq) { + // disable amcc interrupts + outl(0, cb_priv->amcc_iobase + INTCSR_REG); + free_irq(cb_priv->irq, board); + } + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + pci_release_regions(cb_priv->pci_device); + } + if (cb_priv->pci_device) + pci_dev_put(cb_priv->pci_device); + } + cb7210_generic_detach(board); +} + +int cb_isa_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + int isr_flags = 0; + struct cb7210_priv *cb_priv; + struct nec7210_priv *nec_priv; + unsigned int bits; + int retval; + + retval = cb7210_generic_attach(board); + if (retval) + return retval; + cb_priv = board->private_data; + nec_priv = &cb_priv->nec7210_priv; + if (request_region((unsigned long)config->ibbase, cb7210_iosize, "cb7210") == 0) { + pr_err("gpib: ioports starting at 0x%p are already in use\n", config->ibbase); + return -EIO; + } + nec_priv->iobase = config->ibbase; + cb_priv->fifo_iobase = nec7210_iobase(cb_priv); + + bits = irq_bits(config->ibirq); + if (bits == 0) + pr_err("board incapable of using irq %i, try 2-5, 7, 10, or 11\n", config->ibirq); + + // install interrupt handler + if (request_irq(config->ibirq, cb7210_interrupt, isr_flags, "cb7210", board)) { + pr_err("gpib: can't request IRQ %d\n", config->ibirq); + return -EBUSY; + } + cb_priv->irq = config->ibirq; + + return cb7210_init(cb_priv, board); +} + +void cb_isa_detach(gpib_board_t *board) +{ + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (cb_priv) { + gpib_free_pseudo_irq(board); + nec_priv = &cb_priv->nec7210_priv; + if (cb_priv->irq) + free_irq(cb_priv->irq, board); + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + release_region(nec7210_iobase(cb_priv), cb7210_iosize); + } + } + cb7210_generic_detach(board); +} + +static int cb7210_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return 0; +} + +static const struct pci_device_id cb7210_pci_table[] = { + {PCI_VENDOR_ID_CBOARDS, PCI_DEVICE_ID_CBOARDS_PCI_GPIB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + {PCI_VENDOR_ID_CBOARDS, PCI_DEVICE_ID_CBOARDS_CPCI_GPIB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + {PCI_VENDOR_ID_QUANCOM, PCI_DEVICE_ID_QUANCOM_GPIB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, cb7210_pci_table); + +static struct pci_driver cb7210_pci_driver = { + .name = "cb7210", + .id_table = cb7210_pci_table, + .probe = &cb7210_pci_probe +}; + +/*************************************************************************** + * Support for computer boards pcmcia-gpib card + * + * Based on gpib PCMCIA client driver written by Claus Schroeter + * (clausi@chemie.fu-berlin.de), which was adapted from the + * pcmcia skeleton example (presumably David Hinds) + ***************************************************************************/ + +#ifdef GPIB_PCMCIA + +#include +#include +#include +#include + +#include +#include + +/* + * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If + * you do not define PCMCIA_DEBUG at all, all the debug code will be + * left out. If you compile with PCMCIA_DEBUG=0, the debug code will + * be present but disabled -- but it can then be enabled for specific + * modules at load time with a 'pc_debug=#' option to insmod. + */ + +#define PCMCIA_DEBUG 1 + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +#define DEBUG(n, args...) do {if (pc_debug > (n)) pr_debug(args); } while (0) +#else +#define DEBUG(args...) +#endif + +/* + * The event() function is this driver's Card Services event handler. + * It will be called by Card Services when an appropriate card status + * event is received. The config() and release() entry points are + * used to configure or release a socket, in response to card insertion + * and ejection events. They are invoked from the gpib event + * handler. + */ + +static int cb_gpib_config(struct pcmcia_device *link); +static void cb_gpib_release(struct pcmcia_device *link); +static int cb_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config); +static void cb_pcmcia_detach(gpib_board_t *board); + +/* + * A linked list of "instances" of the gpib device. Each actual + * PCMCIA card corresponds to one device instance, and is described + * by one dev_link_t structure (defined in ds.h). + * + * You may not want to use a linked list for this -- for example, the + * memory card driver uses an array of dev_link_t pointers, where minor + * device numbers are used to derive the corresponding array index. + */ + +static struct pcmcia_device *curr_dev; + +/* + * A dev_link_t structure has fields for most things that are needed + * to keep track of a socket, but there will usually be some device + * specific information that also needs to be kept track of. The + * 'priv' pointer in a dev_link_t structure can be used to point to + * a device-specific private data structure, like this. + * + * A driver needs to provide a dev_node_t structure for each device + * on a card. In some cases, there is only one device per card (for + * example, ethernet cards, modems). In other cases, there may be + * many actual or logical devices (SCSI adapters, memory cards with + * multiple partitions). The dev_node_t structures need to be kept + * in a linked list starting at the 'dev' field of a dev_link_t + * structure. We allocate them in the card's private data structure, + * because they generally can't be allocated dynamically. + */ + +struct local_info { + struct pcmcia_device *p_dev; + gpib_board_t *dev; +}; + +/* + * gpib_attach() creates an "instance" of the driver, allocating + * local data structures for one device. The device is registered + * with Card Services. + * + * The dev_link structure is initialized, but we don't actually + * configure the card at this point -- we wait until we receive a + * card insertion event. + */ + +static int cb_gpib_probe(struct pcmcia_device *link) +{ + struct local_info *info; + +// int ret, i; + + DEBUG(0, "%s(0x%p)\n", __func__, link); + + /* Allocate space for private device-specific data */ + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->p_dev = link; + link->priv = info; + + /* The io structure describes IO port mapping */ + link->resource[0]->end = 16; + link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + link->resource[1]->end = 16; + link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; + link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; + link->io_lines = 10; + + /* General socket configuration */ + link->config_flags = CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; + link->config_index = 1; + link->config_regs = PRESENT_OPTION; + + /* Register with Card Services */ + curr_dev = link; + return cb_gpib_config(link); +} /* gpib_attach */ + +/* + * This deletes a driver "instance". The device is de-registered + * with Card Services. If it has been released, all local data + * structures are freed. Otherwise, the structures will be freed + * when the device is released. + */ + +static void cb_gpib_remove(struct pcmcia_device *link) +{ + struct local_info *info = link->priv; + //struct gpib_board_t *dev = info->dev; + + DEBUG(0, "%s(0x%p)\n", __func__, link); + + if (info->dev) + cb_pcmcia_detach(info->dev); + cb_gpib_release(link); + + //free_netdev(dev); + kfree(info); +} + +static int cb_gpib_config_iteration(struct pcmcia_device *link, void *priv_data) +{ + return pcmcia_request_io(link); +} + +/* + * gpib_config() is scheduled to run after a CARD_INSERTION event + * is received, to configure the PCMCIA socket, and to make the + * ethernet device available to the system. + */ + +static int cb_gpib_config(struct pcmcia_device *link) +{ + struct pcmcia_device *handle; + struct local_info *dev; + int retval; + + handle = link; + dev = link->priv; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + retval = pcmcia_loop_config(link, &cb_gpib_config_iteration, NULL); + if (retval) { + dev_warn(&link->dev, "no configuration found\n"); + cb_gpib_release(link); + return -ENODEV; + } + + DEBUG(0, "gpib_cs: manufacturer: 0x%x card: 0x%x\n", link->manf_id, link->card_id); + + /* + * This actually configures the PCMCIA socket -- setting up + * the I/O windows and the interrupt mapping. + */ + retval = pcmcia_enable_device(link); + if (retval) { + dev_warn(&link->dev, "pcmcia_enable_device failed\n"); + cb_gpib_release(link); + return -ENODEV; + } + + pr_info("gpib device loaded\n"); + return 0; +} /* gpib_config */ + +/* + * After a card is removed, gpib_release() will unregister the net + * device, and release the PCMCIA configuration. If the device is + * still open, this will be postponed until it is closed. + */ + +static void cb_gpib_release(struct pcmcia_device *link) +{ + DEBUG(0, "%s(0x%p)\n", __func__, link); + pcmcia_disable_device(link); +} + +static int cb_gpib_suspend(struct pcmcia_device *link) +{ + //struct local_info *info = link->priv; + //struct gpib_board_t *dev = info->dev; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + if (link->open) + pr_warn("Device still open ???\n"); + //netif_device_detach(dev); + + return 0; +} + +static int cb_gpib_resume(struct pcmcia_device *link) +{ + //struct local_info *info = link->priv; + //struct gpib_board_t *dev = info->dev; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + /*if (link->open) { + * ni_gpib_probe(dev); / really? + * printk("Gpib resumed ???\n"); + * //netif_device_attach(dev); + * + */ + return cb_gpib_config(link); +} + +/*====================================================================*/ + +static struct pcmcia_device_id cb_pcmcia_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0005), + PCMCIA_DEVICE_NULL +}; +MODULE_DEVICE_TABLE(pcmcia, cb_pcmcia_ids); + +static struct pcmcia_driver cb_gpib_cs_driver = { + .owner = THIS_MODULE, + .drv = { .name = "cb_gpib_cs", }, + .id_table = cb_pcmcia_ids, + .probe = cb_gpib_probe, + .remove = cb_gpib_remove, + .suspend = cb_gpib_suspend, + .resume = cb_gpib_resume, +}; + +int cb_pcmcia_init_module(void) +{ + pcmcia_register_driver(&cb_gpib_cs_driver); + return 0; +} + +void cb_pcmcia_cleanup_module(void) +{ + DEBUG(0, "cb_gpib_cs: unloading\n"); + pcmcia_unregister_driver(&cb_gpib_cs_driver); +} + +gpib_interface_t cb_pcmcia_unaccel_interface = { +name: "cbi_pcmcia_unaccel", +attach : cb_pcmcia_attach, +detach : cb_pcmcia_detach, +read : cb7210_read, +write : cb7210_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +gpib_interface_t cb_pcmcia_interface = { +name: "cbi_pcmcia", +attach : cb_pcmcia_attach, +detach : cb_pcmcia_detach, +read : cb7210_accel_read, +write : cb7210_accel_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +gpib_interface_t cb_pcmcia_accel_interface = { +name: "cbi_pcmcia_accel", +attach : cb_pcmcia_attach, +detach : cb_pcmcia_detach, +read : cb7210_accel_read, +write : cb7210_accel_write, +command : cb7210_command, +take_control : cb7210_take_control, +go_to_standby : cb7210_go_to_standby, +request_system_control : cb7210_request_system_control, +interface_clear : cb7210_interface_clear, +remote_enable : cb7210_remote_enable, +enable_eos : cb7210_enable_eos, +disable_eos : cb7210_disable_eos, +parallel_poll : cb7210_parallel_poll, +parallel_poll_configure : cb7210_parallel_poll_configure, +parallel_poll_response : cb7210_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : cb7210_line_status, +update_status : cb7210_update_status, +primary_address : cb7210_primary_address, +secondary_address : cb7210_secondary_address, +serial_poll_response : cb7210_serial_poll_response, +serial_poll_status : cb7210_serial_poll_status, +t1_delay : cb7210_t1_delay, +return_to_local : cb7210_return_to_local, +}; + +int cb_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct cb7210_priv *cb_priv; + struct nec7210_priv *nec_priv; + int retval; + + if (!curr_dev) { + pr_err("no cb pcmcia cards found\n"); + return -1; + } + + retval = cb7210_generic_attach(board); + if (retval) + return retval; + + cb_priv = board->private_data; + nec_priv = &cb_priv->nec7210_priv; + + if (request_region(curr_dev->resource[0]->start, resource_size(curr_dev->resource[0]), + "cb7210") == 0) { + pr_err("gpib: ioports starting at 0x%lx are already in use\n", + (unsigned long)curr_dev->resource[0]->start); + return -EIO; + } + nec_priv->iobase = (void *)(unsigned long)curr_dev->resource[0]->start; + cb_priv->fifo_iobase = curr_dev->resource[0]->start; + + if (request_irq(curr_dev->irq, cb7210_interrupt, IRQF_SHARED, + "cb7210", board)) { + pr_err("cb7210: failed to request IRQ %d\n", curr_dev->irq); + return -1; + } + cb_priv->irq = curr_dev->irq; + + return cb7210_init(cb_priv, board); +} + +void cb_pcmcia_detach(gpib_board_t *board) +{ + struct cb7210_priv *cb_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (cb_priv) { + nec_priv = &cb_priv->nec7210_priv; + gpib_free_pseudo_irq(board); + if (cb_priv->irq) + free_irq(cb_priv->irq, board); + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + release_region(nec7210_iobase(cb_priv), cb7210_iosize); + } + } + cb7210_generic_detach(board); +} + +#endif /* GPIB_PCMCIA */ + +static int __init cb7210_init_module(void) +{ + int err = 0; + int result; + + result = pci_register_driver(&cb7210_pci_driver); + if (result) { + pr_err("cb7210: pci_driver_register failed!\n"); + return result; + } + + gpib_register_driver(&cb_pci_interface, THIS_MODULE); + gpib_register_driver(&cb_isa_interface, THIS_MODULE); + gpib_register_driver(&cb_pci_accel_interface, THIS_MODULE); + gpib_register_driver(&cb_pci_unaccel_interface, THIS_MODULE); + gpib_register_driver(&cb_isa_accel_interface, THIS_MODULE); + gpib_register_driver(&cb_isa_unaccel_interface, THIS_MODULE); + +#ifdef GPIB__PCMCIA + gpib_register_driver(&cb_pcmcia_interface, THIS_MODULE); + gpib_register_driver(&cb_pcmcia_accel_interface, THIS_MODULE); + gpib_register_driver(&cb_pcmcia_unaccel_interface, THIS_MODULE); + err += cb_pcmcia_init_module(); +#endif + if (err) + return -1; + + return 0; +} + +static void __exit cb7210_exit_module(void) +{ + gpib_unregister_driver(&cb_pci_interface); + gpib_unregister_driver(&cb_isa_interface); + gpib_unregister_driver(&cb_pci_accel_interface); + gpib_unregister_driver(&cb_pci_unaccel_interface); + gpib_unregister_driver(&cb_isa_accel_interface); + gpib_unregister_driver(&cb_isa_unaccel_interface); +#ifdef GPIB_PCMCIA + gpib_unregister_driver(&cb_pcmcia_interface); + gpib_unregister_driver(&cb_pcmcia_accel_interface); + gpib_unregister_driver(&cb_pcmcia_unaccel_interface); + cb_pcmcia_cleanup_module(); +#endif + + pci_unregister_driver(&cb7210_pci_driver); +} + +module_init(cb7210_init_module); +module_exit(cb7210_exit_module); diff --git a/drivers/staging/gpib/cb7210/cb7210.h b/drivers/staging/gpib/cb7210/cb7210.h new file mode 100644 index 0000000000000000000000000000000000000000..4ad976de2b68400a37408e289b51ee2c76d05a80 --- /dev/null +++ b/drivers/staging/gpib/cb7210/cb7210.h @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#include "nec7210.h" +#include "gpibP.h" +#include "amccs5933.h" + +#include +#include + +enum { + PCI_DEVICE_ID_CBOARDS_PCI_GPIB = 0x6, + PCI_DEVICE_ID_CBOARDS_CPCI_GPIB = 0xe, +}; + +enum pci_chip { + PCI_CHIP_NONE = 0, + PCI_CHIP_AMCC_S5933, + PCI_CHIP_QUANCOM +}; + +// struct which defines private_data for cb7210 boards +struct cb7210_priv { + struct nec7210_priv nec7210_priv; + struct pci_dev *pci_device; + // base address of amccs5933 pci chip + unsigned long amcc_iobase; + unsigned long fifo_iobase; + unsigned int irq; + enum pci_chip pci_chip; + u8 hs_mode_bits; + unsigned out_fifo_half_empty : 1; + unsigned in_fifo_half_full : 1; +}; + +// interfaces +extern gpib_interface_t cb_pcmcia_interface; +extern gpib_interface_t cb_pcmcia_accel_interface; +extern gpib_interface_t cb_pcmcia_unaccel_interface; + +// interrupt service routines +irqreturn_t cb_pci_interrupt(int irq, void *arg); +irqreturn_t cb7210_interrupt(int irq, void *arg); +irqreturn_t cb7210_internal_interrupt(gpib_board_t *board); + +// interface functions +int cb7210_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read); +int cb7210_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read); +int cb7210_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written); +int cb7210_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written); +int cb7210_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written); +int cb7210_take_control(gpib_board_t *board, int synchronous); +int cb7210_go_to_standby(gpib_board_t *board); +void cb7210_request_system_control(gpib_board_t *board, int request_control); +void cb7210_interface_clear(gpib_board_t *board, int assert); +void cb7210_remote_enable(gpib_board_t *board, int enable); +int cb7210_enable_eos(gpib_board_t *board, uint8_t eos_byte, + int compare_8_bits); +void cb7210_disable_eos(gpib_board_t *board); +unsigned int cb7210_update_status(gpib_board_t *board, unsigned int clear_mask); +int cb7210_primary_address(gpib_board_t *board, unsigned int address); +int cb7210_secondary_address(gpib_board_t *board, unsigned int address, + int enable); +int cb7210_parallel_poll(gpib_board_t *board, uint8_t *result); +void cb7210_serial_poll_response(gpib_board_t *board, uint8_t status); +uint8_t cb7210_serial_poll_status(gpib_board_t *board); +void cb7210_parallel_poll_configure(gpib_board_t *board, uint8_t configuration); +void cb7210_parallel_poll_response(gpib_board_t *board, int ist); +int cb7210_line_status(const gpib_board_t *board); +unsigned int cb7210_t1_delay(gpib_board_t *board, unsigned int nano_sec); +void cb7210_return_to_local(gpib_board_t *board); + +// utility functions +void cb7210_generic_detach(gpib_board_t *board); +int cb7210_generic_attach(gpib_board_t *board); +int cb7210_init(struct cb7210_priv *priv, gpib_board_t *board); + +// pcmcia init/cleanup +int cb_pcmcia_init_module(void); +void cb_pcmcia_cleanup_module(void); + +// pci-gpib register offset +static const int cb7210_reg_offset = 1; + +// uses 10 ioports +static const int cb7210_iosize = 10; + +// fifo size in bytes +static const int cb7210_fifo_size = 2048; +static const int cb7210_fifo_width = 2; + +// cb7210 specific registers and bits +enum cb7210_regs { + BUS_STATUS = 0x7, +}; + +enum cb7210_page_in { + BUS_STATUS_PAGE = 1, +}; + +enum hs_regs { + //write registers + HS_MODE = 0x8, /* HS_MODE register */ + HS_INT_LEVEL = 0x9, /* HS_INT_LEVEL register */ + //read registers + HS_STATUS = 0x8, /* HS_STATUS register */ +}; + +static inline unsigned long nec7210_iobase(const struct cb7210_priv *cb_priv) +{ + return (unsigned long)(cb_priv->nec7210_priv.iobase); +} + +static inline int cb7210_page_in_bits(unsigned int page) +{ + return 0x50 | (page & 0xf); +} + +static inline uint8_t cb7210_paged_read_byte(struct cb7210_priv *cb_priv, + unsigned int register_num, unsigned int page) +{ + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + u8 retval; + unsigned long flags; + + spin_lock_irqsave(&nec_priv->register_page_lock, flags); + outb(cb7210_page_in_bits(page), nec7210_iobase(cb_priv) + AUXMR * nec_priv->offset); + udelay(1); + retval = inb(nec7210_iobase(cb_priv) + register_num * nec_priv->offset); + spin_unlock_irqrestore(&nec_priv->register_page_lock, flags); + return retval; +} + +// don't use for register_num < 8, since it doesn't lock +static inline uint8_t cb7210_read_byte(const struct cb7210_priv *cb_priv, + enum hs_regs register_num) +{ + const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + u8 retval; + + retval = inb(nec7210_iobase(cb_priv) + register_num * nec_priv->offset); + return retval; +} + +static inline void cb7210_paged_write_byte(struct cb7210_priv *cb_priv, uint8_t data, + unsigned int register_num, unsigned int page) +{ + struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + unsigned long flags; + + spin_lock_irqsave(&nec_priv->register_page_lock, flags); + outb(cb7210_page_in_bits(page), nec7210_iobase(cb_priv) + AUXMR * nec_priv->offset); + udelay(1); + outb(data, nec7210_iobase(cb_priv) + register_num * nec_priv->offset); + spin_unlock_irqrestore(&nec_priv->register_page_lock, flags); +} + +// don't use for register_num < 8, since it doesn't lock +static inline void cb7210_write_byte(const struct cb7210_priv *cb_priv, uint8_t data, + enum hs_regs register_num) +{ + const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv; + + outb(data, nec7210_iobase(cb_priv) + register_num * nec_priv->offset); +} + +enum bus_status_bits { + BSR_ATN_BIT = 0x1, + BSR_EOI_BIT = 0x2, + BSR_SRQ_BIT = 0x4, + BSR_IFC_BIT = 0x8, + BSR_REN_BIT = 0x10, + BSR_DAV_BIT = 0x20, + BSR_NRFD_BIT = 0x40, + BSR_NDAC_BIT = 0x80, +}; + +/* CBI 488.2 HS control */ + +/* when both bit 0 and 1 are set, it + * 1 clears the transmit state machine to an initial condition + * 2 clears any residual interrupts left latched on cbi488.2 + * 3 resets all control bits in HS_MODE to zero + * 4 enables TX empty interrupts + * when both bit 0 and 1 are zero, then the high speed mode is disabled + */ +enum hs_mode_bits { + HS_ENABLE_MASK = 0x3, + HS_TX_ENABLE = (1 << 0), + HS_RX_ENABLE = (1 << 1), + HS_HF_INT_EN = (1 << 3), + HS_CLR_SRQ_INT = (1 << 4), + HS_CLR_EOI_EMPTY_INT = (1 << 5), + HS_CLR_HF_INT = (1 << 6), + HS_SYS_CONTROL = (1 << 7), +}; + +/* CBI 488.2 status */ +enum hs_status_bits { + HS_FIFO_FULL = (1 << 0), + HS_HALF_FULL = (1 << 1), + HS_SRQ_INT = (1 << 2), + HS_EOI_INT = (1 << 3), + HS_TX_MSB_NOT_EMPTY = (1 << 4), + HS_RX_MSB_NOT_EMPTY = (1 << 5), + HS_TX_LSB_NOT_EMPTY = (1 << 6), + HS_RX_LSB_NOT_EMPTY = (1 << 7), +}; + +/* CBI488.2 hs_int_level register */ +enum hs_int_level_bits { + HS_RESET7210 = (1 << 7), +}; + +static inline unsigned int irq_bits(unsigned int irq) +{ + switch (irq) { + case 2: + case 3: + case 4: + case 5: + return irq - 1; + case 7: + return 0x5; + case 10: + return 0x6; + case 11: + return 0x7; + default: + return 0; + } +} + +enum cb7210_aux_cmds { +/* AUX_RTL2 is an undocumented aux command which causes cb7210 to assert + * (and keep asserted) local rtl message. This is used in conjunction + * with the (stupid) cb7210 implementation + * of the normal nec7210 AUX_RTL aux command, which + * causes the rtl message to toggle between on and off. + */ + AUX_RTL2 = 0xd, + AUX_LO_SPEED = 0x40, + AUX_HI_SPEED = 0x41, +}; diff --git a/drivers/staging/gpib/cec/Makefile b/drivers/staging/gpib/cec/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f4638628ff294599e223f2531943dadad0d6ee55 --- /dev/null +++ b/drivers/staging/gpib/cec/Makefile @@ -0,0 +1,3 @@ + +obj-m += cec_gpib.o + diff --git a/drivers/staging/gpib/cec/cec.h b/drivers/staging/gpib/cec/cec.h new file mode 100644 index 0000000000000000000000000000000000000000..352cf83d8328f77ca079f4bb8842f01220b83efc --- /dev/null +++ b/drivers/staging/gpib/cec/cec.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#include "nec7210.h" +#include "gpibP.h" +#include "plx9050.h" + +struct cec_priv { + struct nec7210_priv nec7210_priv; + struct pci_dev *pci_device; + // base address for plx9052 pci chip + unsigned long plx_iobase; + unsigned int irq; +}; + +// interfaces +extern gpib_interface_t cec_pci_interface; +extern gpib_interface_t cec_pcmcia_interface; + +// interface functions +int cec_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read); +int cec_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written); +int cec_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written); +int cec_take_control(gpib_board_t *board, int synchronous); +int cec_go_to_standby(gpib_board_t *board); +void cec_request_system_control(gpib_board_t *board, int request_control); +void cec_interface_clear(gpib_board_t *board, int assert); +void cec_remote_enable(gpib_board_t *board, int enable); +int cec_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits); +void cec_disable_eos(gpib_board_t *board); +unsigned int cec_update_status(gpib_board_t *board, unsigned int clear_mask); +int cec_primary_address(gpib_board_t *board, unsigned int address); +int cec_secondary_address(gpib_board_t *board, unsigned int address, int enable); +int cec_parallel_poll(gpib_board_t *board, uint8_t *result); +void cec_parallel_poll_configure(gpib_board_t *board, uint8_t configuration); +void cec_parallel_poll_response(gpib_board_t *board, int ist); +void cec_serial_poll_response(gpib_board_t *board, uint8_t status); +void cec_return_to_local(gpib_board_t *board); + +// interrupt service routines +irqreturn_t cec_interrupt(int irq, void *arg); + +// utility functions +void cec_free_private(gpib_board_t *board); +int cec_generic_attach(gpib_board_t *board); +void cec_init(struct cec_priv *priv, const gpib_board_t *board); + +// offset between consecutive nec7210 registers +static const int cec_reg_offset = 1; diff --git a/drivers/staging/gpib/cec/cec_gpib.c b/drivers/staging/gpib/cec/cec_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..3dc933deb40180bcf4c5b19e021e016283692d5a --- /dev/null +++ b/drivers/staging/gpib/cec/cec_gpib.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#include "cec.h" +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for CEC PCI and PCMCIA boards"); + +/* + * GPIB interrupt service routines + */ + +irqreturn_t cec_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + struct cec_priv *priv = board->private_data; + unsigned long flags; + irqreturn_t retval; + + spin_lock_irqsave(&board->spinlock, flags); + retval = nec7210_interrupt(board, &priv->nec7210_priv); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +#define CEC_VENDOR_ID 0x12fc +#define CEC_DEV_ID 0x5cec +#define CEC_SUBID 0x9050 + +static int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config); + +static void cec_pci_detach(gpib_board_t *board); + +// wrappers for interface functions +int cec_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); +} + +int cec_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); +} + +int cec_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); +} + +int cec_take_control(gpib_board_t *board, int synchronous) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_take_control(board, &priv->nec7210_priv, synchronous); +} + +int cec_go_to_standby(gpib_board_t *board) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_go_to_standby(board, &priv->nec7210_priv); +} + +void cec_request_system_control(gpib_board_t *board, int request_control) +{ + struct cec_priv *priv = board->private_data; + + nec7210_request_system_control(board, &priv->nec7210_priv, request_control); +} + +void cec_interface_clear(gpib_board_t *board, int assert) +{ + struct cec_priv *priv = board->private_data; + + nec7210_interface_clear(board, &priv->nec7210_priv, assert); +} + +void cec_remote_enable(gpib_board_t *board, int enable) +{ + struct cec_priv *priv = board->private_data; + + nec7210_remote_enable(board, &priv->nec7210_priv, enable); +} + +int cec_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); +} + +void cec_disable_eos(gpib_board_t *board) +{ + struct cec_priv *priv = board->private_data; + + nec7210_disable_eos(board, &priv->nec7210_priv); +} + +unsigned int cec_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); +} + +int cec_primary_address(gpib_board_t *board, unsigned int address) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_primary_address(board, &priv->nec7210_priv, address); +} + +int cec_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); +} + +int cec_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_parallel_poll(board, &priv->nec7210_priv, result); +} + +void cec_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + struct cec_priv *priv = board->private_data; + + nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config); +} + +void cec_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct cec_priv *priv = board->private_data; + + nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); +} + +void cec_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct cec_priv *priv = board->private_data; + + nec7210_serial_poll_response(board, &priv->nec7210_priv, status); +} + +static uint8_t cec_serial_poll_status(gpib_board_t *board) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_serial_poll_status(board, &priv->nec7210_priv); +} + +static unsigned int cec_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct cec_priv *priv = board->private_data; + + return nec7210_t1_delay(board, &priv->nec7210_priv, nano_sec); +} + +void cec_return_to_local(gpib_board_t *board) +{ + struct cec_priv *priv = board->private_data; + + nec7210_return_to_local(board, &priv->nec7210_priv); +} + +gpib_interface_t cec_pci_interface = { +name: "cec_pci", +attach : cec_pci_attach, +detach : cec_pci_detach, +read : cec_read, +write : cec_write, +command : cec_command, +take_control : cec_take_control, +go_to_standby : cec_go_to_standby, +request_system_control : cec_request_system_control, +interface_clear : cec_interface_clear, +remote_enable : cec_remote_enable, +enable_eos : cec_enable_eos, +disable_eos : cec_disable_eos, +parallel_poll : cec_parallel_poll, +parallel_poll_configure : cec_parallel_poll_configure, +parallel_poll_response : cec_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : NULL, //XXX +update_status : cec_update_status, +primary_address : cec_primary_address, +secondary_address : cec_secondary_address, +serial_poll_response : cec_serial_poll_response, +serial_poll_status : cec_serial_poll_status, +t1_delay : cec_t1_delay, +return_to_local : cec_return_to_local, +}; + +static int cec_allocate_private(gpib_board_t *board) +{ + struct cec_priv *priv; + + board->private_data = kmalloc(sizeof(struct cec_priv), GFP_KERNEL); + if (!board->private_data) + return -1; + priv = board->private_data; + memset(priv, 0, sizeof(struct cec_priv)); + init_nec7210_private(&priv->nec7210_priv); + return 0; +} + +void cec_free_private(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +int cec_generic_attach(gpib_board_t *board) +{ + struct cec_priv *cec_priv; + struct nec7210_priv *nec_priv; + + board->status = 0; + + if (cec_allocate_private(board)) + return -ENOMEM; + cec_priv = board->private_data; + nec_priv = &cec_priv->nec7210_priv; + nec_priv->read_byte = nec7210_ioport_read_byte; + nec_priv->write_byte = nec7210_ioport_write_byte; + nec_priv->offset = cec_reg_offset; + nec_priv->type = NEC7210; // guess + return 0; +} + +void cec_init(struct cec_priv *cec_priv, const gpib_board_t *board) +{ + struct nec7210_priv *nec_priv = &cec_priv->nec7210_priv; + + nec7210_board_reset(nec_priv, board); + + /* set internal counter register for 8 MHz input clock */ + write_byte(nec_priv, ICR | 8, AUXMR); + + nec7210_board_online(nec_priv, board); +} + +int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct cec_priv *cec_priv; + struct nec7210_priv *nec_priv; + int isr_flags = 0; + int retval; + + retval = cec_generic_attach(board); + if (retval) + return retval; + + cec_priv = board->private_data; + nec_priv = &cec_priv->nec7210_priv; + + // find board + cec_priv->pci_device = NULL; + while ((cec_priv->pci_device = + gpib_pci_get_device(config, CEC_VENDOR_ID, + CEC_DEV_ID, cec_priv->pci_device))) { + // check for board with plx9050 controller + if (cec_priv->pci_device->subsystem_device == CEC_SUBID) + break; + } + if (!cec_priv->pci_device) { + pr_err("gpib: no cec PCI board found\n"); + return -1; + } + + if (pci_enable_device(cec_priv->pci_device)) { + pr_err("error enabling pci device\n"); + return -1; + } + + if (pci_request_regions(cec_priv->pci_device, "cec-gpib")) + return -1; + + cec_priv->plx_iobase = pci_resource_start(cec_priv->pci_device, 1); + pr_info(" plx9050 base address 0x%lx\n", cec_priv->plx_iobase); + nec_priv->iobase = (void *)(pci_resource_start(cec_priv->pci_device, 3)); + pr_info(" nec7210 base address 0x%p\n", nec_priv->iobase); + + isr_flags |= IRQF_SHARED; + if (request_irq(cec_priv->pci_device->irq, cec_interrupt, isr_flags, "pci-gpib", board)) { + pr_err("gpib: can't request IRQ %d\n", cec_priv->pci_device->irq); + return -1; + } + cec_priv->irq = cec_priv->pci_device->irq; + if (gpib_request_pseudo_irq(board, cec_interrupt)) { + pr_err("cec: failed to allocate pseudo irq\n"); + return -1; + } + cec_init(cec_priv, board); + + // enable interrupts on plx chip + outl(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR1_POLARITY_BIT | PLX9050_PCI_INTR_EN_BIT, + cec_priv->plx_iobase + PLX9050_INTCSR_REG); + + return 0; +} + +void cec_pci_detach(gpib_board_t *board) +{ + struct cec_priv *cec_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (cec_priv) { + nec_priv = &cec_priv->nec7210_priv; + gpib_free_pseudo_irq(board); + if (cec_priv->irq) { + // disable plx9050 interrupts + outl(0, cec_priv->plx_iobase + PLX9050_INTCSR_REG); + free_irq(cec_priv->irq, board); + } + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + pci_release_regions(cec_priv->pci_device); + } + if (cec_priv->pci_device) + pci_dev_put(cec_priv->pci_device); + } + cec_free_private(board); +} + +static int cec_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return 0; +} + +static const struct pci_device_id cec_pci_table[] = { + {CEC_VENDOR_ID, CEC_DEV_ID, PCI_ANY_ID, CEC_SUBID, 0, 0, 0 }, + {0} +}; +MODULE_DEVICE_TABLE(pci, cec_pci_table); + +static struct pci_driver cec_pci_driver = { + .name = "cec_gpib", + .id_table = cec_pci_table, + .probe = &cec_pci_probe +}; + +static int __init cec_init_module(void) +{ + int result; + + result = pci_register_driver(&cec_pci_driver); + if (result) { + pr_err("cec_gpib: pci_driver_register failed!\n"); + return result; + } + + gpib_register_driver(&cec_pci_interface, THIS_MODULE); + + return 0; +} + +static void cec_exit_module(void) +{ + gpib_unregister_driver(&cec_pci_interface); + + pci_unregister_driver(&cec_pci_driver); +} + +module_init(cec_init_module); +module_exit(cec_exit_module); diff --git a/drivers/staging/gpib/common/Makefile b/drivers/staging/gpib/common/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0c4c77bea75b3e14c8c79f2210ac057f0dc93589 --- /dev/null +++ b/drivers/staging/gpib/common/Makefile @@ -0,0 +1,6 @@ + +obj-m += gpib_common.o + +gpib_common-objs := gpib_os.o iblib.o + + diff --git a/drivers/staging/gpib/common/gpib_os.c b/drivers/staging/gpib/common/gpib_os.c new file mode 100644 index 0000000000000000000000000000000000000000..405237d8cb479f25a01e6988f13ee47c8ffed822 --- /dev/null +++ b/drivers/staging/gpib/common/gpib_os.c @@ -0,0 +1,2328 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2001, 2004 by Frank Mori Hess + *************************************************************************** + */ + +#include "ibsys.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB base support"); +MODULE_ALIAS_CHARDEV_MAJOR(GPIB_CODE); + +static int board_type_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, unsigned long arg); +static int read_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, + unsigned long arg); +static int write_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, + unsigned long arg); +static int command_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, + unsigned long arg); +static int open_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg); +static int close_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg); +static int serial_poll_ioctl(gpib_board_t *board, unsigned long arg); +static int wait_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, unsigned long arg); +static int parallel_poll_ioctl(gpib_board_t *board, unsigned long arg); +static int online_ioctl(gpib_board_t *board, unsigned long arg); +static int remote_enable_ioctl(gpib_board_t *board, unsigned long arg); +static int take_control_ioctl(gpib_board_t *board, unsigned long arg); +static int line_status_ioctl(gpib_board_t *board, unsigned long arg); +static int pad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg); +static int sad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg); +static int eos_ioctl(gpib_board_t *board, unsigned long arg); +static int request_service_ioctl(gpib_board_t *board, unsigned long arg); +static int request_service2_ioctl(gpib_board_t *board, unsigned long arg); +static int iobase_ioctl(gpib_board_config_t *config, unsigned long arg); +static int irq_ioctl(gpib_board_config_t *config, unsigned long arg); +static int dma_ioctl(gpib_board_config_t *config, unsigned long arg); +static int autospoll_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg); +static int mutex_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg); +static int timeout_ioctl(gpib_board_t *board, unsigned long arg); +static int status_bytes_ioctl(gpib_board_t *board, unsigned long arg); +static int board_info_ioctl(const gpib_board_t *board, unsigned long arg); +static int ppc_ioctl(gpib_board_t *board, unsigned long arg); +static int set_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg); +static int get_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg); +static int query_board_rsv_ioctl(gpib_board_t *board, unsigned long arg); +static int interface_clear_ioctl(gpib_board_t *board, unsigned long arg); +static int select_pci_ioctl(gpib_board_config_t *config, unsigned long arg); +static int select_device_path_ioctl(gpib_board_config_t *config, unsigned long arg); +static int event_ioctl(gpib_board_t *board, unsigned long arg); +static int request_system_control_ioctl(gpib_board_t *board, unsigned long arg); +static int t1_delay_ioctl(gpib_board_t *board, unsigned long arg); + +static int cleanup_open_devices(gpib_file_private_t *file_priv, gpib_board_t *board); + +static int pop_gpib_event_nolock(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type); + +/* + * Timer functions + */ + +/* Watchdog timeout routine */ + +static void watchdog_timeout(struct timer_list *t) +{ + gpib_board_t *board = from_timer(board, t, timer); + + set_bit(TIMO_NUM, &board->status); + wake_up_interruptible(&board->wait); +} + +/* install timer interrupt handler */ +void os_start_timer(gpib_board_t *board, unsigned int usec_timeout) +/* Starts the timeout task */ +{ + if (timer_pending(&board->timer)) { + pr_err("gpib: bug! timer already running?\n"); + return; + } + clear_bit(TIMO_NUM, &board->status); + + if (usec_timeout > 0) { + board->timer.function = watchdog_timeout; + /* set number of ticks */ + mod_timer(&board->timer, jiffies + usec_to_jiffies(usec_timeout)); + } +} + +void os_remove_timer(gpib_board_t *board) +/* Removes the timeout task */ +{ + if (timer_pending(&board->timer)) + del_timer_sync(&board->timer); +} + +int io_timed_out(gpib_board_t *board) +{ + if (test_bit(TIMO_NUM, &board->status)) + return 1; + return 0; +} + +void writeb_wrapper(unsigned int value, void *address) +{ + writeb(value, address); +}; +EXPORT_SYMBOL(writeb_wrapper); + +void writew_wrapper(unsigned int value, void *address) +{ + writew(value, address); +}; +EXPORT_SYMBOL(writew_wrapper); + +unsigned int readb_wrapper(void *address) +{ + return readb(address); +}; +EXPORT_SYMBOL(readb_wrapper); + +unsigned int readw_wrapper(void *address) +{ + return readw(address); +}; +EXPORT_SYMBOL(readw_wrapper); + +#ifdef CONFIG_HAS_IOPORT +void outb_wrapper(unsigned int value, void *address) +{ + outb(value, (unsigned long)(address)); +}; +EXPORT_SYMBOL(outb_wrapper); + +void outw_wrapper(unsigned int value, void *address) +{ + outw(value, (unsigned long)(address)); +}; +EXPORT_SYMBOL(outw_wrapper); + +unsigned int inb_wrapper(void *address) +{ + return inb((unsigned long)(address)); +}; +EXPORT_SYMBOL(inb_wrapper); + +unsigned int inw_wrapper(void *address) +{ + return inw((unsigned long)(address)); +}; +EXPORT_SYMBOL(inw_wrapper); +#endif + +/* this is a function instead of a constant because of Suse + * defining HZ to be a function call to get_hz() + */ +static inline int pseudo_irq_period(void) +{ + return (HZ + 99) / 100; +} + +static void pseudo_irq_handler(struct timer_list *t) +{ + struct gpib_pseudo_irq *pseudo_irq = from_timer(pseudo_irq, t, timer); + + if (pseudo_irq->handler) + pseudo_irq->handler(0, pseudo_irq->board); + else + pr_err("gpib: bug! pseudo_irq.handler is NULL\n"); + + if (atomic_read(&pseudo_irq->active)) + mod_timer(&pseudo_irq->timer, jiffies + pseudo_irq_period()); +} + +int gpib_request_pseudo_irq(gpib_board_t *board, irqreturn_t (*handler)(int, void *)) +{ + if (timer_pending(&board->pseudo_irq.timer) || board->pseudo_irq.handler) { + pr_err("gpib: only one pseudo interrupt per board allowed\n"); + return -1; + } + + board->pseudo_irq.handler = handler; + board->pseudo_irq.timer.function = pseudo_irq_handler; + board->pseudo_irq.board = board; + + atomic_set(&board->pseudo_irq.active, 1); + + mod_timer(&board->pseudo_irq.timer, jiffies + pseudo_irq_period()); + + return 0; +} +EXPORT_SYMBOL(gpib_request_pseudo_irq); + +void gpib_free_pseudo_irq(gpib_board_t *board) +{ + atomic_set(&board->pseudo_irq.active, 0); + + del_timer_sync(&board->pseudo_irq.timer); + board->pseudo_irq.handler = NULL; +} +EXPORT_SYMBOL(gpib_free_pseudo_irq); + +static const unsigned int serial_timeout = 1000000; + +unsigned int num_status_bytes(const gpib_status_queue_t *dev) +{ + if (!dev) + return 0; + return dev->num_status_bytes; +} + +// push status byte onto back of status byte fifo +int push_status_byte(gpib_board_t *board, gpib_status_queue_t *device, u8 poll_byte) +{ + struct list_head *head = &device->status_bytes; + status_byte_t *status; + static const unsigned int max_num_status_bytes = 1024; + int retval; + + if (num_status_bytes(device) >= max_num_status_bytes) { + u8 lost_byte; + + device->dropped_byte = 1; + retval = pop_status_byte(board, device, &lost_byte); + if (retval < 0) + return retval; + } + + status = kmalloc(sizeof(status_byte_t), GFP_KERNEL); + if (!status) + return -ENOMEM; + + INIT_LIST_HEAD(&status->list); + status->poll_byte = poll_byte; + + list_add_tail(&status->list, head); + + device->num_status_bytes++; + + dev_dbg(board->gpib_dev, "pushed status byte 0x%x, %i in queue\n", + (int)poll_byte, num_status_bytes(device)); + + return 0; +} + +// pop status byte from front of status byte fifo +int pop_status_byte(gpib_board_t *board, gpib_status_queue_t *device, u8 *poll_byte) +{ + struct list_head *head = &device->status_bytes; + struct list_head *front = head->next; + status_byte_t *status; + + if (num_status_bytes(device) == 0) + return -EIO; + + if (front == head) + return -EIO; + + if (device->dropped_byte) { + device->dropped_byte = 0; + return -EPIPE; + } + + status = list_entry(front, status_byte_t, list); + *poll_byte = status->poll_byte; + + list_del(front); + kfree(status); + + device->num_status_bytes--; + + dev_dbg(board->gpib_dev, "popped status byte 0x%x, %i in queue\n", + (int)*poll_byte, num_status_bytes(device)); + + return 0; +} + +gpib_status_queue_t *get_gpib_status_queue(gpib_board_t *board, unsigned int pad, int sad) +{ + gpib_status_queue_t *device; + struct list_head *list_ptr; + const struct list_head *head = &board->device_list; + + for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) { + device = list_entry(list_ptr, gpib_status_queue_t, list); + if (gpib_address_equal(device->pad, device->sad, pad, sad)) + return device; + } + + return NULL; +} + +int get_serial_poll_byte(gpib_board_t *board, unsigned int pad, int sad, unsigned int usec_timeout, + uint8_t *poll_byte) +{ + gpib_status_queue_t *device; + + dev_dbg(board->gpib_dev, "%s:()\n", __func__); + + device = get_gpib_status_queue(board, pad, sad); + if (num_status_bytes(device)) + return pop_status_byte(board, device, poll_byte); + else + return dvrsp(board, pad, sad, usec_timeout, poll_byte); +} + +int autopoll_all_devices(gpib_board_t *board) +{ + int retval; + + dev_dbg(board->gpib_dev, "entering %s()\n", __func__); + if (mutex_lock_interruptible(&board->user_mutex)) + return -ERESTARTSYS; + if (mutex_lock_interruptible(&board->big_gpib_mutex)) { + mutex_unlock(&board->user_mutex); + return -ERESTARTSYS; + } + + dev_dbg(board->gpib_dev, "autopoll has board lock\n"); + + retval = serial_poll_all(board, serial_timeout); + if (retval < 0) { + mutex_unlock(&board->big_gpib_mutex); + mutex_unlock(&board->user_mutex); + return retval; + } + + dev_dbg(board->gpib_dev, "%s complete\n", __func__); + /* need to wake wait queue in case someone is + * waiting on RQS + */ + wake_up_interruptible(&board->wait); + mutex_unlock(&board->big_gpib_mutex); + mutex_unlock(&board->user_mutex); + + return retval; +} + +static int setup_serial_poll(gpib_board_t *board, unsigned int usec_timeout) +{ + u8 cmd_string[8]; + int i; + size_t bytes_written; + int ret; + + dev_dbg(board->gpib_dev, "entering %s()\n", __func__); + + os_start_timer(board, usec_timeout); + ret = ibcac(board, 1, 1); + if (ret < 0) { + os_remove_timer(board); + return ret; + } + + i = 0; + cmd_string[i++] = UNL; + cmd_string[i++] = MLA(board->pad); /* controller's listen address */ + if (board->sad >= 0) + cmd_string[i++] = MSA(board->sad); + cmd_string[i++] = SPE; //serial poll enable + + ret = board->interface->command(board, cmd_string, i, &bytes_written); + if (ret < 0 || bytes_written < i) { + pr_err("gpib: failed to setup serial poll\n"); + os_remove_timer(board); + return -EIO; + } + os_remove_timer(board); + + return 0; +} + +static int read_serial_poll_byte(gpib_board_t *board, unsigned int pad, + int sad, unsigned int usec_timeout, uint8_t *result) +{ + u8 cmd_string[8]; + int end_flag; + int ret; + int i; + size_t nbytes; + + dev_dbg(board->gpib_dev, "entering %s(), pad=%i sad=%i\n", __func__, pad, sad); + + os_start_timer(board, usec_timeout); + ret = ibcac(board, 1, 1); + if (ret < 0) { + os_remove_timer(board); + return ret; + } + + i = 0; + // send talk address + cmd_string[i++] = MTA(pad); + if (sad >= 0) + cmd_string[i++] = MSA(sad); + + ret = board->interface->command(board, cmd_string, i, &nbytes); + if (ret < 0 || nbytes < i) { + pr_err("gpib: failed to setup serial poll\n"); + os_remove_timer(board); + return -EIO; + } + + ibgts(board); + + // read poll result + ret = board->interface->read(board, result, 1, &end_flag, &nbytes); + if (ret < 0 || nbytes < 1) { + pr_err("gpib: serial poll failed\n"); + os_remove_timer(board); + return -EIO; + } + os_remove_timer(board); + + return 0; +} + +static int cleanup_serial_poll(gpib_board_t *board, unsigned int usec_timeout) +{ + u8 cmd_string[8]; + int ret; + size_t bytes_written; + + dev_dbg(board->gpib_dev, "entering %s()\n", __func__); + + os_start_timer(board, usec_timeout); + ret = ibcac(board, 1, 1); + if (ret < 0) { + os_remove_timer(board); + return ret; + } + + cmd_string[0] = SPD; /* disable serial poll bytes */ + cmd_string[1] = UNT; + ret = board->interface->command(board, cmd_string, 2, &bytes_written); + if (ret < 0 || bytes_written < 2) { + pr_err("gpib: failed to disable serial poll\n"); + os_remove_timer(board); + return -EIO; + } + os_remove_timer(board); + + return 0; +} + +static int serial_poll_single(gpib_board_t *board, unsigned int pad, int sad, + unsigned int usec_timeout, uint8_t *result) +{ + int retval, cleanup_retval; + + retval = setup_serial_poll(board, usec_timeout); + if (retval < 0) + return retval; + retval = read_serial_poll_byte(board, pad, sad, usec_timeout, result); + cleanup_retval = cleanup_serial_poll(board, usec_timeout); + if (retval < 0) + return retval; + if (cleanup_retval < 0) + return retval; + + return 0; +} + +int serial_poll_all(gpib_board_t *board, unsigned int usec_timeout) +{ + int retval = 0; + struct list_head *cur; + const struct list_head *head = NULL; + gpib_status_queue_t *device; + u8 result; + unsigned int num_bytes = 0; + + dev_dbg(board->gpib_dev, "entering %s()\n", __func__); + + head = &board->device_list; + if (head->next == head) + return 0; + + retval = setup_serial_poll(board, usec_timeout); + if (retval < 0) + return retval; + + for (cur = head->next; cur != head; cur = cur->next) { + device = list_entry(cur, gpib_status_queue_t, list); + retval = read_serial_poll_byte(board, + device->pad, device->sad, usec_timeout, &result); + if (retval < 0) + continue; + if (result & request_service_bit) { + retval = push_status_byte(board, device, result); + if (retval < 0) + continue; + num_bytes++; + } + } + + retval = cleanup_serial_poll(board, usec_timeout); + if (retval < 0) + return retval; + + return num_bytes; +} + +/* + * DVRSP + * This function performs a serial poll of the device with primary + * address pad and secondary address sad. If the device has no + * secondary address, pass a negative number in for this argument. At the + * end of a successful serial poll the response is returned in result. + * SPD and UNT are sent at the completion of the poll. + */ + +int dvrsp(gpib_board_t *board, unsigned int pad, int sad, + unsigned int usec_timeout, uint8_t *result) +{ + int status = ibstatus(board); + int retval; + + if ((status & CIC) == 0) { + pr_err("gpib: not CIC during serial poll\n"); + return -1; + } + + if (pad > MAX_GPIB_PRIMARY_ADDRESS || sad > MAX_GPIB_SECONDARY_ADDRESS) { + pr_err("gpib: bad address for serial poll"); + return -1; + } + + retval = serial_poll_single(board, pad, sad, usec_timeout, result); + if (io_timed_out(board)) + retval = -ETIMEDOUT; + + return retval; +} + +static gpib_descriptor_t *handle_to_descriptor(const gpib_file_private_t *file_priv, + int handle) +{ + if (handle < 0 || handle >= GPIB_MAX_NUM_DESCRIPTORS) { + pr_err("gpib: invalid handle %i\n", handle); + return NULL; + } + + return file_priv->descriptors[handle]; +} + +static int init_gpib_file_private(gpib_file_private_t *priv) +{ + memset(priv, 0, sizeof(*priv)); + atomic_set(&priv->holding_mutex, 0); + priv->descriptors[0] = kmalloc(sizeof(gpib_descriptor_t), GFP_KERNEL); + if (!priv->descriptors[0]) { + pr_err("gpib: failed to allocate default board descriptor\n"); + return -ENOMEM; + } + init_gpib_descriptor(priv->descriptors[0]); + priv->descriptors[0]->is_board = 1; + mutex_init(&priv->descriptors_mutex); + return 0; +} + +int ibopen(struct inode *inode, struct file *filep) +{ + unsigned int minor = iminor(inode); + gpib_board_t *board; + gpib_file_private_t *priv; + + if (minor >= GPIB_MAX_NUM_BOARDS) { + pr_err("gpib: invalid minor number of device file\n"); + return -ENXIO; + } + + board = &board_array[minor]; + + filep->private_data = kmalloc(sizeof(gpib_file_private_t), GFP_KERNEL); + if (!filep->private_data) + return -ENOMEM; + + priv = filep->private_data; + init_gpib_file_private((gpib_file_private_t *)filep->private_data); + + dev_dbg(board->gpib_dev, "pid %i, gpib: opening minor %d\n", current->pid, minor); + + if (board->use_count == 0) { + int retval; + + retval = request_module("gpib%i", minor); + if (retval) { + dev_dbg(board->gpib_dev, "pid %i, gpib: request module returned %i\n", + current->pid, retval); + } + } + if (board->interface) { + if (!try_module_get(board->provider_module)) { + pr_err("gpib: try_module_get() failed\n"); + return -EIO; + } + board->use_count++; + priv->got_module = 1; + } + return 0; +} + +int ibclose(struct inode *inode, struct file *filep) +{ + unsigned int minor = iminor(inode); + gpib_board_t *board; + gpib_file_private_t *priv = filep->private_data; + gpib_descriptor_t *desc; + + if (minor >= GPIB_MAX_NUM_BOARDS) { + pr_err("gpib: invalid minor number of device file\n"); + return -ENODEV; + } + + board = &board_array[minor]; + + dev_dbg(board->gpib_dev, "pid %i, closing minor %d\n", current->pid, minor); + + if (priv) { + desc = handle_to_descriptor(priv, 0); + if (desc) { + if (desc->autopoll_enabled) { + dev_dbg(board->gpib_dev, "pid %i, decrementing autospollers\n", + current->pid); + if (board->autospollers > 0) + board->autospollers--; + else + pr_err("gpib: Attempt to decrement zero autospollers\n"); + } + } else { + pr_err("gpib: Unexpected null gpib_descriptor\n"); + } + + cleanup_open_devices(priv, board); + + if (atomic_read(&priv->holding_mutex)) + mutex_unlock(&board->user_mutex); + + if (priv->got_module && board->use_count) { + module_put(board->provider_module); + --board->use_count; + } + + kfree(filep->private_data); + filep->private_data = NULL; + } + + return 0; +} + +long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg) +{ + unsigned int minor = iminor(filep->f_path.dentry->d_inode); + gpib_board_t *board; + gpib_file_private_t *file_priv = filep->private_data; + long retval = -ENOTTY; + + if (minor >= GPIB_MAX_NUM_BOARDS) { + pr_err("gpib: invalid minor number of device file\n"); + return -ENODEV; + } + board = &board_array[minor]; + + if (mutex_lock_interruptible(&board->big_gpib_mutex)) + return -ERESTARTSYS; + + dev_dbg(board->gpib_dev, "pid %i, ioctl %d, interface=%s, use=%d, onl=%d\n", + current->pid, cmd & 0xff, + board->interface ? board->interface->name : "", + board->use_count, + board->online); + + switch (cmd) { + case CFCBOARDTYPE: + retval = board_type_ioctl(file_priv, board, arg); + goto done; + case IBONL: + retval = online_ioctl(board, arg); + goto done; + default: + break; + } + if (!board->interface) { + pr_err("gpib: no gpib board configured on /dev/gpib%i\n", minor); + retval = -ENODEV; + goto done; + } + if (file_priv->got_module == 0) { + if (!try_module_get(board->provider_module)) { + pr_err("gpib: try_module_get() failed\n"); + retval = -EIO; + goto done; + } + file_priv->got_module = 1; + board->use_count++; + } + switch (cmd) { + case CFCBASE: + retval = iobase_ioctl(&board->config, arg); + goto done; + case CFCIRQ: + retval = irq_ioctl(&board->config, arg); + goto done; + case CFCDMA: + retval = dma_ioctl(&board->config, arg); + goto done; + case IBAUTOSPOLL: + retval = autospoll_ioctl(board, file_priv, arg); + goto done; + case IBBOARD_INFO: + retval = board_info_ioctl(board, arg); + goto done; + case IBMUTEX: + /* Need to unlock board->big_gpib_mutex before potentially locking board->user_mutex + * to maintain consistent locking order + */ + mutex_unlock(&board->big_gpib_mutex); + return mutex_ioctl(board, file_priv, arg); + case IBPAD: + retval = pad_ioctl(board, file_priv, arg); + goto done; + case IBSAD: + retval = sad_ioctl(board, file_priv, arg); + goto done; + case IBSELECT_PCI: + retval = select_pci_ioctl(&board->config, arg); + goto done; + case IBSELECT_DEVICE_PATH: + retval = select_device_path_ioctl(&board->config, arg); + goto done; + default: + break; + } + + if (!board->online) { + pr_err("gpib: ioctl %i invalid for offline board\n", + cmd & 0xff); + retval = -EINVAL; + goto done; + } + + switch (cmd) { + case IBEVENT: + retval = event_ioctl(board, arg); + goto done; + case IBCLOSEDEV: + retval = close_dev_ioctl(filep, board, arg); + goto done; + case IBOPENDEV: + retval = open_dev_ioctl(filep, board, arg); + goto done; + case IBSPOLL_BYTES: + retval = status_bytes_ioctl(board, arg); + goto done; + case IBWAIT: + retval = wait_ioctl(file_priv, board, arg); + if (retval == -ERESTARTSYS) + return retval; + goto done; + case IBLINES: + retval = line_status_ioctl(board, arg); + goto done; + case IBLOC: + board->interface->return_to_local(board); + retval = 0; + goto done; + default: + break; + } + + spin_lock(&board->locking_pid_spinlock); + if (current->pid != board->locking_pid) { + spin_unlock(&board->locking_pid_spinlock); + pr_err("gpib: need to hold board lock to perform ioctl %i\n", + cmd & 0xff); + retval = -EPERM; + goto done; + } + spin_unlock(&board->locking_pid_spinlock); + + switch (cmd) { + case IB_T1_DELAY: + retval = t1_delay_ioctl(board, arg); + goto done; + case IBCAC: + retval = take_control_ioctl(board, arg); + goto done; + case IBCMD: + /* IO ioctls can take a long time, we need to unlock board->big_gpib_mutex + * before we call them. + */ + mutex_unlock(&board->big_gpib_mutex); + return command_ioctl(file_priv, board, arg); + case IBEOS: + retval = eos_ioctl(board, arg); + goto done; + case IBGTS: + retval = ibgts(board); + goto done; + case IBPPC: + retval = ppc_ioctl(board, arg); + goto done; + case IBPP2_SET: + retval = set_local_ppoll_mode_ioctl(board, arg); + goto done; + case IBPP2_GET: + retval = get_local_ppoll_mode_ioctl(board, arg); + goto done; + case IBQUERY_BOARD_RSV: + retval = query_board_rsv_ioctl(board, arg); + goto done; + case IBRD: + /* IO ioctls can take a long time, we need to unlock board->big_gpib_mutex + * before we call them. + */ + mutex_unlock(&board->big_gpib_mutex); + return read_ioctl(file_priv, board, arg); + case IBRPP: + retval = parallel_poll_ioctl(board, arg); + goto done; + case IBRSC: + retval = request_system_control_ioctl(board, arg); + goto done; + case IBRSP: + retval = serial_poll_ioctl(board, arg); + goto done; + case IBRSV: + retval = request_service_ioctl(board, arg); + goto done; + case IBRSV2: + retval = request_service2_ioctl(board, arg); + goto done; + case IBSIC: + retval = interface_clear_ioctl(board, arg); + goto done; + case IBSRE: + retval = remote_enable_ioctl(board, arg); + goto done; + case IBTMO: + retval = timeout_ioctl(board, arg); + goto done; + case IBWRT: + /* IO ioctls can take a long time, we need to unlock board->big_gpib_mutex + * before we call them. + */ + mutex_unlock(&board->big_gpib_mutex); + return write_ioctl(file_priv, board, arg); + default: + retval = -ENOTTY; + goto done; + } + +done: + mutex_unlock(&board->big_gpib_mutex); + dev_dbg(board->gpib_dev, "ioctl done status = 0x%lx\n", board->status); + return retval; +} + +static int board_type_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, unsigned long arg) +{ + struct list_head *list_ptr; + board_type_ioctl_t cmd; + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (board->online) { + pr_err("gpib: can't change board type while board is online.\n"); + return -EBUSY; + } + + retval = copy_from_user(&cmd, (void *)arg, sizeof(board_type_ioctl_t)); + if (retval) + return retval; + + for (list_ptr = registered_drivers.next; list_ptr != ®istered_drivers; + list_ptr = list_ptr->next) { + gpib_interface_list_t *entry; + + entry = list_entry(list_ptr, gpib_interface_list_t, list); + if (strcmp(entry->interface->name, cmd.name) == 0) { + int i; + int had_module = file_priv->got_module; + + if (board->use_count) { + for (i = 0; i < board->use_count; ++i) + module_put(board->provider_module); + board->interface = NULL; + file_priv->got_module = 0; + } + board->interface = entry->interface; + board->provider_module = entry->module; + for (i = 0; i < board->use_count; ++i) { + if (!try_module_get(entry->module)) { + board->use_count = i; + return -EIO; + } + } + if (had_module == 0) { + if (!try_module_get(entry->module)) + return -EIO; + ++board->use_count; + } + file_priv->got_module = 1; + return 0; + } + } + + return -EINVAL; +} + +static int read_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, + unsigned long arg) +{ + read_write_ioctl_t read_cmd; + u8 *userbuf; + unsigned long remain; + int end_flag = 0; + int retval; + ssize_t read_ret = 0; + gpib_descriptor_t *desc; + size_t nbytes; + + retval = copy_from_user(&read_cmd, (void *)arg, sizeof(read_cmd)); + if (retval) + return -EFAULT; + + if (read_cmd.completed_transfer_count > read_cmd.requested_transfer_count) + return -EINVAL; + + desc = handle_to_descriptor(file_priv, read_cmd.handle); + if (!desc) + return -EINVAL; + + if (WARN_ON_ONCE(sizeof(userbuf) > sizeof(read_cmd.buffer_ptr))) + return -EFAULT; + + userbuf = (u8 *)(unsigned long)read_cmd.buffer_ptr; + userbuf += read_cmd.completed_transfer_count; + + remain = read_cmd.requested_transfer_count - read_cmd.completed_transfer_count; + + /* Check write access to buffer */ + if (!access_ok(userbuf, remain)) + return -EFAULT; + + atomic_set(&desc->io_in_progress, 1); + + /* Read buffer loads till we fill the user supplied buffer */ + while (remain > 0 && end_flag == 0) { + nbytes = 0; + read_ret = ibrd(board, board->buffer, (board->buffer_length < remain) ? + board->buffer_length : remain, &end_flag, &nbytes); + if (nbytes == 0) + break; + retval = copy_to_user(userbuf, board->buffer, nbytes); + if (retval) { + retval = -EFAULT; + break; + } + remain -= nbytes; + userbuf += nbytes; + if (read_ret < 0) + break; + } + read_cmd.completed_transfer_count = read_cmd.requested_transfer_count - remain; + read_cmd.end = end_flag; + /* suppress errors (for example due to timeout or interruption by device clear) + * if all bytes got sent. This prevents races that can occur in the various drivers + * if a device receives a device clear immediately after a transfer completes and + * the driver code wasn't careful enough to handle that case. + */ + if (remain == 0 || end_flag) + read_ret = 0; + if (retval == 0) + retval = copy_to_user((void *)arg, &read_cmd, sizeof(read_cmd)); + + atomic_set(&desc->io_in_progress, 0); + + wake_up_interruptible(&board->wait); + if (retval) + return -EFAULT; + + return read_ret; +} + +static int command_ioctl(gpib_file_private_t *file_priv, + gpib_board_t *board, unsigned long arg) +{ + read_write_ioctl_t cmd; + u8 *userbuf; + unsigned long remain; + int retval; + int fault = 0; + gpib_descriptor_t *desc; + size_t bytes_written; + int no_clear_io_in_prog; + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + if (cmd.completed_transfer_count > cmd.requested_transfer_count) + return -EINVAL; + + desc = handle_to_descriptor(file_priv, cmd.handle); + if (!desc) + return -EINVAL; + + userbuf = (u8 *)(unsigned long)cmd.buffer_ptr; + userbuf += cmd.completed_transfer_count; + + no_clear_io_in_prog = cmd.end; + cmd.end = 0; + + remain = cmd.requested_transfer_count - cmd.completed_transfer_count; + + /* Check read access to buffer */ + if (!access_ok(userbuf, remain)) + return -EFAULT; + + /* Write buffer loads till we empty the user supplied buffer. + * Call drivers at least once, even if remain is zero, in + * order to allow them to insure previous commands were + * completely finished, in the case of a restarted ioctl. + */ + + atomic_set(&desc->io_in_progress, 1); + + do { + fault = copy_from_user(board->buffer, userbuf, (board->buffer_length < remain) ? + board->buffer_length : remain); + if (fault) { + retval = -EFAULT; + bytes_written = 0; + } else { + retval = ibcmd(board, board->buffer, (board->buffer_length < remain) ? + board->buffer_length : remain, &bytes_written); + } + remain -= bytes_written; + userbuf += bytes_written; + if (retval < 0) { + atomic_set(&desc->io_in_progress, 0); + + wake_up_interruptible(&board->wait); + break; + } + } while (remain > 0); + + cmd.completed_transfer_count = cmd.requested_transfer_count - remain; + + if (fault == 0) + fault = copy_to_user((void *)arg, &cmd, sizeof(cmd)); + + /* + * no_clear_io_in_prog (cmd.end) is true when io_in_progress should + * not be set to zero because the cmd in progress is the address setup + * operation for an async read or write. This causes CMPL not to be set + * in general_ibstatus until the async read or write completes. + */ + if (!no_clear_io_in_prog || fault) + atomic_set(&desc->io_in_progress, 0); + + wake_up_interruptible(&board->wait); + if (fault) + return -EFAULT; + + return retval; +} + +static int write_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, + unsigned long arg) +{ + read_write_ioctl_t write_cmd; + u8 *userbuf; + unsigned long remain; + int retval = 0; + int fault; + gpib_descriptor_t *desc; + + fault = copy_from_user(&write_cmd, (void *)arg, sizeof(write_cmd)); + if (fault) + return -EFAULT; + + if (write_cmd.completed_transfer_count > write_cmd.requested_transfer_count) + return -EINVAL; + + desc = handle_to_descriptor(file_priv, write_cmd.handle); + if (!desc) + return -EINVAL; + + userbuf = (u8 *)(unsigned long)write_cmd.buffer_ptr; + userbuf += write_cmd.completed_transfer_count; + + remain = write_cmd.requested_transfer_count - write_cmd.completed_transfer_count; + + /* Check read access to buffer */ + if (!access_ok(userbuf, remain)) + return -EFAULT; + + atomic_set(&desc->io_in_progress, 1); + + /* Write buffer loads till we empty the user supplied buffer */ + while (remain > 0) { + int send_eoi; + size_t bytes_written = 0; + + send_eoi = remain <= board->buffer_length && write_cmd.end; + fault = copy_from_user(board->buffer, userbuf, (board->buffer_length < remain) ? + board->buffer_length : remain); + if (fault) { + retval = -EFAULT; + break; + } + retval = ibwrt(board, board->buffer, (board->buffer_length < remain) ? + board->buffer_length : remain, send_eoi, &bytes_written); + remain -= bytes_written; + userbuf += bytes_written; + if (retval < 0) + break; + } + write_cmd.completed_transfer_count = write_cmd.requested_transfer_count - remain; + /* suppress errors (for example due to timeout or interruption by device clear) + * if all bytes got sent. This prevents races that can occur in the various drivers + * if a device receives a device clear immediately after a transfer completes and + * the driver code wasn't careful enough to handle that case. + */ + if (remain == 0) + retval = 0; + if (fault == 0) + fault = copy_to_user((void *)arg, &write_cmd, sizeof(write_cmd)); + + atomic_set(&desc->io_in_progress, 0); + + wake_up_interruptible(&board->wait); + if (fault) + return -EFAULT; + + return retval; +} + +static int status_bytes_ioctl(gpib_board_t *board, unsigned long arg) +{ + gpib_status_queue_t *device; + spoll_bytes_ioctl_t cmd; + int retval; + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + device = get_gpib_status_queue(board, cmd.pad, cmd.sad); + if (!device) + cmd.num_bytes = 0; + else + cmd.num_bytes = num_status_bytes(device); + + retval = copy_to_user((void *)arg, &cmd, sizeof(cmd)); + if (retval) + return -EFAULT; + + return 0; +} + +static int increment_open_device_count(gpib_board_t *board, struct list_head *head, + unsigned int pad, int sad) +{ + struct list_head *list_ptr; + gpib_status_queue_t *device; + + /* first see if address has already been opened, then increment + * open count + */ + for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) { + device = list_entry(list_ptr, gpib_status_queue_t, list); + if (gpib_address_equal(device->pad, device->sad, pad, sad)) { + dev_dbg(board->gpib_dev, "pid %i, incrementing open count for pad %i, sad %i\n", + current->pid, device->pad, device->sad); + device->reference_count++; + return 0; + } + } + + /* otherwise we need to allocate a new gpib_status_queue_t */ + device = kmalloc(sizeof(gpib_status_queue_t), GFP_ATOMIC); + if (!device) + return -ENOMEM; + init_gpib_status_queue(device); + device->pad = pad; + device->sad = sad; + device->reference_count = 1; + + list_add(&device->list, head); + + dev_dbg(board->gpib_dev, "pid %i, opened pad %i, sad %i\n", + current->pid, device->pad, device->sad); + + return 0; +} + +static int subtract_open_device_count(gpib_board_t *board, struct list_head *head, + unsigned int pad, int sad, unsigned int count) +{ + gpib_status_queue_t *device; + struct list_head *list_ptr; + + for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) { + device = list_entry(list_ptr, gpib_status_queue_t, list); + if (gpib_address_equal(device->pad, device->sad, pad, sad)) { + dev_dbg(board->gpib_dev, "pid %i, decrementing open count for pad %i, sad %i\n", + current->pid, device->pad, device->sad); + if (count > device->reference_count) { + pr_err("gpib: bug! in %s()\n", __func__); + return -EINVAL; + } + device->reference_count -= count; + if (device->reference_count == 0) { + dev_dbg(board->gpib_dev, "pid %i, closing pad %i, sad %i\n", + current->pid, device->pad, device->sad); + list_del(list_ptr); + kfree(device); + } + return 0; + } + } + pr_err("gpib: bug! tried to close address that was never opened!\n"); + return -EINVAL; +} + +static inline int decrement_open_device_count(gpib_board_t *board, struct list_head *head, + unsigned int pad, int sad) +{ + return subtract_open_device_count(board, head, pad, sad, 1); +} + +static int cleanup_open_devices(gpib_file_private_t *file_priv, gpib_board_t *board) +{ + int retval = 0; + int i; + + for (i = 0; i < GPIB_MAX_NUM_DESCRIPTORS; i++) { + gpib_descriptor_t *desc; + + desc = file_priv->descriptors[i]; + if (!desc) + continue; + + if (desc->is_board == 0) { + retval = decrement_open_device_count(board, &board->device_list, desc->pad, + desc->sad); + if (retval < 0) + return retval; + } + kfree(desc); + file_priv->descriptors[i] = NULL; + } + + return 0; +} + +static int open_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg) +{ + open_dev_ioctl_t open_dev_cmd; + int retval; + gpib_file_private_t *file_priv = filep->private_data; + int i; + + retval = copy_from_user(&open_dev_cmd, (void *)arg, sizeof(open_dev_cmd)); + if (retval) + return -EFAULT; + + if (mutex_lock_interruptible(&file_priv->descriptors_mutex)) + return -ERESTARTSYS; + for (i = 0; i < GPIB_MAX_NUM_DESCRIPTORS; i++) + if (!file_priv->descriptors[i]) + break; + if (i == GPIB_MAX_NUM_DESCRIPTORS) { + mutex_unlock(&file_priv->descriptors_mutex); + return -ERANGE; + } + file_priv->descriptors[i] = kmalloc(sizeof(gpib_descriptor_t), GFP_KERNEL); + if (!file_priv->descriptors[i]) { + mutex_unlock(&file_priv->descriptors_mutex); + return -ENOMEM; + } + init_gpib_descriptor(file_priv->descriptors[i]); + + file_priv->descriptors[i]->pad = open_dev_cmd.pad; + file_priv->descriptors[i]->sad = open_dev_cmd.sad; + file_priv->descriptors[i]->is_board = open_dev_cmd.is_board; + mutex_unlock(&file_priv->descriptors_mutex); + + retval = increment_open_device_count(board, &board->device_list, open_dev_cmd.pad, + open_dev_cmd.sad); + if (retval < 0) + return retval; + + /* clear stuck srq state, since we may be able to find service request on + * the new device + */ + atomic_set(&board->stuck_srq, 0); + + open_dev_cmd.handle = i; + retval = copy_to_user((void *)arg, &open_dev_cmd, sizeof(open_dev_cmd)); + if (retval) + return -EFAULT; + + return 0; +} + +static int close_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg) +{ + close_dev_ioctl_t cmd; + gpib_file_private_t *file_priv = filep->private_data; + int retval; + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + if (cmd.handle >= GPIB_MAX_NUM_DESCRIPTORS) + return -EINVAL; + if (!file_priv->descriptors[cmd.handle]) + return -EINVAL; + + retval = decrement_open_device_count(board, &board->device_list, + file_priv->descriptors[cmd.handle]->pad, + file_priv->descriptors[cmd.handle]->sad); + if (retval < 0) + return retval; + + kfree(file_priv->descriptors[cmd.handle]); + file_priv->descriptors[cmd.handle] = NULL; + + return 0; +} + +static int serial_poll_ioctl(gpib_board_t *board, unsigned long arg) +{ + serial_poll_ioctl_t serial_cmd; + int retval; + + dev_dbg(board->gpib_dev, "pid %i, entering %s()\n", current->pid, __func__); + + retval = copy_from_user(&serial_cmd, (void *)arg, sizeof(serial_cmd)); + if (retval) + return -EFAULT; + + retval = get_serial_poll_byte(board, serial_cmd.pad, serial_cmd.sad, board->usec_timeout, + &serial_cmd.status_byte); + if (retval < 0) + return retval; + + retval = copy_to_user((void *)arg, &serial_cmd, sizeof(serial_cmd)); + if (retval) + return -EFAULT; + + return 0; +} + +static int wait_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, + unsigned long arg) +{ + wait_ioctl_t wait_cmd; + int retval; + gpib_descriptor_t *desc; + + retval = copy_from_user(&wait_cmd, (void *)arg, sizeof(wait_cmd)); + if (retval) + return -EFAULT; + + desc = handle_to_descriptor(file_priv, wait_cmd.handle); + if (!desc) + return -EINVAL; + + retval = ibwait(board, wait_cmd.wait_mask, wait_cmd.clear_mask, + wait_cmd.set_mask, &wait_cmd.ibsta, wait_cmd.usec_timeout, desc); + if (retval < 0) + return retval; + + retval = copy_to_user((void *)arg, &wait_cmd, sizeof(wait_cmd)); + if (retval) + return -EFAULT; + + return 0; +} + +static int parallel_poll_ioctl(gpib_board_t *board, unsigned long arg) +{ + u8 poll_byte; + int retval; + + retval = ibrpp(board, &poll_byte); + if (retval < 0) + return retval; + + retval = copy_to_user((void *)arg, &poll_byte, sizeof(poll_byte)); + if (retval) + return -EFAULT; + + return 0; +} + +static int online_ioctl(gpib_board_t *board, unsigned long arg) +{ + online_ioctl_t online_cmd; + int retval; + void *init_data = NULL; + + board->config.init_data = NULL; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + retval = copy_from_user(&online_cmd, (void *)arg, sizeof(online_cmd)); + if (retval) + return -EFAULT; + if (online_cmd.init_data_length > 0) { + board->config.init_data = vmalloc(online_cmd.init_data_length); + if (!board->config.init_data) + return -ENOMEM; + if (WARN_ON_ONCE(sizeof(init_data) > sizeof(online_cmd.init_data_ptr))) + return -EFAULT; + init_data = (void *)(unsigned long)(online_cmd.init_data_ptr); + retval = copy_from_user(board->config.init_data, init_data, + online_cmd.init_data_length); + if (retval) { + vfree(board->config.init_data); + return -EFAULT; + } + board->config.init_data_length = online_cmd.init_data_length; + } else { + board->config.init_data = NULL; + board->config.init_data_length = 0; + } + if (online_cmd.online) + retval = ibonline(board); + else + retval = iboffline(board); + if (board->config.init_data) { + vfree(board->config.init_data); + board->config.init_data = NULL; + board->config.init_data_length = 0; + } + return retval; +} + +static int remote_enable_ioctl(gpib_board_t *board, unsigned long arg) +{ + int enable; + int retval; + + retval = copy_from_user(&enable, (void *)arg, sizeof(enable)); + if (retval) + return -EFAULT; + + return ibsre(board, enable); +} + +static int take_control_ioctl(gpib_board_t *board, unsigned long arg) +{ + int synchronous; + int retval; + + retval = copy_from_user(&synchronous, (void *)arg, sizeof(synchronous)); + if (retval) + return -EFAULT; + + return ibcac(board, synchronous, 1); +} + +static int line_status_ioctl(gpib_board_t *board, unsigned long arg) +{ + short lines; + int retval; + + retval = iblines(board, &lines); + if (retval < 0) + return retval; + + retval = copy_to_user((void *)arg, &lines, sizeof(lines)); + if (retval) + return -EFAULT; + + return 0; +} + +static int pad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg) +{ + pad_ioctl_t cmd; + int retval; + gpib_descriptor_t *desc; + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + desc = handle_to_descriptor(file_priv, cmd.handle); + if (!desc) + return -EINVAL; + + if (desc->is_board) { + retval = ibpad(board, cmd.pad); + if (retval < 0) + return retval; + } else { + retval = decrement_open_device_count(board, &board->device_list, desc->pad, + desc->sad); + if (retval < 0) + return retval; + + desc->pad = cmd.pad; + + retval = increment_open_device_count(board, &board->device_list, desc->pad, + desc->sad); + if (retval < 0) + return retval; + } + + return 0; +} + +static int sad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg) +{ + sad_ioctl_t cmd; + int retval; + gpib_descriptor_t *desc; + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + desc = handle_to_descriptor(file_priv, cmd.handle); + if (!desc) + return -EINVAL; + + if (desc->is_board) { + retval = ibsad(board, cmd.sad); + if (retval < 0) + return retval; + } else { + retval = decrement_open_device_count(board, &board->device_list, desc->pad, + desc->sad); + if (retval < 0) + return retval; + + desc->sad = cmd.sad; + + retval = increment_open_device_count(board, &board->device_list, desc->pad, + desc->sad); + if (retval < 0) + return retval; + } + return 0; +} + +static int eos_ioctl(gpib_board_t *board, unsigned long arg) +{ + eos_ioctl_t eos_cmd; + int retval; + + retval = copy_from_user(&eos_cmd, (void *)arg, sizeof(eos_cmd)); + if (retval) + return -EFAULT; + + return ibeos(board, eos_cmd.eos, eos_cmd.eos_flags); +} + +static int request_service_ioctl(gpib_board_t *board, unsigned long arg) +{ + u8 status_byte; + int retval; + + retval = copy_from_user(&status_byte, (void *)arg, sizeof(status_byte)); + if (retval) + return -EFAULT; + + return ibrsv2(board, status_byte, status_byte & request_service_bit); +} + +static int request_service2_ioctl(gpib_board_t *board, unsigned long arg) +{ + request_service2_t request_service2_cmd; + int retval; + + retval = copy_from_user(&request_service2_cmd, (void *)arg, sizeof(request_service2_t)); + if (retval) + return -EFAULT; + + return ibrsv2(board, request_service2_cmd.status_byte, + request_service2_cmd.new_reason_for_service); +} + +static int iobase_ioctl(gpib_board_config_t *config, unsigned long arg) +{ + u64 base_addr; + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + retval = copy_from_user(&base_addr, (void *)arg, sizeof(base_addr)); + if (retval) + return -EFAULT; + + if (WARN_ON_ONCE(sizeof(void *) > sizeof(base_addr))) + return -EFAULT; + config->ibbase = (void *)(unsigned long)(base_addr); + + return 0; +} + +static int irq_ioctl(gpib_board_config_t *config, unsigned long arg) +{ + unsigned int irq; + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + retval = copy_from_user(&irq, (void *)arg, sizeof(irq)); + if (retval) + return -EFAULT; + + config->ibirq = irq; + + return 0; +} + +static int dma_ioctl(gpib_board_config_t *config, unsigned long arg) +{ + unsigned int dma_channel; + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + retval = copy_from_user(&dma_channel, (void *)arg, sizeof(dma_channel)); + if (retval) + return -EFAULT; + + config->ibdma = dma_channel; + + return 0; +} + +static int autospoll_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg) +{ + autospoll_ioctl_t enable; + int retval; + gpib_descriptor_t *desc; + + retval = copy_from_user(&enable, (void *)arg, sizeof(enable)); + if (retval) + return -EFAULT; + + desc = handle_to_descriptor(file_priv, 0); /* board handle is 0 */ + + if (enable) { + if (!desc->autopoll_enabled) { + board->autospollers++; + desc->autopoll_enabled = 1; + } + retval = 0; + } else { + if (desc->autopoll_enabled) { + desc->autopoll_enabled = 0; + if (board->autospollers > 0) { + board->autospollers--; + retval = 0; + } else { + pr_err("gpib: tried to set number of autospollers negative\n"); + retval = -EINVAL; + } + } else { + pr_err("gpib: autopoll disable requested before enable\n"); + retval = -EINVAL; + } + } + return retval; +} + +static int mutex_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv, + unsigned long arg) +{ + int retval, lock_mutex; + + retval = copy_from_user(&lock_mutex, (void *)arg, sizeof(lock_mutex)); + if (retval) + return -EFAULT; + + if (lock_mutex) { + retval = mutex_lock_interruptible(&board->user_mutex); + if (retval) { + pr_warn("gpib: ioctl interrupted while waiting on lock\n"); + return -ERESTARTSYS; + } + + spin_lock(&board->locking_pid_spinlock); + board->locking_pid = current->pid; + spin_unlock(&board->locking_pid_spinlock); + + atomic_set(&file_priv->holding_mutex, 1); + + dev_dbg(board->gpib_dev, "pid %i, locked board %d mutex\n", + current->pid, board->minor); + } else { + spin_lock(&board->locking_pid_spinlock); + if (current->pid != board->locking_pid) { + pr_err("gpib: bug! pid %i tried to release mutex held by pid %i\n", + current->pid, board->locking_pid); + spin_unlock(&board->locking_pid_spinlock); + return -EPERM; + } + board->locking_pid = 0; + spin_unlock(&board->locking_pid_spinlock); + + atomic_set(&file_priv->holding_mutex, 0); + + mutex_unlock(&board->user_mutex); + dev_dbg(board->gpib_dev, "pid %i, unlocked board %i mutex\n", + current->pid, board->minor); + } + return 0; +} + +static int timeout_ioctl(gpib_board_t *board, unsigned long arg) +{ + unsigned int timeout; + int retval; + + retval = copy_from_user(&timeout, (void *)arg, sizeof(timeout)); + if (retval) + return -EFAULT; + + board->usec_timeout = timeout; + dev_dbg(board->gpib_dev, "pid %i, timeout set to %i usec\n", current->pid, timeout); + + return 0; +} + +static int ppc_ioctl(gpib_board_t *board, unsigned long arg) +{ + ppoll_config_ioctl_t cmd; + int retval; + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + if (cmd.set_ist) { + board->ist = 1; + board->interface->parallel_poll_response(board, board->ist); + } else if (cmd.clear_ist) { + board->ist = 0; + board->interface->parallel_poll_response(board, board->ist); + } + + if (cmd.config) { + retval = ibppc(board, cmd.config); + if (retval < 0) + return retval; + } + + return 0; +} + +static int set_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg) +{ + local_ppoll_mode_ioctl_t cmd; + int retval; + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + if (!board->interface->local_parallel_poll_mode) { + pr_warn("gpib: local/remote parallel poll mode not supported by driver."); + return -EIO; + } + board->local_ppoll_mode = cmd != 0; + board->interface->local_parallel_poll_mode(board, board->local_ppoll_mode); + + return 0; +} + +static int get_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg) +{ + local_ppoll_mode_ioctl_t cmd; + int retval; + + cmd = board->local_ppoll_mode; + retval = copy_to_user((void *)arg, &cmd, sizeof(cmd)); + if (retval) + return -EFAULT; + + return 0; +} + +static int query_board_rsv_ioctl(gpib_board_t *board, unsigned long arg) +{ + int status; + int retval; + + status = board->interface->serial_poll_status(board); + + retval = copy_to_user((void *)arg, &status, sizeof(status)); + if (retval) + return -EFAULT; + + return 0; +} + +static int board_info_ioctl(const gpib_board_t *board, unsigned long arg) +{ + board_info_ioctl_t info; + int retval; + + info.pad = board->pad; + info.sad = board->sad; + info.parallel_poll_configuration = board->parallel_poll_configuration; + info.is_system_controller = board->master; + if (board->autospollers) + info.autopolling = 1; + else + info.autopolling = 0; + info.t1_delay = board->t1_nano_sec; + info.ist = board->ist; + info.no_7_bit_eos = board->interface->no_7_bit_eos; + retval = copy_to_user((void *)arg, &info, sizeof(info)); + if (retval) + return -EFAULT; + + return 0; +} + +static int interface_clear_ioctl(gpib_board_t *board, unsigned long arg) +{ + unsigned int usec_duration; + int retval; + + retval = copy_from_user(&usec_duration, (void *)arg, sizeof(usec_duration)); + if (retval) + return -EFAULT; + + return ibsic(board, usec_duration); +} + +static int select_pci_ioctl(gpib_board_config_t *config, unsigned long arg) +{ + select_pci_ioctl_t selection; + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + retval = copy_from_user(&selection, (void *)arg, sizeof(selection)); + if (retval) + return -EFAULT; + + config->pci_bus = selection.pci_bus; + config->pci_slot = selection.pci_slot; + + return 0; +} + +static int select_device_path_ioctl(gpib_board_config_t *config, unsigned long arg) +{ + select_device_path_ioctl_t *selection; + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + selection = vmalloc(sizeof(select_device_path_ioctl_t)); + if (!selection) + return -ENOMEM; + + retval = copy_from_user(selection, (void *)arg, sizeof(select_device_path_ioctl_t)); + if (retval) { + vfree(selection); + return -EFAULT; + } + + selection->device_path[sizeof(selection->device_path) - 1] = '\0'; + kfree(config->device_path); + config->device_path = NULL; + if (strlen(selection->device_path) > 0) + config->device_path = kstrdup(selection->device_path, GFP_KERNEL); + + vfree(selection); + return 0; +} + +unsigned int num_gpib_events(const gpib_event_queue_t *queue) +{ + return queue->num_events; +} + +static int push_gpib_event_nolock(gpib_board_t *board, short event_type) +{ + gpib_event_queue_t *queue = &board->event_queue; + struct list_head *head = &queue->event_head; + gpib_event_t *event; + static const unsigned int max_num_events = 1024; + int retval; + + if (num_gpib_events(queue) >= max_num_events) { + short lost_event; + + queue->dropped_event = 1; + retval = pop_gpib_event_nolock(board, queue, &lost_event); + if (retval < 0) + return retval; + } + + event = kmalloc(sizeof(gpib_event_t), GFP_ATOMIC); + if (!event) { + queue->dropped_event = 1; + pr_err("gpib: failed to allocate memory for event\n"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&event->list); + event->event_type = event_type; + + list_add_tail(&event->list, head); + + queue->num_events++; + + dev_dbg(board->gpib_dev, "pushed event %i, %i in queue\n", + (int)event_type, num_gpib_events(queue)); + + return 0; +} + +// push event onto back of event queue +int push_gpib_event(gpib_board_t *board, short event_type) +{ + unsigned long flags; + int retval; + + spin_lock_irqsave(&board->event_queue.lock, flags); + retval = push_gpib_event_nolock(board, event_type); + spin_unlock_irqrestore(&board->event_queue.lock, flags); + + if (event_type == EventDevTrg) + board->status |= DTAS; + if (event_type == EventDevClr) + board->status |= DCAS; + + return retval; +} +EXPORT_SYMBOL(push_gpib_event); + +static int pop_gpib_event_nolock(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type) +{ + struct list_head *head = &queue->event_head; + struct list_head *front = head->next; + gpib_event_t *event; + + if (num_gpib_events(queue) == 0) { + *event_type = EventNone; + return 0; + } + + if (front == head) + return -EIO; + + if (queue->dropped_event) { + queue->dropped_event = 0; + return -EPIPE; + } + + event = list_entry(front, gpib_event_t, list); + *event_type = event->event_type; + + list_del(front); + kfree(event); + + queue->num_events--; + + dev_dbg(board->gpib_dev, "popped event %i, %i in queue\n", + (int)*event_type, num_gpib_events(queue)); + + return 0; +} + +// pop event from front of event queue +int pop_gpib_event(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type) +{ + unsigned long flags; + int retval; + + spin_lock_irqsave(&queue->lock, flags); + retval = pop_gpib_event_nolock(board, queue, event_type); + spin_unlock_irqrestore(&queue->lock, flags); + return retval; +} + +static int event_ioctl(gpib_board_t *board, unsigned long arg) +{ + event_ioctl_t user_event; + int retval; + short event; + + retval = pop_gpib_event(board, &board->event_queue, &event); + if (retval < 0) + return retval; + + user_event = event; + + retval = copy_to_user((void *)arg, &user_event, sizeof(user_event)); + if (retval) + return -EFAULT; + + return 0; +} + +static int request_system_control_ioctl(gpib_board_t *board, unsigned long arg) +{ + rsc_ioctl_t request_control; + int retval; + + retval = copy_from_user(&request_control, (void *)arg, sizeof(request_control)); + if (retval) + return -EFAULT; + + ibrsc(board, request_control); + + return 0; +} + +static int t1_delay_ioctl(gpib_board_t *board, unsigned long arg) +{ + t1_delay_ioctl_t cmd; + unsigned int delay; + int retval; + + if (!board->interface->t1_delay) { + pr_warn("gpib: t1 delay not implemented in driver!\n"); + return -EIO; + } + + retval = copy_from_user(&cmd, (void *)arg, sizeof(cmd)); + if (retval) + return -EFAULT; + + delay = cmd; + + board->t1_nano_sec = board->interface->t1_delay(board, delay); + + return 0; +} + +const struct file_operations ib_fops = { +owner: THIS_MODULE, +llseek : NULL, +unlocked_ioctl : &ibioctl, +compat_ioctl : &ibioctl, +open : &ibopen, +release : &ibclose, +}; + +gpib_board_t board_array[GPIB_MAX_NUM_BOARDS]; + +LIST_HEAD(registered_drivers); + +void init_gpib_descriptor(gpib_descriptor_t *desc) +{ + desc->pad = 0; + desc->sad = -1; + desc->is_board = 0; + desc->autopoll_enabled = 0; + atomic_set(&desc->io_in_progress, 0); +} + +void gpib_register_driver(gpib_interface_t *interface, struct module *provider_module) +{ + struct gpib_interface_list_struct *entry; + + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return; + + entry->interface = interface; + entry->module = provider_module; + list_add(&entry->list, ®istered_drivers); + pr_info("gpib: registered %s interface\n", interface->name); +} +EXPORT_SYMBOL(gpib_register_driver); + +void gpib_unregister_driver(gpib_interface_t *interface) +{ + int i; + struct list_head *list_ptr; + + for (i = 0; i < GPIB_MAX_NUM_BOARDS; i++) { + gpib_board_t *board = &board_array[i]; + + if (board->interface == interface) { + if (board->use_count > 0) + pr_warn("gpib: Warning: deregistered interface %s in use\n", + interface->name); + iboffline(board); + board->interface = NULL; + } + } + for (list_ptr = registered_drivers.next; list_ptr != ®istered_drivers;) { + gpib_interface_list_t *entry; + + entry = list_entry(list_ptr, gpib_interface_list_t, list); + list_ptr = list_ptr->next; + if (entry->interface == interface) { + list_del(&entry->list); + kfree(entry); + } + } + pr_info("gpib: unregistered %s interface\n", interface->name); +} +EXPORT_SYMBOL(gpib_unregister_driver); + +static void init_gpib_board_config(gpib_board_config_t *config) +{ + memset(config, 0, sizeof(gpib_board_config_t)); + config->pci_bus = -1; + config->pci_slot = -1; +} + +void init_gpib_board(gpib_board_t *board) +{ + board->interface = NULL; + board->provider_module = NULL; + board->buffer = NULL; + board->buffer_length = 0; + board->status = 0; + init_waitqueue_head(&board->wait); + mutex_init(&board->user_mutex); + mutex_init(&board->big_gpib_mutex); + board->locking_pid = 0; + spin_lock_init(&board->locking_pid_spinlock); + spin_lock_init(&board->spinlock); + timer_setup(&board->timer, NULL, 0); + board->dev = NULL; + board->gpib_dev = NULL; + init_gpib_board_config(&board->config); + board->private_data = NULL; + board->use_count = 0; + INIT_LIST_HEAD(&board->device_list); + board->pad = 0; + board->sad = -1; + board->usec_timeout = 3000000; + board->parallel_poll_configuration = 0; + board->online = 0; + board->autospollers = 0; + board->autospoll_task = NULL; + init_event_queue(&board->event_queue); + board->minor = -1; + init_gpib_pseudo_irq(&board->pseudo_irq); + board->master = 1; + atomic_set(&board->stuck_srq, 0); + board->local_ppoll_mode = 0; +} + +int gpib_allocate_board(gpib_board_t *board) +{ + if (!board->buffer) { + board->buffer_length = 0x4000; + board->buffer = vmalloc(board->buffer_length); + if (!board->buffer) { + board->buffer_length = 0; + return -ENOMEM; + } + } + return 0; +} + +void gpib_deallocate_board(gpib_board_t *board) +{ + short dummy; + + if (board->buffer) { + vfree(board->buffer); + board->buffer = NULL; + board->buffer_length = 0; + } + while (num_gpib_events(&board->event_queue)) + pop_gpib_event(board, &board->event_queue, &dummy); +} + +static void init_board_array(gpib_board_t *board_array, unsigned int length) +{ + int i; + + for (i = 0; i < length; i++) { + init_gpib_board(&board_array[i]); + board_array[i].minor = i; + } +} + +void init_gpib_status_queue(gpib_status_queue_t *device) +{ + INIT_LIST_HEAD(&device->list); + INIT_LIST_HEAD(&device->status_bytes); + device->num_status_bytes = 0; + device->reference_count = 0; + device->dropped_byte = 0; +} + +static struct class *gpib_class; + +static int __init gpib_common_init_module(void) +{ + int i; + + pr_info("Linux-GPIB core driver\n"); + init_board_array(board_array, GPIB_MAX_NUM_BOARDS); + if (register_chrdev(GPIB_CODE, "gpib", &ib_fops)) { + pr_err("gpib: can't get major %d\n", GPIB_CODE); + return -EIO; + } + gpib_class = class_create("gpib_common"); + if (IS_ERR(gpib_class)) { + pr_err("gpib: failed to create gpib class\n"); + unregister_chrdev(GPIB_CODE, "gpib"); + return PTR_ERR(gpib_class); + } + for (i = 0; i < GPIB_MAX_NUM_BOARDS; ++i) + board_array[i].gpib_dev = device_create(gpib_class, 0, + MKDEV(GPIB_CODE, i), NULL, "gpib%i", i); + + return 0; +} + +static void __exit gpib_common_exit_module(void) +{ + int i; + + for (i = 0; i < GPIB_MAX_NUM_BOARDS; ++i) + device_destroy(gpib_class, MKDEV(GPIB_CODE, i)); + + class_destroy(gpib_class); + unregister_chrdev(GPIB_CODE, "gpib"); +} + +int gpib_match_device_path(struct device *dev, const char *device_path_in) +{ + if (device_path_in) { + char *device_path; + + device_path = kobject_get_path(&dev->kobj, GFP_KERNEL); + if (!device_path) { + dev_err(dev, "kobject_get_path returned NULL."); + return 0; + } + if (strcmp(device_path_in, device_path) != 0) { + kfree(device_path); + return 0; + } + kfree(device_path); + } + return 1; +} +EXPORT_SYMBOL(gpib_match_device_path); + +struct pci_dev *gpib_pci_get_device(const gpib_board_config_t *config, unsigned int vendor_id, + unsigned int device_id, struct pci_dev *from) +{ + struct pci_dev *pci_device = from; + + while ((pci_device = pci_get_device(vendor_id, device_id, pci_device))) { + if (config->pci_bus >= 0 && config->pci_bus != pci_device->bus->number) + continue; + if (config->pci_slot >= 0 && config->pci_slot != + PCI_SLOT(pci_device->devfn)) + continue; + if (gpib_match_device_path(&pci_device->dev, config->device_path) == 0) + continue; + return pci_device; + } + return NULL; +} +EXPORT_SYMBOL(gpib_pci_get_device); + +struct pci_dev *gpib_pci_get_subsys(const gpib_board_config_t *config, unsigned int vendor_id, + unsigned int device_id, unsigned int ss_vendor, + unsigned int ss_device, + struct pci_dev *from) +{ + struct pci_dev *pci_device = from; + + while ((pci_device = pci_get_subsys(vendor_id, device_id, + ss_vendor, ss_device, pci_device))) { + if (config->pci_bus >= 0 && config->pci_bus != pci_device->bus->number) + continue; + if (config->pci_slot >= 0 && config->pci_slot != + PCI_SLOT(pci_device->devfn)) + continue; + if (gpib_match_device_path(&pci_device->dev, config->device_path) == 0) + continue; + return pci_device; + } + return NULL; +} +EXPORT_SYMBOL(gpib_pci_get_subsys); + +module_init(gpib_common_init_module); +module_exit(gpib_common_exit_module); + diff --git a/drivers/staging/gpib/common/iblib.c b/drivers/staging/gpib/common/iblib.c new file mode 100644 index 0000000000000000000000000000000000000000..db1911cc1b263836484f3e37e0e102745e7c3ce7 --- /dev/null +++ b/drivers/staging/gpib/common/iblib.c @@ -0,0 +1,740 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2001, 2002 by Frank Mori Hess + ***************************************************************************/ + +#include "ibsys.h" +#include +#include +#include + +/* + * IBCAC + * Return to the controller active state from the + * controller standby state, i.e., turn ATN on. Note + * that in order to enter the controller active state + * from the controller idle state, ibsic must be called. + * If sync is non-zero, attempt to take control synchronously. + * If fallback_to_async is non-zero, try to take control asynchronously + * if synchronous attempt fails. + */ +int ibcac(gpib_board_t *board, int sync, int fallback_to_async) +{ + int status = ibstatus(board); + int retval; + + if ((status & CIC) == 0) { + pr_err("gpib: not CIC during %s()\n", __func__); + return -1; + } + + if (status & ATN) + return 0; + + if (sync && (status & LACS) == 0) + /* tcs (take control synchronously) can only possibly work when + * controller is listener. Error code also needs to be -ETIMEDOUT + * or it will giveout without doing fallback. + */ + retval = -ETIMEDOUT; + else + retval = board->interface->take_control(board, sync); + + if (retval < 0 && fallback_to_async) { + if (sync && retval == -ETIMEDOUT) + retval = board->interface->take_control(board, 0); + } + board->interface->update_status(board, 0); + + return retval; +} + +/* After ATN is asserted, it should cause any connected devices + * to start listening for command bytes and leave acceptor idle state. + * So if ATN is asserted and neither NDAC or NRFD are asserted, + * then there are no devices and ibcmd should error out immediately. + * Some gpib hardware sees itself asserting NDAC/NRFD when it + * is controller in charge, in which case this check will + * do nothing useful (but shouldn't cause any harm either). + * Drivers that don't need this check (ni_usb for example) may + * set the skip_check_for_command_acceptors flag in their + * gpib_interface_struct to avoid useless overhead. + */ +static int check_for_command_acceptors(gpib_board_t *board) +{ + int lines; + + if (board->interface->skip_check_for_command_acceptors) + return 0; + if (!board->interface->line_status) + return 0; + + udelay(2); // allow time for devices to respond to ATN if it was just asserted + + lines = board->interface->line_status(board); + if (lines < 0) + return lines; + + if (lines & ValidATN) { + if ((lines & BusATN) == 0) { + pr_err("gpib: ATN not asserted in %s()?", __func__); + return 0; + } + } + + if ((lines & ValidNRFD) && (lines & ValidNDAC)) { + if ((lines & BusNRFD) == 0 && (lines & BusNDAC) == 0) + return -ENOTCONN; + } + + return 0; +} + +/* + * IBCMD + * Write cnt command bytes from buf to the GPIB. The + * command operation terminates only on I/O complete. + * + * NOTE: + * 1. Prior to beginning the command, the interface is + * placed in the controller active state. + * 2. Before calling ibcmd for the first time, ibsic + * must be called to initialize the GPIB and enable + * the interface to leave the controller idle state. + */ +int ibcmd(gpib_board_t *board, uint8_t *buf, size_t length, size_t *bytes_written) +{ + ssize_t ret = 0; + int status; + + *bytes_written = 0; + + status = ibstatus(board); + + if ((status & CIC) == 0) { + pr_err("gpib: cannot send command when not controller-in-charge\n"); + return -EIO; + } + + os_start_timer(board, board->usec_timeout); + + ret = ibcac(board, 1, 1); + if (ret == 0) { + ret = check_for_command_acceptors(board); + if (ret == 0) + ret = board->interface->command(board, buf, length, bytes_written); + } + + os_remove_timer(board); + + if (io_timed_out(board)) + ret = -ETIMEDOUT; + + return ret; +} + +/* + * IBGTS + * Go to the controller standby state from the controller + * active state, i.e., turn ATN off. + */ + +int ibgts(gpib_board_t *board) +{ + int status = ibstatus(board); + int retval; + + if ((status & CIC) == 0) { + pr_err("gpib: not CIC during %s()\n", __func__); + return -1; + } + + retval = board->interface->go_to_standby(board); /* go to standby */ + if (retval < 0) + pr_err("gpib: error while going to standby\n"); + + board->interface->update_status(board, 0); + + return retval; +} + +static int autospoll_wait_should_wake_up(gpib_board_t *board) +{ + int retval; + + mutex_lock(&board->big_gpib_mutex); + + retval = board->master && board->autospollers > 0 && + !atomic_read(&board->stuck_srq) && + test_and_clear_bit(SRQI_NUM, &board->status); + + mutex_unlock(&board->big_gpib_mutex); + return retval; +} + +static int autospoll_thread(void *board_void) +{ + gpib_board_t *board = board_void; + int retval = 0; + + dev_dbg(board->gpib_dev, "entering autospoll thread\n"); + + while (1) { + wait_event_interruptible(board->wait, + kthread_should_stop() || + autospoll_wait_should_wake_up(board)); + dev_dbg(board->gpib_dev, "autospoll wait satisfied\n"); + if (kthread_should_stop()) + break; + + mutex_lock(&board->big_gpib_mutex); + /* make sure we are still good after we have lock */ + if (board->autospollers <= 0 || board->master == 0) { + mutex_unlock(&board->big_gpib_mutex); + continue; + } + mutex_unlock(&board->big_gpib_mutex); + + if (try_module_get(board->provider_module)) { + retval = autopoll_all_devices(board); + module_put(board->provider_module); + } else { + pr_err("gpib%i: %s: try_module_get() failed!\n", board->minor, __func__); + } + if (retval <= 0) { + pr_err("gpib%i: %s: stuck SRQ\n", board->minor, __func__); + + atomic_set(&board->stuck_srq, 1); // XXX could be better + set_bit(SRQI_NUM, &board->status); + } + } + pr_info("gpib%i: exiting autospoll thread\n", board->minor); + return retval; +} + +int ibonline(gpib_board_t *board) +{ + int retval; + + if (board->online) + return -EBUSY; + if (!board->interface) + return -ENODEV; + retval = gpib_allocate_board(board); + if (retval < 0) + return retval; + + board->dev = NULL; + board->local_ppoll_mode = 0; + retval = board->interface->attach(board, &board->config); + if (retval < 0) { + board->interface->detach(board); + pr_err("gpib: interface attach failed\n"); + return retval; + } + /* nios2nommu on 2.6.11 uclinux kernel has weird problems + * with autospoll thread causing huge slowdowns + */ +#ifndef CONFIG_NIOS2 + board->autospoll_task = kthread_run(&autospoll_thread, board, + "gpib%d_autospoll_kthread", board->minor); + retval = IS_ERR(board->autospoll_task); + if (retval) { + pr_err("gpib: failed to create autospoll thread\n"); + board->interface->detach(board); + return retval; + } +#endif + board->online = 1; + dev_dbg(board->gpib_dev, "gpib: board online\n"); + + return 0; +} + +/* XXX need to make sure board is generally not in use (grab board lock?) */ +int iboffline(gpib_board_t *board) +{ + int retval; + + if (board->online == 0) + return 0; + if (!board->interface) + return -ENODEV; + + if (board->autospoll_task && !IS_ERR(board->autospoll_task)) { + retval = kthread_stop(board->autospoll_task); + if (retval) + pr_err("gpib: kthread_stop returned %i\n", retval); + board->autospoll_task = NULL; + } + + board->interface->detach(board); + gpib_deallocate_board(board); + board->online = 0; + dev_dbg(board->gpib_dev, "gpib: board offline\n"); + + return 0; +} + +/* + * IBLINES + * Poll the GPIB control lines and return their status in buf. + * + * LSB (bits 0-7) - VALID lines mask (lines that can be monitored). + * Next LSB (bits 8-15) - STATUS lines mask (lines that are currently set). + * + */ +int iblines(const gpib_board_t *board, short *lines) +{ + int retval; + + *lines = 0; + if (!board->interface->line_status) + return 0; + retval = board->interface->line_status(board); + if (retval < 0) + return retval; + *lines = retval; + return 0; +} + +/* + * IBRD + * Read up to 'length' bytes of data from the GPIB into buf. End + * on detection of END (EOI and or EOS) and set 'end_flag'. + * + * NOTE: + * 1. The interface is placed in the controller standby + * state prior to beginning the read. + * 2. Prior to calling ibrd, the intended devices as well + * as the interface board itself must be addressed by + * calling ibcmd. + */ + +int ibrd(gpib_board_t *board, uint8_t *buf, size_t length, int *end_flag, size_t *nbytes) +{ + ssize_t ret = 0; + int retval; + size_t bytes_read; + + *nbytes = 0; + *end_flag = 0; + if (length == 0) { + pr_warn("gpib: %s() called with zero length?\n", __func__); + return 0; + } + + if (board->master) { + retval = ibgts(board); + if (retval < 0) + return retval; + } + /* XXX resetting timer here could cause timeouts take longer than they should, + * since read_ioctl calls this + * function in a loop, there is probably a similar problem with writes/commands + */ + os_start_timer(board, board->usec_timeout); + + do { + ret = board->interface->read(board, buf, length - *nbytes, end_flag, &bytes_read); + if (ret < 0) { + pr_err("gpib read error\n"); + goto ibrd_out; + } + buf += bytes_read; + *nbytes += bytes_read; + if (need_resched()) + schedule(); + } while (ret == 0 && *nbytes > 0 && *nbytes < length && *end_flag == 0); +ibrd_out: + os_remove_timer(board); + + return ret; +} + +/* + * IBRPP + * Conduct a parallel poll and return the byte in buf. + * + * NOTE: + * 1. Prior to conducting the poll the interface is placed + * in the controller active state. + */ +int ibrpp(gpib_board_t *board, uint8_t *result) +{ + int retval = 0; + + os_start_timer(board, board->usec_timeout); + retval = ibcac(board, 1, 1); + if (retval) + return -1; + + if (board->interface->parallel_poll(board, result)) { + pr_err("gpib: parallel poll failed\n"); + retval = -1; + } + os_remove_timer(board); + return retval; +} + +int ibppc(gpib_board_t *board, uint8_t configuration) +{ + configuration &= 0x1f; + board->interface->parallel_poll_configure(board, configuration); + board->parallel_poll_configuration = configuration; + + return 0; +} + +int ibrsv2(gpib_board_t *board, uint8_t status_byte, int new_reason_for_service) +{ + int board_status = ibstatus(board); + const unsigned int MSS = status_byte & request_service_bit; + + if ((board_status & CIC)) { + pr_err("gpib: interface requested service while CIC\n"); + return -EINVAL; + } + + if (MSS == 0 && new_reason_for_service) + return -EINVAL; + + if (board->interface->serial_poll_response2) { + board->interface->serial_poll_response2(board, status_byte, new_reason_for_service); + // fall back on simpler serial_poll_response if the behavior would be the same + } else if (board->interface->serial_poll_response && + (MSS == 0 || (MSS && new_reason_for_service))) { + board->interface->serial_poll_response(board, status_byte); + } else { + return -EOPNOTSUPP; + } + + return 0; +} + +/* + * IBSIC + * Send IFC for at least 100 microseconds. + * + * NOTE: + * 1. Ibsic must be called prior to the first call to + * ibcmd in order to initialize the bus and enable the + * interface to leave the controller idle state. + */ +int ibsic(gpib_board_t *board, unsigned int usec_duration) +{ + if (board->master == 0) { + pr_err("gpib: tried to assert IFC when not system controller\n"); + return -1; + } + + if (usec_duration < 100) + usec_duration = 100; + if (usec_duration > 1000) { + usec_duration = 1000; + pr_warn("gpib: warning, shortening long udelay\n"); + } + + dev_dbg(board->gpib_dev, "sending interface clear\n"); + board->interface->interface_clear(board, 1); + udelay(usec_duration); + board->interface->interface_clear(board, 0); + + return 0; +} + +void ibrsc(gpib_board_t *board, int request_control) +{ + board->master = request_control != 0; + if (!board->interface->request_system_control) { + pr_err("gpib: bug! driver does not implement request_system_control()\n"); + return; + } + board->interface->request_system_control(board, request_control); +} + +/* + * IBSRE + * Send REN true if v is non-zero or false if v is zero. + */ +int ibsre(gpib_board_t *board, int enable) +{ + if (board->master == 0) { + pr_err("gpib: tried to set REN when not system controller\n"); + return -1; + } + + board->interface->remote_enable(board, enable); /* set or clear REN */ + if (!enable) + usleep_range(100, 150); + + return 0; +} + +/* + * IBPAD + * change the GPIB address of the interface board. The address + * must be 0 through 30. ibonl resets the address to PAD. + */ +int ibpad(gpib_board_t *board, unsigned int addr) +{ + if (addr > MAX_GPIB_PRIMARY_ADDRESS) { + pr_err("gpib: invalid primary address %u\n", addr); + return -1; + } + board->pad = addr; + if (board->online) + board->interface->primary_address(board, board->pad); + dev_dbg(board->gpib_dev, "set primary addr to %i\n", board->pad); + return 0; +} + +/* + * IBSAD + * change the secondary GPIB address of the interface board. + * The address must be 0 through 30, or negative disables. ibonl resets the + * address to SAD. + */ +int ibsad(gpib_board_t *board, int addr) +{ + if (addr > MAX_GPIB_SECONDARY_ADDRESS) { + pr_err("gpib: invalid secondary address %i\n", addr); + return -1; + } + board->sad = addr; + if (board->online) { + if (board->sad >= 0) + board->interface->secondary_address(board, board->sad, 1); + else + board->interface->secondary_address(board, 0, 0); + } + dev_dbg(board->gpib_dev, "set secondary addr to %i\n", board->sad); + + return 0; +} + +/* + * IBEOS + * Set the end-of-string modes for I/O operations to v. + * + */ +int ibeos(gpib_board_t *board, int eos, int eosflags) +{ + int retval; + + if (eosflags & ~EOS_MASK) { + pr_err("bad EOS modes\n"); + return -EINVAL; + } + if (eosflags & REOS) { + retval = board->interface->enable_eos(board, eos, eosflags & BIN); + } else { + board->interface->disable_eos(board); + retval = 0; + } + return retval; +} + +int ibstatus(gpib_board_t *board) +{ + return general_ibstatus(board, NULL, 0, 0, NULL); +} + +int general_ibstatus(gpib_board_t *board, const gpib_status_queue_t *device, + int clear_mask, int set_mask, gpib_descriptor_t *desc) +{ + int status = 0; + short line_status; + + if (board->private_data) { + status = board->interface->update_status(board, clear_mask); + /* XXX should probably stop having drivers use TIMO bit in + * board->status to avoid confusion + */ + status &= ~TIMO; + /* get real SRQI status if we can */ + if (iblines(board, &line_status) == 0) { + if ((line_status & ValidSRQ)) { + if ((line_status & BusSRQ)) + status |= SRQI; + else + status &= ~SRQI; + } + } + } + if (device) + if (num_status_bytes(device)) + status |= RQS; + + if (desc) { + if (set_mask & CMPL) + atomic_set(&desc->io_in_progress, 0); + else if (clear_mask & CMPL) + atomic_set(&desc->io_in_progress, 1); + + if (atomic_read(&desc->io_in_progress)) + status &= ~CMPL; + else + status |= CMPL; + } + if (num_gpib_events(&board->event_queue)) + status |= EVENT; + else + status &= ~EVENT; + + return status; +} + +struct wait_info { + gpib_board_t *board; + struct timer_list timer; + int timed_out; + unsigned long usec_timeout; +}; + +static void wait_timeout(struct timer_list *t) +{ + struct wait_info *winfo = from_timer(winfo, t, timer); + + winfo->timed_out = 1; + wake_up_interruptible(&winfo->board->wait); +} + +static void init_wait_info(struct wait_info *winfo) +{ + winfo->board = NULL; + winfo->timed_out = 0; + timer_setup_on_stack(&winfo->timer, wait_timeout, 0); +} + +static int wait_satisfied(struct wait_info *winfo, gpib_status_queue_t *status_queue, + int wait_mask, int *status, gpib_descriptor_t *desc) +{ + gpib_board_t *board = winfo->board; + int temp_status; + + if (mutex_lock_interruptible(&board->big_gpib_mutex)) + return -ERESTARTSYS; + + temp_status = general_ibstatus(board, status_queue, 0, 0, desc); + + mutex_unlock(&board->big_gpib_mutex); + + if (winfo->timed_out) + temp_status |= TIMO; + else + temp_status &= ~TIMO; + if (wait_mask & temp_status) { + *status = temp_status; + return 1; + } +//XXX does wait for END work? + return 0; +} + +/* install timer interrupt handler */ +static void start_wait_timer(struct wait_info *winfo) +/* Starts the timeout task */ +{ + winfo->timed_out = 0; + + if (winfo->usec_timeout > 0) + mod_timer(&winfo->timer, jiffies + usec_to_jiffies(winfo->usec_timeout)); +} + +static void remove_wait_timer(struct wait_info *winfo) +{ + del_timer_sync(&winfo->timer); + destroy_timer_on_stack(&winfo->timer); +} + +/* + * IBWAIT + * Check or wait for a GPIB event to occur. The mask argument + * is a bit vector corresponding to the status bit vector. It + * has a bit set for each condition which can terminate the wait + * If the mask is 0 then + * no condition is waited for. + */ +int ibwait(gpib_board_t *board, int wait_mask, int clear_mask, int set_mask, + int *status, unsigned long usec_timeout, gpib_descriptor_t *desc) +{ + int retval = 0; + gpib_status_queue_t *status_queue; + struct wait_info winfo; + + if (desc->is_board) + status_queue = NULL; + else + status_queue = get_gpib_status_queue(board, desc->pad, desc->sad); + + if (wait_mask == 0) { + *status = general_ibstatus(board, status_queue, clear_mask, set_mask, desc); + return 0; + } + + mutex_unlock(&board->big_gpib_mutex); + + init_wait_info(&winfo); + winfo.board = board; + winfo.usec_timeout = usec_timeout; + start_wait_timer(&winfo); + + if (wait_event_interruptible(board->wait, wait_satisfied(&winfo, status_queue, + wait_mask, status, desc))) { + dev_dbg(board->gpib_dev, "wait interrupted\n"); + retval = -ERESTARTSYS; + } + remove_wait_timer(&winfo); + + if (retval) + return retval; + if (mutex_lock_interruptible(&board->big_gpib_mutex)) + return -ERESTARTSYS; + + /* make sure we only clear status bits that we are reporting */ + if (*status & clear_mask || set_mask) + general_ibstatus(board, status_queue, *status & clear_mask, set_mask, 0); + + return 0; +} + +/* + * IBWRT + * Write cnt bytes of data from buf to the GPIB. The write + * operation terminates only on I/O complete. + * + * NOTE: + * 1. Prior to beginning the write, the interface is + * placed in the controller standby state. + * 2. Prior to calling ibwrt, the intended devices as + * well as the interface board itself must be + * addressed by calling ibcmd. + */ +int ibwrt(gpib_board_t *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written) +{ + int ret = 0; + int retval; + + if (cnt == 0) { + pr_warn("gpib: %s() called with zero length?\n", __func__); + return 0; + } + + if (board->master) { + retval = ibgts(board); + if (retval < 0) + return retval; + } + os_start_timer(board, board->usec_timeout); + ret = board->interface->write(board, buf, cnt, send_eoi, bytes_written); + + if (io_timed_out(board)) + ret = -ETIMEDOUT; + + os_remove_timer(board); + + return ret; +} + diff --git a/drivers/staging/gpib/common/ibsys.h b/drivers/staging/gpib/common/ibsys.h new file mode 100644 index 0000000000000000000000000000000000000000..da20971e9c7ee05e857dab4972f0f2fecf9f8a9f --- /dev/null +++ b/drivers/staging/gpib/common/ibsys.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include "gpibP.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define MAX_GPIB_PRIMARY_ADDRESS 30 +#define MAX_GPIB_SECONDARY_ADDRESS 31 + +int gpib_allocate_board(gpib_board_t *board); +void gpib_deallocate_board(gpib_board_t *board); + +unsigned int num_status_bytes(const gpib_status_queue_t *dev); +int push_status_byte(gpib_board_t *board, gpib_status_queue_t *device, uint8_t poll_byte); +int pop_status_byte(gpib_board_t *board, gpib_status_queue_t *device, uint8_t *poll_byte); +gpib_status_queue_t *get_gpib_status_queue(gpib_board_t *board, unsigned int pad, int sad); +int get_serial_poll_byte(gpib_board_t *board, unsigned int pad, int sad, + unsigned int usec_timeout, uint8_t *poll_byte); +int autopoll_all_devices(gpib_board_t *board); diff --git a/drivers/staging/gpib/eastwood/Makefile b/drivers/staging/gpib/eastwood/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c74056f959d034b0dda4ccde6984074c130593ee --- /dev/null +++ b/drivers/staging/gpib/eastwood/Makefile @@ -0,0 +1,3 @@ + +obj-m += fluke_gpib.o + diff --git a/drivers/staging/gpib/eastwood/fluke_gpib.c b/drivers/staging/gpib/eastwood/fluke_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..3f938ab0c84d98a05b0080a8c32dd17640c6972d --- /dev/null +++ b/drivers/staging/gpib/eastwood/fluke_gpib.c @@ -0,0 +1,1179 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * GPIB Driver for Fluke cda devices. Basically, its a driver for a (bugfixed) + * cb7210 connected to channel 0 of a pl330 dma controller. + * Author: Frank Mori Hess + * copyright: (C) 2006, 2010, 2015 Fluke Corporation + ***************************************************************************/ + +#include "fluke_gpib.h" + +#include "gpibP.h" +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB Driver for Fluke cda devices"); + +static int fluke_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config); +static int fluke_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config); +static void fluke_detach(gpib_board_t *board); +static int fluke_config_dma(gpib_board_t *board, int output); +static irqreturn_t fluke_gpib_internal_interrupt(gpib_board_t *board); + +static struct platform_device *fluke_gpib_pdev; + +static uint8_t fluke_locking_read_byte(struct nec7210_priv *nec_priv, unsigned int register_number) +{ + u8 retval; + unsigned long flags; + + spin_lock_irqsave(&nec_priv->register_page_lock, flags); + retval = fluke_read_byte_nolock(nec_priv, register_number); + spin_unlock_irqrestore(&nec_priv->register_page_lock, flags); + return retval; +} + +static void fluke_locking_write_byte(struct nec7210_priv *nec_priv, uint8_t byte, + unsigned int register_number) +{ + unsigned long flags; + + spin_lock_irqsave(&nec_priv->register_page_lock, flags); + fluke_write_byte_nolock(nec_priv, byte, register_number); + spin_unlock_irqrestore(&nec_priv->register_page_lock, flags); +} + +// wrappers for interface functions +static int fluke_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); +} + +static int fluke_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); +} + +static int fluke_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); +} + +static int fluke_take_control(gpib_board_t *board, int synchronous) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_take_control(board, &priv->nec7210_priv, synchronous); +} + +static int fluke_go_to_standby(gpib_board_t *board) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_go_to_standby(board, &priv->nec7210_priv); +} + +static void fluke_request_system_control(gpib_board_t *board, int request_control) +{ + struct fluke_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + + nec7210_request_system_control(board, nec_priv, request_control); +} + +static void fluke_interface_clear(gpib_board_t *board, int assert) +{ + struct fluke_priv *priv = board->private_data; + + nec7210_interface_clear(board, &priv->nec7210_priv, assert); +} + +static void fluke_remote_enable(gpib_board_t *board, int enable) +{ + struct fluke_priv *priv = board->private_data; + + nec7210_remote_enable(board, &priv->nec7210_priv, enable); +} + +static int fluke_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); +} + +static void fluke_disable_eos(gpib_board_t *board) +{ + struct fluke_priv *priv = board->private_data; + + nec7210_disable_eos(board, &priv->nec7210_priv); +} + +static unsigned int fluke_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); +} + +static int fluke_primary_address(gpib_board_t *board, unsigned int address) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_primary_address(board, &priv->nec7210_priv, address); +} + +static int fluke_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); +} + +static int fluke_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_parallel_poll(board, &priv->nec7210_priv, result); +} + +static void fluke_parallel_poll_configure(gpib_board_t *board, uint8_t configuration) +{ + struct fluke_priv *priv = board->private_data; + + nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration); +} + +static void fluke_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct fluke_priv *priv = board->private_data; + + nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); +} + +static void fluke_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct fluke_priv *priv = board->private_data; + + nec7210_serial_poll_response(board, &priv->nec7210_priv, status); +} + +static uint8_t fluke_serial_poll_status(gpib_board_t *board) +{ + struct fluke_priv *priv = board->private_data; + + return nec7210_serial_poll_status(board, &priv->nec7210_priv); +} + +static void fluke_return_to_local(gpib_board_t *board) +{ + struct fluke_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + + write_byte(nec_priv, AUX_RTL2, AUXMR); + udelay(1); + write_byte(nec_priv, AUX_RTL, AUXMR); +} + +static int fluke_line_status(const gpib_board_t *board) +{ + int status = ValidALL; + int bsr_bits; + struct fluke_priv *e_priv; + struct nec7210_priv *nec_priv; + + e_priv = board->private_data; + nec_priv = &e_priv->nec7210_priv; + + bsr_bits = fluke_paged_read_byte(e_priv, BUS_STATUS, BUS_STATUS_PAGE); + + if ((bsr_bits & BSR_REN_BIT) == 0) + status |= BusREN; + if ((bsr_bits & BSR_IFC_BIT) == 0) + status |= BusIFC; + if ((bsr_bits & BSR_SRQ_BIT) == 0) + status |= BusSRQ; + if ((bsr_bits & BSR_EOI_BIT) == 0) + status |= BusEOI; + if ((bsr_bits & BSR_NRFD_BIT) == 0) + status |= BusNRFD; + if ((bsr_bits & BSR_NDAC_BIT) == 0) + status |= BusNDAC; + if ((bsr_bits & BSR_DAV_BIT) == 0) + status |= BusDAV; + if ((bsr_bits & BSR_ATN_BIT) == 0) + status |= BusATN; + + return status; +} + +static unsigned int fluke_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned int retval; + + retval = nec7210_t1_delay(board, nec_priv, nano_sec); + + if (nano_sec <= 350) { + write_byte(nec_priv, AUX_HI_SPEED, AUXMR); + retval = 350; + } else { + write_byte(nec_priv, AUX_LO_SPEED, AUXMR); + } + return retval; +} + +static int lacs_or_read_ready(gpib_board_t *board) +{ + const struct fluke_priv *e_priv = board->private_data; + const struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned long flags; + int retval; + + spin_lock_irqsave(&board->spinlock, flags); + retval = test_bit(LACS_NUM, &board->status) || test_bit(READ_READY_BN, &nec_priv->state); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +/* Wait until it is possible for a read to do something useful. This + * is not essential, it only exists to prevent RFD holdoff from being released pointlessly. + */ +static int wait_for_read(gpib_board_t *board) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + + if (wait_event_interruptible(board->wait, + lacs_or_read_ready(board) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + return retval; +} + +/* Check if the SH state machine is in SGNS. We check twice since there is a very small chance + * we could be blowing through SGNS from SIDS to SDYS if there is already a + * byte available in the handshake state machine. We are interested + * in the case where the handshake is stuck in SGNS due to no byte being + * available to the chip (and thus we can be confident a dma transfer will + * result in at least one byte making it into the chip). This matters + * because we want to be confident before sending a "send eoi" auxilary + * command that we will be able to also put the associated data byte + * in the chip before any potential timeout. + */ +static int source_handshake_is_sgns(struct fluke_priv *e_priv) +{ + int i; + + for (i = 0; i < 2; ++i) { + if ((fluke_paged_read_byte(e_priv, STATE1_REG, STATE1_PAGE) & + SOURCE_HANDSHAKE_MASK) != SOURCE_HANDSHAKE_SGNS_BITS) { + return 0; + } + } + return 1; +} + +static int source_handshake_is_sids_or_sgns(struct fluke_priv *e_priv) +{ + unsigned int source_handshake_bits; + + source_handshake_bits = fluke_paged_read_byte(e_priv, STATE1_REG, STATE1_PAGE) & + SOURCE_HANDSHAKE_MASK; + + return (source_handshake_bits == SOURCE_HANDSHAKE_SGNS_BITS) || + (source_handshake_bits == SOURCE_HANDSHAKE_SIDS_BITS); +} + +/* Wait until the gpib chip is ready to accept a data out byte. + * If the chip is SGNS it is probably waiting for a a byte to + * be written to it. + */ +static int wait_for_data_out_ready(gpib_board_t *board) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; +// printk("%s: enter\n", __FUNCTION__); + + if (wait_event_interruptible(board->wait, + (test_bit(TACS_NUM, &board->status) && + source_handshake_is_sgns(e_priv)) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; +// printk("%s: exit, retval=%i\n", __FUNCTION__, retval); + return retval; +} + +static int wait_for_sids_or_sgns(gpib_board_t *board) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; +// printk("%s: enter\n", __FUNCTION__); + + if (wait_event_interruptible(board->wait, + source_handshake_is_sids_or_sgns(e_priv) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) + retval = -ERESTARTSYS; + + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; +// printk("%s: exit, retval=%i\n", __FUNCTION__, retval); + return retval; +} + +static void fluke_dma_callback(void *arg) +{ + gpib_board_t *board = arg; + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); +// printk("%s: enter\n", __FUNCTION__); + + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, HR_DOIE | HR_DIIE); + wake_up_interruptible(&board->wait); + + fluke_gpib_internal_interrupt(board); + clear_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state); + clear_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state); +// printk("%s: exit\n", __FUNCTION__); + spin_unlock_irqrestore(&board->spinlock, flags); +} + +static int fluke_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned long flags; + int retval = 0; + dma_addr_t address; + struct dma_async_tx_descriptor *tx_desc; + + *bytes_written = 0; +// printk("%s: enter\n", __FUNCTION__); + if (WARN_ON_ONCE(length > e_priv->dma_buffer_size)) + return -EFAULT; + dmaengine_terminate_all(e_priv->dma_channel); + // write-clear counter + writel(0x0, e_priv->write_transfer_counter); + + memcpy(e_priv->dma_buffer, buffer, length); + address = dma_map_single(board->dev, e_priv->dma_buffer, + length, DMA_TO_DEVICE); + /* program dma controller */ + retval = fluke_config_dma(board, 1); + if (retval) + goto cleanup; + + tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, address, length, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!tx_desc) { + pr_err("fluke_gpib: failed to allocate dma transmit descriptor\n"); + retval = -ENOMEM; + goto cleanup; + } + tx_desc->callback = fluke_dma_callback; + tx_desc->callback_param = board; + + spin_lock_irqsave(&board->spinlock, flags); + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO); + dmaengine_submit(tx_desc); + dma_async_issue_pending(e_priv->dma_channel); + + clear_bit(WRITE_READY_BN, &nec_priv->state); + set_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state); + + // printk("%s: in spin lock\n", __FUNCTION__); + spin_unlock_irqrestore(&board->spinlock, flags); + +// printk("%s: waiting for write.\n", __FUNCTION__); + // suspend until message is sent + if (wait_event_interruptible(board->wait, + ((readl(e_priv->write_transfer_counter) & + write_transfer_counter_mask) == length) || + test_bit(BUS_ERROR_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted!\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state)) + retval = -EIO; + // disable board's dma + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0); + + dmaengine_terminate_all(e_priv->dma_channel); + // make sure fluke_dma_callback got called + if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state)) + fluke_dma_callback(board); + + /* if everything went fine, try to wait until last byte is actually + * transmitted across gpib (but don't try _too_ hard) + */ + if (retval == 0) + retval = wait_for_sids_or_sgns(board); + + *bytes_written = readl(e_priv->write_transfer_counter) & write_transfer_counter_mask; + if (WARN_ON_ONCE(*bytes_written > length)) + return -EFAULT; + +cleanup: + dma_unmap_single(board->dev, address, length, DMA_TO_DEVICE); +// printk("%s: exit, retval=%d\n", __FUNCTION__, retval); + return retval; +} + +static int fluke_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + size_t remainder = length; + size_t transfer_size; + ssize_t retval = 0; + size_t dma_remainder = remainder; + + if (!e_priv->dma_channel) { + pr_err("fluke_gpib: No dma channel available, cannot do accel write."); + return -ENXIO; + } + + *bytes_written = 0; + if (length < 1) + return 0; + + clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME + + if (send_eoi) + --dma_remainder; +// printk("%s: entering while loop\n", __FUNCTION__); + + while (dma_remainder > 0) { + size_t num_bytes; + + retval = wait_for_data_out_ready(board); + if (retval < 0) + break; + + transfer_size = (e_priv->dma_buffer_size < dma_remainder) ? + e_priv->dma_buffer_size : dma_remainder; + retval = fluke_dma_write(board, buffer, transfer_size, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + break; + dma_remainder -= num_bytes; + remainder -= num_bytes; + buffer += num_bytes; + if (need_resched()) + schedule(); + } + if (retval < 0) + return retval; + //handle sending of last byte with eoi + if (send_eoi) { + size_t num_bytes; + // printk("%s: handling last byte\n", __FUNCTION__); + if (WARN_ON_ONCE(remainder != 1)) + return -EFAULT; + + /* wait until we are sure we will be able to write the data byte + * into the chip before we send AUX_SEOI. This prevents a timeout + * scenerio where we send AUX_SEOI but then timeout without getting + * any bytes into the gpib chip. This will result in the first byte + * of the next write having a spurious EOI set on the first byte. + */ + retval = wait_for_data_out_ready(board); + if (retval < 0) + return retval; + + write_byte(nec_priv, AUX_SEOI, AUXMR); + retval = fluke_dma_write(board, buffer, remainder, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + remainder -= num_bytes; + } +// printk("%s: bytes send=%i\n", __FUNCTION__, (int)(length - remainder)); + return 0; +} + +static int fluke_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie) +{ + struct dma_tx_state state; + int result; + + result = dmaengine_pause(chan); + if (result < 0) { + pr_err("fluke_gpib: dma pause failed?\n"); + return result; + } + dmaengine_tx_status(chan, cookie, &state); + // hardware doesn't support resume, so dont call this + // method unless the dma transfer is done. + return state.residue; +} + +static int fluke_dma_read(gpib_board_t *board, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + unsigned long flags; + int residue; + dma_addr_t bus_address; + struct dma_async_tx_descriptor *tx_desc; + dma_cookie_t dma_cookie; + int i; + static const int timeout = 10; + + // printk("%s: enter, bus_address=0x%x, length=%i\n", __FUNCTION__, + // (unsigned)bus_address, + // (int)length); + + *bytes_read = 0; + *end = 0; + if (length == 0) + return 0; + + bus_address = dma_map_single(board->dev, e_priv->dma_buffer, + length, DMA_FROM_DEVICE); + + /* program dma controller */ + retval = fluke_config_dma(board, 0); + if (retval) { + dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE); + return retval; + } + tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, + bus_address, length, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!tx_desc) { + pr_err("fluke_gpib: failed to allocate dma transmit descriptor\n"); + dma_unmap_single(NULL, bus_address, length, DMA_FROM_DEVICE); + return -EIO; + } + tx_desc->callback = fluke_dma_callback; + tx_desc->callback_param = board; + + spin_lock_irqsave(&board->spinlock, flags); + // enable nec7210 dma + nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI); + + dma_cookie = dmaengine_submit(tx_desc); + dma_async_issue_pending(e_priv->dma_channel); + + set_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state); + clear_bit(READ_READY_BN, &nec_priv->state); + + spin_unlock_irqrestore(&board->spinlock, flags); +// printk("waiting for data transfer.\n"); + // wait for data to transfer + if (wait_event_interruptible(board->wait, + test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state) == 0 || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_warn("fluke: dma read wait interrupted\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + + /* If we woke up because of end, wait until the dma transfer has pulled + * the data byte associated with the end before we cancel the dma transfer. + */ + if (test_bit(RECEIVED_END_BN, &nec_priv->state)) { + for (i = 0; i < timeout; ++i) { + if (test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state) == 0) + break; + if ((read_byte(nec_priv, ADR0) & DATA_IN_STATUS) == 0) + break; + usleep_range(10, 15); + } + if (i == timeout) + pr_warn("fluke_gpib: timeout waiting for dma to transfer end data byte.\n"); + } + + // stop the dma transfer + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + /* delay a little just to make sure any bytes in dma controller's fifo get + * written to memory before we disable it + */ + usleep_range(10, 15); + residue = fluke_get_dma_residue(e_priv->dma_channel, dma_cookie); + if (WARN_ON_ONCE(residue > length || residue < 0)) + return -EFAULT; + *bytes_read += length - residue; + dmaengine_terminate_all(e_priv->dma_channel); + // make sure fluke_dma_callback got called + if (test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state)) + fluke_dma_callback(board); + + dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE); + memcpy(buffer, e_priv->dma_buffer, *bytes_read); + + /* If we got an end interrupt, figure out if it was + * associated with the last byte we dma'd or with a + * byte still sitting on the cb7210. + */ + spin_lock_irqsave(&board->spinlock, flags); + if (test_bit(READ_READY_BN, &nec_priv->state) == 0) { + // There is no byte sitting on the cb7210. If we + // saw an end interrupt, we need to deal with it now + if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) + *end = 1; + } + spin_unlock_irqrestore(&board->spinlock, flags); + + return retval; +} + +static int fluke_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + size_t remain = length; + size_t transfer_size; + int retval = 0; + size_t dma_nbytes; + +/* printk("%s: enter, buffer=0x%p, length=%i\n", __FUNCTION__, + * buffer, (int)length); + * printk("\t dma_buffer=0x%p\n", e_priv->dma_buffer); + */ + *end = 0; + *bytes_read = 0; + + smp_mb__before_atomic(); + clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME + smp_mb__after_atomic(); + + retval = wait_for_read(board); + if (retval < 0) + return retval; + + nec7210_release_rfd_holdoff(board, nec_priv); + +// printk("%s: entering while loop\n", __FUNCTION__); + while (remain > 0) { + transfer_size = (e_priv->dma_buffer_size < remain) ? + e_priv->dma_buffer_size : remain; + retval = fluke_dma_read(board, buffer, transfer_size, end, &dma_nbytes); + remain -= dma_nbytes; + buffer += dma_nbytes; + *bytes_read += dma_nbytes; + if (*end) + break; + if (retval < 0) { +// printk("%s: early exit, retval=%i\n", __FUNCTION__, (int)retval); + return retval; + } + if (need_resched()) + schedule(); + } +// printk("%s: exit, retval=%i\n", __FUNCTION__, (int)retval); + return retval; +} + +gpib_interface_t fluke_unaccel_interface = { +name: "fluke_unaccel", +attach : fluke_attach_holdoff_all, +detach : fluke_detach, +read : fluke_read, +write : fluke_write, +command : fluke_command, +take_control : fluke_take_control, +go_to_standby : fluke_go_to_standby, +request_system_control : fluke_request_system_control, +interface_clear : fluke_interface_clear, +remote_enable : fluke_remote_enable, +enable_eos : fluke_enable_eos, +disable_eos : fluke_disable_eos, +parallel_poll : fluke_parallel_poll, +parallel_poll_configure : fluke_parallel_poll_configure, +parallel_poll_response : fluke_parallel_poll_response, +line_status : fluke_line_status, +update_status : fluke_update_status, +primary_address : fluke_primary_address, +secondary_address : fluke_secondary_address, +serial_poll_response : fluke_serial_poll_response, +serial_poll_status : fluke_serial_poll_status, +t1_delay : fluke_t1_delay, +return_to_local : fluke_return_to_local, +}; + +/* fluke_hybrid uses dma for writes but not for reads. Added + * to deal with occasional corruption of bytes seen when doing dma + * reads. From looking at the cb7210 vhdl, I believe the corruption + * is due to a hardware bug triggered by the cpu reading a cb7210 + * } + * register just as the dma controller is also doing a read. + */ + +gpib_interface_t fluke_hybrid_interface = { +name: "fluke_hybrid", +attach : fluke_attach_holdoff_all, +detach : fluke_detach, +read : fluke_read, +write : fluke_accel_write, +command : fluke_command, +take_control : fluke_take_control, +go_to_standby : fluke_go_to_standby, +request_system_control : fluke_request_system_control, +interface_clear : fluke_interface_clear, +remote_enable : fluke_remote_enable, +enable_eos : fluke_enable_eos, +disable_eos : fluke_disable_eos, +parallel_poll : fluke_parallel_poll, +parallel_poll_configure : fluke_parallel_poll_configure, +parallel_poll_response : fluke_parallel_poll_response, +line_status : fluke_line_status, +update_status : fluke_update_status, +primary_address : fluke_primary_address, +secondary_address : fluke_secondary_address, +serial_poll_response : fluke_serial_poll_response, +serial_poll_status : fluke_serial_poll_status, +t1_delay : fluke_t1_delay, +return_to_local : fluke_return_to_local, +}; + +gpib_interface_t fluke_interface = { +name: "fluke", +attach : fluke_attach_holdoff_end, +detach : fluke_detach, +read : fluke_accel_read, +write : fluke_accel_write, +command : fluke_command, +take_control : fluke_take_control, +go_to_standby : fluke_go_to_standby, +request_system_control : fluke_request_system_control, +interface_clear : fluke_interface_clear, +remote_enable : fluke_remote_enable, +enable_eos : fluke_enable_eos, +disable_eos : fluke_disable_eos, +parallel_poll : fluke_parallel_poll, +parallel_poll_configure : fluke_parallel_poll_configure, +parallel_poll_response : fluke_parallel_poll_response, +line_status : fluke_line_status, +update_status : fluke_update_status, +primary_address : fluke_primary_address, +secondary_address : fluke_secondary_address, +serial_poll_response : fluke_serial_poll_response, +serial_poll_status : fluke_serial_poll_status, +t1_delay : fluke_t1_delay, +return_to_local : fluke_return_to_local, +}; + +irqreturn_t fluke_gpib_internal_interrupt(gpib_board_t *board) +{ + int status0, status1, status2; + struct fluke_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + int retval = IRQ_NONE; + + if (read_byte(nec_priv, ADR0) & DATA_IN_STATUS) + set_bit(READ_READY_BN, &nec_priv->state); + + status0 = fluke_paged_read_byte(priv, ISR0_IMR0, ISR0_IMR0_PAGE); + status1 = read_byte(nec_priv, ISR1); + status2 = read_byte(nec_priv, ISR2); + + if (status0 & FLUKE_IFCI_BIT) { + push_gpib_event(board, EventIFC); + retval = IRQ_HANDLED; + } + + if (nec7210_interrupt_have_status(board, nec_priv, status1, status2) == IRQ_HANDLED) + retval = IRQ_HANDLED; +/* + * if((status1 & nec_priv->reg_bits[IMR1]) || + * (status2 & (nec_priv->reg_bits[IMR2] & IMR2_ENABLE_INTR_MASK))) + * { + * printk("fluke: status1 0x%x, status2 0x%x\n", status1, status2); + * } + */ + + if (read_byte(nec_priv, ADR0) & DATA_IN_STATUS) { + if (test_bit(RFD_HOLDOFF_BN, &nec_priv->state)) + set_bit(READ_READY_BN, &nec_priv->state); + else + clear_bit(READ_READY_BN, &nec_priv->state); + } + + if (retval == IRQ_HANDLED) + wake_up_interruptible(&board->wait); + + return retval; +} + +static irqreturn_t fluke_gpib_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + unsigned long flags; + irqreturn_t retval; + + spin_lock_irqsave(&board->spinlock, flags); + retval = fluke_gpib_internal_interrupt(board); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +static int fluke_allocate_private(gpib_board_t *board) +{ + struct fluke_priv *priv; + + board->private_data = kmalloc(sizeof(struct fluke_priv), GFP_KERNEL); + if (!board->private_data) + return -ENOMEM; + priv = board->private_data; + memset(priv, 0, sizeof(struct fluke_priv)); + init_nec7210_private(&priv->nec7210_priv); + priv->dma_buffer_size = 0x7ff; + priv->dma_buffer = kmalloc(priv->dma_buffer_size, GFP_KERNEL); + if (!priv->dma_buffer) + return -ENOMEM; + return 0; +} + +static void fluke_generic_detach(gpib_board_t *board) +{ + if (board->private_data) { + struct fluke_priv *e_priv = board->private_data; + + kfree(e_priv->dma_buffer); + kfree(board->private_data); + board->private_data = NULL; + } +} + +// generic part of attach functions shared by all cb7210 boards +static int fluke_generic_attach(gpib_board_t *board) +{ + struct fluke_priv *e_priv; + struct nec7210_priv *nec_priv; + int retval; + + board->status = 0; + + retval = fluke_allocate_private(board); + if (retval < 0) + return retval; + e_priv = board->private_data; + nec_priv = &e_priv->nec7210_priv; + nec_priv->read_byte = fluke_locking_read_byte; + nec_priv->write_byte = fluke_locking_write_byte; + nec_priv->offset = fluke_reg_offset; + nec_priv->type = CB7210; + return 0; +} + +static int fluke_config_dma(gpib_board_t *board, int output) +{ + struct fluke_priv *e_priv = board->private_data; + struct dma_slave_config config; + + config.src_maxburst = 1; + config.dst_maxburst = 1; + config.device_fc = true; + + if (output) { + config.direction = DMA_MEM_TO_DEV; + config.src_addr = 0; + config.dst_addr = e_priv->dma_port_res->start; + config.src_addr_width = 1; + config.dst_addr_width = 1; + } else { + config.direction = DMA_DEV_TO_MEM; + config.src_addr = e_priv->dma_port_res->start; + config.dst_addr = 0; + config.src_addr_width = 1; + config.dst_addr_width = 1; + } + return dmaengine_slave_config(e_priv->dma_channel, &config); +} + +static int fluke_init(struct fluke_priv *e_priv, gpib_board_t *board, int handshake_mode) +{ + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + + nec7210_board_reset(nec_priv, board); + write_byte(nec_priv, AUX_LO_SPEED, AUXMR); + /* set clock register for driving frequency + * ICR should be set to clock in megahertz (1-15) and to zero + * for clocks faster than 15 MHz (max 20MHz) + */ + write_byte(nec_priv, ICR | 10, AUXMR); + nec7210_set_handshake_mode(board, nec_priv, handshake_mode); + + nec7210_board_online(nec_priv, board); + + /* poll so we can detect ATN changes */ + if (gpib_request_pseudo_irq(board, fluke_gpib_interrupt)) { + pr_err("fluke_gpib: failed to allocate pseudo_irq\n"); + return -EINVAL; + } + + fluke_paged_write_byte(e_priv, FLUKE_IFCIE_BIT, ISR0_IMR0, ISR0_IMR0_PAGE); + return 0; +} + +/* This function is passed to dma_request_channel() in order to + * select the pl330 dma channel which has been hardwired to + * the gpib controller. + */ +static bool gpib_dma_channel_filter(struct dma_chan *chan, void *filter_param) +{ + // select the channel which is wired to the gpib chip + return chan->chan_id == 0; +} + +static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *config, + unsigned int handshake_mode) +{ + struct fluke_priv *e_priv; + struct nec7210_priv *nec_priv; + int isr_flags = 0; + int retval; + int irq; + struct resource *res; + dma_cap_mask_t dma_cap; + + if (!fluke_gpib_pdev) { + pr_err("No gpib platform device was found, attach failed.\n"); + return -ENODEV; + } + + retval = fluke_generic_attach(board); + if (retval) + return retval; + + e_priv = board->private_data; + nec_priv = &e_priv->nec7210_priv; + nec_priv->offset = fluke_reg_offset; + board->dev = &fluke_gpib_pdev->dev; + + res = platform_get_resource(fluke_gpib_pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource for cb7210 gpib\n"); + return -ENODEV; + } + + if (request_mem_region(res->start, + resource_size(res), + fluke_gpib_pdev->name) == NULL) { + dev_err(&fluke_gpib_pdev->dev, "cannot claim registers\n"); + return -ENXIO; + } + e_priv->gpib_iomem_res = res; + + nec_priv->iobase = ioremap(e_priv->gpib_iomem_res->start, + resource_size(e_priv->gpib_iomem_res)); + pr_info("gpib: iobase %lx remapped to %p, length=%d\n", + (unsigned long)e_priv->gpib_iomem_res->start, + nec_priv->iobase, (int)resource_size(e_priv->gpib_iomem_res)); + if (!nec_priv->iobase) { + dev_err(&fluke_gpib_pdev->dev, "Could not map I/O memory\n"); + return -ENOMEM; + } + + res = platform_get_resource(fluke_gpib_pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource for gpib dma port\n"); + return -ENODEV; + } + if (request_mem_region(res->start, + resource_size(res), + fluke_gpib_pdev->name) == NULL) { + dev_err(&fluke_gpib_pdev->dev, "cannot claim registers\n"); + return -ENXIO; + } + e_priv->dma_port_res = res; + + res = platform_get_resource(fluke_gpib_pdev, IORESOURCE_MEM, 2); + if (!res) { + dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource for write transfer counter\n"); + return -ENODEV; + } + + if (request_mem_region(res->start, + resource_size(res), + fluke_gpib_pdev->name) == NULL) { + dev_err(&fluke_gpib_pdev->dev, "cannot claim registers\n"); + return -ENXIO; + } + e_priv->write_transfer_counter_res = res; + + e_priv->write_transfer_counter = ioremap(e_priv->write_transfer_counter_res->start, + resource_size(e_priv->write_transfer_counter_res)); + pr_info("gpib: write transfer counter %lx remapped to %p, length=%d\n", + (unsigned long)e_priv->write_transfer_counter_res->start, + e_priv->write_transfer_counter, + (int)resource_size(e_priv->write_transfer_counter_res)); + if (!e_priv->write_transfer_counter) { + dev_err(&fluke_gpib_pdev->dev, "Could not map I/O memory\n"); + return -ENOMEM; + } + + irq = platform_get_irq(fluke_gpib_pdev, 0); + pr_info("gpib: irq %d\n", irq); + if (irq < 0) { + dev_err(&fluke_gpib_pdev->dev, "fluke_gpib: request for IRQ failed\n"); + return -EBUSY; + } + retval = request_irq(irq, fluke_gpib_interrupt, isr_flags, fluke_gpib_pdev->name, board); + if (retval) { + dev_err(&fluke_gpib_pdev->dev, + "cannot register interrupt handler err=%d\n", + retval); + return retval; + } + e_priv->irq = irq; + + dma_cap_zero(dma_cap); + dma_cap_set(DMA_SLAVE, dma_cap); + e_priv->dma_channel = dma_request_channel(dma_cap, gpib_dma_channel_filter, NULL); + if (!e_priv->dma_channel) { + pr_err("fluke_gpib: failed to allocate a dma channel.\n"); + // we don't error out here because unaccel interface will still + // work without dma + } + + return fluke_init(e_priv, board, handshake_mode); +} + +int fluke_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config) +{ + return fluke_attach_impl(board, config, HR_HLDA); +} + +int fluke_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config) +{ + return fluke_attach_impl(board, config, HR_HLDE); +} + +void fluke_detach(gpib_board_t *board) +{ + struct fluke_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (e_priv) { + if (e_priv->dma_channel) + dma_release_channel(e_priv->dma_channel); + gpib_free_pseudo_irq(board); + nec_priv = &e_priv->nec7210_priv; + + if (nec_priv->iobase) { + fluke_paged_write_byte(e_priv, 0, ISR0_IMR0, ISR0_IMR0_PAGE); + nec7210_board_reset(nec_priv, board); + } + if (e_priv->irq) + free_irq(e_priv->irq, board); + if (e_priv->write_transfer_counter_res) { + release_mem_region(e_priv->write_transfer_counter_res->start, + resource_size(e_priv->write_transfer_counter_res)); + } + if (e_priv->dma_port_res) { + release_mem_region(e_priv->dma_port_res->start, + resource_size(e_priv->dma_port_res)); + } + if (e_priv->gpib_iomem_res) + release_mem_region(e_priv->gpib_iomem_res->start, + resource_size(e_priv->gpib_iomem_res)); + } + fluke_generic_detach(board); +} + +static int fluke_gpib_probe(struct platform_device *pdev) +{ + fluke_gpib_pdev = pdev; + return 0; +} + +static const struct of_device_id fluke_gpib_of_match[] = { + { .compatible = "flk,fgpib-4.0"}, + { {0} } +}; +MODULE_DEVICE_TABLE(of, fluke_gpib_of_match); + +static struct platform_driver fluke_gpib_platform_driver = { + .driver = { + .name = "fluke_gpib", + .owner = THIS_MODULE, + .of_match_table = fluke_gpib_of_match, + }, + .probe = &fluke_gpib_probe +}; + +static int __init fluke_init_module(void) +{ + int result; + + result = platform_driver_register(&fluke_gpib_platform_driver); + if (result) { + pr_err("fluke_gpib: platform_driver_register failed!\n"); + return result; + } + + gpib_register_driver(&fluke_unaccel_interface, THIS_MODULE); + gpib_register_driver(&fluke_hybrid_interface, THIS_MODULE); + gpib_register_driver(&fluke_interface, THIS_MODULE); + + pr_info("fluke_gpib\n"); + return 0; +} + +static void __exit fluke_exit_module(void) +{ + gpib_unregister_driver(&fluke_unaccel_interface); + gpib_unregister_driver(&fluke_hybrid_interface); + gpib_unregister_driver(&fluke_interface); + platform_driver_unregister(&fluke_gpib_platform_driver); +} + +module_init(fluke_init_module); +module_exit(fluke_exit_module); diff --git a/drivers/staging/gpib/eastwood/fluke_gpib.h b/drivers/staging/gpib/eastwood/fluke_gpib.h new file mode 100644 index 0000000000000000000000000000000000000000..fcbd42f8f9af6144d57ff342c9adb51da6134bc6 --- /dev/null +++ b/drivers/staging/gpib/eastwood/fluke_gpib.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Author: Frank Mori Hess + * copyright: (C) 2006, 2010, 2015 Fluke Corporation + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include "nec7210.h" + +struct fluke_priv { + struct nec7210_priv nec7210_priv; + struct resource *gpib_iomem_res; + struct resource *write_transfer_counter_res; + struct resource *dma_port_res; + int irq; + struct dma_chan *dma_channel; + u8 *dma_buffer; + int dma_buffer_size; + void *write_transfer_counter; +}; + +// cb7210 specific registers and bits +enum cb7210_regs { + STATE1_REG = 0x4, + ISR0_IMR0 = 0x6, + BUS_STATUS = 0x7 +}; + +enum cb7210_page_in { + ISR0_IMR0_PAGE = 1, + BUS_STATUS_PAGE = 1, + STATE1_PAGE = 1 +}; + +/* IMR0 -- Interrupt Mode Register 0 */ +enum imr0_bits { + FLUKE_IFCIE_BIT = 0x8, /* interface clear interrupt */ +}; + +/* ISR0 -- Interrupt Status Register 0 */ +enum isr0_bits { + FLUKE_IFCI_BIT = 0x8, /* interface clear interrupt */ +}; + +enum state1_bits { + SOURCE_HANDSHAKE_SIDS_BITS = 0x0, /* source idle state */ + SOURCE_HANDSHAKE_SGNS_BITS = 0x1, /* source generate state */ + SOURCE_HANDSHAKE_SDYS_BITS = 0x2, /* source delay state */ + SOURCE_HANDSHAKE_STRS_BITS = 0x5, /* source transfer state */ + SOURCE_HANDSHAKE_MASK = 0x7 +}; + +// we customized the cb7210 vhdl to give the "data in" status +// on the unused bit 7 of the address0 register. +enum cb7210_address0 { + DATA_IN_STATUS = 0x80 +}; + +static inline int cb7210_page_in_bits(unsigned int page) +{ + return 0x50 | (page & 0xf); +} + +// don't use without locking nec_priv->register_page_lock +static inline uint8_t fluke_read_byte_nolock(struct nec7210_priv *nec_priv, + int register_num) +{ + u8 retval; + + retval = readl(nec_priv->iobase + register_num * nec_priv->offset); + return retval; +} + +// don't use without locking nec_priv->register_page_lock +static inline void fluke_write_byte_nolock(struct nec7210_priv *nec_priv, uint8_t data, + int register_num) +{ + writel(data, nec_priv->iobase + register_num * nec_priv->offset); +} + +static inline uint8_t fluke_paged_read_byte(struct fluke_priv *e_priv, + unsigned int register_num, unsigned int page) +{ + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + u8 retval; + unsigned long flags; + + spin_lock_irqsave(&nec_priv->register_page_lock, flags); + fluke_write_byte_nolock(nec_priv, cb7210_page_in_bits(page), AUXMR); + udelay(1); + /* chip auto clears the page after a read */ + retval = fluke_read_byte_nolock(nec_priv, register_num); + spin_unlock_irqrestore(&nec_priv->register_page_lock, flags); + return retval; +} + +static inline void fluke_paged_write_byte(struct fluke_priv *e_priv, uint8_t data, + unsigned int register_num, unsigned int page) +{ + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned long flags; + + spin_lock_irqsave(&nec_priv->register_page_lock, flags); + fluke_write_byte_nolock(nec_priv, cb7210_page_in_bits(page), AUXMR); + udelay(1); + fluke_write_byte_nolock(nec_priv, data, register_num); + spin_unlock_irqrestore(&nec_priv->register_page_lock, flags); +} + +enum bus_status_bits { + BSR_ATN_BIT = 0x1, + BSR_EOI_BIT = 0x2, + BSR_SRQ_BIT = 0x4, + BSR_IFC_BIT = 0x8, + BSR_REN_BIT = 0x10, + BSR_DAV_BIT = 0x20, + BSR_NRFD_BIT = 0x40, + BSR_NDAC_BIT = 0x80, +}; + +enum cb7210_aux_cmds { +/* AUX_RTL2 is an undocumented aux command which causes cb7210 to assert + * (and keep asserted) local rtl message. This is used in conjunction + * with the (stupid) cb7210 implementation + * of the normal nec7210 AUX_RTL aux command, which + * causes the rtl message to toggle between on and off. + */ + AUX_RTL2 = 0xd, + AUX_NBAF = 0xe, // new byte available false (also clears seoi) + AUX_LO_SPEED = 0x40, + AUX_HI_SPEED = 0x41, +}; + +enum { + fluke_reg_offset = 4, + fluke_num_regs = 8, + write_transfer_counter_mask = 0x7ff, +}; diff --git a/drivers/staging/gpib/fmh_gpib/Makefile b/drivers/staging/gpib/fmh_gpib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cc4d9e7cd5cdc674a82ad645bf7fde75e7fbc88d --- /dev/null +++ b/drivers/staging/gpib/fmh_gpib/Makefile @@ -0,0 +1,2 @@ + +obj-$(CONFIG_GPIB_FMH) += fmh_gpib.o diff --git a/drivers/staging/gpib/fmh_gpib/fmh_gpib.c b/drivers/staging/gpib/fmh_gpib/fmh_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..62791db1c34a4fc25978c1bea85fb079a8053e4e --- /dev/null +++ b/drivers/staging/gpib/fmh_gpib/fmh_gpib.c @@ -0,0 +1,1725 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * GPIB Driver for fmh_gpib_core, see + * https://github.com/fmhess/fmh_gpib_core + * + * More specifically, it is a driver for the hardware arrangement described by + * src/examples/fmh_gpib_top.vhd in the fmh_gpib_core repository. + * + * Author: Frank Mori Hess + * Copyright: (C) 2006, 2010, 2015 Fluke Corporation + * (C) 2017 Frank Mori Hess + ***************************************************************************/ + +#include "fmh_gpib.h" + +#include "gpibP.h" +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +static irqreturn_t fmh_gpib_interrupt(int irq, void *arg); +static int fmh_gpib_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config); +static int fmh_gpib_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config); +static void fmh_gpib_detach(gpib_board_t *board); +static int fmh_gpib_pci_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config); +static int fmh_gpib_pci_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config); +static void fmh_gpib_pci_detach(gpib_board_t *board); +static int fmh_gpib_config_dma(gpib_board_t *board, int output); +static irqreturn_t fmh_gpib_internal_interrupt(gpib_board_t *board); +static struct platform_driver fmh_gpib_platform_driver; +static struct pci_driver fmh_gpib_pci_driver; + +// wrappers for interface functions +static int fmh_gpib_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); +} + +static int fmh_gpib_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); +} + +static int fmh_gpib_command(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); +} + +static int fmh_gpib_take_control(gpib_board_t *board, int synchronous) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_take_control(board, &priv->nec7210_priv, synchronous); +} + +static int fmh_gpib_go_to_standby(gpib_board_t *board) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_go_to_standby(board, &priv->nec7210_priv); +} + +static void fmh_gpib_request_system_control(gpib_board_t *board, int request_control) +{ + struct fmh_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + + nec7210_request_system_control(board, nec_priv, request_control); +} + +static void fmh_gpib_interface_clear(gpib_board_t *board, int assert) +{ + struct fmh_priv *priv = board->private_data; + + nec7210_interface_clear(board, &priv->nec7210_priv, assert); +} + +static void fmh_gpib_remote_enable(gpib_board_t *board, int enable) +{ + struct fmh_priv *priv = board->private_data; + + nec7210_remote_enable(board, &priv->nec7210_priv, enable); +} + +static int fmh_gpib_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); +} + +static void fmh_gpib_disable_eos(gpib_board_t *board) +{ + struct fmh_priv *priv = board->private_data; + + nec7210_disable_eos(board, &priv->nec7210_priv); +} + +static unsigned int fmh_gpib_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); +} + +static int fmh_gpib_primary_address(gpib_board_t *board, unsigned int address) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_primary_address(board, &priv->nec7210_priv, address); +} + +static int fmh_gpib_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); +} + +static int fmh_gpib_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_parallel_poll(board, &priv->nec7210_priv, result); +} + +static void fmh_gpib_parallel_poll_configure(gpib_board_t *board, uint8_t configuration) +{ + struct fmh_priv *priv = board->private_data; + + nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration); +} + +static void fmh_gpib_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct fmh_priv *priv = board->private_data; + + nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); +} + +static void fmh_gpib_local_parallel_poll_mode(gpib_board_t *board, int local) +{ + struct fmh_priv *priv = board->private_data; + + if (local) { + write_byte(&priv->nec7210_priv, AUX_I_REG | LOCAL_PPOLL_MODE_BIT, AUXMR); + } else { + /* For fmh_gpib_core, remote parallel poll config mode is unaffected by the + * state of the disable bit of the parallel poll register (unlike the tnt4882). + * So, we don't need to worry about that. + */ + write_byte(&priv->nec7210_priv, AUX_I_REG | 0x0, AUXMR); + } +} + +static void fmh_gpib_serial_poll_response2(gpib_board_t *board, uint8_t status, + int new_reason_for_service) +{ + struct fmh_priv *priv = board->private_data; + unsigned long flags; + const int MSS = status & request_service_bit; + const int reqt = MSS && new_reason_for_service; + const int reqf = MSS == 0; + + spin_lock_irqsave(&board->spinlock, flags); + if (reqt) { + priv->nec7210_priv.srq_pending = 1; + clear_bit(SPOLL_NUM, &board->status); + } else if (reqf) { + priv->nec7210_priv.srq_pending = 0; + } + + if (reqt) { + /* It may seem like a race to issue reqt before updating + * the status byte, but it is not. The chip does not + * issue the reqt until the SPMR is written to at + * a later time. + */ + write_byte(&priv->nec7210_priv, AUX_REQT, AUXMR); + } else if (reqf) { + write_byte(&priv->nec7210_priv, AUX_REQF, AUXMR); + } + /* We need to always zero bit 6 of the status byte before writing it to + * the SPMR to insure we are using + * serial poll mode SP1, and not accidentally triggering mode SP3. + */ + write_byte(&priv->nec7210_priv, status & ~request_service_bit, SPMR); + spin_unlock_irqrestore(&board->spinlock, flags); +} + +static uint8_t fmh_gpib_serial_poll_status(gpib_board_t *board) +{ + struct fmh_priv *priv = board->private_data; + + return nec7210_serial_poll_status(board, &priv->nec7210_priv); +} + +static void fmh_gpib_return_to_local(gpib_board_t *board) +{ + struct fmh_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + + write_byte(nec_priv, AUX_RTL2, AUXMR); + udelay(1); + write_byte(nec_priv, AUX_RTL, AUXMR); +} + +static int fmh_gpib_line_status(const gpib_board_t *board) +{ + int status = ValidALL; + int bsr_bits; + struct fmh_priv *e_priv; + struct nec7210_priv *nec_priv; + + e_priv = board->private_data; + nec_priv = &e_priv->nec7210_priv; + + bsr_bits = read_byte(nec_priv, BUS_STATUS_REG); + + if ((bsr_bits & BSR_REN_BIT) == 0) + status |= BusREN; + if ((bsr_bits & BSR_IFC_BIT) == 0) + status |= BusIFC; + if ((bsr_bits & BSR_SRQ_BIT) == 0) + status |= BusSRQ; + if ((bsr_bits & BSR_EOI_BIT) == 0) + status |= BusEOI; + if ((bsr_bits & BSR_NRFD_BIT) == 0) + status |= BusNRFD; + if ((bsr_bits & BSR_NDAC_BIT) == 0) + status |= BusNDAC; + if ((bsr_bits & BSR_DAV_BIT) == 0) + status |= BusDAV; + if ((bsr_bits & BSR_ATN_BIT) == 0) + status |= BusATN; + + return status; +} + +static unsigned int fmh_gpib_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned int retval; + + retval = nec7210_t1_delay(board, nec_priv, nano_sec); + + if (nano_sec <= 350) { + write_byte(nec_priv, AUX_HI_SPEED, AUXMR); + retval = 350; + } else { + write_byte(nec_priv, AUX_LO_SPEED, AUXMR); + } + return retval; +} + +static int lacs_or_read_ready(gpib_board_t *board) +{ + const struct fmh_priv *e_priv = board->private_data; + const struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + retval = test_bit(LACS_NUM, &board->status) || + test_bit(READ_READY_BN, &nec_priv->state); + spin_unlock_irqrestore(&board->spinlock, flags); + + return retval; +} + +static int wait_for_read(gpib_board_t *board) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + + if (wait_event_interruptible(board->wait, + lacs_or_read_ready(board) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) + retval = -ERESTARTSYS; + + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + return retval; +} + +static int wait_for_rx_fifo_half_full_or_end(gpib_board_t *board) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + + if (wait_event_interruptible(board->wait, + (fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) & + RX_FIFO_HALF_FULL) || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) + retval = -ERESTARTSYS; + + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + return retval; +} + +/* Wait until the gpib chip is ready to accept a data out byte. + */ +static int wait_for_data_out_ready(gpib_board_t *board) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; +// printk("%s: enter\n", __FUNCTION__); + + if (wait_event_interruptible(board->wait, + (test_bit(TACS_NUM, &board->status) && + (read_byte(nec_priv, EXT_STATUS_1_REG) & + DATA_OUT_STATUS_BIT)) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) + retval = -ERESTARTSYS; + + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; +// printk("%s: exit, retval=%i\n", __FUNCTION__, retval); + return retval; +} + +static void fmh_gpib_dma_callback(void *arg) +{ + gpib_board_t *board = arg; + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); +// printk("%s: enter\n", __FUNCTION__); + + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, HR_DOIE | HR_DIIE); + wake_up_interruptible(&board->wait); + + fmh_gpib_internal_interrupt(board); + + clear_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state); + clear_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state); + + // printk("%s: exit\n", __FUNCTION__); + spin_unlock_irqrestore(&board->spinlock, flags); +} + +/* returns true when all the bytes of a write have been transferred to + * the chip and successfully transferred out over the gpib bus. + */ +static int fmh_gpib_all_bytes_are_sent(struct fmh_priv *e_priv) +{ + if (fifos_read(e_priv, FIFO_XFER_COUNTER_REG) & fifo_xfer_counter_mask) + return 0; + + if ((read_byte(&e_priv->nec7210_priv, EXT_STATUS_1_REG) & DATA_OUT_STATUS_BIT) == 0) + return 0; + + return 1; +} + +static int fmh_gpib_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned long flags; + int retval = 0; + dma_addr_t address; + struct dma_async_tx_descriptor *tx_desc; + + *bytes_written = 0; +// printk("%s: enter\n", __FUNCTION__); + if (WARN_ON_ONCE(length > e_priv->dma_buffer_size)) + return -EFAULT; + dmaengine_terminate_all(e_priv->dma_channel); + memcpy(e_priv->dma_buffer, buffer, length); + address = dma_map_single(board->dev, e_priv->dma_buffer, length, DMA_TO_DEVICE); + if (dma_mapping_error(board->dev, address)) + pr_err("dma mapping error in dma write!\n"); + /* program dma controller */ + retval = fmh_gpib_config_dma(board, 1); + if (retval) + goto cleanup; + + tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, address, length, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!tx_desc) { + pr_err("fmh_gpib_gpib: failed to allocate dma transmit descriptor\n"); + retval = -ENOMEM; + goto cleanup; + } + tx_desc->callback = fmh_gpib_dma_callback; + tx_desc->callback_param = board; + + spin_lock_irqsave(&board->spinlock, flags); + fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG); + fifos_write(e_priv, TX_FIFO_DMA_REQUEST_ENABLE | TX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG); + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO); + + dmaengine_submit(tx_desc); + dma_async_issue_pending(e_priv->dma_channel); + clear_bit(WRITE_READY_BN, &nec_priv->state); + set_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state); +// printk("%s: in spin lock\n", __FUNCTION__); + spin_unlock_irqrestore(&board->spinlock, flags); + +// printk("%s: waiting for write.\n", __FUNCTION__); + // suspend until message is sent + if (wait_event_interruptible(board->wait, + fmh_gpib_all_bytes_are_sent(e_priv) || + test_bit(BUS_ERROR_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted!\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state)) + retval = -EIO; + // disable board's dma + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0); + fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG); + + dmaengine_terminate_all(e_priv->dma_channel); + // make sure fmh_gpib_dma_callback got called + if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state)) + fmh_gpib_dma_callback(board); + + *bytes_written = length - (fifos_read(e_priv, FIFO_XFER_COUNTER_REG) & + fifo_xfer_counter_mask); + if (WARN_ON_ONCE(*bytes_written > length)) + return -EFAULT; + /* printk("length=%i, *bytes_written=%i, residue=%i, retval=%i\n", + * length, *bytes_written, get_dma_residue(e_priv->dma_channel), retval); + */ +cleanup: + dma_unmap_single(board->dev, address, length, DMA_TO_DEVICE); +// printk("%s: exit, retval=%d\n", __FUNCTION__, retval); + return retval; +} + +static int fmh_gpib_accel_write(gpib_board_t *board, uint8_t *buffer, + size_t length, int send_eoi, size_t *bytes_written) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + size_t remainder = length; + size_t transfer_size; + ssize_t retval = 0; + size_t dma_remainder = remainder; + + if (!e_priv->dma_channel) { + pr_err("fmh_gpib_gpib: No dma channel available, cannot do accel write."); + return -ENXIO; + } + + *bytes_written = 0; + if (length < 1) + return 0; + + smp_mb__before_atomic(); + clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME + smp_mb__after_atomic(); + + if (send_eoi) + --dma_remainder; +// printk("%s: entering while loop\n", __FUNCTION__); + + while (dma_remainder > 0) { + size_t num_bytes; + + retval = wait_for_data_out_ready(board); + if (retval < 0) + break; + + transfer_size = (e_priv->dma_buffer_size < dma_remainder) ? + e_priv->dma_buffer_size : dma_remainder; + retval = fmh_gpib_dma_write(board, buffer, transfer_size, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + break; + dma_remainder -= num_bytes; + remainder -= num_bytes; + buffer += num_bytes; + if (need_resched()) + schedule(); + } + if (retval < 0) + return retval; + //handle sending of last byte with eoi + if (send_eoi) { + size_t num_bytes; + // printk("%s: handling last byte\n", __FUNCTION__); + if (WARN_ON_ONCE(remainder != 1)) + return -EFAULT; + + /* wait until we are sure we will be able to write the data byte + * into the chip before we send AUX_SEOI. This prevents a timeout + * scenario where we send AUX_SEOI but then timeout without getting + * any bytes into the gpib chip. This will result in the first byte + * of the next write having a spurious EOI set on the first byte. + */ + retval = wait_for_data_out_ready(board); + if (retval < 0) + return retval; + + write_byte(nec_priv, AUX_SEOI, AUXMR); + retval = fmh_gpib_dma_write(board, buffer, remainder, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + remainder -= num_bytes; + } +// printk("%s: bytes send=%i\n", __FUNCTION__, (int)(length - remainder)); + return 0; +} + +static int fmh_gpib_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie) +{ + struct dma_tx_state state; + int result; + + result = dmaengine_pause(chan); + if (result < 0) { + pr_err("fmh_gpib_gpib: dma pause failed?\n"); + return result; + } + dmaengine_tx_status(chan, cookie, &state); + // dma330 hardware doesn't support resume, so dont call this + // method unless the dma transfer is done. + return state.residue; +} + +static int wait_for_tx_fifo_half_empty(gpib_board_t *board) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; +// printk("%s: enter\n", __FUNCTION__); + + if (wait_event_interruptible(board->wait, + (test_bit(TACS_NUM, &board->status) && + (fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) & + TX_FIFO_HALF_EMPTY)) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) + retval = -ERESTARTSYS; + + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; +// printk("%s: exit, retval=%i\n", __FUNCTION__, retval); + return retval; +} + +/* supports writing a chunk of data whose length must fit into the hardware'd xfer counter, + * called in a loop by fmh_gpib_fifo_write() + */ +static int fmh_gpib_fifo_write_countable(gpib_board_t *board, uint8_t *buffer, + size_t length, int send_eoi, size_t *bytes_written) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + unsigned int remainder; + + *bytes_written = 0; +// printk("%s: enter\n", __FUNCTION__); + if (WARN_ON_ONCE(length > fifo_xfer_counter_mask)) + return -EFAULT; + + fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG); + fifos_write(e_priv, TX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG); + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO); + + remainder = length; + while (remainder > 0) { + int i; + + fifos_write(e_priv, TX_FIFO_HALF_EMPTY_INTERRUPT_ENABLE, FIFO_CONTROL_STATUS_REG); + retval = wait_for_tx_fifo_half_empty(board); + if (retval < 0) + goto cleanup; + + for (i = 0; i < fmh_gpib_half_fifo_size(e_priv) && remainder > 0; ++i) { + unsigned int data_value = *buffer; + + if (send_eoi && remainder == 1) + data_value |= FIFO_DATA_EOI_FLAG; + fifos_write(e_priv, data_value, FIFO_DATA_REG); + ++buffer; + --remainder; + } + } + + // suspend until last byte is sent + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, HR_DOIE); + if (wait_event_interruptible(board->wait, + fmh_gpib_all_bytes_are_sent(e_priv) || + test_bit(BUS_ERROR_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted!\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state)) + retval = -EIO; + +cleanup: + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0); + fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG); + + *bytes_written = length - (fifos_read(e_priv, FIFO_XFER_COUNTER_REG) & + fifo_xfer_counter_mask); + if (WARN_ON_ONCE(*bytes_written > length)) + return -EFAULT; + /* printk("length=%i, *bytes_written=%i, residue=%i, retval=%i\n", + * length, *bytes_written, get_dma_residue(e_priv->dma_channel), retval); + */ + +// printk("%s: exit, retval=%d\n", __FUNCTION__, retval); + return retval; +} + +static int fmh_gpib_fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + size_t remainder = length; + size_t transfer_size; + ssize_t retval = 0; + + *bytes_written = 0; + if (length < 1) + return 0; + + clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME + +// printk("%s: entering while loop\n", __FUNCTION__); + + while (remainder > 0) { + size_t num_bytes; + int last_pass; + + retval = wait_for_data_out_ready(board); + if (retval < 0) + break; + + if (fifo_xfer_counter_mask < remainder) { + // round transfer size to a multiple of half fifo size + transfer_size = (fifo_xfer_counter_mask / + fmh_gpib_half_fifo_size(e_priv)) * + fmh_gpib_half_fifo_size(e_priv); + last_pass = 0; + } else { + transfer_size = remainder; + last_pass = 1; + } + retval = fmh_gpib_fifo_write_countable(board, buffer, transfer_size, + last_pass && send_eoi, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + break; + remainder -= num_bytes; + buffer += num_bytes; + if (need_resched()) + schedule(); + } +// printk("%s: bytes send=%i\n", __FUNCTION__, (int)(length - remainder)); + return retval; +} + +static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + unsigned long flags; + int residue; + int wait_retval; + dma_addr_t bus_address; + struct dma_async_tx_descriptor *tx_desc; + dma_cookie_t dma_cookie; + + // printk("%s: enter, bus_address=0x%x, length=%i\n", __FUNCTION__, + //(unsigned)bus_address, +// (int)length); + + *bytes_read = 0; + *end = 0; + if (length == 0) + return 0; + + bus_address = dma_map_single(board->dev, e_priv->dma_buffer, + length, DMA_FROM_DEVICE); + if (dma_mapping_error(board->dev, bus_address)) + pr_err("dma mapping error in dma read!"); + + /* program dma controller */ + retval = fmh_gpib_config_dma(board, 0); + if (retval) { + dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE); + return retval; + } + tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, bus_address, + length, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!tx_desc) { + pr_err("fmh_gpib_gpib: failed to allocate dma transmit descriptor\n"); + dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE); + return -EIO; + } + tx_desc->callback = fmh_gpib_dma_callback; + tx_desc->callback_param = board; + + spin_lock_irqsave(&board->spinlock, flags); + // enable nec7210 dma + fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG); + fifos_write(e_priv, RX_FIFO_DMA_REQUEST_ENABLE | RX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG); + nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI); + + dma_cookie = dmaengine_submit(tx_desc); + dma_async_issue_pending(e_priv->dma_channel); + + set_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state); + + spin_unlock_irqrestore(&board->spinlock, flags); +// printk("waiting for data transfer.\n"); + // wait for data to transfer + wait_retval = wait_event_interruptible(board->wait, + test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state) + == 0 || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status)); + if (wait_retval) { + pr_warn("fmh_gpib: dma read wait interrupted\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) + retval = -EINTR; + // stop the dma transfer + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG); + // give time for pl330 to transfer any in-flight data, since + // pl330 will throw it away when dmaengine_pause is called. + usleep_range(10, 15); + residue = fmh_gpib_get_dma_residue(e_priv->dma_channel, dma_cookie); + if (WARN_ON_ONCE(residue > length || residue < 0)) + return -EFAULT; + *bytes_read += length - residue; + dmaengine_terminate_all(e_priv->dma_channel); + // make sure fmh_gpib_dma_callback got called + if (test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state)) + fmh_gpib_dma_callback(board); + + dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE); + memcpy(buffer, e_priv->dma_buffer, *bytes_read); + + /* Manually read any dregs out of fifo. */ + while ((fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) & RX_FIFO_EMPTY) == 0) { + if ((*bytes_read) >= length) { + dev_err(board->dev, "unexpected extra bytes in rx fifo, discarding! bytes_read=%d length=%d residue=%d\n", + (int)(*bytes_read), (int)length, (int)residue); + break; + } + buffer[(*bytes_read)++] = fifos_read(e_priv, FIFO_DATA_REG) & fifo_data_mask; + } + + /* If we got an end interrupt, figure out if it was + * associated with the last byte we dma'd or with a + * byte still sitting on the cb7210. + */ + spin_lock_irqsave(&board->spinlock, flags); + if (*bytes_read > 0 && test_bit(READ_READY_BN, &nec_priv->state) == 0) { + // If there is no byte sitting on the cb7210 and we + // saw an end, we need to deal with it now + if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) + *end = 1; + } + spin_unlock_irqrestore(&board->spinlock, flags); +// printk("\tbytes_read=%i, residue=%i, end=%i, retval=%i, wait_retval=%i\n", +// *bytes_read, residue, *end, retval, wait_retval); + + return retval; +} + +static void fmh_gpib_release_rfd_holdoff(gpib_board_t *board, struct fmh_priv *e_priv) +{ + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned int ext_status_1; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + + ext_status_1 = read_byte(nec_priv, EXT_STATUS_1_REG); + + /* if there is an end byte sitting on the chip, don't release + * holdoff. We want it left set after we read out the end + * byte. + */ + if ((ext_status_1 & (DATA_IN_STATUS_BIT | END_STATUS_BIT)) != + (DATA_IN_STATUS_BIT | END_STATUS_BIT)) { + if (ext_status_1 & RFD_HOLDOFF_STATUS_BIT) + write_byte(nec_priv, AUX_FH, AUXMR); + + /* Check if an end byte raced in before we executed the AUX_FH command. + * If it did, we want to make sure the rfd holdoff is in effect. The end + * byte can arrive since + * AUX_RFD_HOLDOFF_ASAP doesn't immediately force the acceptor handshake + * to leave ACRS. + */ + if ((read_byte(nec_priv, EXT_STATUS_1_REG) & + (RFD_HOLDOFF_STATUS_BIT | DATA_IN_STATUS_BIT | END_STATUS_BIT)) == + (DATA_IN_STATUS_BIT | END_STATUS_BIT)) { + write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR); + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + } else { + clear_bit(RFD_HOLDOFF_BN, &nec_priv->state); + } + } + spin_unlock_irqrestore(&board->spinlock, flags); +} + +static int fmh_gpib_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + size_t remain = length; + size_t transfer_size; + int retval = 0; + size_t dma_nbytes; + unsigned long flags; + + smp_mb__before_atomic(); + clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME + smp_mb__after_atomic(); + *end = 0; + *bytes_read = 0; + + retval = wait_for_read(board); + if (retval < 0) + return retval; + + fmh_gpib_release_rfd_holdoff(board, e_priv); + while (remain > 0) { + transfer_size = (e_priv->dma_buffer_size < remain) ? + e_priv->dma_buffer_size : remain; + retval = fmh_gpib_dma_read(board, buffer, transfer_size, end, &dma_nbytes); + remain -= dma_nbytes; + buffer += dma_nbytes; + *bytes_read += dma_nbytes; + if (*end) + break; + if (retval < 0) + break; + if (need_resched()) + schedule(); + } + + spin_lock_irqsave(&board->spinlock, flags); + if (test_bit(RFD_HOLDOFF_BN, &nec_priv->state) == 0) { + write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR); + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + } + spin_unlock_irqrestore(&board->spinlock, flags); + + return retval; +} + +/* Read a chunk of data whose length is within the limits of the hardware's + * xfer counter. Called in a loop from fmh_gpib_fifo_read(). + */ +static int fmh_gpib_fifo_read_countable(gpib_board_t *board, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + int retval = 0; + + // printk("%s: enter, bus_address=0x%x, length=%i\n", __FUNCTION__, + // (unsigned)bus_address, +// (int)length); + + *bytes_read = 0; + *end = 0; + if (length == 0) + return 0; + + fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG); + fifos_write(e_priv, RX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG); + nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI); + + while (*bytes_read < length && *end == 0) { + int i; + + fifos_write(e_priv, RX_FIFO_HALF_FULL_INTERRUPT_ENABLE, FIFO_CONTROL_STATUS_REG); + retval = wait_for_rx_fifo_half_full_or_end(board); + if (retval < 0) + goto cleanup; + + for (i = 0; i < fmh_gpib_half_fifo_size(e_priv) && *end == 0; ++i) { + unsigned int data_value; + + data_value = fifos_read(e_priv, FIFO_DATA_REG); + buffer[(*bytes_read)++] = data_value & fifo_data_mask; + if (data_value & FIFO_DATA_EOI_FLAG) + *end = 1; + } + } + +cleanup: + // stop the transfer + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG); + + /* Manually read any dregs out of fifo. */ + while ((fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) & RX_FIFO_EMPTY) == 0) { + unsigned int data_value; + + if ((*bytes_read) >= length) { + dev_err(board->dev, "unexpected extra bytes in rx fifo, discarding! bytes_read=%d length=%d\n", + (int)(*bytes_read), (int)length); + break; + } + data_value = fifos_read(e_priv, FIFO_DATA_REG); + buffer[(*bytes_read)++] = data_value & fifo_data_mask; + if (data_value & FIFO_DATA_EOI_FLAG) + *end = 1; + } + +// printk("\tbytes_read=%i, end=%i, retval=%i, wait_retval=%i\n", +// *bytes_read, *end, retval, wait_retval); + + return retval; +} + +static int fmh_gpib_fifo_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + size_t remain = length; + size_t transfer_size; + int retval = 0; + size_t nbytes; + unsigned long flags; + + clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME + *end = 0; + *bytes_read = 0; + + /* Do a little prep with data in interrupt so that following wait_for_read() + * will wake up if a data byte is received. + */ + nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, HR_DIIE); + fmh_gpib_interrupt(0, board); + + retval = wait_for_read(board); + if (retval < 0) + return retval; + + fmh_gpib_release_rfd_holdoff(board, e_priv); + while (remain > 0) { + if (fifo_xfer_counter_mask < remain) { + // round transfer size to a multiple of half fifo size + transfer_size = (fifo_xfer_counter_mask / + fmh_gpib_half_fifo_size(e_priv)) * + fmh_gpib_half_fifo_size(e_priv); + } else { + transfer_size = remain; + } + retval = fmh_gpib_fifo_read_countable(board, buffer, transfer_size, end, &nbytes); + remain -= nbytes; + buffer += nbytes; + *bytes_read += nbytes; + if (*end) + break; + if (retval < 0) + break; + if (need_resched()) + schedule(); + } + + if (*end == 0) { + spin_lock_irqsave(&board->spinlock, flags); + write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR); + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + spin_unlock_irqrestore(&board->spinlock, flags); + } + + return retval; +} + +gpib_interface_t fmh_gpib_unaccel_interface = { +name: "fmh_gpib_unaccel", +attach : fmh_gpib_attach_holdoff_all, +detach : fmh_gpib_detach, +read : fmh_gpib_read, +write : fmh_gpib_write, +command : fmh_gpib_command, +take_control : fmh_gpib_take_control, +go_to_standby : fmh_gpib_go_to_standby, +request_system_control : fmh_gpib_request_system_control, +interface_clear : fmh_gpib_interface_clear, +remote_enable : fmh_gpib_remote_enable, +enable_eos : fmh_gpib_enable_eos, +disable_eos : fmh_gpib_disable_eos, +parallel_poll : fmh_gpib_parallel_poll, +parallel_poll_configure : fmh_gpib_parallel_poll_configure, +parallel_poll_response : fmh_gpib_parallel_poll_response, +local_parallel_poll_mode : fmh_gpib_local_parallel_poll_mode, +line_status : fmh_gpib_line_status, +update_status : fmh_gpib_update_status, +primary_address : fmh_gpib_primary_address, +secondary_address : fmh_gpib_secondary_address, +serial_poll_response2 : fmh_gpib_serial_poll_response2, +serial_poll_status : fmh_gpib_serial_poll_status, +t1_delay : fmh_gpib_t1_delay, +return_to_local : fmh_gpib_return_to_local, +}; + +gpib_interface_t fmh_gpib_interface = { +name: "fmh_gpib", +attach : fmh_gpib_attach_holdoff_end, +detach : fmh_gpib_detach, +read : fmh_gpib_accel_read, +write : fmh_gpib_accel_write, +command : fmh_gpib_command, +take_control : fmh_gpib_take_control, +go_to_standby : fmh_gpib_go_to_standby, +request_system_control : fmh_gpib_request_system_control, +interface_clear : fmh_gpib_interface_clear, +remote_enable : fmh_gpib_remote_enable, +enable_eos : fmh_gpib_enable_eos, +disable_eos : fmh_gpib_disable_eos, +parallel_poll : fmh_gpib_parallel_poll, +parallel_poll_configure : fmh_gpib_parallel_poll_configure, +parallel_poll_response : fmh_gpib_parallel_poll_response, +local_parallel_poll_mode : fmh_gpib_local_parallel_poll_mode, +line_status : fmh_gpib_line_status, +update_status : fmh_gpib_update_status, +primary_address : fmh_gpib_primary_address, +secondary_address : fmh_gpib_secondary_address, +serial_poll_response2 : fmh_gpib_serial_poll_response2, +serial_poll_status : fmh_gpib_serial_poll_status, +t1_delay : fmh_gpib_t1_delay, +return_to_local : fmh_gpib_return_to_local, +}; + +gpib_interface_t fmh_gpib_pci_interface = { +name: "fmh_gpib_pci", +attach : fmh_gpib_pci_attach_holdoff_end, +detach : fmh_gpib_pci_detach, +read : fmh_gpib_fifo_read, +write : fmh_gpib_fifo_write, +command : fmh_gpib_command, +take_control : fmh_gpib_take_control, +go_to_standby : fmh_gpib_go_to_standby, +request_system_control : fmh_gpib_request_system_control, +interface_clear : fmh_gpib_interface_clear, +remote_enable : fmh_gpib_remote_enable, +enable_eos : fmh_gpib_enable_eos, +disable_eos : fmh_gpib_disable_eos, +parallel_poll : fmh_gpib_parallel_poll, +parallel_poll_configure : fmh_gpib_parallel_poll_configure, +parallel_poll_response : fmh_gpib_parallel_poll_response, +local_parallel_poll_mode : fmh_gpib_local_parallel_poll_mode, +line_status : fmh_gpib_line_status, +update_status : fmh_gpib_update_status, +primary_address : fmh_gpib_primary_address, +secondary_address : fmh_gpib_secondary_address, +serial_poll_response2 : fmh_gpib_serial_poll_response2, +serial_poll_status : fmh_gpib_serial_poll_status, +t1_delay : fmh_gpib_t1_delay, +return_to_local : fmh_gpib_return_to_local, +}; + +gpib_interface_t fmh_gpib_pci_unaccel_interface = { +name: "fmh_gpib_pci_unaccel", +attach : fmh_gpib_pci_attach_holdoff_all, +detach : fmh_gpib_pci_detach, +read : fmh_gpib_read, +write : fmh_gpib_write, +command : fmh_gpib_command, +take_control : fmh_gpib_take_control, +go_to_standby : fmh_gpib_go_to_standby, +request_system_control : fmh_gpib_request_system_control, +interface_clear : fmh_gpib_interface_clear, +remote_enable : fmh_gpib_remote_enable, +enable_eos : fmh_gpib_enable_eos, +disable_eos : fmh_gpib_disable_eos, +parallel_poll : fmh_gpib_parallel_poll, +parallel_poll_configure : fmh_gpib_parallel_poll_configure, +parallel_poll_response : fmh_gpib_parallel_poll_response, +local_parallel_poll_mode : fmh_gpib_local_parallel_poll_mode, +line_status : fmh_gpib_line_status, +update_status : fmh_gpib_update_status, +primary_address : fmh_gpib_primary_address, +secondary_address : fmh_gpib_secondary_address, +serial_poll_response2 : fmh_gpib_serial_poll_response2, +serial_poll_status : fmh_gpib_serial_poll_status, +t1_delay : fmh_gpib_t1_delay, +return_to_local : fmh_gpib_return_to_local, +}; + +irqreturn_t fmh_gpib_internal_interrupt(gpib_board_t *board) +{ + unsigned int status0, status1, status2, ext_status_1, fifo_status; + struct fmh_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + int retval = IRQ_NONE; + + status0 = read_byte(nec_priv, ISR0_IMR0_REG); + status1 = read_byte(nec_priv, ISR1); + status2 = read_byte(nec_priv, ISR2); + fifo_status = fifos_read(priv, FIFO_CONTROL_STATUS_REG); + + if (status0 & IFC_INTERRUPT_BIT) { + push_gpib_event(board, EventIFC); + retval = IRQ_HANDLED; + } + + if (nec7210_interrupt_have_status(board, nec_priv, status1, status2) == IRQ_HANDLED) + retval = IRQ_HANDLED; + + ext_status_1 = read_byte(nec_priv, EXT_STATUS_1_REG); + + if (ext_status_1 & DATA_IN_STATUS_BIT) + set_bit(READ_READY_BN, &nec_priv->state); + else + clear_bit(READ_READY_BN, &nec_priv->state); + + if (ext_status_1 & DATA_OUT_STATUS_BIT) + set_bit(WRITE_READY_BN, &nec_priv->state); + else + clear_bit(WRITE_READY_BN, &nec_priv->state); + + if (ext_status_1 & COMMAND_OUT_STATUS_BIT) + set_bit(COMMAND_READY_BN, &nec_priv->state); + else + clear_bit(COMMAND_READY_BN, &nec_priv->state); + + if (ext_status_1 & RFD_HOLDOFF_STATUS_BIT) + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + else + clear_bit(RFD_HOLDOFF_BN, &nec_priv->state); + + if (ext_status_1 & END_STATUS_BIT) { + /* only set RECEIVED_END while there is still a data + * byte sitting in the chip, to avoid spuriously + * setting it multiple times after it has been cleared + * during a read. + */ + if (ext_status_1 & DATA_IN_STATUS_BIT) + set_bit(RECEIVED_END_BN, &nec_priv->state); + } else { + clear_bit(RECEIVED_END_BN, &nec_priv->state); + } + + if ((fifo_status & TX_FIFO_HALF_EMPTY_INTERRUPT_IS_ENABLED) && + (fifo_status & TX_FIFO_HALF_EMPTY)) { + /* We really only want to clear the + * TX_FIFO_HALF_EMPTY_INTERRUPT_ENABLE bit in the + * FIFO_CONTROL_STATUS_REG. Since we are not being + * careful, this also has a side effect of disabling + * DMA requests and the RX fifo interrupt. That is + * fine though, since they should never be in use at + * the same time as the TX fifo interrupt. + */ + fifos_write(priv, 0x0, FIFO_CONTROL_STATUS_REG); + retval = IRQ_HANDLED; + } + + if ((fifo_status & RX_FIFO_HALF_FULL_INTERRUPT_IS_ENABLED) && + (fifo_status & RX_FIFO_HALF_FULL)) { + /* We really only want to clear the + * RX_FIFO_HALF_FULL_INTERRUPT_ENABLE bit in the + * FIFO_CONTROL_STATUS_REG. Since we are not being + * careful, this also has a side effect of disabling + * DMA requests and the TX fifo interrupt. That is + * fine though, since they should never be in use at + * the same time as the RX fifo interrupt. + */ + fifos_write(priv, 0x0, FIFO_CONTROL_STATUS_REG); + retval = IRQ_HANDLED; + } + + if (retval == IRQ_HANDLED) + wake_up_interruptible(&board->wait); + + return retval; +} + +irqreturn_t fmh_gpib_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + unsigned long flags; + irqreturn_t retval; + + spin_lock_irqsave(&board->spinlock, flags); + retval = fmh_gpib_internal_interrupt(board); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +static int fmh_gpib_allocate_private(gpib_board_t *board) +{ + struct fmh_priv *priv; + + board->private_data = kmalloc(sizeof(struct fmh_priv), GFP_KERNEL); + if (!board->private_data) + return -ENOMEM; + priv = board->private_data; + memset(priv, 0, sizeof(struct fmh_priv)); + init_nec7210_private(&priv->nec7210_priv); + priv->dma_buffer_size = 0x800; + priv->dma_buffer = kmalloc(priv->dma_buffer_size, GFP_KERNEL); + if (!priv->dma_buffer) + return -ENOMEM; + return 0; +} + +static void fmh_gpib_generic_detach(gpib_board_t *board) +{ + if (board->private_data) { + struct fmh_priv *e_priv = board->private_data; + + kfree(e_priv->dma_buffer); + kfree(board->private_data); + board->private_data = NULL; + } + if (board->dev) + dev_set_drvdata(board->dev, NULL); +} + +// generic part of attach functions +static int fmh_gpib_generic_attach(gpib_board_t *board) +{ + struct fmh_priv *e_priv; + struct nec7210_priv *nec_priv; + int retval; + + board->status = 0; + + retval = fmh_gpib_allocate_private(board); + if (retval < 0) + return retval; + e_priv = board->private_data; + nec_priv = &e_priv->nec7210_priv; + nec_priv->read_byte = gpib_cs_read_byte; + nec_priv->write_byte = gpib_cs_write_byte; + nec_priv->offset = 1; + nec_priv->type = CB7210; + return 0; +} + +static int fmh_gpib_config_dma(gpib_board_t *board, int output) +{ + struct fmh_priv *e_priv = board->private_data; + struct dma_slave_config config; + + config.device_fc = true; + + if (e_priv->dma_burst_length < 1) { + config.src_maxburst = 1; + config.dst_maxburst = 1; + } else { + config.src_maxburst = e_priv->dma_burst_length; + config.dst_maxburst = e_priv->dma_burst_length; + } + + config.src_addr_width = 1; + config.dst_addr_width = 1; + + if (output) { + config.direction = DMA_MEM_TO_DEV; + config.src_addr = 0; + config.dst_addr = e_priv->dma_port_res->start + FIFO_DATA_REG * fifo_reg_offset; + } else { + config.direction = DMA_DEV_TO_MEM; + config.src_addr = e_priv->dma_port_res->start + FIFO_DATA_REG * fifo_reg_offset; + config.dst_addr = 0; + } + return dmaengine_slave_config(e_priv->dma_channel, &config); +} + +static int fmh_gpib_init(struct fmh_priv *e_priv, gpib_board_t *board, int handshake_mode) +{ + struct nec7210_priv *nec_priv = &e_priv->nec7210_priv; + unsigned long flags; + unsigned int fifo_status_bits; + + fifos_write(e_priv, RX_FIFO_CLEAR | TX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG); + + nec7210_board_reset(nec_priv, board); + write_byte(nec_priv, AUX_LO_SPEED, AUXMR); + nec7210_set_handshake_mode(board, nec_priv, handshake_mode); + + /* Hueristically check if hardware supports fifo half full/empty interrupts */ + fifo_status_bits = fifos_read(e_priv, FIFO_CONTROL_STATUS_REG); + e_priv->supports_fifo_interrupts = (fifo_status_bits & TX_FIFO_EMPTY) && + (fifo_status_bits & TX_FIFO_HALF_EMPTY); + + nec7210_board_online(nec_priv, board); + + write_byte(nec_priv, IFC_INTERRUPT_ENABLE_BIT | ATN_INTERRUPT_ENABLE_BIT, ISR0_IMR0_REG); + + spin_lock_irqsave(&board->spinlock, flags); + write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR); + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + spin_unlock_irqrestore(&board->spinlock, flags); + return 0; +} + +/* Match callback for driver_find_device */ +static int fmh_gpib_device_match(struct device *dev, const void *data) +{ + const gpib_board_config_t *config = data; + + if (dev_get_drvdata(dev)) + return 0; + + if (gpib_match_device_path(dev, config->device_path) == 0) + return 0; + + // driver doesn't support selection by serial number + if (config->serial_number) + return 0; + + dev_notice(dev, "matched: %s\n", of_node_full_name(dev_of_node((dev)))); + return 1; +} + +static int fmh_gpib_attach_impl(gpib_board_t *board, const gpib_board_config_t *config, + unsigned int handshake_mode, int acquire_dma) +{ + struct fmh_priv *e_priv; + struct nec7210_priv *nec_priv; + int retval; + int irq; + struct resource *res; + struct platform_device *pdev; + + board->dev = driver_find_device(&fmh_gpib_platform_driver.driver, + NULL, (const void *)config, &fmh_gpib_device_match); + if (!board->dev) { + pr_err("No matching fmh_gpib_core device was found, attach failed."); + return -ENODEV; + } + // currently only used to mark the device as already attached + dev_set_drvdata(board->dev, board); + pdev = to_platform_device(board->dev); + + retval = fmh_gpib_generic_attach(board); + if (retval) + return retval; + + e_priv = board->private_data; + nec_priv = &e_priv->nec7210_priv; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpib_control_status"); + if (!res) { + dev_err(board->dev, "Unable to locate mmio resource for cb7210 gpib\n"); + return -ENODEV; + } + + if (request_mem_region(res->start, + resource_size(res), + pdev->name) == NULL) { + dev_err(board->dev, "cannot claim registers\n"); + return -ENXIO; + } + e_priv->gpib_iomem_res = res; + + nec_priv->iobase = ioremap(e_priv->gpib_iomem_res->start, + resource_size(e_priv->gpib_iomem_res)); + if (!nec_priv->iobase) { + dev_err(board->dev, "Could not map I/O memory for gpib\n"); + return -ENOMEM; + } + dev_info(board->dev, "iobase 0x%lx remapped to %p, length=%ld\n", + (unsigned long)e_priv->gpib_iomem_res->start, + nec_priv->iobase, (unsigned long)resource_size(e_priv->gpib_iomem_res)); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma_fifos"); + if (!res) { + dev_err(board->dev, "Unable to locate mmio resource for gpib dma port\n"); + return -ENODEV; + } + if (request_mem_region(res->start, + resource_size(res), + pdev->name) == NULL) { + dev_err(board->dev, "cannot claim registers\n"); + return -ENXIO; + } + e_priv->dma_port_res = res; + e_priv->fifo_base = ioremap(e_priv->dma_port_res->start, + resource_size(e_priv->dma_port_res)); + if (!e_priv->fifo_base) { + dev_err(board->dev, "Could not map I/O memory for fifos\n"); + return -ENOMEM; + } + dev_info(board->dev, "dma fifos 0x%lx remapped to %p, length=%ld\n", + (unsigned long)e_priv->dma_port_res->start, e_priv->fifo_base, + (unsigned long)resource_size(e_priv->dma_port_res)); + + irq = platform_get_irq(pdev, 0); + pr_info("gpib: irq %d\n", irq); + if (irq < 0) { + dev_err(board->dev, "fmh_gpib_gpib: request for IRQ failed\n"); + return -EBUSY; + } + retval = request_irq(irq, fmh_gpib_interrupt, IRQF_SHARED, pdev->name, board); + if (retval) { + dev_err(board->dev, + "cannot register interrupt handler err=%d\n", + retval); + return retval; + } + e_priv->irq = irq; + + if (acquire_dma) { + e_priv->dma_channel = dma_request_slave_channel(board->dev, "rxtx"); + if (!e_priv->dma_channel) { + dev_err(board->dev, "failed to acquire dma channel \"rxtx\".\n"); + return -EIO; + } + } + /* in the future we might want to know the half-fifo size + * (dma_burst_length) even when not using dma, so go ahead an + * initialize it unconditionally. + */ + e_priv->dma_burst_length = fifos_read(e_priv, FIFO_MAX_BURST_LENGTH_REG) & + fifo_max_burst_length_mask; + + return fmh_gpib_init(e_priv, board, handshake_mode); +} + +int fmh_gpib_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config) +{ + return fmh_gpib_attach_impl(board, config, HR_HLDA, 0); +} + +int fmh_gpib_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config) +{ + return fmh_gpib_attach_impl(board, config, HR_HLDE, 1); +} + +void fmh_gpib_detach(gpib_board_t *board) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (e_priv) { + if (e_priv->dma_channel) + dma_release_channel(e_priv->dma_channel); + nec_priv = &e_priv->nec7210_priv; + + if (e_priv->irq) + free_irq(e_priv->irq, board); + if (e_priv->fifo_base) + fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG); + if (nec_priv->iobase) { + write_byte(nec_priv, 0, ISR0_IMR0_REG); + nec7210_board_reset(nec_priv, board); + } + if (e_priv->fifo_base) + iounmap(e_priv->fifo_base); + if (nec_priv->iobase) + iounmap(nec_priv->iobase); + if (e_priv->dma_port_res) { + release_mem_region(e_priv->dma_port_res->start, + resource_size(e_priv->dma_port_res)); + } + if (e_priv->gpib_iomem_res) + release_mem_region(e_priv->gpib_iomem_res->start, + resource_size(e_priv->gpib_iomem_res)); + } + fmh_gpib_generic_detach(board); +} + +static int fmh_gpib_pci_attach_impl(gpib_board_t *board, const gpib_board_config_t *config, + unsigned int handshake_mode) +{ + struct fmh_priv *e_priv; + struct nec7210_priv *nec_priv; + int retval; + struct pci_dev *pci_device; + + retval = fmh_gpib_generic_attach(board); + if (retval) + return retval; + + e_priv = board->private_data; + nec_priv = &e_priv->nec7210_priv; + + // find board + pci_device = gpib_pci_get_device(config, BOGUS_PCI_VENDOR_ID_FLUKE, + BOGUS_PCI_DEVICE_ID_FLUKE_BLADERUNNER, NULL); + if (!pci_device) { + pr_err("No matching fmh_gpib_core pci device was found, attach failed."); + return -ENODEV; + } + board->dev = &pci_device->dev; + + // bladerunner prototype has offset of 4 between gpib control/status registers + nec_priv->offset = 4; + + if (pci_enable_device(pci_device)) { + dev_err(board->dev, "error enabling pci device\n"); + return -EIO; + } + if (pci_request_regions(pci_device, KBUILD_MODNAME)) { + dev_err(board->dev, "pci_request_regions failed\n"); + return -EIO; + } + e_priv->gpib_iomem_res = &pci_device->resource[gpib_control_status_pci_resource_index]; + e_priv->dma_port_res = &pci_device->resource[gpib_fifo_pci_resource_index]; + + nec_priv->iobase = ioremap(pci_resource_start(pci_device, + gpib_control_status_pci_resource_index), + pci_resource_len(pci_device, + gpib_control_status_pci_resource_index)); + dev_info(board->dev, "base address for gpib control/status registers remapped to 0x%p\n", + nec_priv->iobase); + + if (e_priv->dma_port_res->flags & IORESOURCE_MEM) { + e_priv->fifo_base = ioremap(pci_resource_start(pci_device, + gpib_fifo_pci_resource_index), + pci_resource_len(pci_device, + gpib_fifo_pci_resource_index)); + dev_info(board->dev, "base address for gpib fifo registers remapped to 0x%p\n", + e_priv->fifo_base); + } else { + e_priv->fifo_base = NULL; + dev_info(board->dev, "hardware has no gpib fifo registers.\n"); + } + + if (pci_device->irq) { + retval = request_irq(pci_device->irq, fmh_gpib_interrupt, IRQF_SHARED, + KBUILD_MODNAME, board); + if (retval) { + dev_err(board->dev, + "cannot register interrupt handler err=%d\n", + retval); + return retval; + } + } + e_priv->irq = pci_device->irq; + + e_priv->dma_burst_length = fifos_read(e_priv, FIFO_MAX_BURST_LENGTH_REG) & + fifo_max_burst_length_mask; + + return fmh_gpib_init(e_priv, board, handshake_mode); +} + +int fmh_gpib_pci_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config) +{ + return fmh_gpib_pci_attach_impl(board, config, HR_HLDA); +} + +int fmh_gpib_pci_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config) +{ + int retval; + struct fmh_priv *e_priv; + + retval = fmh_gpib_pci_attach_impl(board, config, HR_HLDE); + e_priv = board->private_data; + if (retval == 0 && e_priv && e_priv->supports_fifo_interrupts == 0) { + pr_err("fmh_gpib: your fmh_gpib_core does not appear to support fifo interrupts. Try the fmh_gpib_pci_unaccel board type instead."); + return -EIO; + } + return retval; +} + +void fmh_gpib_pci_detach(gpib_board_t *board) +{ + struct fmh_priv *e_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (e_priv) { + nec_priv = &e_priv->nec7210_priv; + + if (e_priv->irq) + free_irq(e_priv->irq, board); + if (e_priv->fifo_base) + fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG); + if (nec_priv->iobase) { + write_byte(nec_priv, 0, ISR0_IMR0_REG); + nec7210_board_reset(nec_priv, board); + } + if (e_priv->fifo_base) + iounmap(e_priv->fifo_base); + if (nec_priv->iobase) + iounmap(nec_priv->iobase); + if (e_priv->dma_port_res || e_priv->gpib_iomem_res) + pci_release_regions(to_pci_dev(board->dev)); + if (board->dev) + pci_dev_put(to_pci_dev(board->dev)); + } + fmh_gpib_generic_detach(board); +} + +static int fmh_gpib_platform_probe(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id fmh_gpib_of_match[] = { + { .compatible = "fmhess,fmh_gpib_core"}, + { {0} } +}; +MODULE_DEVICE_TABLE(of, fmh_gpib_of_match); + +static struct platform_driver fmh_gpib_platform_driver = { + .driver = { + .name = "fmh_gpib", + .owner = THIS_MODULE, + .of_match_table = fmh_gpib_of_match, + }, + .probe = &fmh_gpib_platform_probe +}; + +static int fmh_gpib_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return 0; +} + +static const struct pci_device_id fmh_gpib_pci_match[] = { + { BOGUS_PCI_VENDOR_ID_FLUKE, BOGUS_PCI_DEVICE_ID_FLUKE_BLADERUNNER, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, fmh_gpib_pci_match); + +static struct pci_driver fmh_gpib_pci_driver = { + .name = "fmh_gpib", + .id_table = fmh_gpib_pci_match, + .probe = &fmh_gpib_pci_probe +}; + +static int __init fmh_gpib_init_module(void) +{ + int result; + + result = platform_driver_register(&fmh_gpib_platform_driver); + if (result) { + pr_err("fmh_gpib: platform_driver_register failed!\n"); + return result; + } + + result = pci_register_driver(&fmh_gpib_pci_driver); + if (result) { + pr_err("fmh_gpib: pci_driver_register failed!\n"); + return result; + } + + gpib_register_driver(&fmh_gpib_unaccel_interface, THIS_MODULE); + gpib_register_driver(&fmh_gpib_interface, THIS_MODULE); + gpib_register_driver(&fmh_gpib_pci_unaccel_interface, THIS_MODULE); + gpib_register_driver(&fmh_gpib_pci_interface, THIS_MODULE); + + pr_info("fmh_gpib\n"); + return 0; +} + +static void __exit fmh_gpib_exit_module(void) +{ + gpib_unregister_driver(&fmh_gpib_pci_interface); + gpib_unregister_driver(&fmh_gpib_pci_unaccel_interface); + gpib_unregister_driver(&fmh_gpib_unaccel_interface); + gpib_unregister_driver(&fmh_gpib_interface); + + pci_unregister_driver(&fmh_gpib_pci_driver); + platform_driver_unregister(&fmh_gpib_platform_driver); +} + +module_init(fmh_gpib_init_module); +module_exit(fmh_gpib_exit_module); diff --git a/drivers/staging/gpib/fmh_gpib/fmh_gpib.h b/drivers/staging/gpib/fmh_gpib/fmh_gpib.h new file mode 100644 index 0000000000000000000000000000000000000000..43bfc89d2a6feb4c7fab742fa54c971cfa2c584f --- /dev/null +++ b/drivers/staging/gpib/fmh_gpib/fmh_gpib.h @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Author: Frank Mori Hess + * Copyright: (C) 2006, 2010, 2015 Fluke Corporation + * (C) 2017 Frank Mori Hess + ***************************************************************************/ + +#include +#include +#include +#include +#include "nec7210.h" + +static const int fifo_reg_offset = 2; + +static const int gpib_control_status_pci_resource_index; +static const int gpib_fifo_pci_resource_index = 1; + +/* We don't have a real pci vendor/device id, the following will need to be + * patched to match prototype hardware. + */ +#define BOGUS_PCI_VENDOR_ID_FLUKE 0xffff +#define BOGUS_PCI_DEVICE_ID_FLUKE_BLADERUNNER 0x0 + +struct fmh_priv { + struct nec7210_priv nec7210_priv; + struct resource *gpib_iomem_res; + struct resource *write_transfer_counter_res; + struct resource *dma_port_res; + int irq; + struct dma_chan *dma_channel; + u8 *dma_buffer; + int dma_buffer_size; + int dma_burst_length; + void *fifo_base; + unsigned supports_fifo_interrupts : 1; +}; + +static inline int fmh_gpib_half_fifo_size(struct fmh_priv *priv) +{ + return priv->dma_burst_length; +} + +// registers beyond the nec7210 register set +enum fmh_gpib_regs { + EXT_STATUS_1_REG = 0x9, + STATE1_REG = 0xc, + ISR0_IMR0_REG = 0xe, + BUS_STATUS_REG = 0xf +}; + +/* IMR0 -- Interrupt Mode Register 0 */ +enum imr0_bits { + ATN_INTERRUPT_ENABLE_BIT = 0x4, + IFC_INTERRUPT_ENABLE_BIT = 0x8 +}; + +/* ISR0 -- Interrupt Status Register 0 */ +enum isr0_bits { + ATN_INTERRUPT_BIT = 0x4, + IFC_INTERRUPT_BIT = 0x8 +}; + +enum state1_bits { + SOURCE_HANDSHAKE_SIDS_BITS = 0x0, /* source idle state */ + SOURCE_HANDSHAKE_SGNS_BITS = 0x1, /* source generate state */ + SOURCE_HANDSHAKE_SDYS_BITS = 0x2, /* source delay state */ + SOURCE_HANDSHAKE_STRS_BITS = 0x5, /* source transfer state */ + SOURCE_HANDSHAKE_MASK = 0x7 +}; + +enum fmh_gpib_auxmr_bits { + AUX_I_REG = 0xe0, +}; + +enum aux_reg_i_bits { + LOCAL_PPOLL_MODE_BIT = 0x4 +}; + +enum ext_status_1_bits { + DATA_IN_STATUS_BIT = 0x01, + DATA_OUT_STATUS_BIT = 0x02, + COMMAND_OUT_STATUS_BIT = 0x04, + RFD_HOLDOFF_STATUS_BIT = 0x08, + END_STATUS_BIT = 0x10 +}; + +/* dma fifo reg and bits */ +enum dma_fifo_regs { + FIFO_DATA_REG = 0x0, + FIFO_CONTROL_STATUS_REG = 0x1, + FIFO_XFER_COUNTER_REG = 0x2, + FIFO_MAX_BURST_LENGTH_REG = 0x3 +}; + +enum fifo_data_bits { + FIFO_DATA_EOI_FLAG = 0x100 +}; + +enum fifo_control_bits { + TX_FIFO_DMA_REQUEST_ENABLE = 0x0001, + TX_FIFO_CLEAR = 0x0002, + TX_FIFO_HALF_EMPTY_INTERRUPT_ENABLE = 0x0008, + RX_FIFO_DMA_REQUEST_ENABLE = 0x0100, + RX_FIFO_CLEAR = 0x0200, + RX_FIFO_HALF_FULL_INTERRUPT_ENABLE = 0x0800 +}; + +enum fifo_status_bits { + TX_FIFO_EMPTY = 0x0001, + TX_FIFO_FULL = 0x0002, + TX_FIFO_HALF_EMPTY = 0x0004, + TX_FIFO_HALF_EMPTY_INTERRUPT_IS_ENABLED = 0x0008, + TX_FIFO_DMA_REQUEST_IS_ENABLED = 0x0010, + RX_FIFO_EMPTY = 0x0100, + RX_FIFO_FULL = 0x0200, + RX_FIFO_HALF_FULL = 0x0400, + RX_FIFO_HALF_FULL_INTERRUPT_IS_ENABLED = 0x0800, + RX_FIFO_DMA_REQUEST_IS_ENABLED = 0x1000 +}; + +static const unsigned int fifo_data_mask = 0x00ff; +static const unsigned int fifo_xfer_counter_mask = 0x0fff; +static const unsigned int fifo_max_burst_length_mask = 0x00ff; + +static inline uint8_t gpib_cs_read_byte(struct nec7210_priv *nec_priv, + unsigned int register_num) +{ + return readb(nec_priv->iobase + register_num * nec_priv->offset); +} + +static inline void gpib_cs_write_byte(struct nec7210_priv *nec_priv, uint8_t data, + unsigned int register_num) +{ + writeb(data, nec_priv->iobase + register_num * nec_priv->offset); +} + +static inline uint16_t fifos_read(struct fmh_priv *fmh_priv, int register_num) +{ + if (!fmh_priv->fifo_base) + return 0; + return readw(fmh_priv->fifo_base + register_num * fifo_reg_offset); +} + +static inline void fifos_write(struct fmh_priv *fmh_priv, uint16_t data, int register_num) +{ + if (!fmh_priv->fifo_base) + return; + writew(data, fmh_priv->fifo_base + register_num * fifo_reg_offset); +} + +enum bus_status_bits { + BSR_ATN_BIT = 0x01, + BSR_EOI_BIT = 0x02, + BSR_SRQ_BIT = 0x04, + BSR_IFC_BIT = 0x08, + BSR_REN_BIT = 0x10, + BSR_DAV_BIT = 0x20, + BSR_NRFD_BIT = 0x40, + BSR_NDAC_BIT = 0x80, +}; + +enum fmh_gpib_aux_cmds { + /* AUX_RTL2 is an auxiliary command which causes the cb7210 to assert + * (and keep asserted) the local rtl message. This is used in conjunction + * with the normal nec7210 AUX_RTL command, which + * pulses the rtl message, having the effect of clearing rtl if it was left + * asserted by AUX_RTL2. + */ + AUX_RTL2 = 0x0d, + AUX_RFD_HOLDOFF_ASAP = 0x15, + AUX_REQT = 0x18, + AUX_REQF = 0x19, + AUX_LO_SPEED = 0x40, + AUX_HI_SPEED = 0x41 +}; diff --git a/drivers/staging/gpib/gpio/Makefile b/drivers/staging/gpib/gpio/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a31ded6e59245e3ccd9ff308cf6179ad3a74353e --- /dev/null +++ b/drivers/staging/gpib/gpio/Makefile @@ -0,0 +1,4 @@ + +obj-m += gpib_bitbang.o + + diff --git a/drivers/staging/gpib/gpio/gpib_bitbang.c b/drivers/staging/gpib/gpio/gpib_bitbang.c new file mode 100644 index 0000000000000000000000000000000000000000..a2d562cbd65b43bd902c6ba6f1c117323423abf2 --- /dev/null +++ b/drivers/staging/gpib/gpio/gpib_bitbang.c @@ -0,0 +1,1476 @@ +// SPDX-License-Identifier: GPL-2.0 + +/************************************************************************* + * This code has been developed at the Institute of Sensor and Actuator * + * Systems (Technical University of Vienna, Austria) to enable the GPIO * + * lines (e.g. of a raspberry pi) to function as a GPIO master device * + * * + * authors : Thomas Klima * + * Marcello Carla' * + * Dave Penkler * + * * + * copyright : (C) 2016 Thomas Klima * + * * + *************************************************************************/ + +/* + * limitations: + * works only on RPi + * cannot function as non-CIC system controller with SN7516x because + * SN75161B cannot simultaneously make ATN input with IFC and REN as + * outputs. + * not implemented: + * parallel poll + * return2local + * device support (non master operation) + */ + +#define NAME KBUILD_MODNAME + +#define ENABLE_IRQ(IRQ, TYPE) irq_set_irq_type(IRQ, TYPE) +#define DISABLE_IRQ(IRQ) irq_set_irq_type(IRQ, IRQ_TYPE_NONE) + +/* Debug print levels: + * 0 = load/unload info and errors that make the driver fail; + * 1 = + warnings for unforeseen events that may break the current + * operation and lead to a timeout, but do not affect the + * driver integrity (mainly unexpected interrupts); + * 2 = + trace of function calls; + * 3 = + trace of protocol codes; + * 4 = + trace of interrupt operation. + */ +#define dbg_printk(level, frm, ...) \ + do { if (debug >= (level)) \ + pr_info("%s:%s - " frm, NAME, __func__, ## __VA_ARGS__); } \ + while (0) + +#define LINVAL gpiod_get_value(DAV), \ + gpiod_get_value(NRFD), \ + gpiod_get_value(NDAC), \ + gpiod_get_value(SRQ) +#define LINFMT "DAV: %d NRFD:%d NDAC: %d SRQ: %d" + +#include "gpibP.h" +#include "gpib_state_machines.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int sn7516x_used = 1, sn7516x; +module_param(sn7516x_used, int, 0660); + +#define PINMAP_0 "elektronomikon" +#define PINMAP_1 "gpib4pi-1.1" +#define PINMAP_2 "yoga" +static char *pin_map = PINMAP_0; +module_param(pin_map, charp, 0660); +MODULE_PARM_DESC(pin_map, " valid values: " PINMAP_0 " " PINMAP_1 " " PINMAP_2); + +/********************************************** + * Signal pairing and pin wiring between the * + * Raspberry-Pi connector and the GPIB bus * + * * + * signal pin wiring * + * GPIB Pi-gpio GPIB -> RPi * + ********************************************** + */ +enum lines_t { + D01_pin_nr = 20, /* 1 -> 38 */ + D02_pin_nr = 26, /* 2 -> 37 */ + D03_pin_nr = 16, /* 3 -> 36 */ + D04_pin_nr = 19, /* 4 -> 35 */ + D05_pin_nr = 13, /* 13 -> 33 */ + D06_pin_nr = 12, /* 14 -> 32 */ + D07_pin_nr = 6, /* 15 -> 31 */ + D08_pin_nr = 5, /* 16 -> 29 */ + EOI_pin_nr = 9, /* 5 -> 21 */ + DAV_pin_nr = 10, /* 6 -> 19 */ + NRFD_pin_nr = 24, /* 7 -> 18 */ + NDAC_pin_nr = 23, /* 8 -> 16 */ + IFC_pin_nr = 22, /* 9 -> 15 */ + SRQ_pin_nr = 11, /* 10 -> 23 */ + _ATN_pin_nr = 25, /* 11 -> 22 */ + REN_pin_nr = 27, /* 17 -> 13 */ +/* + * GROUND PINS + * 12,18,19,20,21,22,23,24 => 14,20,25,30,34,39 + */ + +/* + * These lines are used to control the external + * SN75160/161 driver chips when used. + * When not used there is reduced fan out; + * currently tested with up to 4 devices. + */ + +/* Pi GPIO RPI 75161B 75160B Description */ + PE_pin_nr = 7, /* 26 -> nc 11 Pullup Enable */ + DC_pin_nr = 8, /* 24 -> 12 nc Direction control */ + TE_pin_nr = 18, /* 12 -> 2 1 Talk Enable */ + ACT_LED_pin_nr = 4, /* 7 -> LED */ + +/* YOGA adapter uses different pinout to ease layout */ + YOGA_D03_pin_nr = 13, + YOGA_D04_pin_nr = 12, + YOGA_D05_pin_nr = 21, + YOGA_D06_pin_nr = 19, +}; + +/* + * GPIO descriptors and pins - WARNING: STRICTLY KEEP ITEMS ORDER + */ + +#define GPIB_PINS 16 +#define SN7516X_PINS 4 +#define NUM_PINS (GPIB_PINS + SN7516X_PINS) + +DEFINE_LED_TRIGGER(ledtrig_gpib); +#define ACT_LED_ON do { \ + if (ACT_LED) \ + gpiod_direction_output(ACT_LED, 1); \ + else \ + led_trigger_event(ledtrig_gpib, LED_FULL); } \ + while (0) +#define ACT_LED_OFF do { \ + if (ACT_LED) \ + gpiod_direction_output(ACT_LED, 0); \ + else \ + led_trigger_event(ledtrig_gpib, LED_OFF); } \ + while (0) + +struct gpio_desc *all_descriptors[GPIB_PINS + SN7516X_PINS]; + +#define D01 all_descriptors[0] +#define D02 all_descriptors[1] +#define D03 all_descriptors[2] +#define D04 all_descriptors[3] +#define D05 all_descriptors[4] +#define D06 all_descriptors[5] +#define D07 all_descriptors[6] +#define D08 all_descriptors[7] + +#define EOI all_descriptors[8] +#define NRFD all_descriptors[9] +#define IFC all_descriptors[10] +#define _ATN all_descriptors[11] +#define REN all_descriptors[12] +#define DAV all_descriptors[13] +#define NDAC all_descriptors[14] +#define SRQ all_descriptors[15] + +#define PE all_descriptors[16] +#define DC all_descriptors[17] +#define TE all_descriptors[18] +#define ACT_LED all_descriptors[19] + +/* YOGA dapter uses a global enable for the buffer chips, re-using the TE pin */ +#define YOGA_ENABLE TE + +int gpios_vector[] = { + D01_pin_nr, + D02_pin_nr, + D03_pin_nr, + D04_pin_nr, + D05_pin_nr, + D06_pin_nr, + D07_pin_nr, + D08_pin_nr, + + EOI_pin_nr, + NRFD_pin_nr, + IFC_pin_nr, + _ATN_pin_nr, + REN_pin_nr, + DAV_pin_nr, + NDAC_pin_nr, + SRQ_pin_nr, + + PE_pin_nr, + DC_pin_nr, + TE_pin_nr, + ACT_LED_pin_nr +}; + +/* Lookup table for general GPIOs */ + +static struct gpiod_lookup_table gpib_gpio_table_1 = { + // for bcm2835/6 + .dev_id = "", // device id of board device + .table = { + GPIO_LOOKUP_IDX("GPIO_GCLK", U16_MAX, NULL, 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO5", U16_MAX, NULL, 5, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO6", U16_MAX, NULL, 6, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("SPI_CE1_N", U16_MAX, NULL, 7, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("SPI_CE0_N", U16_MAX, NULL, 8, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("SPI_MISO", U16_MAX, NULL, 9, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("SPI_MOSI", U16_MAX, NULL, 10, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("SPI_SCLK", U16_MAX, NULL, 11, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO12", U16_MAX, NULL, 12, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO13", U16_MAX, NULL, 13, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO16", U16_MAX, NULL, 16, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO17", U16_MAX, NULL, 17, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO18", U16_MAX, NULL, 18, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO19", U16_MAX, NULL, 19, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO20", U16_MAX, NULL, 20, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO21", U16_MAX, NULL, 21, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO22", U16_MAX, NULL, 22, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO23", U16_MAX, NULL, 23, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO24", U16_MAX, NULL, 24, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO25", U16_MAX, NULL, 25, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO26", U16_MAX, NULL, 26, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO27", U16_MAX, NULL, 27, GPIO_ACTIVE_HIGH), + { } + }, +}; + +static struct gpiod_lookup_table gpib_gpio_table_0 = { + .dev_id = "", // device id of board device + .table = { + // for bcm27xx based pis (b b+ 2b 3b 3b+ 4 5) + GPIO_LOOKUP_IDX("GPIO4", U16_MAX, NULL, 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO5", U16_MAX, NULL, 5, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO6", U16_MAX, NULL, 6, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO7", U16_MAX, NULL, 7, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO8", U16_MAX, NULL, 8, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO9", U16_MAX, NULL, 9, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO10", U16_MAX, NULL, 10, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO11", U16_MAX, NULL, 11, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO12", U16_MAX, NULL, 12, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO13", U16_MAX, NULL, 13, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO16", U16_MAX, NULL, 16, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO17", U16_MAX, NULL, 17, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO18", U16_MAX, NULL, 18, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO19", U16_MAX, NULL, 19, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO20", U16_MAX, NULL, 20, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO21", U16_MAX, NULL, 21, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO22", U16_MAX, NULL, 22, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO23", U16_MAX, NULL, 23, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO24", U16_MAX, NULL, 24, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO25", U16_MAX, NULL, 25, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO26", U16_MAX, NULL, 26, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIO27", U16_MAX, NULL, 27, GPIO_ACTIVE_HIGH), + { } + }, +}; + +static struct gpiod_lookup_table *lookup_tables[] = { + &gpib_gpio_table_0, + &gpib_gpio_table_1, + 0 +}; + +/* struct which defines private_data for gpio driver */ + +struct bb_priv { + int irq_NRFD; + int irq_NDAC; + int irq_DAV; + int irq_SRQ; + int dav_mode; /* dav interrupt mode 0/1 -> edge/levels */ + int nrfd_mode; /* nrfd interrupt mode 0/1 -> edge/levels */ + int ndac_mode; /* nrfd interrupt mode 0/1 -> edge/levels */ + int dav_tx; /* keep trace of DAV status while sending */ + int dav_rx; /* keep trace of DAV status while receiving */ + u8 eos; // eos character + short eos_flags; // eos mode + short eos_check; /* eos check required in current operation ... */ + short eos_check_8; /* ... with byte comparison */ + short eos_mask_7; /* ... with 7 bit masked character */ + short int end; + int request; + int count; + int direction; + int t1_delay; + u8 *rbuf; + u8 *wbuf; + int end_flag; + int r_busy; /* 0==idle 1==busy */ + int w_busy; + int write_done; + int cmd; /* 1 = cmd write in progress */ + size_t w_cnt; + size_t length; + u8 *w_buf; + spinlock_t rw_lock; // protect mods to rw_lock + int phase; + int ndac_idle; + int ndac_seq; + int nrfd_idle; + int nrfd_seq; + int dav_seq; + long all_irqs; + int dav_idle; + int atn_asserted; + + enum talker_function_state talker_state; + enum listener_function_state listener_state; +}; + +inline long usec_diff(struct timespec64 *a, struct timespec64 *b); +static void bb_buffer_print(unsigned char *buffer, size_t length, int cmd, int eoi); +static void set_data_lines(u8 byte); +static u8 get_data_lines(void); +static void set_data_lines_input(void); +static void set_data_lines_output(void); +static inline int check_for_eos(struct bb_priv *priv, uint8_t byte); +static void set_atn(struct bb_priv *priv, int atn_asserted); + +static inline void SET_DIR_WRITE(struct bb_priv *priv); +static inline void SET_DIR_READ(struct bb_priv *priv); + +#define DIR_READ 0 +#define DIR_WRITE 1 + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB helper functions for bitbanging I/O"); + +/**** global variables ****/ +#ifdef CONFIG_GPIB_DEBUG +static int debug = 1; +#else +static int debug; +#endif +module_param(debug, int, 0644); + +static char printable(char x) +{ + if (x < 32 || x > 126) + return ' '; + return x; +} + +/*************************************************************************** + * * + * READ * + * * + ***************************************************************************/ + +static int bb_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read) +{ + struct bb_priv *priv = board->private_data; + unsigned long flags; + int retval = 0; + + ACT_LED_ON; + SET_DIR_READ(priv); + + dbg_printk(2, "board: %p lock %d length: %zu\n", + board, mutex_is_locked(&board->user_mutex), length); + + priv->end = 0; + priv->count = 0; + priv->rbuf = buffer; + if (length == 0) + goto read_end; + priv->request = length; + priv->eos_check = (priv->eos_flags & REOS) == 0; /* do eos check */ + priv->eos_check_8 = priv->eos_flags & BIN; /* over 8 bits */ + priv->eos_mask_7 = priv->eos & 0x7f; /* with this 7 bit eos */ + + dbg_printk(3, ".........." LINFMT "\n", LINVAL); + + spin_lock_irqsave(&priv->rw_lock, flags); + priv->dav_mode = 1; + priv->dav_rx = 1; + ENABLE_IRQ(priv->irq_DAV, IRQ_TYPE_LEVEL_LOW); + priv->end_flag = 0; + gpiod_set_value(NRFD, 1); // ready for data + priv->r_busy = 1; + priv->phase = 100; + spin_unlock_irqrestore(&priv->rw_lock, flags); + + /* wait for the interrupt routines finish their work */ + + retval = wait_event_interruptible(board->wait, + (priv->end_flag || board->status & TIMO)); + + dbg_printk(3, "awake from wait queue: %d\n", retval); + + if (retval == 0 && board->status & TIMO) { + retval = -ETIMEDOUT; + dbg_printk(1, "timeout\n"); + } else if (retval) { + retval = -ERESTARTSYS; + } + + DISABLE_IRQ(priv->irq_DAV); + spin_lock_irqsave(&priv->rw_lock, flags); + gpiod_set_value(NRFD, 0); // DIR_READ line state + priv->r_busy = 0; + spin_unlock_irqrestore(&priv->rw_lock, flags); + +read_end: + ACT_LED_OFF; + *bytes_read = priv->count; + *end = priv->end; + priv->r_busy = 0; + dbg_printk(2, "return: %d eoi|eos: %d count: %d\n\n", retval, priv->end, priv->count); + return retval; +} + +/*************************************************************************** + * * + * READ interrupt routine (DAV line) * + * * + ***************************************************************************/ + +static irqreturn_t bb_DAV_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + struct bb_priv *priv = board->private_data; + int val; + unsigned long flags; + + spin_lock_irqsave(&priv->rw_lock, flags); + + priv->all_irqs++; + + if (priv->dav_mode) { + ENABLE_IRQ(priv->irq_DAV, IRQ_TYPE_EDGE_BOTH); + priv->dav_mode = 0; + } + + if (priv->r_busy == 0) { + dbg_printk(1, "interrupt while idle after %d at %d\n", + priv->count, priv->phase); + priv->dav_idle++; + priv->phase = 200; + goto dav_exit; /* idle */ + } + + val = gpiod_get_value(DAV); + if (val == priv->dav_rx) { + dbg_printk(1, "out of order DAV interrupt %d/%d after %zu/%zu at %d cmd %d " + LINFMT ".\n", val, priv->dav_rx, priv->w_cnt, priv->length, + priv->phase, priv->cmd, LINVAL); + priv->dav_seq++; + } + priv->dav_rx = val; + + dbg_printk(3, "> irq: %d DAV: %d st: %4lx dir: %d busy: %d:%d\n", + irq, val, board->status, priv->direction, priv->r_busy, priv->w_busy); + + if (val == 0) { + gpiod_set_value(NRFD, 0); // not ready for data + priv->rbuf[priv->count++] = get_data_lines(); + priv->end = !gpiod_get_value(EOI); + gpiod_set_value(NDAC, 1); // data accepted + priv->end |= check_for_eos(priv, priv->rbuf[priv->count - 1]); + priv->end_flag = ((priv->count >= priv->request) || priv->end); + priv->phase = 210; + } else { + gpiod_set_value(NDAC, 0); // data not accepted + if (priv->end_flag) { + priv->r_busy = 0; + wake_up_interruptible(&board->wait); + priv->phase = 220; + } else { + gpiod_set_value(NRFD, 1); // ready for data + priv->phase = 230; + } + } + +dav_exit: + spin_unlock_irqrestore(&priv->rw_lock, flags); + dbg_printk(3, "< irq: %d count %d\n", irq, priv->count); + return IRQ_HANDLED; +} + +/*************************************************************************** + * * + * WRITE * + * * + ***************************************************************************/ + +static int bb_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + unsigned long flags; + int retval = 0; + + struct bb_priv *priv = board->private_data; + + ACT_LED_ON; + + priv->w_cnt = 0; + priv->w_buf = buffer; + dbg_printk(2, "board %p lock %d length: %zu\n", + board, mutex_is_locked(&board->user_mutex), length); + + if (debug > 1) + bb_buffer_print(buffer, length, priv->cmd, send_eoi); + priv->count = 0; + priv->phase = 300; + + if (length == 0) + goto write_end; + priv->end = send_eoi; + priv->length = length; + + SET_DIR_WRITE(priv); + + dbg_printk(2, "Enabling interrupts - NRFD: %d NDAC: %d\n", + gpiod_get_value(NRFD), gpiod_get_value(NDAC)); + + if (gpiod_get_value(NRFD) && gpiod_get_value(NDAC)) { /* check for listener */ + retval = -ENODEV; + goto write_end; + } + + spin_lock_irqsave(&priv->rw_lock, flags); + priv->w_busy = 1; /* make the interrupt routines active */ + priv->write_done = 0; + priv->nrfd_mode = 1; + priv->ndac_mode = 1; + priv->dav_tx = 1; + ENABLE_IRQ(priv->irq_NDAC, IRQ_TYPE_LEVEL_HIGH); + ENABLE_IRQ(priv->irq_NRFD, IRQ_TYPE_LEVEL_HIGH); + spin_unlock_irqrestore(&priv->rw_lock, flags); + + /* wait for the interrupt routines finish their work */ + + retval = wait_event_interruptible(board->wait, + priv->write_done || (board->status & TIMO)); + + dbg_printk(3, "awake from wait queue: %d\n", retval); + + if (retval == 0) { + if (board->status & TIMO) { + retval = -ETIMEDOUT; + dbg_printk(1, "timeout after %zu/%zu at %d " LINFMT " eoi: %d\n", + priv->w_cnt, length, priv->phase, LINVAL, send_eoi); + } else { + // dbg_printk(1,"written %zu\n", priv->w_cnt); + retval = priv->w_cnt; + } + } else { + retval = -ERESTARTSYS; + } + + DISABLE_IRQ(priv->irq_NRFD); + DISABLE_IRQ(priv->irq_NDAC); + + spin_lock_irqsave(&priv->rw_lock, flags); + priv->w_busy = 0; + gpiod_set_value(DAV, 1); // DIR_WRITE line state + gpiod_set_value(EOI, 1); // De-assert EOI (in case) + spin_unlock_irqrestore(&priv->rw_lock, flags); + +write_end: + *bytes_written = priv->w_cnt; + ACT_LED_OFF; + dbg_printk(2, "sent %zu bytes\r\n\r\n", *bytes_written); + priv->phase = 310; + return retval; +} + +/*************************************************************************** + * * + * WRITE interrupt routine (NRFD line) * + * * + ***************************************************************************/ + +static irqreturn_t bb_NRFD_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + struct bb_priv *priv = board->private_data; + unsigned long flags; + int nrfd; + + spin_lock_irqsave(&priv->rw_lock, flags); + + nrfd = gpiod_get_value(NRFD); + priv->all_irqs++; + + dbg_printk(3, "> irq: %d NRFD: %d NDAC: %d st: %4lx dir: %d busy: %d:%d\n", + irq, nrfd, gpiod_get_value(NDAC), board->status, priv->direction, + priv->w_busy, priv->r_busy); + + if (priv->nrfd_mode) { + ENABLE_IRQ(priv->irq_NRFD, IRQ_TYPE_EDGE_RISING); + priv->nrfd_mode = 0; + } + + if (priv->w_busy == 0) { + dbg_printk(1, "interrupt while idle after %zu/%zu at %d\n", + priv->w_cnt, priv->length, priv->phase); + priv->nrfd_idle++; + goto nrfd_exit; /* idle */ + } + if (nrfd == 0) { + dbg_printk(1, "out of order interrupt after %zu/%zu at %d cmd %d " LINFMT ".\n", + priv->w_cnt, priv->length, priv->phase, priv->cmd, LINVAL); + priv->phase = 400; + priv->nrfd_seq++; + goto nrfd_exit; + } + if (!priv->dav_tx) { + dbg_printk(1, "DAV low after %zu/%zu cmd %d " LINFMT ". No action.\n", + priv->w_cnt, priv->length, priv->cmd, LINVAL); + priv->dav_seq++; + goto nrfd_exit; + } + + if (priv->atn_asserted && priv->w_cnt >= priv->length) { // test for end of transfer + priv->write_done = 1; + priv->w_busy = 0; + wake_up_interruptible(&board->wait); + goto nrfd_exit; + } + + dbg_printk(3, "sending %zu\n", priv->w_cnt); + + set_data_lines(priv->w_buf[priv->w_cnt++]); // put the data on the lines + + if (priv->w_cnt == priv->length && priv->end) { + dbg_printk(3, "Asserting EOI\n"); + gpiod_set_value(EOI, 0); // Assert EOI + } + + gpiod_set_value(DAV, 0); // Data available + priv->dav_tx = 0; + priv->phase = 410; + +nrfd_exit: + spin_unlock_irqrestore(&priv->rw_lock, flags); + + return IRQ_HANDLED; +} + +/*************************************************************************** + * * + * WRITE interrupt routine (NDAC line) * + * * + ***************************************************************************/ + +static irqreturn_t bb_NDAC_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + struct bb_priv *priv = board->private_data; + unsigned long flags; + int ndac; + + spin_lock_irqsave(&priv->rw_lock, flags); + + ndac = gpiod_get_value(NDAC); + priv->all_irqs++; + dbg_printk(3, "> irq: %d NRFD: %d NDAC: %d st: %4lx dir: %d busy: %d:%d\n", + irq, gpiod_get_value(NRFD), ndac, board->status, priv->direction, + priv->w_busy, priv->r_busy); + + if (priv->ndac_mode) { + ENABLE_IRQ(priv->irq_NDAC, IRQ_TYPE_EDGE_RISING); + priv->ndac_mode = 0; + } + + if (priv->w_busy == 0) { + dbg_printk(1, "interrupt while idle.\n"); + priv->ndac_idle++; + goto ndac_exit; + } + if (ndac == 0) { + dbg_printk(1, "out of order interrupt at %zu:%d.\n", priv->w_cnt, priv->phase); + priv->phase = 500; + priv->ndac_seq++; + goto ndac_exit; + } + if (priv->dav_tx) { + dbg_printk(1, "DAV high after %zu/%zu cmd %d " LINFMT ". No action.\n", + priv->w_cnt, priv->length, priv->cmd, LINVAL); + priv->dav_seq++; + goto ndac_exit; + } + + dbg_printk(3, "accepted %zu\n", priv->w_cnt - 1); + + if (!priv->atn_asserted && priv->w_cnt >= priv->length) { // test for end of transfer + priv->write_done = 1; + priv->w_busy = 0; + wake_up_interruptible(&board->wait); + } else { + gpiod_set_value(DAV, 1); // Data not available + priv->dav_tx = 1; + priv->phase = 510; + } + +ndac_exit: + spin_unlock_irqrestore(&priv->rw_lock, flags); + return IRQ_HANDLED; +} + +/*************************************************************************** + * * + * interrupt routine for SRQ line * + * * + ***************************************************************************/ + +static irqreturn_t bb_SRQ_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + + int val = gpiod_get_value(SRQ); + + dbg_printk(3, "> %d st: %4lx\n", val, board->status); + + if (!val) + set_bit(SRQI_NUM, &board->status); /* set_bit() is atomic */ + + wake_up_interruptible(&board->wait); + + return IRQ_HANDLED; +} + +static int bb_command(gpib_board_t *board, uint8_t *buffer, + size_t length, size_t *bytes_written) +{ + size_t ret; + struct bb_priv *priv = board->private_data; + int i; + + dbg_printk(2, "%p %p\n", buffer, board->buffer); + + /* the _ATN line has already been asserted by bb_take_control() */ + + priv->cmd = 1; + + ret = bb_write(board, buffer, length, 0, bytes_written); // no eoi + + for (i = 0; i < length; i++) { + if (buffer[i] == UNT) { + priv->talker_state = talker_idle; + } else { + if (buffer[i] == UNL) { + priv->listener_state = listener_idle; + } else { + if (buffer[i] == (MTA(board->pad))) { + priv->talker_state = talker_addressed; + priv->listener_state = listener_idle; + } else if (buffer[i] == (MLA(board->pad))) { + priv->listener_state = listener_addressed; + priv->talker_state = talker_idle; + } + } + } + } + + /* the _ATN line will be released by bb_go_to_stby */ + + priv->cmd = 0; + + return ret; +} + +/*************************************************************************** + * * + * Buffer print with decode for debug/trace * + * * + ***************************************************************************/ + +static char *cmd_string[32] = { + "", // 0x00 + "GTL", // 0x01 + "", // 0x02 + "", // 0x03 + "SDC", // 0x04 + "PPC", // 0x05 + "", // 0x06 + "", // 0x07 + "GET", // 0x08 + "TCT", // 0x09 + "", // 0x0a + "", // 0x0b + "", // 0x0c + "", // 0x0d + "", // 0x0e + "", // 0x0f + "", // 0x10 + "LLO", // 0x11 + "", // 0x12 + "", // 0x13 + "DCL", // 0x14 + "PPU", // 0x15 + "", // 0x16 + "", // 0x17 + "SPE", // 0x18 + "SPD", // 0x19 + "", // 0x1a + "", // 0x1b + "", // 0x1c + "", // 0x1d + "", // 0x1e + "CFE" // 0x1f +}; + +static void bb_buffer_print(unsigned char *buffer, size_t length, int cmd, int eoi) +{ + int i; + + if (cmd) { + dbg_printk(2, "\n", length); + for (i = 0; i < length; i++) { + if (buffer[i] < 0x20) { + dbg_printk(3, "0x%x=%s\n", buffer[i], cmd_string[buffer[i]]); + } else if (buffer[i] == 0x3f) { + dbg_printk(3, "0x%x=%s\n", buffer[i], "UNL"); + } else if (buffer[i] == 0x5f) { + dbg_printk(3, "0x%x=%s\n", buffer[i], "UNT"); + } else if (buffer[i] < 0x60) { + dbg_printk(3, "0x%x=%s%d\n", buffer[i], + (buffer[i] & 0x40) ? "TLK" : "LSN", buffer[i] & 0x1F); + } else { + dbg_printk(3, "0x%x\n", buffer[i]); + } + } + } else { + dbg_printk(2, "\n", length, (eoi) ? "w.EOI" : " "); + for (i = 0; i < length; i++) + dbg_printk(2, "%3d 0x%x->%c\n", i, buffer[i], printable(buffer[i])); + } +} + +/*************************************************************************** + * * + * STATUS Management * + * * + ***************************************************************************/ +static void set_atn(struct bb_priv *priv, int atn_asserted) +{ + if (priv->listener_state != listener_idle && + priv->talker_state != talker_idle) { + dbg_printk(0, "listener/talker state machine conflict\n"); + } + if (atn_asserted) { + if (priv->listener_state == listener_active) + priv->listener_state = listener_addressed; + if (priv->talker_state == talker_active) + priv->talker_state = talker_addressed; + } else { + if (priv->listener_state == listener_addressed) { + priv->listener_state = listener_active; + SET_DIR_READ(priv); // make sure holdoff is active when we unassert ATN + } + if (priv->talker_state == talker_addressed) + priv->talker_state = talker_active; + } + gpiod_direction_output(_ATN, !atn_asserted); + priv->atn_asserted = atn_asserted; +} + +static int bb_take_control(gpib_board_t *board, int synchronous) +{ + dbg_printk(2, "%d\n", synchronous); + set_atn(board->private_data, 1); + set_bit(CIC_NUM, &board->status); + return 0; +} + +static int bb_go_to_standby(gpib_board_t *board) +{ + dbg_printk(2, "\n"); + set_atn(board->private_data, 0); + return 0; +} + +static void bb_request_system_control(gpib_board_t *board, int request_control) +{ + dbg_printk(2, "%d\n", request_control); + if (request_control) { + set_bit(CIC_NUM, &board->status); + // drive DAV & EOI false, enable NRFD & NDAC irqs + SET_DIR_WRITE(board->private_data); + } else { + clear_bit(CIC_NUM, &board->status); + } +} + +static void bb_interface_clear(gpib_board_t *board, int assert) +{ + struct bb_priv *priv = board->private_data; + + dbg_printk(2, "%d\n", assert); + if (assert) { + gpiod_direction_output(IFC, 0); + priv->talker_state = talker_idle; + priv->listener_state = listener_idle; + } else { + gpiod_direction_output(IFC, 1); + } +} + +static void bb_remote_enable(gpib_board_t *board, int enable) +{ + dbg_printk(2, "%d\n", enable); + if (enable) { + set_bit(REM_NUM, &board->status); + gpiod_direction_output(REN, 0); + } else { + clear_bit(REM_NUM, &board->status); + gpiod_direction_output(REN, 1); + } +} + +static int bb_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct bb_priv *priv = board->private_data; + + dbg_printk(2, "%s\n", "EOS_en"); + priv->eos = eos_byte; + priv->eos_flags = REOS; + if (compare_8_bits) + priv->eos_flags |= BIN; + + return 0; +} + +static void bb_disable_eos(gpib_board_t *board) +{ + struct bb_priv *priv = board->private_data; + + dbg_printk(2, "\n"); + priv->eos_flags &= ~REOS; +} + +static unsigned int bb_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct bb_priv *priv = board->private_data; + + board->status &= ~clear_mask; + + if (gpiod_get_value(SRQ)) /* SRQ asserted low */ + clear_bit(SRQI_NUM, &board->status); + else + set_bit(SRQI_NUM, &board->status); + if (gpiod_get_value(_ATN)) /* ATN asserted low */ + clear_bit(ATN_NUM, &board->status); + else + set_bit(ATN_NUM, &board->status); + if (priv->talker_state == talker_active || + priv->talker_state == talker_addressed) + set_bit(TACS_NUM, &board->status); + else + clear_bit(TACS_NUM, &board->status); + + if (priv->listener_state == listener_active || + priv->listener_state == listener_addressed) + set_bit(LACS_NUM, &board->status); + else + clear_bit(LACS_NUM, &board->status); + + dbg_printk(2, "0x%lx mask 0x%x\n", board->status, clear_mask); + + return board->status; +} + +static int bb_primary_address(gpib_board_t *board, unsigned int address) +{ + dbg_printk(2, "%d\n", address); + board->pad = address; + return 0; +} + +static int bb_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + dbg_printk(2, "%d %d\n", address, enable); + if (enable) + board->sad = address; + return 0; +} + +static int bb_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + dbg_printk(1, "%s\n", "not implemented"); + return -EPERM; +} + +static void bb_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + dbg_printk(1, "%s\n", "not implemented"); +} + +static void bb_parallel_poll_response(gpib_board_t *board, int ist) +{ +} + +static void bb_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + dbg_printk(1, "%s\n", "not implemented"); +} + +static uint8_t bb_serial_poll_status(gpib_board_t *board) +{ + dbg_printk(1, "%s\n", "not implemented"); + return 0; // -ENOSYS; +} + +static unsigned int bb_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct bb_priv *priv = board->private_data; + + if (nano_sec <= 350) + priv->t1_delay = 350; + else if (nano_sec <= 1100) + priv->t1_delay = 1100; + else + priv->t1_delay = 2000; + + dbg_printk(2, "t1 delay set to %d nanosec\n", priv->t1_delay); + + return priv->t1_delay; +} + +static void bb_return_to_local(gpib_board_t *board) +{ + dbg_printk(1, "%s\n", "not implemented"); +} + +static int bb_line_status(const gpib_board_t *board) +{ + int line_status = ValidALL; + +// dbg_printk(1,"\n"); + + if (gpiod_get_value(REN) == 0) + line_status |= BusREN; + if (gpiod_get_value(IFC) == 0) + line_status |= BusIFC; + if (gpiod_get_value(NDAC) == 0) + line_status |= BusNDAC; + if (gpiod_get_value(NRFD) == 0) + line_status |= BusNRFD; + if (gpiod_get_value(DAV) == 0) + line_status |= BusDAV; + if (gpiod_get_value(EOI) == 0) + line_status |= BusEOI; + if (gpiod_get_value(_ATN) == 0) + line_status |= BusATN; + if (gpiod_get_value(SRQ) == 0) + line_status |= BusSRQ; + + dbg_printk(2, "status lines: %4x\n", line_status); + + return line_status; +} + +/*************************************************************************** + * * + * Module Management * + * * + ***************************************************************************/ + +static int allocate_private(gpib_board_t *board) +{ + board->private_data = kzalloc(sizeof(struct bb_priv), GFP_KERNEL); + if (!board->private_data) + return -1; + return 0; +} + +static void free_private(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +static int bb_get_irq(gpib_board_t *board, char *name, + struct gpio_desc *gpio, int *irq, + irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags) +{ + if (!gpio) + return -1; + gpiod_direction_input(gpio); + *irq = gpiod_to_irq(gpio); + dbg_printk(2, "IRQ %s: %d\n", name, *irq); + if (*irq < 0) { + dbg_printk(0, "gpib: can't get IRQ for %s\n", name); + return -1; + } + if (request_threaded_irq(*irq, handler, thread_fn, flags, name, board)) { + dbg_printk(0, "gpib: can't request IRQ for %s %d\n", name, *irq); + *irq = 0; + return -1; + } + DISABLE_IRQ(*irq); + return 0; +} + +static void bb_free_irq(gpib_board_t *board, int *irq, char *name) +{ + if (*irq) { + free_irq(*irq, board); + dbg_printk(2, "IRQ %d(%s) freed\n", *irq, name); + *irq = 0; + } +} + +static void release_gpios(void) +{ + int j; + + for (j = 0 ; j < NUM_PINS ; j++) { + if (all_descriptors[j]) { + gpiod_put(all_descriptors[j]); + all_descriptors[j] = 0; + } + } +} + +static int allocate_gpios(gpib_board_t *board) +{ + int j, retval = 0; + bool error = false; + int table_index = 0; + char name[256]; + struct gpio_desc *desc; + struct gpiod_lookup_table *lookup_table; + + if (!board->gpib_dev) { + pr_err("NULL gpib dev for board\n"); + return -ENOENT; + } + + lookup_table = lookup_tables[0]; + lookup_table->dev_id = dev_name(board->gpib_dev); + gpiod_add_lookup_table(lookup_table); + dbg_printk(1, "Allocating gpios using table index %d\n", table_index); + + for (j = 0 ; j < NUM_PINS ; j++) { + if (gpios_vector[j] < 0) + continue; + /* name not really used in gpiod_get_index() */ + sprintf(name, "GPIO%d", gpios_vector[j]); +try_again: + dbg_printk(1, "Allocating gpio %s pin no %d\n", name, gpios_vector[j]); + desc = gpiod_get_index(board->gpib_dev, name, gpios_vector[j], GPIOD_IN); + + if (IS_ERR(desc)) { + gpiod_remove_lookup_table(lookup_table); + table_index++; + lookup_table = lookup_tables[table_index]; + if (lookup_table) { + dbg_printk(1, "Allocation failed, now using table_index %d\n", + table_index); + lookup_table->dev_id = dev_name(board->gpib_dev); + gpiod_add_lookup_table(lookup_table); + goto try_again; + } + dbg_printk(0, "Unable to obtain gpio descriptor for pin %d error %ld\n", + gpios_vector[j], PTR_ERR(desc)); + error = true; + break; + } + all_descriptors[j] = desc; + } + + if (error) { /* undo what already done */ + release_gpios(); + retval = -1; + } + if (lookup_table) + gpiod_remove_lookup_table(lookup_table); + // Initialize LED trigger + led_trigger_register_simple("gpib", &ledtrig_gpib); + return retval; +} + +static void bb_detach(gpib_board_t *board) +{ + struct bb_priv *priv = board->private_data; + + dbg_printk(2, "Enter with data %p\n", board->private_data); + if (!board->private_data) + return; + + led_trigger_unregister_simple(ledtrig_gpib); + + bb_free_irq(board, &priv->irq_DAV, NAME "_DAV"); + bb_free_irq(board, &priv->irq_NRFD, NAME "_NRFD"); + bb_free_irq(board, &priv->irq_NDAC, NAME "_NDAC"); + bb_free_irq(board, &priv->irq_SRQ, NAME "_SRQ"); + + if (strcmp(PINMAP_2, pin_map) == 0) { /* YOGA */ + gpiod_set_value(YOGA_ENABLE, 0); + } + + release_gpios(); + + dbg_printk(2, "detached board: %d\n", board->minor); + dbg_printk(0, "NRFD: idle %d, seq %d, NDAC: idle %d, seq %d DAV: idle %d seq: %d all: %ld", + priv->nrfd_idle, priv->nrfd_seq, + priv->ndac_idle, priv->ndac_seq, + priv->dav_idle, priv->dav_seq, priv->all_irqs); + + free_private(board); +} + +static int bb_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct bb_priv *priv; + int retval = 0; + + dbg_printk(2, "%s\n", "Enter ..."); + + board->status = 0; + + if (allocate_private(board)) + return -ENOMEM; + priv = board->private_data; + priv->direction = -1; + priv->t1_delay = 2000; + priv->listener_state = listener_idle; + priv->talker_state = talker_idle; + + sn7516x = sn7516x_used; + if (strcmp(PINMAP_0, pin_map) == 0) { + if (!sn7516x) { + gpios_vector[&(PE) - &all_descriptors[0]] = -1; + gpios_vector[&(DC) - &all_descriptors[0]] = -1; + gpios_vector[&(TE) - &all_descriptors[0]] = -1; + } + } else if (strcmp(PINMAP_1, pin_map) == 0) { + if (!sn7516x) { + gpios_vector[&(PE) - &all_descriptors[0]] = -1; + gpios_vector[&(DC) - &all_descriptors[0]] = -1; + gpios_vector[&(TE) - &all_descriptors[0]] = -1; + } + gpios_vector[&(REN) - &all_descriptors[0]] = 0; /* 27 -> 0 REN on GPIB pin 0 */ + } else if (strcmp(PINMAP_2, pin_map) == 0) { /* YOGA */ + sn7516x = 0; + gpios_vector[&(D03) - &all_descriptors[0]] = YOGA_D03_pin_nr; + gpios_vector[&(D04) - &all_descriptors[0]] = YOGA_D04_pin_nr; + gpios_vector[&(D05) - &all_descriptors[0]] = YOGA_D05_pin_nr; + gpios_vector[&(D06) - &all_descriptors[0]] = YOGA_D06_pin_nr; + gpios_vector[&(PE) - &all_descriptors[0]] = -1; + gpios_vector[&(DC) - &all_descriptors[0]] = -1; + gpios_vector[&(ACT_LED) - &all_descriptors[0]] = -1; + } else { + dbg_printk(0, "Unrecognized pin mapping.\n"); + goto bb_attach_fail; + } + dbg_printk(0, "Using pin map \"%s\" %s\n", pin_map, (sn7516x) ? + " with SN7516x driver support" : ""); + + if (allocate_gpios(board)) + goto bb_attach_fail; + +/* Configure SN7516X control lines. + * drive ATN, IFC and REN as outputs only when master + * i.e. system controller. In this mode can only be the CIC + * When not master then enable device mode ATN, IFC & REN as inputs + */ + if (sn7516x) { + gpiod_direction_output(DC, 0); + gpiod_direction_output(TE, 1); + gpiod_direction_output(PE, 1); + } + + if (strcmp(PINMAP_2, pin_map) == 0) { /* YOGA: enable level shifters */ + gpiod_direction_output(YOGA_ENABLE, 1); + } + + spin_lock_init(&priv->rw_lock); + + /* request DAV interrupt for read */ + if (bb_get_irq(board, NAME "_DAV", DAV, &priv->irq_DAV, bb_DAV_interrupt, NULL, + IRQF_TRIGGER_NONE)) + goto bb_attach_fail_r; + + /* request NRFD interrupt for write */ + if (bb_get_irq(board, NAME "_NRFD", NRFD, &priv->irq_NRFD, bb_NRFD_interrupt, NULL, + IRQF_TRIGGER_NONE)) + goto bb_attach_fail_r; + + /* request NDAC interrupt for write */ + if (bb_get_irq(board, NAME "_NDAC", NDAC, &priv->irq_NDAC, bb_NDAC_interrupt, NULL, + IRQF_TRIGGER_NONE)) + goto bb_attach_fail_r; + + /* request SRQ interrupt for Service Request */ + if (bb_get_irq(board, NAME "_SRQ", SRQ, &priv->irq_SRQ, bb_SRQ_interrupt, NULL, + IRQF_TRIGGER_NONE)) + goto bb_attach_fail_r; + + ENABLE_IRQ(priv->irq_SRQ, IRQ_TYPE_EDGE_FALLING); + + dbg_printk(0, "attached board %d\n", board->minor); + goto bb_attach_out; + +bb_attach_fail_r: + release_gpios(); +bb_attach_fail: + retval = -1; +bb_attach_out: + return retval; +} + +gpib_interface_t bb_interface = { +name: NAME, +attach : bb_attach, +detach : bb_detach, +read : bb_read, +write : bb_write, +command : bb_command, +take_control : bb_take_control, +go_to_standby : bb_go_to_standby, +request_system_control : bb_request_system_control, +interface_clear : bb_interface_clear, +remote_enable : bb_remote_enable, +enable_eos : bb_enable_eos, +disable_eos : bb_disable_eos, +parallel_poll : bb_parallel_poll, +parallel_poll_configure : bb_parallel_poll_configure, +parallel_poll_response : bb_parallel_poll_response, +line_status : bb_line_status, +update_status : bb_update_status, +primary_address : bb_primary_address, +secondary_address : bb_secondary_address, +serial_poll_response : bb_serial_poll_response, +serial_poll_status : bb_serial_poll_status, +t1_delay : bb_t1_delay, +return_to_local : bb_return_to_local, +}; + +static int __init bb_init_module(void) +{ + gpib_register_driver(&bb_interface, THIS_MODULE); + + dbg_printk(0, "module loaded with pin map \"%s\"%s\n", + pin_map, (sn7516x_used) ? " and SN7516x driver support" : ""); + return 0; +} + +static void __exit bb_exit_module(void) +{ + dbg_printk(0, "module unloaded!"); + + gpib_unregister_driver(&bb_interface); +} + +module_init(bb_init_module); +module_exit(bb_exit_module); + +/*************************************************************************** + * * + * UTILITY Functions * + * * + ***************************************************************************/ +inline long usec_diff(struct timespec64 *a, struct timespec64 *b) +{ + return ((a->tv_sec - b->tv_sec) * 1000000 + + (a->tv_nsec - b->tv_nsec) / 1000); +} + +static inline int check_for_eos(struct bb_priv *priv, uint8_t byte) +{ + if (priv->eos_check) + return 0; + + if (priv->eos_check_8) { + if (priv->eos == byte) + return 1; + } else { + if (priv->eos_mask_7 == (byte & 0x7f)) + return 1; + } + return 0; +} + +static void set_data_lines_output(void) +{ + gpiod_direction_output(D01, 1); + gpiod_direction_output(D02, 1); + gpiod_direction_output(D03, 1); + gpiod_direction_output(D04, 1); + gpiod_direction_output(D05, 1); + gpiod_direction_output(D06, 1); + gpiod_direction_output(D07, 1); + gpiod_direction_output(D08, 1); +} + +static void set_data_lines(u8 byte) +{ + gpiod_set_value(D01, !(byte & 0x01)); + gpiod_set_value(D02, !(byte & 0x02)); + gpiod_set_value(D03, !(byte & 0x04)); + gpiod_set_value(D04, !(byte & 0x08)); + gpiod_set_value(D05, !(byte & 0x10)); + gpiod_set_value(D06, !(byte & 0x20)); + gpiod_set_value(D07, !(byte & 0x40)); + gpiod_set_value(D08, !(byte & 0x80)); +} + +static u8 get_data_lines(void) +{ + u8 ret; + + ret = gpiod_get_value(D01); + ret |= gpiod_get_value(D02) << 1; + ret |= gpiod_get_value(D03) << 2; + ret |= gpiod_get_value(D04) << 3; + ret |= gpiod_get_value(D05) << 4; + ret |= gpiod_get_value(D06) << 5; + ret |= gpiod_get_value(D07) << 6; + ret |= gpiod_get_value(D08) << 7; + return ~ret; +} + +static void set_data_lines_input(void) +{ + gpiod_direction_input(D01); + gpiod_direction_input(D02); + gpiod_direction_input(D03); + gpiod_direction_input(D04); + gpiod_direction_input(D05); + gpiod_direction_input(D06); + gpiod_direction_input(D07); + gpiod_direction_input(D08); +} + +static inline void SET_DIR_WRITE(struct bb_priv *priv) +{ + if (priv->direction == DIR_WRITE) + return; + + gpiod_direction_input(NRFD); + gpiod_direction_input(NDAC); + set_data_lines_output(); + gpiod_direction_output(DAV, 1); + gpiod_direction_output(EOI, 1); + + if (sn7516x) { + gpiod_set_value(PE, 1); /* set data lines to transmit on sn75160b */ + gpiod_set_value(TE, 1); /* set NDAC and NRFD to receive and DAV to transmit */ + } + + priv->direction = DIR_WRITE; +} + +static inline void SET_DIR_READ(struct bb_priv *priv) +{ + if (priv->direction == DIR_READ) + return; + + gpiod_direction_input(DAV); + gpiod_direction_input(EOI); + + set_data_lines_input(); + + if (sn7516x) { + gpiod_set_value(PE, 0); /* set data lines to receive on sn75160b */ + gpiod_set_value(TE, 0); /* set NDAC and NRFD to transmit and DAV to receive */ + } + + gpiod_direction_output(NRFD, 0); // hold off the talker + gpiod_direction_output(NDAC, 0); // data not accepted + + priv->direction = DIR_READ; +} diff --git a/drivers/staging/gpib/hp_82335/Makefile b/drivers/staging/gpib/hp_82335/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8b7a552e935566bfe7085bf76f49e47244a339d6 --- /dev/null +++ b/drivers/staging/gpib/hp_82335/Makefile @@ -0,0 +1,4 @@ + +obj-m += hp82335.o + + diff --git a/drivers/staging/gpib/hp_82335/hp82335.c b/drivers/staging/gpib/hp_82335/hp82335.c new file mode 100644 index 0000000000000000000000000000000000000000..40afe42aea4788ad9683e71cc9205a42b7f0abb9 --- /dev/null +++ b/drivers/staging/gpib/hp_82335/hp82335.c @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess * + ***************************************************************************/ + +/*should enable ATN interrupts (and update board->status on occurrence), + * implement recovery from bus errors (if necessary) + */ + +#include "hp82335.h" +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for HP 82335 interface cards"); + +static int hp82335_attach(gpib_board_t *board, const gpib_board_config_t *config); + +static void hp82335_detach(gpib_board_t *board); + +// wrappers for interface functions +int hp82335_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read); +} + +int hp82335_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written); +} + +int hp82335_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written); +} + +int hp82335_take_control(gpib_board_t *board, int synchronous) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_take_control(board, &priv->tms9914_priv, synchronous); +} + +int hp82335_go_to_standby(gpib_board_t *board) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_go_to_standby(board, &priv->tms9914_priv); +} + +void hp82335_request_system_control(gpib_board_t *board, int request_control) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_request_system_control(board, &priv->tms9914_priv, request_control); +} + +void hp82335_interface_clear(gpib_board_t *board, int assert) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_interface_clear(board, &priv->tms9914_priv, assert); +} + +void hp82335_remote_enable(gpib_board_t *board, int enable) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_remote_enable(board, &priv->tms9914_priv, enable); +} + +int hp82335_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits); +} + +void hp82335_disable_eos(gpib_board_t *board) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_disable_eos(board, &priv->tms9914_priv); +} + +unsigned int hp82335_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_update_status(board, &priv->tms9914_priv, clear_mask); +} + +int hp82335_primary_address(gpib_board_t *board, unsigned int address) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_primary_address(board, &priv->tms9914_priv, address); +} + +int hp82335_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable); +} + +int hp82335_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_parallel_poll(board, &priv->tms9914_priv, result); +} + +void hp82335_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config); +} + +void hp82335_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist); +} + +void hp82335_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_serial_poll_response(board, &priv->tms9914_priv, status); +} + +static uint8_t hp82335_serial_poll_status(gpib_board_t *board) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_serial_poll_status(board, &priv->tms9914_priv); +} + +static int hp82335_line_status(const gpib_board_t *board) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_line_status(board, &priv->tms9914_priv); +} + +static unsigned int hp82335_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct hp82335_priv *priv = board->private_data; + + return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec); +} + +void hp82335_return_to_local(gpib_board_t *board) +{ + struct hp82335_priv *priv = board->private_data; + + tms9914_return_to_local(board, &priv->tms9914_priv); +} + +gpib_interface_t hp82335_interface = { +name: "hp82335", +attach : hp82335_attach, +detach : hp82335_detach, +read : hp82335_read, +write : hp82335_write, +command : hp82335_command, +request_system_control : hp82335_request_system_control, +take_control : hp82335_take_control, +go_to_standby : hp82335_go_to_standby, +interface_clear : hp82335_interface_clear, +remote_enable : hp82335_remote_enable, +enable_eos : hp82335_enable_eos, +disable_eos : hp82335_disable_eos, +parallel_poll : hp82335_parallel_poll, +parallel_poll_configure : hp82335_parallel_poll_configure, +parallel_poll_response : hp82335_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : hp82335_line_status, +update_status : hp82335_update_status, +primary_address : hp82335_primary_address, +secondary_address : hp82335_secondary_address, +serial_poll_response : hp82335_serial_poll_response, +serial_poll_status : hp82335_serial_poll_status, +t1_delay : hp82335_t1_delay, +return_to_local : hp82335_return_to_local, +}; + +int hp82335_allocate_private(gpib_board_t *board) +{ + board->private_data = kzalloc(sizeof(struct hp82335_priv), GFP_KERNEL); + if (!board->private_data) + return -1; + return 0; +} + +void hp82335_free_private(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +static inline unsigned int tms9914_to_hp82335_offset(unsigned int register_num) +{ + return 0x1ff8 + register_num; +} + +static uint8_t hp82335_read_byte(struct tms9914_priv *priv, unsigned int register_num) +{ + return tms9914_iomem_read_byte(priv, tms9914_to_hp82335_offset(register_num)); +} + +static void hp82335_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +{ + tms9914_iomem_write_byte(priv, data, tms9914_to_hp82335_offset(register_num)); +} + +static void hp82335_clear_interrupt(struct hp82335_priv *hp_priv) +{ + struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv; + + writeb(0, tms_priv->iobase + HPREG_INTR_CLEAR); +} + +int hp82335_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct hp82335_priv *hp_priv; + struct tms9914_priv *tms_priv; + int retval; + const unsigned long upper_iomem_base = (unsigned long)config->ibbase + hp82335_rom_size; + + board->status = 0; + + if (hp82335_allocate_private(board)) + return -ENOMEM; + hp_priv = board->private_data; + tms_priv = &hp_priv->tms9914_priv; + tms_priv->read_byte = hp82335_read_byte; + tms_priv->write_byte = hp82335_write_byte; + tms_priv->offset = 1; + + switch ((unsigned long)(config->ibbase)) { + case 0xc4000: + case 0xc8000: + case 0xcc000: + case 0xd0000: + case 0xd4000: + case 0xd8000: + case 0xdc000: + case 0xe0000: + case 0xe4000: + case 0xe8000: + case 0xec000: + case 0xf0000: + case 0xf4000: + case 0xf8000: + case 0xfc000: + break; + default: + pr_err("hp82335: invalid base io address 0x%p\n", config->ibbase); + return -EINVAL; + } + if (!request_mem_region(upper_iomem_base, hp82335_upper_iomem_size, "hp82335")) { + pr_err("hp82335: failed to allocate io memory region 0x%lx-0x%lx\n", + upper_iomem_base, upper_iomem_base + hp82335_upper_iomem_size - 1); + return -EBUSY; + } + hp_priv->raw_iobase = upper_iomem_base; + tms_priv->iobase = ioremap(upper_iomem_base, hp82335_upper_iomem_size); + pr_info("hp82335: upper half of 82335 iomem region 0x%lx remapped to 0x%p\n", + hp_priv->raw_iobase, tms_priv->iobase); + + retval = request_irq(config->ibirq, hp82335_interrupt, 0, "hp82335", board); + if (retval) { + pr_err("hp82335: can't request IRQ %d\n", config->ibirq); + return retval; + } + hp_priv->irq = config->ibirq; + pr_info("hp82335: IRQ %d\n", config->ibirq); + + tms9914_board_reset(tms_priv); + + hp82335_clear_interrupt(hp_priv); + + writeb(INTR_ENABLE, tms_priv->iobase + HPREG_CCR); + + tms9914_online(board, tms_priv); + + return 0; +} + +void hp82335_detach(gpib_board_t *board) +{ + struct hp82335_priv *hp_priv = board->private_data; + struct tms9914_priv *tms_priv; + + if (hp_priv) { + tms_priv = &hp_priv->tms9914_priv; + if (hp_priv->irq) + free_irq(hp_priv->irq, board); + if (tms_priv->iobase) { + writeb(0, tms_priv->iobase + HPREG_CCR); + tms9914_board_reset(tms_priv); + iounmap((void *)tms_priv->iobase); + } + if (hp_priv->raw_iobase) + release_mem_region(hp_priv->raw_iobase, hp82335_upper_iomem_size); + } + hp82335_free_private(board); +} + +static int __init hp82335_init_module(void) +{ + gpib_register_driver(&hp82335_interface, THIS_MODULE); + return 0; +} + +static void __exit hp82335_exit_module(void) +{ + gpib_unregister_driver(&hp82335_interface); +} + +module_init(hp82335_init_module); +module_exit(hp82335_exit_module); + +/* + * GPIB interrupt service routines + */ + +irqreturn_t hp82335_interrupt(int irq, void *arg) +{ + int status1, status2; + gpib_board_t *board = arg; + struct hp82335_priv *priv = board->private_data; + unsigned long flags; + irqreturn_t retval; + + spin_lock_irqsave(&board->spinlock, flags); + status1 = read_byte(&priv->tms9914_priv, ISR0); + status2 = read_byte(&priv->tms9914_priv, ISR1); + hp82335_clear_interrupt(priv); + retval = tms9914_interrupt_have_status(board, &priv->tms9914_priv, status1, status2); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + diff --git a/drivers/staging/gpib/hp_82335/hp82335.h b/drivers/staging/gpib/hp_82335/hp82335.h new file mode 100644 index 0000000000000000000000000000000000000000..5e5297af731ae24a69942047ffba032c5ad88474 --- /dev/null +++ b/drivers/staging/gpib/hp_82335/hp82335.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess * + ***************************************************************************/ + +#ifndef _HP82335_H +#define _HP82335_H + +#include "tms9914.h" +#include "gpibP.h" + +// struct which defines private_data for board +struct hp82335_priv { + struct tms9914_priv tms9914_priv; + unsigned int irq; + unsigned long raw_iobase; +}; + +// interfaces +extern gpib_interface_t hp82335_interface; + +// interface functions +int hp82335_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read); +int hp82335_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written); +int hp82335_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written); +int hp82335_take_control(gpib_board_t *board, int synchronous); +int hp82335_go_to_standby(gpib_board_t *board); +void hp82335_request_system_control(gpib_board_t *board, int request_control); +void hp82335_interface_clear(gpib_board_t *board, int assert); +void hp82335_remote_enable(gpib_board_t *board, int enable); +int hp82335_enable_eos(gpib_board_t *board, uint8_t eos_byte, int + compare_8_bits); +void hp82335_disable_eos(gpib_board_t *board); +unsigned int hp82335_update_status(gpib_board_t *board, unsigned int clear_mask); +int hp82335_primary_address(gpib_board_t *board, unsigned int address); +int hp82335_secondary_address(gpib_board_t *board, unsigned int address, int + enable); +int hp82335_parallel_poll(gpib_board_t *board, uint8_t *result); +void hp82335_parallel_poll_configure(gpib_board_t *board, uint8_t config); +void hp82335_parallel_poll_response(gpib_board_t *board, int ist); +void hp82335_serial_poll_response(gpib_board_t *board, uint8_t status); +void hp82335_return_to_local(gpib_board_t *board); + +// interrupt service routines +irqreturn_t hp82335_interrupt(int irq, void *arg); + +// utility functions +int hp82335_allocate_private(gpib_board_t *board); +void hp82335_free_private(gpib_board_t *board); + +// size of io memory region used +static const int hp82335_rom_size = 0x2000; +static const int hp82335_upper_iomem_size = 0x2000; + +// hp82335 register offsets +enum hp_read_regs { + HPREG_CSR = 0x17f8, + HPREG_STATUS = 0x1ffc, +}; + +enum hp_write_regs { + HPREG_INTR_CLEAR = 0x17f7, + HPREG_CCR = HPREG_CSR, +}; + +enum ccr_bits { + DMA_ENABLE = (1 << 0), /* DMA enable */ + DMA_CHAN_SELECT = (1 << 1), /* DMA channel select O=3,1=2 */ + INTR_ENABLE = (1 << 2), /* interrupt enable */ + SYS_DISABLE = (1 << 3), /* system controller disable */ +}; + +enum csr_bits { + SWITCH6 = (1 << 0), /* switch 6 position */ + SWITCH5 = (1 << 1), /* switch 5 position */ + SYS_CONTROLLER = (1 << 2), /* system controller bit */ + DMA_ENABLE_STATUS = (1 << 4), /* DMA enabled */ + DMA_CHAN_STATUS = (1 << 5), /* DMA channel 0=3,1=2 */ + INTR_ENABLE_STATUS = (1 << 6), /* Interrupt enable */ + INTR_PENDING = (1 << 7), /* Interrupt Pending */ +}; + +#endif // _HP82335_H diff --git a/drivers/staging/gpib/hp_82341/Makefile b/drivers/staging/gpib/hp_82341/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1fe7db4f8ca4733c85b10c841644fbcb0fdae5a9 --- /dev/null +++ b/drivers/staging/gpib/hp_82341/Makefile @@ -0,0 +1,2 @@ + +obj-m += hp_82341.o diff --git a/drivers/staging/gpib/hp_82341/hp_82341.c b/drivers/staging/gpib/hp_82341/hp_82341.c new file mode 100644 index 0000000000000000000000000000000000000000..8ad1c885a9fb60aae9035e555830706275a26900 --- /dev/null +++ b/drivers/staging/gpib/hp_82341/hp_82341.c @@ -0,0 +1,895 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * Driver for hp 82341a/b/c/d boards. * + * Might be worth merging with Agilent 82350b driver. * + * copyright : (C) 2002, 2005 by Frank Mori Hess * + ***************************************************************************/ + +#include "hp_82341.h" +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read) +{ + struct hp_82341_priv *hp_priv = board->private_data; + struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv; + int retval = 0; + unsigned short event_status; + int i; + int num_fifo_bytes; + //hardware doesn't support checking for end-of-string character when using fifo + if (tms_priv->eos_flags & REOS) + return tms9914_read(board, tms_priv, buffer, length, end, bytes_read); + + clear_bit(DEV_CLEAR_BN, &tms_priv->state); + + read_and_clear_event_status(board); + *end = 0; + *bytes_read = 0; + if (length == 0) + return 0; + //disable fifo for the moment + outb(DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG); + // Handle corner case of board not in holdoff and one byte has slipped in already. + // Also, board sometimes has problems (spurious 1 byte reads) when read fifo is + // started up with board in + // TACS under certain data holdoff conditions. Doing a 1 byte tms9914-style + // read avoids these problems. + if (/*tms_priv->holdoff_active == 0 && */length > 1) { + size_t num_bytes; + + retval = tms9914_read(board, tms_priv, buffer, 1, end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + pr_err("tms9914_read failed retval=%i\n", retval); + if (retval < 0 || *end) + return retval; + ++buffer; + --length; + } + tms9914_set_holdoff_mode(tms_priv, TMS9914_HOLDOFF_EOI); + tms9914_release_holdoff(tms_priv); + outb(0x00, hp_priv->iobase[3] + BUFFER_FLUSH_REG); + i = 0; + num_fifo_bytes = length - 1; + while (i < num_fifo_bytes && *end == 0) { + int block_size; + int j; + int count; + + if (num_fifo_bytes - i < hp_82341_fifo_size) + block_size = num_fifo_bytes - i; + else + block_size = hp_82341_fifo_size; + set_transfer_counter(hp_priv, block_size); + outb(ENABLE_TI_BUFFER_BIT | DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + + BUFFER_CONTROL_REG); + if (inb(hp_priv->iobase[0] + STREAM_STATUS_REG) & HALTED_STATUS_BIT) + outb(RESTART_STREAM_BIT, hp_priv->iobase[0] + STREAM_STATUS_REG); + + clear_bit(READ_READY_BN, &tms_priv->state); + + retval = wait_event_interruptible(board->wait, + ((event_status = + read_and_clear_event_status(board)) & + (TERMINAL_COUNT_EVENT_BIT | + BUFFER_END_EVENT_BIT)) || + test_bit(DEV_CLEAR_BN, &tms_priv->state) || + test_bit(TIMO_NUM, &board->status)); + if (retval) { + pr_warn("%s: read wait interrupted\n", __func__); + retval = -ERESTARTSYS; + break; + } + // have to disable buffer before we can read from buffer port + outb(DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG); + count = block_size - read_transfer_counter(hp_priv); + j = 0; + while (j < count && i < num_fifo_bytes) { + unsigned short data_word = inw(hp_priv->iobase[3] + BUFFER_PORT_LOW_REG); + + buffer[i++] = data_word & 0xff; + ++j; + if (j < count && i < num_fifo_bytes) { + buffer[i++] = (data_word >> 8) & 0xff; + ++j; + } + } + if (event_status & BUFFER_END_EVENT_BIT) { + clear_bit(RECEIVED_END_BN, &tms_priv->state); + + *end = 1; + tms_priv->holdoff_active = 1; + } + if (test_bit(TIMO_NUM, &board->status)) { + pr_debug("%s: minor %i: read timed out\n", __FILE__, board->minor); + retval = -ETIMEDOUT; + break; + } + if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) { + pr_warn("%s: device clear interrupted read\n", __FILE__); + retval = -EINTR; + break; + } + } + *bytes_read += i; + buffer += i; + length -= i; + if (retval < 0) + return retval; + // read last byte if we havn't received an END yet + if (*end == 0) { + size_t num_bytes; + // try to make sure we holdoff after last byte read + retval = tms9914_read(board, tms_priv, buffer, length, end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + return retval; + } + return 0; +} + +static int restart_write_fifo(gpib_board_t *board, struct hp_82341_priv *hp_priv) +{ + struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv; + + if ((inb(hp_priv->iobase[0] + STREAM_STATUS_REG) & HALTED_STATUS_BIT) == 0) + return 0; + while (1) { + int status; + + //restart doesn't work if data holdoff is in effect + status = tms9914_line_status(board, tms_priv); + if ((status & BusNRFD) == 0) { + outb(RESTART_STREAM_BIT, hp_priv->iobase[0] + STREAM_STATUS_REG); + return 0; + } + if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) + return -EINTR; + if (test_bit(TIMO_NUM, &board->status)) + return -ETIMEDOUT; + if (msleep_interruptible(1)) + return -EINTR; + } + return 0; +} + +int hp_82341_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + struct hp_82341_priv *hp_priv = board->private_data; + struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv; + int i, j; + unsigned short event_status; + int retval = 0; + int fifo_xfer_len = length; + + *bytes_written = 0; + if (send_eoi) + --fifo_xfer_len; + + clear_bit(DEV_CLEAR_BN, &tms_priv->state); + + read_and_clear_event_status(board); + outb(0, hp_priv->iobase[3] + BUFFER_CONTROL_REG); + outb(0x00, hp_priv->iobase[3] + BUFFER_FLUSH_REG); + for (i = 0; i < fifo_xfer_len;) { + int block_size; + + if (fifo_xfer_len - i < hp_82341_fifo_size) + block_size = fifo_xfer_len - i; + else + block_size = hp_82341_fifo_size; + set_transfer_counter(hp_priv, block_size); + // load data into board's fifo + for (j = 0; j < block_size;) { + unsigned short data_word = buffer[i++]; + ++j; + if (j < block_size) { + data_word |= buffer[i++] << 8; + ++j; + } + outw(data_word, hp_priv->iobase[3] + BUFFER_PORT_LOW_REG); + } + clear_bit(WRITE_READY_BN, &tms_priv->state); + outb(ENABLE_TI_BUFFER_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG); + retval = restart_write_fifo(board, hp_priv); + if (retval < 0) { + pr_err("hp82341: failed to restart write stream\n"); + break; + } + retval = wait_event_interruptible(board->wait, + ((event_status = + read_and_clear_event_status(board)) & + TERMINAL_COUNT_EVENT_BIT) || + test_bit(DEV_CLEAR_BN, &tms_priv->state) || + test_bit(TIMO_NUM, &board->status)); + outb(0, hp_priv->iobase[3] + BUFFER_CONTROL_REG); + *bytes_written += block_size - read_transfer_counter(hp_priv); + if (retval) { + pr_warn("%s: write wait interrupted\n", __FILE__); + retval = -ERESTARTSYS; + break; + } + if (test_bit(TIMO_NUM, &board->status)) { + pr_debug("%s: minor %i: write timed out\n", __FILE__, board->minor); + retval = -ETIMEDOUT; + break; + } + if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) { + pr_warn("%s: device clear interrupted write\n", __FILE__); + retval = -EINTR; + break; + } + } + if (retval) + return retval; + if (send_eoi) { + size_t num_bytes; + + retval = hp_82341_write(board, buffer + fifo_xfer_len, 1, 1, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + } + return 0; +} + +static int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config); + +static void hp_82341_detach(gpib_board_t *board); + +// wrappers for interface functions +int hp_82341_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read); +} + +int hp_82341_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written); +} + +int hp_82341_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written); +} + +int hp_82341_take_control(gpib_board_t *board, int synchronous) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_take_control(board, &priv->tms9914_priv, synchronous); +} + +int hp_82341_go_to_standby(gpib_board_t *board) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_go_to_standby(board, &priv->tms9914_priv); +} + +void hp_82341_request_system_control(gpib_board_t *board, int request_control) +{ + struct hp_82341_priv *priv = board->private_data; + + if (request_control) + priv->mode_control_bits |= SYSTEM_CONTROLLER_BIT; + else + priv->mode_control_bits &= ~SYSTEM_CONTROLLER_BIT; + outb(priv->mode_control_bits, priv->iobase[0] + MODE_CONTROL_STATUS_REG); + tms9914_request_system_control(board, &priv->tms9914_priv, request_control); +} + +void hp_82341_interface_clear(gpib_board_t *board, int assert) +{ + struct hp_82341_priv *priv = board->private_data; + + tms9914_interface_clear(board, &priv->tms9914_priv, assert); +} + +void hp_82341_remote_enable(gpib_board_t *board, int enable) +{ + struct hp_82341_priv *priv = board->private_data; + + tms9914_remote_enable(board, &priv->tms9914_priv, enable); +} + +int hp_82341_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits); +} + +void hp_82341_disable_eos(gpib_board_t *board) +{ + struct hp_82341_priv *priv = board->private_data; + + tms9914_disable_eos(board, &priv->tms9914_priv); +} + +unsigned int hp_82341_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_update_status(board, &priv->tms9914_priv, clear_mask); +} + +int hp_82341_primary_address(gpib_board_t *board, unsigned int address) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_primary_address(board, &priv->tms9914_priv, address); +} + +int hp_82341_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable); +} + +int hp_82341_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_parallel_poll(board, &priv->tms9914_priv, result); +} + +void hp_82341_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + struct hp_82341_priv *priv = board->private_data; + + tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config); +} + +void hp_82341_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct hp_82341_priv *priv = board->private_data; + + tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist); +} + +void hp_82341_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct hp_82341_priv *priv = board->private_data; + + tms9914_serial_poll_response(board, &priv->tms9914_priv, status); +} + +static uint8_t hp_82341_serial_poll_status(gpib_board_t *board) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_serial_poll_status(board, &priv->tms9914_priv); +} + +static int hp_82341_line_status(const gpib_board_t *board) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_line_status(board, &priv->tms9914_priv); +} + +static unsigned int hp_82341_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct hp_82341_priv *priv = board->private_data; + + return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec); +} + +void hp_82341_return_to_local(gpib_board_t *board) +{ + struct hp_82341_priv *priv = board->private_data; + + tms9914_return_to_local(board, &priv->tms9914_priv); +} + +gpib_interface_t hp_82341_unaccel_interface = { +name: "hp_82341_unaccel", +attach : hp_82341_attach, +detach : hp_82341_detach, +read : hp_82341_read, +write : hp_82341_write, +command : hp_82341_command, +request_system_control : hp_82341_request_system_control, +take_control : hp_82341_take_control, +go_to_standby : hp_82341_go_to_standby, +interface_clear : hp_82341_interface_clear, +remote_enable : hp_82341_remote_enable, +enable_eos : hp_82341_enable_eos, +disable_eos : hp_82341_disable_eos, +parallel_poll : hp_82341_parallel_poll, +parallel_poll_configure : hp_82341_parallel_poll_configure, +parallel_poll_response : hp_82341_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : hp_82341_line_status, +update_status : hp_82341_update_status, +primary_address : hp_82341_primary_address, +secondary_address : hp_82341_secondary_address, +serial_poll_response : hp_82341_serial_poll_response, +serial_poll_status : hp_82341_serial_poll_status, +t1_delay : hp_82341_t1_delay, +return_to_local : hp_82341_return_to_local, +}; + +gpib_interface_t hp_82341_interface = { +name: "hp_82341", +attach : hp_82341_attach, +detach : hp_82341_detach, +read : hp_82341_accel_read, +write : hp_82341_accel_write, +command : hp_82341_command, +request_system_control : hp_82341_request_system_control, +take_control : hp_82341_take_control, +go_to_standby : hp_82341_go_to_standby, +interface_clear : hp_82341_interface_clear, +remote_enable : hp_82341_remote_enable, +enable_eos : hp_82341_enable_eos, +disable_eos : hp_82341_disable_eos, +parallel_poll : hp_82341_parallel_poll, +parallel_poll_configure : hp_82341_parallel_poll_configure, +parallel_poll_response : hp_82341_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : hp_82341_line_status, +update_status : hp_82341_update_status, +primary_address : hp_82341_primary_address, +secondary_address : hp_82341_secondary_address, +serial_poll_response : hp_82341_serial_poll_response, +t1_delay : hp_82341_t1_delay, +return_to_local : hp_82341_return_to_local, +}; + +int hp_82341_allocate_private(gpib_board_t *board) +{ + board->private_data = kzalloc(sizeof(struct hp_82341_priv), GFP_KERNEL); + if (!board->private_data) + return -ENOMEM; + return 0; +} + +void hp_82341_free_private(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +static uint8_t hp_82341_read_byte(struct tms9914_priv *priv, unsigned int register_num) +{ + return inb((unsigned long)(priv->iobase) + register_num); +} + +static void hp_82341_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +{ + outb(data, (unsigned long)(priv->iobase) + register_num); +} + +static int hp_82341_find_isapnp_board(struct pnp_dev **dev) +{ + *dev = pnp_find_dev(NULL, ISAPNP_VENDOR('H', 'W', 'P'), + ISAPNP_FUNCTION(0x1411), NULL); + if (!*dev || !(*dev)->card) { + pr_err("hp_82341: failed to find isapnp board\n"); + return -ENODEV; + } + if (pnp_device_attach(*dev) < 0) { + pr_err("hp_82341: board already active, skipping\n"); + return -EBUSY; + } + if (pnp_activate_dev(*dev) < 0) { + pnp_device_detach(*dev); + pr_err("hp_82341: failed to activate() atgpib/tnt, aborting\n"); + return -EAGAIN; + } + if (!pnp_port_valid(*dev, 0) || !pnp_irq_valid(*dev, 0)) { + pnp_device_detach(*dev); + pr_err("hp_82341: invalid port or irq for atgpib/tnt, aborting\n"); + return -ENOMEM; + } + return 0; +} + +static int xilinx_ready(struct hp_82341_priv *hp_priv) +{ + switch (hp_priv->hw_version) { + case HW_VERSION_82341C: + if (inb(hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG) & XILINX_READY_BIT) + return 1; + else + return 0; + break; + case HW_VERSION_82341D: + if (isapnp_read_byte(PIO_DATA_REG) & HP_82341D_XILINX_READY_BIT) + return 1; + else + return 0; + default: + pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__); + break; + } + return 0; +} + +static int xilinx_done(struct hp_82341_priv *hp_priv) +{ + switch (hp_priv->hw_version) { + case HW_VERSION_82341C: + if (inb(hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG) & DONE_PGL_BIT) + return 1; + else + return 0; + case HW_VERSION_82341D: + if (isapnp_read_byte(PIO_DATA_REG) & HP_82341D_XILINX_DONE_BIT) + return 1; + else + return 0; + default: + pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__); + break; + } + return 0; +} + +static int irq_valid(struct hp_82341_priv *hp_priv, int irq) +{ + switch (hp_priv->hw_version) { + case HW_VERSION_82341C: + switch (irq) { + case 3: + case 5: + case 7: + case 9: + case 10: + case 11: + case 12: + case 15: + return 1; + default: + pr_err("hp_82341: invalid irq=%i for 82341C, irq must be 3, 5, 7, 9, 10, 11, 12, or 15.\n", + irq); + return 0; + } + break; + case HW_VERSION_82341D: + return 1; + default: + pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__); + break; + } + return 0; +} + +static int hp_82341_load_firmware_array(struct hp_82341_priv *hp_priv, + const unsigned char *firmware_data, + unsigned int firmware_length) +{ + int i, j; + static const int timeout = 100; + + for (i = 0; i < firmware_length; ++i) { + for (j = 0; j < timeout; ++j) { + if (need_resched()) + schedule(); + if (xilinx_ready(hp_priv)) + break; + usleep_range(10, 15); + } + if (j == timeout) { + pr_err("hp_82341: timed out waiting for Xilinx ready.\n"); + return -ETIMEDOUT; + } + outb(firmware_data[i], hp_priv->iobase[0] + XILINX_DATA_REG); + } + for (j = 0; j < timeout; ++j) { + if (xilinx_done(hp_priv)) + break; + if (need_resched()) + schedule(); + usleep_range(10, 15); + } + if (j == timeout) { + pr_err("hp_82341: timed out waiting for Xilinx done.\n"); + return -ETIMEDOUT; + } + return 0; +} + +static int hp_82341_load_firmware(struct hp_82341_priv *hp_priv, const gpib_board_config_t *config) +{ + if (config->init_data_length == 0) { + if (xilinx_done(hp_priv)) + return 0; + pr_err("hp_82341: board needs be initialized with firmware upload.\n" + "\tUse the --init-data option of gpib_config.\n"); + return -EINVAL; + } + switch (hp_priv->hw_version) { + case HW_VERSION_82341C: + if (config->init_data_length != hp_82341c_firmware_length) { + pr_err("hp_82341: bad firmware length=%i for 82341c (expected %i).\n", + config->init_data_length, hp_82341c_firmware_length); + return -EINVAL; + } + break; + case HW_VERSION_82341D: + if (config->init_data_length != hp_82341d_firmware_length) { + pr_err("hp_82341: bad firmware length=%i for 82341d (expected %i).\n", + config->init_data_length, hp_82341d_firmware_length); + return -EINVAL; + } + break; + default: + pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__); + break; + } + return hp_82341_load_firmware_array(hp_priv, config->init_data, config->init_data_length); +} + +static void set_xilinx_not_prog(struct hp_82341_priv *hp_priv, int assert) +{ + switch (hp_priv->hw_version) { + case HW_VERSION_82341C: + if (assert) + hp_priv->config_control_bits |= DONE_PGL_BIT; + else + hp_priv->config_control_bits &= ~DONE_PGL_BIT; + outb(hp_priv->config_control_bits, hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG); + break; + case HW_VERSION_82341D: + if (assert) + isapnp_write_byte(PIO_DATA_REG, HP_82341D_NOT_PROG_BIT); + else + isapnp_write_byte(PIO_DATA_REG, 0x0); + break; + default: + break; + } +} + +// clear xilinx firmware +static int clear_xilinx(struct hp_82341_priv *hp_priv) +{ + set_xilinx_not_prog(hp_priv, 1); + if (msleep_interruptible(1)) + return -EINTR; + set_xilinx_not_prog(hp_priv, 0); + if (msleep_interruptible(1)) + return -EINTR; + set_xilinx_not_prog(hp_priv, 1); + if (msleep_interruptible(1)) + return -EINTR; + return 0; +} + +int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct hp_82341_priv *hp_priv; + struct tms9914_priv *tms_priv; + unsigned long start_addr; + void *iobase; + int irq; + int i; + int retval; + + board->status = 0; + if (hp_82341_allocate_private(board)) + return -ENOMEM; + hp_priv = board->private_data; + tms_priv = &hp_priv->tms9914_priv; + tms_priv->read_byte = hp_82341_read_byte; + tms_priv->write_byte = hp_82341_write_byte; + tms_priv->offset = 1; + + if (config->ibbase == 0) { + struct pnp_dev *dev; + int retval = hp_82341_find_isapnp_board(&dev); + + if (retval < 0) + return retval; + hp_priv->pnp_dev = dev; + iobase = (void *)(pnp_port_start(dev, 0)); + irq = pnp_irq(dev, 0); + hp_priv->hw_version = HW_VERSION_82341D; + hp_priv->io_region_offset = 0x8; + } else { + iobase = config->ibbase; + irq = config->ibirq; + hp_priv->hw_version = HW_VERSION_82341C; + hp_priv->io_region_offset = 0x400; + } + pr_info("hp_82341: base io 0x%p\n", iobase); + for (i = 0; i < hp_82341_num_io_regions; ++i) { + start_addr = (unsigned long)(iobase) + i * hp_priv->io_region_offset; + if (!request_region(start_addr, hp_82341_region_iosize, "hp_82341")) { + pr_err("hp_82341: failed to allocate io ports 0x%lx-0x%lx\n", + start_addr, + start_addr + hp_82341_region_iosize - 1); + return -EIO; + } + hp_priv->iobase[i] = start_addr; + } + tms_priv->iobase = (void *)(hp_priv->iobase[2]); + if (hp_priv->hw_version == HW_VERSION_82341D) { + retval = isapnp_cfg_begin(hp_priv->pnp_dev->card->number, + hp_priv->pnp_dev->number); + if (retval < 0) { + pr_err("hp_82341: isapnp_cfg_begin returned error\n"); + return retval; + } + isapnp_write_byte(PIO_DIRECTION_REG, HP_82341D_XILINX_READY_BIT | + HP_82341D_XILINX_DONE_BIT); + } + retval = clear_xilinx(hp_priv); + if (retval < 0) + return retval; + retval = hp_82341_load_firmware(hp_priv, config); + if (hp_priv->hw_version == HW_VERSION_82341D) + isapnp_cfg_end(); + if (retval < 0) + return retval; + if (irq_valid(hp_priv, irq) == 0) + return -EINVAL; + if (request_irq(irq, hp_82341_interrupt, 0, "hp_82341", board)) { + pr_err("hp_82341: failed to allocate IRQ %d\n", irq); + return -EIO; + } + hp_priv->irq = irq; + pr_info("hp_82341: IRQ %d\n", irq); + hp_priv->config_control_bits &= ~IRQ_SELECT_MASK; + hp_priv->config_control_bits |= IRQ_SELECT_BITS(irq); + outb(hp_priv->config_control_bits, hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG); + hp_priv->mode_control_bits |= ENABLE_IRQ_CONFIG_BIT; + outb(hp_priv->mode_control_bits, hp_priv->iobase[0] + MODE_CONTROL_STATUS_REG); + tms9914_board_reset(tms_priv); + outb(ENABLE_BUFFER_END_EVENT_BIT | ENABLE_TERMINAL_COUNT_EVENT_BIT | + ENABLE_TI_INTERRUPT_EVENT_BIT, hp_priv->iobase[0] + EVENT_ENABLE_REG); + outb(ENABLE_BUFFER_END_INTERRUPT_BIT | ENABLE_TERMINAL_COUNT_INTERRUPT_BIT | + ENABLE_TI_INTERRUPT_BIT, hp_priv->iobase[0] + INTERRUPT_ENABLE_REG); + //write clear event register + outb((TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT | + BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT), + hp_priv->iobase[0] + EVENT_STATUS_REG); + + tms9914_online(board, tms_priv); + pr_info("hp_82341: board id %x %x %x %x\n", inb(hp_priv->iobase[1] + ID0_REG), + inb(hp_priv->iobase[1] + ID1_REG), inb(hp_priv->iobase[2] + ID2_REG), + inb(hp_priv->iobase[2] + ID3_REG)); + return 0; +} + +void hp_82341_detach(gpib_board_t *board) +{ + struct hp_82341_priv *hp_priv = board->private_data; + struct tms9914_priv *tms_priv; + int i; + + if (hp_priv) { + tms_priv = &hp_priv->tms9914_priv; + if (hp_priv->iobase[0]) { + outb(0, hp_priv->iobase[0] + INTERRUPT_ENABLE_REG); + if (tms_priv->iobase) + tms9914_board_reset(tms_priv); + if (hp_priv->irq) + free_irq(hp_priv->irq, board); + } + for (i = 0; i < hp_82341_num_io_regions; ++i) { + if (hp_priv->iobase[i]) + release_region(hp_priv->iobase[i], hp_82341_region_iosize); + } + if (hp_priv->pnp_dev) + pnp_device_detach(hp_priv->pnp_dev); + } + hp_82341_free_private(board); +} + +static const struct pnp_device_id hp_82341_pnp_table[] = { + {.id = "HWP1411"}, + {.id = ""} +}; +MODULE_DEVICE_TABLE(pnp, hp_82341_pnp_table); + +static int __init hp_82341_init_module(void) +{ + gpib_register_driver(&hp_82341_unaccel_interface, THIS_MODULE); + gpib_register_driver(&hp_82341_interface, THIS_MODULE); + return 0; +} + +static void __exit hp_82341_exit_module(void) +{ + gpib_unregister_driver(&hp_82341_interface); + gpib_unregister_driver(&hp_82341_unaccel_interface); +} + +module_init(hp_82341_init_module); +module_exit(hp_82341_exit_module); + +/* + * GPIB interrupt service routines + */ +unsigned short read_and_clear_event_status(gpib_board_t *board) +{ + struct hp_82341_priv *hp_priv = board->private_data; + unsigned long flags; + unsigned short status; + + spin_lock_irqsave(&board->spinlock, flags); + status = hp_priv->event_status_bits; + hp_priv->event_status_bits = 0; + spin_unlock_irqrestore(&board->spinlock, flags); + return status; +} + +irqreturn_t hp_82341_interrupt(int irq, void *arg) +{ + int status1, status2; + gpib_board_t *board = arg; + struct hp_82341_priv *hp_priv = board->private_data; + struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv; + unsigned long flags; + irqreturn_t retval = IRQ_NONE; + int event_status; + + spin_lock_irqsave(&board->spinlock, flags); + event_status = inb(hp_priv->iobase[0] + EVENT_STATUS_REG); +// printk("hp_82341: interrupt event_status=0x%x\n", event_status); + if (event_status & INTERRUPT_PENDING_EVENT_BIT) + retval = IRQ_HANDLED; + //write-clear status bits + if (event_status & (TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT | + BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT)) { + outb(event_status & (TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT | + BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT), + hp_priv->iobase[0] + EVENT_STATUS_REG); + hp_priv->event_status_bits |= event_status; + } + if (event_status & TI_INTERRUPT_EVENT_BIT) { + status1 = read_byte(tms_priv, ISR0); + status2 = read_byte(tms_priv, ISR1); + tms9914_interrupt_have_status(board, tms_priv, status1, status2); +/* printk("hp_82341: interrupt status1=0x%x status2=0x%x\n", + * status1, status2); + */ + } + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +int read_transfer_counter(struct hp_82341_priv *hp_priv) +{ + int lo, mid, value; + + lo = inb(hp_priv->iobase[1] + TRANSFER_COUNT_LOW_REG); + mid = inb(hp_priv->iobase[1] + TRANSFER_COUNT_MID_REG); + value = (lo & 0xff) | ((mid << 8) & 0x7f00); + value = ~(value - 1) & 0x7fff; + return value; +} + +void set_transfer_counter(struct hp_82341_priv *hp_priv, int count) +{ + int complement = -count; + + outb(complement & 0xff, hp_priv->iobase[1] + TRANSFER_COUNT_LOW_REG); + outb((complement >> 8) & 0xff, hp_priv->iobase[1] + TRANSFER_COUNT_MID_REG); + //I don't think the hi count reg is even used, but oh well + outb((complement >> 16) & 0xf, hp_priv->iobase[1] + TRANSFER_COUNT_HIGH_REG); +} + diff --git a/drivers/staging/gpib/hp_82341/hp_82341.h b/drivers/staging/gpib/hp_82341/hp_82341.h new file mode 100644 index 0000000000000000000000000000000000000000..7c391860b3994e4df571588c7e105ac6b07f5bc3 --- /dev/null +++ b/drivers/staging/gpib/hp_82341/hp_82341.h @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002, 2005 by Frank Mori Hess * + ***************************************************************************/ + +#include "tms9914.h" +#include "gpibP.h" + +enum hp_82341_hardware_version { + HW_VERSION_UNKNOWN, + HW_VERSION_82341C, + HW_VERSION_82341D, +}; + +// struct which defines private_data for board +struct hp_82341_priv { + struct tms9914_priv tms9914_priv; + unsigned int irq; + unsigned short config_control_bits; + unsigned short mode_control_bits; + unsigned short event_status_bits; + struct pnp_dev *pnp_dev; + unsigned long iobase[4]; + unsigned long io_region_offset; + enum hp_82341_hardware_version hw_version; +}; + +// interfaces +extern gpib_interface_t hp_82341_interface; + +// interface functions +int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read); +int hp_82341_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written); +int hp_82341_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read); +int hp_82341_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written); +int hp_82341_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written); +int hp_82341_take_control(gpib_board_t *board, int synchronous); +int hp_82341_go_to_standby(gpib_board_t *board); +void hp_82341_request_system_control(gpib_board_t *board, int request_control); +void hp_82341_interface_clear(gpib_board_t *board, int assert); +void hp_82341_remote_enable(gpib_board_t *board, int enable); +int hp_82341_enable_eos(gpib_board_t *board, uint8_t eos_byte, int + compare_8_bits); +void hp_82341_disable_eos(gpib_board_t *board); +unsigned int hp_82341_update_status(gpib_board_t *board, unsigned int clear_mask); +int hp_82341_primary_address(gpib_board_t *board, unsigned int address); +int hp_82341_secondary_address(gpib_board_t *board, unsigned int address, int + enable); +int hp_82341_parallel_poll(gpib_board_t *board, uint8_t *result); +void hp_82341_parallel_poll_configure(gpib_board_t *board, uint8_t config); +void hp_82341_parallel_poll_response(gpib_board_t *board, int ist); +void hp_82341_serial_poll_response(gpib_board_t *board, uint8_t status); +void hp_82341_return_to_local(gpib_board_t *board); + +// interrupt service routines +irqreturn_t hp_82341_interrupt(int irq, void *arg); + +// utility functions +int hp_82341_allocate_private(gpib_board_t *board); +void hp_82341_free_private(gpib_board_t *board); + +static const int hp_82341_region_iosize = 0x8; +static const int hp_82341_num_io_regions = 4; +static const int hp_82341_fifo_size = 0xffe; +static const int hp_82341c_firmware_length = 5764; +static const int hp_82341d_firmware_length = 5302; + +// hp 82341 register offsets +enum hp_82341_region_0_registers { + CONFIG_CONTROL_STATUS_REG = 0x0, + MODE_CONTROL_STATUS_REG = 0x1, + MONITOR_REG = 0x2, // after initialization + XILINX_DATA_REG = 0x2, // before initialization, write only + INTERRUPT_ENABLE_REG = 0x3, + EVENT_STATUS_REG = 0x4, + EVENT_ENABLE_REG = 0x5, + STREAM_STATUS_REG = 0x7, +}; + +enum hp_82341_region_1_registers { + ID0_REG = 0x2, + ID1_REG = 0x3, + TRANSFER_COUNT_LOW_REG = 0x4, + TRANSFER_COUNT_MID_REG = 0x5, + TRANSFER_COUNT_HIGH_REG = 0x6, +}; + +enum hp_82341_region_3_registers { + BUFFER_PORT_LOW_REG = 0x0, + BUFFER_PORT_HIGH_REG = 0x1, + ID2_REG = 0x2, + ID3_REG = 0x3, + BUFFER_FLUSH_REG = 0x4, + BUFFER_CONTROL_REG = 0x7 +}; + +enum config_control_status_bits { + IRQ_SELECT_MASK = 0x7, + DMA_CONFIG_MASK = 0x18, + ENABLE_DMA_CONFIG_BIT = 0x20, + XILINX_READY_BIT = 0x40, //read only + DONE_PGL_BIT = 0x80 +}; + +static inline unsigned int IRQ_SELECT_BITS(int irq) +{ + switch (irq) { + case 3: + return 0x3; + case 5: + return 0x2; + case 7: + return 0x1; + case 9: + return 0x0; + case 10: + return 0x7; + case 11: + return 0x6; + case 12: + return 0x5; + case 15: + return 0x4; + default: + return 0x0; + } +}; + +enum mode_control_status_bits { + SLOT8_BIT = 0x1, // read only + ACTIVE_CONTROLLER_BIT = 0x2, // read only + ENABLE_DMA_BIT = 0x4, + SYSTEM_CONTROLLER_BIT = 0x8, + MONITOR_BIT = 0x10, + ENABLE_IRQ_CONFIG_BIT = 0x20, + ENABLE_TI_STREAM_BIT = 0x40 +}; + +enum monitor_bits { + MONITOR_INTERRUPT_PENDING_BIT = 0x1, // read only + MONITOR_CLEAR_HOLDOFF_BIT = 0x2, // write only + MONITOR_PPOLL_BIT = 0x4, // write clear + MONITOR_SRQ_BIT = 0x8, // write clear + MONITOR_IFC_BIT = 0x10, // write clear + MONITOR_REN_BIT = 0x20, // write clear + MONITOR_END_BIT = 0x40, // write clear + MONITOR_DAV_BIT = 0x80 // write clear +}; + +enum interrupt_enable_bits { + ENABLE_TI_INTERRUPT_BIT = 0x1, + ENABLE_POINTERS_EQUAL_INTERRUPT_BIT = 0x4, + ENABLE_BUFFER_END_INTERRUPT_BIT = 0x10, + ENABLE_TERMINAL_COUNT_INTERRUPT_BIT = 0x20, + ENABLE_DMA_TERMINAL_COUNT_INTERRUPT_BIT = 0x80, +}; + +enum event_status_bits { + TI_INTERRUPT_EVENT_BIT = 0x1, //write clear + INTERRUPT_PENDING_EVENT_BIT = 0x2, // read only + POINTERS_EQUAL_EVENT_BIT = 0x4, //write clear + BUFFER_END_EVENT_BIT = 0x10, //write clear + TERMINAL_COUNT_EVENT_BIT = 0x20, // write clear + DMA_TERMINAL_COUNT_EVENT_BIT = 0x80, // write clear +}; + +enum event_enable_bits { + ENABLE_TI_INTERRUPT_EVENT_BIT = 0x1, //write clear + ENABLE_POINTERS_EQUAL_EVENT_BIT = 0x4, //write clear + ENABLE_BUFFER_END_EVENT_BIT = 0x10, //write clear + ENABLE_TERMINAL_COUNT_EVENT_BIT = 0x20, // write clear + ENABLE_DMA_TERMINAL_COUNT_EVENT_BIT = 0x80, // write clear +}; + +enum stream_status_bits { + HALTED_STATUS_BIT = 0x1, //read + RESTART_STREAM_BIT = 0x1 //write +}; + +enum buffer_control_bits { + DIRECTION_GPIB_TO_HOST_BIT = 0x20, // transfer direction (set for gpib to host) + ENABLE_TI_BUFFER_BIT = 0x40, //enable fifo + FAST_WR_EN_BIT = 0x80, // 350 ns t1 delay? +}; + +// registers accessible through isapnp chip on 82341d +enum hp_82341d_pnp_registers { + PIO_DATA_REG = 0x20, //read/write pio data lines + PIO_DIRECTION_REG = 0x21, // set pio data line directions (set for input) +}; + +enum hp_82341d_pnp_pio_bits { + HP_82341D_XILINX_READY_BIT = 0x1, + HP_82341D_XILINX_DONE_BIT = 0x2, + // use register layout compatible with C and older versions instead of 32 contiguous ioports + HP_82341D_LEGACY_MODE_BIT = 0x4, + HP_82341D_NOT_PROG_BIT = 0x8, // clear to reinitialize xilinx +}; + +unsigned short read_and_clear_event_status(gpib_board_t *board); +int read_transfer_counter(struct hp_82341_priv *hp_priv); +void set_transfer_counter(struct hp_82341_priv *hp_priv, int count); diff --git a/drivers/staging/gpib/include/amcc5920.h b/drivers/staging/gpib/include/amcc5920.h new file mode 100644 index 0000000000000000000000000000000000000000..766b3799223f14c12325ee86f0f555ed0bbd43be --- /dev/null +++ b/drivers/staging/gpib/include/amcc5920.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Header for amcc5920 pci chip + * + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +// plx pci chip registers and bits +enum amcc_registers { + AMCC_INTCS_REG = 0x38, + AMCC_PASS_THRU_REG = 0x60, +}; + +enum amcc_incsr_bits { + AMCC_ADDON_INTR_ENABLE_BIT = 0x2000, + AMCC_ADDON_INTR_ACTIVE_BIT = 0x400000, + AMCC_INTR_ACTIVE_BIT = 0x800000, +}; + +static const int bits_per_region = 8; + +static inline uint32_t amcc_wait_state_bits(unsigned int region, unsigned int num_wait_states) +{ + return (num_wait_states & 0x7) << (-region * bits_per_region); +}; + +enum amcc_prefetch_bits { + PREFETCH_DISABLED = 0x0, + PREFETCH_SMALL = 0x8, + PREFETCH_MEDIUM = 0x10, + PREFETCH_LARGE = 0x18, +}; + +static inline uint32_t amcc_prefetch_bits(unsigned int region, enum amcc_prefetch_bits prefetch) +{ + return prefetch << (--region * bits_per_region); +}; + +static inline uint32_t amcc_PTADR_mode_bit(unsigned int region) +{ + return 0x80 << (--region * bits_per_region); +}; + +static inline uint32_t amcc_disable_write_fifo_bit(unsigned int region) +{ + return 0x20 << (--region * bits_per_region); +}; + diff --git a/drivers/staging/gpib/include/amccs5933.h b/drivers/staging/gpib/include/amccs5933.h new file mode 100644 index 0000000000000000000000000000000000000000..4de0f6797458477cfd5ed7235f743348305ed2f7 --- /dev/null +++ b/drivers/staging/gpib/include/amccs5933.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Registers and bits for amccs5933 pci chip + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +// register offsets +enum { + MBEF_REG = 0x34, // mailbux empty/full + INTCSR_REG = 0x38, // interrupt control and status + BMCSR_REG = 0x3c, // bus master control and status +}; + +// incoming mailbox 0-3 register offsets +extern inline int INCOMING_MAILBOX_REG(unsigned int mailbox) +{ + return (0x10 + 4 * mailbox); +}; + +// bit definitions + +// INTCSR bits +enum { + OUTBOX_EMPTY_INTR_BIT = 0x10, // enable outbox empty interrupt + INBOX_FULL_INTR_BIT = 0x1000, // enable inbox full interrupt + INBOX_INTR_CS_BIT = 0x20000, // read, or write clear inbox full interrupt + INTR_ASSERTED_BIT = 0x800000, // read only, interrupt asserted +}; + +// select byte 0 to 3 of incoming mailbox +extern inline int INBOX_BYTE_BITS(unsigned int byte) +{ + return (byte & 0x3) << 8; +}; + +// select incoming mailbox 0 to 3 +extern inline int INBOX_SELECT_BITS(unsigned int mailbox) +{ + return (mailbox & 0x3) << 10; +}; + +// select byte 0 to 3 of outgoing mailbox +extern inline int OUTBOX_BYTE_BITS(unsigned int byte) +{ + return (byte & 0x3); +}; + +// select outgoing mailbox 0 to 3 +extern inline int OUTBOX_SELECT_BITS(unsigned int mailbox) +{ + return (mailbox & 0x3) << 2; +}; + +//BMCSR bits +enum { + MBOX_FLAGS_RESET_BIT = 0x08000000, // resets mailbox empty/full flags +}; + diff --git a/drivers/staging/gpib/include/gpibP.h b/drivers/staging/gpib/include/gpibP.h new file mode 100644 index 0000000000000000000000000000000000000000..5fc42b645ab70c29ad0400188ed1a4b384a2b380 --- /dev/null +++ b/drivers/staging/gpib/include/gpibP.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002,2003 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_P_H +#define _GPIB_P_H + +#include + +#include "gpib_types.h" +#include "gpib_proto.h" +#include "gpib_user.h" +#include "gpib_ioctl.h" + +#include +#include + +void gpib_register_driver(gpib_interface_t *interface, struct module *mod); +void gpib_unregister_driver(gpib_interface_t *interface); +struct pci_dev *gpib_pci_get_device(const gpib_board_config_t *config, unsigned int vendor_id, + unsigned int device_id, struct pci_dev *from); +struct pci_dev *gpib_pci_get_subsys(const gpib_board_config_t *config, unsigned int vendor_id, + unsigned int device_id, unsigned int ss_vendor, + unsigned int ss_device, struct pci_dev *from); +unsigned int num_gpib_events(const gpib_event_queue_t *queue); +int push_gpib_event(gpib_board_t *board, short event_type); +int pop_gpib_event(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type); +int gpib_request_pseudo_irq(gpib_board_t *board, irqreturn_t (*handler)(int, void *)); +void gpib_free_pseudo_irq(gpib_board_t *board); +int gpib_match_device_path(struct device *dev, const char *device_path_in); + +extern gpib_board_t board_array[GPIB_MAX_NUM_BOARDS]; + +extern struct list_head registered_drivers; + +#include + +void writeb_wrapper(unsigned int value, void *address); +unsigned int readb_wrapper(void *address); +void outb_wrapper(unsigned int value, void *address); +unsigned int inb_wrapper(void *address); +void writew_wrapper(unsigned int value, void *address); +unsigned int readw_wrapper(void *address); +void outw_wrapper(unsigned int value, void *address); +unsigned int inw_wrapper(void *address); + +#endif // _GPIB_P_H + diff --git a/drivers/staging/gpib/include/gpib_pci_ids.h b/drivers/staging/gpib/include/gpib_pci_ids.h new file mode 100644 index 0000000000000000000000000000000000000000..52dcab07a7d188925a4d696d6b658f397f3b0153 --- /dev/null +++ b/drivers/staging/gpib/include/gpib_pci_ids.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __GPIB_PCI_IDS_H +#define __GPIB_PCI_IDS_H + +#ifndef PCI_VENDOR_ID_AMCC +#define PCI_VENDOR_ID_AMCC 0x10e8 +#endif + +#ifndef PCI_VENDOR_ID_CBOARDS +#define PCI_VENDOR_ID_CBOARDS 0x1307 +#endif + +#ifndef PCI_VENDOR_ID_QUANCOM +#define PCI_VENDOR_ID_QUANCOM 0x8008 +#endif + +#ifndef PCI_DEVICE_ID_QUANCOM_GPIB +#define PCI_DEVICE_ID_QUANCOM_GPIB 0x3302 +#endif + +#endif // __GPIB_PCI_IDS_H + diff --git a/drivers/staging/gpib/include/gpib_proto.h b/drivers/staging/gpib/include/gpib_proto.h new file mode 100644 index 0000000000000000000000000000000000000000..1499f954210b8ce7949f9f10ff71fd116f0f1969 --- /dev/null +++ b/drivers/staging/gpib/include/gpib_proto.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef GPIB_PROTO_INCLUDED +#define GPIB_PROTO_INCLUDED + +#include + +int ibopen(struct inode *inode, struct file *filep); +int ibclose(struct inode *inode, struct file *file); +long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg); +int osInit(void); +void osReset(void); +void os_start_timer(gpib_board_t *board, unsigned int usec_timeout); +void os_remove_timer(gpib_board_t *board); +void osSendEOI(void); +void osSendEOI(void); +void init_gpib_board(gpib_board_t *board); +static inline unsigned long usec_to_jiffies(unsigned int usec) +{ + unsigned long usec_per_jiffy = 1000000 / HZ; + + return 1 + (usec + usec_per_jiffy - 1) / usec_per_jiffy; +}; + +int serial_poll_all(gpib_board_t *board, unsigned int usec_timeout); +void init_gpib_descriptor(gpib_descriptor_t *desc); +int dvrsp(gpib_board_t *board, unsigned int pad, int sad, + unsigned int usec_timeout, uint8_t *result); +int ibAPWait(gpib_board_t *board, int pad); +int ibAPrsp(gpib_board_t *board, int padsad, char *spb); +void ibAPE(gpib_board_t *board, int pad, int v); +int ibcac(gpib_board_t *board, int sync, int fallback_to_async); +int ibcmd(gpib_board_t *board, uint8_t *buf, size_t length, size_t *bytes_written); +int ibgts(gpib_board_t *board); +int ibonline(gpib_board_t *board); +int iboffline(gpib_board_t *board); +int iblines(const gpib_board_t *board, short *lines); +int ibrd(gpib_board_t *board, uint8_t *buf, size_t length, int *end_flag, size_t *bytes_read); +int ibrpp(gpib_board_t *board, uint8_t *buf); +int ibrsv2(gpib_board_t *board, uint8_t status_byte, int new_reason_for_service); +void ibrsc(gpib_board_t *board, int request_control); +int ibsic(gpib_board_t *board, unsigned int usec_duration); +int ibsre(gpib_board_t *board, int enable); +int ibpad(gpib_board_t *board, unsigned int addr); +int ibsad(gpib_board_t *board, int addr); +int ibeos(gpib_board_t *board, int eos, int eosflags); +int ibwait(gpib_board_t *board, int wait_mask, int clear_mask, int set_mask, + int *status, unsigned long usec_timeout, gpib_descriptor_t *desc); +int ibwrt(gpib_board_t *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written); +int ibstatus(gpib_board_t *board); +int general_ibstatus(gpib_board_t *board, const gpib_status_queue_t *device, + int clear_mask, int set_mask, gpib_descriptor_t *desc); +int io_timed_out(gpib_board_t *board); +int ibppc(gpib_board_t *board, uint8_t configuration); + +#endif /* GPIB_PROTO_INCLUDED */ diff --git a/drivers/staging/gpib/include/gpib_state_machines.h b/drivers/staging/gpib/include/gpib_state_machines.h new file mode 100644 index 0000000000000000000000000000000000000000..7488c00f191e80ab8e257dce0e909c8b8d9b11d4 --- /dev/null +++ b/drivers/staging/gpib/include/gpib_state_machines.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2006 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_STATE_MACHINES_H +#define _GPIB_STATE_MACHINES_H + +enum talker_function_state { + talker_idle, + talker_addressed, + talker_active, + serial_poll_active +}; + +enum listener_function_state { + listener_idle, + listener_addressed, + listener_active +}; + +#endif // _GPIB_STATE_MACHINES_H diff --git a/drivers/staging/gpib/include/gpib_types.h b/drivers/staging/gpib/include/gpib_types.h new file mode 100644 index 0000000000000000000000000000000000000000..ee2643da6d71066c1aaea4d6a656d1545b8ad67c --- /dev/null +++ b/drivers/staging/gpib/include/gpib_types.h @@ -0,0 +1,353 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_TYPES_H +#define _GPIB_TYPES_H + +#ifdef __KERNEL__ +/* gpib_interface_t defines the interface + * between the board-specific details dealt with in the drivers + * and generic interface provided by gpib-common. + * This really should be in a different header file. + */ +#include "gpib_user.h" +#include +#include +#include +#include +#include +#include +#include + +typedef struct gpib_interface_struct gpib_interface_t; +typedef struct gpib_board_struct gpib_board_t; + +/* config parameters that are only used by driver attach functions */ +typedef struct { + /* firmware blob */ + void *init_data; + int init_data_length; + /* IO base address to use for non-pnp cards (set by core, driver should make local copy) */ + void *ibbase; + /* IRQ to use for non-pnp cards (set by core, driver should make local copy) */ + unsigned int ibirq; + /* dma channel to use for non-pnp cards (set by core, driver should make local copy) */ + unsigned int ibdma; + /* pci bus of card, useful for distinguishing multiple identical pci cards + * (negative means don't care) + */ + int pci_bus; + /* pci slot of card, useful for distinguishing multiple identical pci cards + * (negative means don't care) + */ + int pci_slot; + /* sysfs device path of hardware to attach */ + char *device_path; + /* serial number of hardware to attach */ + char *serial_number; +} gpib_board_config_t; + +struct gpib_interface_struct { + /* name of board */ + char *name; + /* attach() initializes board and allocates resources */ + int (*attach)(gpib_board_t *board, const gpib_board_config_t *config); + /* detach() shuts down board and frees resources */ + void (*detach)(gpib_board_t *board); + /* read() should read at most 'length' bytes from the bus into + * 'buffer'. It should return when it fills the buffer or + * encounters an END (EOI and or EOS if appropriate). It should set 'end' + * to be nonzero if the read was terminated by an END, otherwise 'end' + * should be zero. + * Ultimately, this will be changed into or replaced by an asynchronous + * read. Zero return value for success, negative + * return indicates error. + * nbytes returns number of bytes read + */ + int (*read)(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read); + /* write() should write 'length' bytes from buffer to the bus. + * If the boolean value send_eoi is nonzero, then EOI should + * be sent along with the last byte. Returns number of bytes + * written or negative value on error. + */ + int (*write)(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written); + /* command() writes the command bytes in 'buffer' to the bus + * Returns zero on success or negative value on error. + */ + int (*command)(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written); + /* Take control (assert ATN). If 'asyncronous' is nonzero, take + * control asyncronously (assert ATN immediately without waiting + * for other processes to complete first). Should not return + * until board becomes controller in charge. Returns zero no success, + * nonzero on error. + */ + int (*take_control)(gpib_board_t *board, int asyncronous); + /* De-assert ATN. Returns zero on success, nonzer on error. + */ + int (*go_to_standby)(gpib_board_t *board); + /* request/release control of the IFC and REN lines (system controller) */ + void (*request_system_control)(gpib_board_t *board, int request_control); + /* Asserts or de-asserts 'interface clear' (IFC) depending on + * boolean value of 'assert' + */ + void (*interface_clear)(gpib_board_t *board, int assert); + /* Sends remote enable command if 'enable' is nonzero, disables remote mode + * if 'enable' is zero + */ + void (*remote_enable)(gpib_board_t *board, int enable); + /* enable END for reads, when byte 'eos' is received. If + * 'compare_8_bits' is nonzero, then all 8 bits are compared + * with the eos bytes. Otherwise only the 7 least significant + * bits are compared. + */ + int (*enable_eos)(gpib_board_t *board, uint8_t eos, int compare_8_bits); + /* disable END on eos byte (END on EOI only)*/ + void (*disable_eos)(gpib_board_t *board); + /* configure parallel poll */ + void (*parallel_poll_configure)(gpib_board_t *board, uint8_t configuration); + /* conduct parallel poll */ + int (*parallel_poll)(gpib_board_t *board, uint8_t *result); + /* set/clear ist (individual status bit) */ + void (*parallel_poll_response)(gpib_board_t *board, int ist); + /* select local parallel poll configuration mode PP2 versus remote PP1 */ + void (*local_parallel_poll_mode)(gpib_board_t *board, int local); + /* Returns current status of the bus lines. Should be set to + * NULL if your board does not have the ability to query the + * state of the bus lines. + */ + int (*line_status)(const gpib_board_t *board); + /* updates and returns the board's current status. + * The meaning of the bits are specified in gpib_user.h + * in the IBSTA section. The driver does not need to + * worry about setting the CMPL, END, TIMO, or ERR bits. + */ + unsigned int (*update_status)(gpib_board_t *board, unsigned int clear_mask); + /* Sets primary address 0-30 for gpib interface card. + */ + int (*primary_address)(gpib_board_t *board, unsigned int address); + /* Sets and enables, or disables secondary address 0-30 + * for gpib interface card. + */ + int (*secondary_address)(gpib_board_t *board, unsigned int address, + int enable); + /* Sets the byte the board should send in response to a serial poll. + * This function should also start or stop requests for service via + * IEEE 488.2 reqt/reqf, based on MSS (bit 6 of the status_byte). + * If the more flexible serial_poll_response2 is implemented by the + * driver, then this method should be left NULL since it will not + * be used. This method can generate spurious service requests + * which are allowed by IEEE 488.2, but not ideal. + * + * This method should implement the serial poll response method described + * by IEEE 488.2 section 11.3.3.4.3 "Allowed Coupled Control of + * STB, reqt, and reqf". + */ + void (*serial_poll_response)(gpib_board_t *board, uint8_t status_byte); + /* Sets the byte the board should send in response to a serial poll. + * This function should also request service via IEEE 488.2 reqt/reqf + * based on MSS (bit 6 of the status_byte) and new_reason_for_service. + * reqt should be set true if new_reason_for_service is true, + * and reqf should be set true if MSS is false. This function + * will never be called with MSS false and new_reason_for_service + * true simultaneously, so don't worry about that case. + * + * This method implements the serial poll response method described + * by IEEE 488.2 section 11.3.3.4.1 "Preferred Implementation". + * + * If this method is left NULL by the driver, then the user library + * function ibrsv2 will not work. + */ + void (*serial_poll_response2)(gpib_board_t *board, uint8_t status_byte, + int new_reason_for_service); + /* returns the byte the board will send in response to a serial poll. + */ + uint8_t (*serial_poll_status)(gpib_board_t *board); + /* adjust T1 delay */ + unsigned int (*t1_delay)(gpib_board_t *board, unsigned int nano_sec); + /* go to local mode */ + void (*return_to_local)(gpib_board_t *board); + /* board does not support 7 bit eos comparisons */ + unsigned no_7_bit_eos : 1; + /* skip check for listeners before trying to send command bytes */ + unsigned skip_check_for_command_acceptors : 1; +}; + +typedef struct { + struct list_head event_head; + spinlock_t lock; // for access to event list + unsigned int num_events; + unsigned dropped_event : 1; +} gpib_event_queue_t; + +static inline void init_event_queue(gpib_event_queue_t *queue) +{ + INIT_LIST_HEAD(&queue->event_head); + queue->num_events = 0; + queue->dropped_event = 0; + spin_lock_init(&queue->lock); +} + +/* struct for supporting polling operation when irq is not available */ +struct gpib_pseudo_irq { + struct timer_list timer; + irqreturn_t (*handler)(int irq, void *arg); + gpib_board_t *board; + atomic_t active; +}; + +static inline void init_gpib_pseudo_irq(struct gpib_pseudo_irq *pseudo_irq) +{ + pseudo_irq->handler = NULL; + timer_setup(&pseudo_irq->timer, NULL, 0); + atomic_set(&pseudo_irq->active, 0); +} + +/* list so we can make a linked list of drivers */ +typedef struct gpib_interface_list_struct { + struct list_head list; + gpib_interface_t *interface; + struct module *module; +} gpib_interface_list_t; + +/* One gpib_board_t is allocated for each physical board in the computer. + * It provides storage for variables local to each board, and interface + * functions for performing operations on the board + */ +struct gpib_board_struct { + /* functions used by this board */ + gpib_interface_t *interface; + /* Pointer to module whose use count we should increment when + * interface is in use + */ + struct module *provider_module; + /* buffer used to store read/write data for this board */ + u8 *buffer; + /* length of buffer */ + unsigned int buffer_length; + /* Used to hold the board's current status (see update_status() above) + */ + unsigned long status; + /* Driver should only sleep on this wait queue. It is special in that the + * core will wake this queue and set the TIMO bit in 'status' when the + * watchdog timer times out. + */ + wait_queue_head_t wait; + /* Lock that only allows one process to access this board at a time. + * Has to be first in any locking order, since it can be locked over + * multiple ioctls. + */ + struct mutex user_mutex; + /* Mutex which compensates for removal of "big kernel lock" from kernel. + * Should not be held for extended waits. + */ + struct mutex big_gpib_mutex; + /* pid of last process to lock the board mutex */ + pid_t locking_pid; + spinlock_t locking_pid_spinlock; // lock for setting locking pid + /* Spin lock for dealing with races with the interrupt handler */ + spinlock_t spinlock; + /* Watchdog timer to enable timeouts */ + struct timer_list timer; + /* device of attached driver if any */ + struct device *dev; + /* gpib_common device gpibN */ + struct device *gpib_dev; + /* 'private_data' can be used as seen fit by the driver to + * store additional variables for this board + */ + void *private_data; + /* Number of open file descriptors using this board */ + unsigned int use_count; + /* list of open devices connected to this board */ + struct list_head device_list; + /* primary address */ + unsigned int pad; + /* secondary address */ + int sad; + /* timeout for io operations, in microseconds */ + unsigned int usec_timeout; + /* board's parallel poll configuration byte */ + u8 parallel_poll_configuration; + /* t1 delay we are using */ + unsigned int t1_nano_sec; + /* Count that keeps track of whether board is up and running or not */ + unsigned int online; + /* number of processes trying to autopoll */ + int autospollers; + /* autospoll kernel thread */ + struct task_struct *autospoll_task; + /* queue for recording received trigger/clear/ifc events */ + gpib_event_queue_t event_queue; + /* minor number for this board's device file */ + int minor; + /* struct to deal with polling mode*/ + struct gpib_pseudo_irq pseudo_irq; + /* error dong autopoll */ + atomic_t stuck_srq; + gpib_board_config_t config; + /* Flag that indicates whether board is system controller of the bus */ + unsigned master : 1; + /* individual status bit */ + unsigned ist : 1; + /* one means local parallel poll mode ieee 488.1 PP2 (or no parallel poll PP0), + * zero means remote parallel poll configuration mode ieee 488.1 PP1 + */ + unsigned local_ppoll_mode : 1; +}; + +/* element of event queue */ +typedef struct { + struct list_head list; + short event_type; +} gpib_event_t; + +/* Each board has a list of gpib_status_queue_t to keep track of all open devices + * on the bus, so we know what address to poll when we get a service request + */ +typedef struct { + /* list_head so we can make a linked list of devices */ + struct list_head list; + unsigned int pad; /* primary gpib address */ + int sad; /* secondary gpib address (negative means disabled) */ + /* stores serial poll bytes for this device */ + struct list_head status_bytes; + unsigned int num_status_bytes; + /* number of times this address is opened */ + unsigned int reference_count; + /* flags loss of status byte error due to limit on size of queue */ + unsigned dropped_byte : 1; +} gpib_status_queue_t; + +typedef struct { + struct list_head list; + u8 poll_byte; +} status_byte_t; + +void init_gpib_status_queue(gpib_status_queue_t *device); + +/* Used to store device-descriptor-specific information */ +typedef struct { + unsigned int pad; /* primary gpib address */ + int sad; /* secondary gpib address (negative means disabled) */ + atomic_t io_in_progress; + unsigned is_board : 1; + unsigned autopoll_enabled : 1; +} gpib_descriptor_t; + +typedef struct { + atomic_t holding_mutex; + gpib_descriptor_t *descriptors[GPIB_MAX_NUM_DESCRIPTORS]; + /* locked while descriptors are being allocated/deallocated */ + struct mutex descriptors_mutex; + unsigned got_module : 1; +} gpib_file_private_t; + +#endif /* __KERNEL__ */ + +#endif /* _GPIB_TYPES_H */ diff --git a/drivers/staging/gpib/include/nec7210.h b/drivers/staging/gpib/include/nec7210.h new file mode 100644 index 0000000000000000000000000000000000000000..c00aba4ce846dc885c7e2d7ed5dc780317f88501 --- /dev/null +++ b/drivers/staging/gpib/include/nec7210.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _NEC7210_H +#define _NEC7210_H + +#include "gpib_state_machines.h" +#include +#include +#include +#include + +#include "gpib_types.h" +#include "nec7210_registers.h" + +/* struct used to provide variables local to a nec7210 chip */ +struct nec7210_priv { + void *iobase; + unsigned int offset; // offset between successive nec7210 io addresses + unsigned int dma_channel; + u8 *dma_buffer; + unsigned int dma_buffer_length; // length of dma buffer + dma_addr_t dma_buffer_addr; // bus address of board->buffer for use with dma + // software copy of bits written to registers + u8 reg_bits[8]; + u8 auxa_bits; // bits written to auxiliary register A + u8 auxb_bits; // bits written to auxiliary register B + // used to keep track of board's state, bit definitions given below + unsigned long state; + /* lock for chips that extend the nec7210 registers by paging in alternate regs */ + spinlock_t register_page_lock; + // wrappers for outb, inb, readb, or writeb + u8 (*read_byte)(struct nec7210_priv *priv, unsigned int register_number); + void (*write_byte)(struct nec7210_priv *priv, u8 byte, unsigned int register_number); + enum nec7210_chipset type; + enum talker_function_state talker_state; + enum listener_function_state listener_state; + void *private; + unsigned srq_pending : 1; +}; + +static inline void init_nec7210_private(struct nec7210_priv *priv) +{ + memset(priv, 0, sizeof(struct nec7210_priv)); + spin_lock_init(&priv->register_page_lock); +} + +// slightly shorter way to access read_byte and write_byte +static inline u8 read_byte(struct nec7210_priv *priv, unsigned int register_number) +{ + return priv->read_byte(priv, register_number); +} + +static inline void write_byte(struct nec7210_priv *priv, u8 byte, unsigned int register_number) +{ + priv->write_byte(priv, byte, register_number); +} + +// struct nec7210_priv.state bit numbers +enum { + PIO_IN_PROGRESS_BN, // pio transfer in progress + DMA_READ_IN_PROGRESS_BN, // dma read transfer in progress + DMA_WRITE_IN_PROGRESS_BN, // dma write transfer in progress + READ_READY_BN, // board has data byte available to read + WRITE_READY_BN, // board is ready to send a data byte + COMMAND_READY_BN, // board is ready to send a command byte + RECEIVED_END_BN, // received END + BUS_ERROR_BN, // output error has occurred + RFD_HOLDOFF_BN, // rfd holdoff in effect + DEV_CLEAR_BN, // device clear received + ADR_CHANGE_BN, // address state change occurred +}; + +// interface functions +int nec7210_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read); +int nec7210_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, int send_eoi, size_t *bytes_written); +int nec7210_command(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, size_t *bytes_written); +int nec7210_take_control(gpib_board_t *board, struct nec7210_priv *priv, int syncronous); +int nec7210_go_to_standby(gpib_board_t *board, struct nec7210_priv *priv); +void nec7210_request_system_control(gpib_board_t *board, + struct nec7210_priv *priv, int request_control); +void nec7210_interface_clear(gpib_board_t *board, struct nec7210_priv *priv, int assert); +void nec7210_remote_enable(gpib_board_t *board, struct nec7210_priv *priv, int enable); +int nec7210_enable_eos(gpib_board_t *board, struct nec7210_priv *priv, uint8_t eos_bytes, + int compare_8_bits); +void nec7210_disable_eos(gpib_board_t *board, struct nec7210_priv *priv); +unsigned int nec7210_update_status(gpib_board_t *board, struct nec7210_priv *priv, + unsigned int clear_mask); +unsigned int nec7210_update_status_nolock(gpib_board_t *board, struct nec7210_priv *priv); +int nec7210_primary_address(const gpib_board_t *board, + struct nec7210_priv *priv, unsigned int address); +int nec7210_secondary_address(const gpib_board_t *board, struct nec7210_priv *priv, + unsigned int address, int enable); +int nec7210_parallel_poll(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *result); +void nec7210_serial_poll_response(gpib_board_t *board, struct nec7210_priv *priv, uint8_t status); +void nec7210_parallel_poll_configure(gpib_board_t *board, + struct nec7210_priv *priv, unsigned int configuration); +void nec7210_parallel_poll_response(gpib_board_t *board, + struct nec7210_priv *priv, int ist); +uint8_t nec7210_serial_poll_status(gpib_board_t *board, + struct nec7210_priv *priv); +unsigned int nec7210_t1_delay(gpib_board_t *board, + struct nec7210_priv *priv, unsigned int nano_sec); +void nec7210_return_to_local(const gpib_board_t *board, struct nec7210_priv *priv); + +// utility functions +void nec7210_board_reset(struct nec7210_priv *priv, const gpib_board_t *board); +void nec7210_board_online(struct nec7210_priv *priv, const gpib_board_t *board); +unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg, + unsigned int mask, unsigned int bits); +void nec7210_set_handshake_mode(gpib_board_t *board, struct nec7210_priv *priv, int mode); +void nec7210_release_rfd_holdoff(gpib_board_t *board, struct nec7210_priv *priv); +uint8_t nec7210_read_data_in(gpib_board_t *board, struct nec7210_priv *priv, int *end); + +// wrappers for io functions +uint8_t nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num); +uint8_t nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num); +uint8_t nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, + unsigned int register_num); +uint8_t nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num); +void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, + unsigned int register_num); + +// interrupt service routine +irqreturn_t nec7210_interrupt(gpib_board_t *board, struct nec7210_priv *priv); +irqreturn_t nec7210_interrupt_have_status(gpib_board_t *board, + struct nec7210_priv *priv, int status1, int status2); + +#endif //_NEC7210_H diff --git a/drivers/staging/gpib/include/nec7210_registers.h b/drivers/staging/gpib/include/nec7210_registers.h new file mode 100644 index 0000000000000000000000000000000000000000..888803dd97f9e7ac2229bff5318e7b245cdff0e8 --- /dev/null +++ b/drivers/staging/gpib/include/nec7210_registers.h @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _NEC7210_REGISTERS_H +#define _NEC7210_REGISTERS_H + +enum nec7210_chipset { + NEC7210, // The original + TNT4882, // NI + NAT4882, // NI + CB7210, // measurement computing + IOT7210, // iotech + IGPIB7210, // Ines + TNT5004, // NI (minor differences to TNT4882) +}; + +/* nec7210 register numbers (might need to be multiplied by + * a board-dependent offset to get actually io address offset) + */ +// write registers +enum nec7210_write_regs { + CDOR, // command/data out + IMR1, // interrupt mask 1 + IMR2, // interrupt mask 2 + SPMR, // serial poll mode + ADMR, // address mode + AUXMR, // auxiliary mode + ADR, // address + EOSR, // end-of-string + + // nec7210 has 8 registers + nec7210_num_registers = 8, +}; + +// read registers +enum nec7210_read_regs { + DIR, // data in + ISR1, // interrupt status 1 + ISR2, // interrupt status 2 + SPSR, // serial poll status + ADSR, // address status + CPTR, // command pass though + ADR0, // address 1 + ADR1, // address 2 +}; + +//bit definitions common to nec-7210 compatible registers + +// ISR1: interrupt status register 1 +enum isr1_bits { + HR_DI = (1 << 0), + HR_DO = (1 << 1), + HR_ERR = (1 << 2), + HR_DEC = (1 << 3), + HR_END = (1 << 4), + HR_DET = (1 << 5), + HR_APT = (1 << 6), + HR_CPT = (1 << 7), +}; + +// IMR1: interrupt mask register 1 +enum imr1_bits { + HR_DIIE = (1 << 0), + HR_DOIE = (1 << 1), + HR_ERRIE = (1 << 2), + HR_DECIE = (1 << 3), + HR_ENDIE = (1 << 4), + HR_DETIE = (1 << 5), + HR_APTIE = (1 << 6), + HR_CPTIE = (1 << 7), +}; + +// ISR2, interrupt status register 2 +enum isr2_bits { + HR_ADSC = (1 << 0), + HR_REMC = (1 << 1), + HR_LOKC = (1 << 2), + HR_CO = (1 << 3), + HR_REM = (1 << 4), + HR_LOK = (1 << 5), + HR_SRQI = (1 << 6), + HR_INT = (1 << 7), +}; + +// IMR2, interrupt mask register 2 +enum imr2_bits { + // all the bits in this register that enable interrupts + IMR2_ENABLE_INTR_MASK = 0x4f, + HR_ACIE = (1 << 0), + HR_REMIE = (1 << 1), + HR_LOKIE = (1 << 2), + HR_COIE = (1 << 3), + HR_DMAI = (1 << 4), + HR_DMAO = (1 << 5), + HR_SRQIE = (1 << 6), +}; + +// SPSR, serial poll status register +enum spsr_bits { + HR_PEND = (1 << 6), +}; + +// SPMR, serial poll mode register +enum spmr_bits { + HR_RSV = (1 << 6), +}; + +// ADSR, address status register +enum adsr_bits { + HR_MJMN = (1 << 0), + HR_TA = (1 << 1), + HR_LA = (1 << 2), + HR_TPAS = (1 << 3), + HR_LPAS = (1 << 4), + HR_SPMS = (1 << 5), + HR_NATN = (1 << 6), + HR_CIC = (1 << 7), +}; + +// ADMR, address mode register +enum admr_bits { + HR_ADM0 = (1 << 0), + HR_ADM1 = (1 << 1), + HR_TRM0 = (1 << 4), + HR_TRM1 = (1 << 5), + HR_TRM_EOIOE_TRIG = 0, + HR_TRM_CIC_TRIG = HR_TRM0, + HR_TRM_CIC_EOIOE = HR_TRM1, + HR_TRM_CIC_PE = HR_TRM0 | HR_TRM1, + HR_LON = (1 << 6), + HR_TON = (1 << 7), +}; + +// ADR, bits used in address0, address1 and address0/1 registers +enum adr_bits { + ADDRESS_MASK = 0x1f, /* mask to specify lower 5 bits */ + HR_DL = (1 << 5), + HR_DT = (1 << 6), + HR_ARS = (1 << 7), +}; + +// ADR1, address1 register +enum adr1_bits { + HR_EOI = (1 << 7), +}; + +// AUXMR, auxiliary mode register +enum auxmr_bits { + ICR = 0x20, + PPR = 0x60, + AUXRA = 0x80, + AUXRB = 0xa0, + AUXRE = 0xc0, +}; + +// auxra, auxiliary register A +enum auxra_bits { + HR_HANDSHAKE_MASK = 0x3, + HR_HLDA = 0x1, + HR_HLDE = 0x2, + HR_LCM = 0x3, /* auxra listen continuous */ + HR_REOS = 0x4, + HR_XEOS = 0x8, + HR_BIN = 0x10, +}; + +// auxrb, auxiliary register B +enum auxrb_bits { + HR_CPTE = (1 << 0), + HR_SPEOI = (1 << 1), + HR_TRI = (1 << 2), + HR_INV = (1 << 3), + HR_ISS = (1 << 4), +}; + +enum auxre_bits { + HR_DAC_HLD_DCAS = 0x1, /* perform DAC holdoff on receiving clear */ + HR_DAC_HLD_DTAS = 0x2, /* perform DAC holdoff on receiving trigger */ +}; + +// parallel poll register +enum ppr_bits { + HR_PPS = (1 << 3), + HR_PPU = (1 << 4), +}; + +/* 7210 Auxiliary Commands */ +enum aux_cmds { + AUX_PON = 0x0, /* Immediate Execute pon */ + AUX_CPPF = 0x1, /* Clear Parallel Poll Flag */ + AUX_CR = 0x2, /* Chip Reset */ + AUX_FH = 0x3, /* Finish Handshake */ + AUX_TRIG = 0x4, /* Trigger */ + AUX_RTL = 0x5, /* Return to local */ + AUX_SEOI = 0x6, /* Send EOI */ + AUX_NVAL = 0x7, /* Non-Valid Secondary Command or Address */ + AUX_SPPF = 0x9, /* Set Parallel Poll Flag */ + AUX_VAL = 0xf, /* Valid Secondary Command or Address */ + AUX_GTS = 0x10, /* Go To Standby */ + AUX_TCA = 0x11, /* Take Control Asynchronously */ + AUX_TCS = 0x12, /* Take Control Synchronously */ + AUX_LTN = 0x13, /* Listen */ + AUX_DSC = 0x14, /* Disable System Control */ + AUX_CIFC = 0x16, /* Clear IFC */ + AUX_CREN = 0x17, /* Clear REN */ + AUX_TCSE = 0x1a, /* Take Control Synchronously on End */ + AUX_LTNC = 0x1b, /* Listen in Continuous Mode */ + AUX_LUN = 0x1c, /* Local Unlisten */ + AUX_EPP = 0x1d, /* Execute Parallel Poll */ + AUX_SIFC = 0x1e, /* Set IFC */ + AUX_SREN = 0x1f, /* Set REN */ +}; + +#endif //_NEC7210_REGISTERS_H diff --git a/drivers/staging/gpib/include/plx9050.h b/drivers/staging/gpib/include/plx9050.h new file mode 100644 index 0000000000000000000000000000000000000000..66c56335f5c0b4aeeef29bed285b2a627dfc7792 --- /dev/null +++ b/drivers/staging/gpib/include/plx9050.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Header for plx9050 pci chip + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _PLX9050_GPIB_H +#define _PLX9050_GPIB_H + +// plx pci chip registers and bits +enum { + PLX9050_INTCSR_REG = 0x4c, + PLX9050_CNTRL_REG = 0x50 +}; + +enum plx9050_intcsr_bits { + PLX9050_LINTR1_EN_BIT = 0x1, + PLX9050_LINTR1_POLARITY_BIT = 0x2, + PLX9050_LINTR1_STATUS_BIT = 0x4, + PLX9050_LINTR2_EN_BIT = 0x8, + PLX9050_LINTR2_POLARITY_BIT = 0x10, + PLX9050_LINTR2_STATUS_BIT = 0x20, + PLX9050_PCI_INTR_EN_BIT = 0x40, + PLX9050_SOFT_INTR_BIT = 0x80, + PLX9050_LINTR1_SELECT_ENABLE_BIT = 0x100, //9052 extension + PLX9050_LINTR2_SELECT_ENABLE_BIT = 0x200, //9052 extension + PLX9050_LINTR1_EDGE_CLEAR_BIT = 0x400, //9052 extension + PLX9050_LINTR2_EDGE_CLEAR_BIT = 0x800, //9052 extension +}; + +enum plx9050_cntrl_bits { + PLX9050_WAITO_NOT_USER0_SELECT_BIT = 0x1, + PLX9050_USER0_OUTPUT_BIT = 0x2, + PLX9050_USER0_DATA_BIT = 0x4, + PLX9050_LLOCK_NOT_USER1_SELECT_BIT = 0x8, + PLX9050_USER1_OUTPUT_BIT = 0x10, + PLX9050_USER1_DATA_BIT = 0x20, + PLX9050_CS2_NOT_USER2_SELECT_BIT = 0x40, + PLX9050_USER2_OUTPUT_BIT = 0x80, + PLX9050_USER2_DATA_BIT = 0x100, + PLX9050_CS3_NOT_USER3_SELECT_BIT = 0x200, + PLX9050_USER3_OUTPUT_BIT = 0x400, + PLX9050_USER3_DATA_BIT = 0x800, + PLX9050_PCIBAR_ENABLE_MASK = 0x3000, + PLX9050_PCIBAR_MEMORY_AND_IO_ENABLE_BITS = 0x0, + PLX9050_PCIBAR_MEMORY_NO_IO_ENABLE_BITS = 0x1000, + PLX9050_PCIBAR_IO_NO_MEMORY_ENABLE_BITS = 0x2000, + PLX9050_PCIBAR_MEMORY_AND_IO_TOO_ENABLE_BITS = 0x3000, + PLX9050_PCI_READ_MODE_BIT = 0x4000, + PLX9050_PCI_READ_WITH_WRITE_FLUSH_MODE_BIT = 0x8000, + PLX9050_PCI_READ_NO_FLUSH_MODE_BIT = 0x10000, + PLX9050_PCI_READ_NO_WRITE_MODE_BIT = 0x20000, + PLX9050_PCI_WRITE_MODE_BIT = 0x40000, + PLX9050_PCI_RETRY_DELAY_MASK = 0x780000, + PLX9050_DIRECT_SLAVE_LOCK_ENABLE_BIT = 0x800000, + PLX9050_EEPROM_CLOCK_BIT = 0x1000000, + PLX9050_EEPROM_CHIP_SELECT_BIT = 0x2000000, + PLX9050_WRITE_TO_EEPROM_BIT = 0x4000000, + PLX9050_READ_EEPROM_DATA_BIT = 0x8000000, + PLX9050_EEPROM_VALID_BIT = 0x10000000, + PLX9050_RELOAD_CONFIG_REGISTERS_BIT = 0x20000000, + PLX9050_PCI_SOFTWARE_RESET_BIT = 0x40000000, + PLX9050_MASK_REVISION_BIT = 0x80000000 +}; + +static inline unsigned int PLX9050_PCI_RETRY_DELAY_BITS(unsigned int clocks) +{ + return ((clocks / 8) << 19) & PLX9050_PCI_RETRY_DELAY_MASK; +} + +#endif // _PLX9050_GPIB_H diff --git a/drivers/staging/gpib/include/quancom_pci.h b/drivers/staging/gpib/include/quancom_pci.h new file mode 100644 index 0000000000000000000000000000000000000000..cdaf0d056be9e7823a7896eb7719221220230121 --- /dev/null +++ b/drivers/staging/gpib/include/quancom_pci.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Quancom pci stuff + * copyright (C) 2005 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _QUANCOM_PCI_H +#define _QUANCOM_PCI_H + +/* quancom registers */ +enum quancom_regs { + QUANCOM_IRQ_CONTROL_STATUS_REG = 0xfc, +}; + +enum quancom_irq_control_status_bits { + QUANCOM_IRQ_ASSERTED_BIT = 0x1, /* readable */ + /* (any write to the register clears the interrupt)*/ + QUANCOM_IRQ_ENABLE_BIT = 0x4, /* writeable */ +}; + +#endif // _QUANCOM_PCI_H diff --git a/drivers/staging/gpib/include/tms9914.h b/drivers/staging/gpib/include/tms9914.h new file mode 100644 index 0000000000000000000000000000000000000000..456b488212d2b7d23981618581d8fb5f5400b69b --- /dev/null +++ b/drivers/staging/gpib/include/tms9914.h @@ -0,0 +1,274 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _TMS9914_H +#define _TMS9914_H + +#include +#include +#include "gpib_state_machines.h" +#include "gpib_types.h" + +enum tms9914_holdoff_mode { + TMS9914_HOLDOFF_NONE, + TMS9914_HOLDOFF_EOI, + TMS9914_HOLDOFF_ALL, +}; + +/* struct used to provide variables local to a tms9914 chip */ +struct tms9914_priv { + void *iobase; + unsigned int offset; // offset between successive tms9914 io addresses + unsigned int dma_channel; + // software copy of bits written to interrupt mask registers + u8 imr0_bits, imr1_bits; + // bits written to address mode register + u8 admr_bits; + u8 auxa_bits; // bits written to auxiliary register A + // used to keep track of board's state, bit definitions given below + unsigned long state; + u8 eos; // eos character + short eos_flags; + u8 spoll_status; + enum tms9914_holdoff_mode holdoff_mode; + unsigned int ppoll_line; + enum talker_function_state talker_state; + enum listener_function_state listener_state; + unsigned ppoll_sense : 1; + unsigned ppoll_enable : 1; + unsigned ppoll_configure_state : 1; + unsigned primary_listen_addressed : 1; + unsigned primary_talk_addressed : 1; + unsigned holdoff_on_end : 1; + unsigned holdoff_on_all : 1; + unsigned holdoff_active : 1; + // wrappers for outb, inb, readb, or writeb + u8 (*read_byte)(struct tms9914_priv *priv, unsigned int register_number); + void (*write_byte)(struct tms9914_priv *priv, u8 byte, unsigned int + register_number); +}; + +// slightly shorter way to access read_byte and write_byte +static inline u8 read_byte(struct tms9914_priv *priv, unsigned int register_number) +{ + return priv->read_byte(priv, register_number); +} + +static inline void write_byte(struct tms9914_priv *priv, u8 byte, unsigned int register_number) +{ + priv->write_byte(priv, byte, register_number); +} + +// struct tms9914_priv.state bit numbers +enum { + PIO_IN_PROGRESS_BN, // pio transfer in progress + DMA_READ_IN_PROGRESS_BN, // dma read transfer in progress + DMA_WRITE_IN_PROGRESS_BN, // dma write transfer in progress + READ_READY_BN, // board has data byte available to read + WRITE_READY_BN, // board is ready to send a data byte + COMMAND_READY_BN, // board is ready to send a command byte + RECEIVED_END_BN, // received END + BUS_ERROR_BN, // bus error + DEV_CLEAR_BN, // device clear received +}; + +// interface functions +int tms9914_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read); +int tms9914_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, int send_eoi, size_t *bytes_written); +int tms9914_command(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, size_t *bytes_written); +int tms9914_take_control(gpib_board_t *board, struct tms9914_priv *priv, int syncronous); +/* alternate version of tms9914_take_control which works around buggy tcs + * implementation. + */ +int tms9914_take_control_workaround(gpib_board_t *board, struct tms9914_priv *priv, + int syncronous); +int tms9914_go_to_standby(gpib_board_t *board, struct tms9914_priv *priv); +void tms9914_request_system_control(gpib_board_t *board, struct tms9914_priv *priv, + int request_control); +void tms9914_interface_clear(gpib_board_t *board, struct tms9914_priv *priv, int assert); +void tms9914_remote_enable(gpib_board_t *board, struct tms9914_priv *priv, int enable); +int tms9914_enable_eos(gpib_board_t *board, struct tms9914_priv *priv, uint8_t eos_bytes, + int compare_8_bits); +void tms9914_disable_eos(gpib_board_t *board, struct tms9914_priv *priv); +unsigned int tms9914_update_status(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int clear_mask); +int tms9914_primary_address(gpib_board_t *board, + struct tms9914_priv *priv, unsigned int address); +int tms9914_secondary_address(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int address, int enable); +int tms9914_parallel_poll(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *result); +void tms9914_parallel_poll_configure(gpib_board_t *board, + struct tms9914_priv *priv, uint8_t config); +void tms9914_parallel_poll_response(gpib_board_t *board, + struct tms9914_priv *priv, int ist); +void tms9914_serial_poll_response(gpib_board_t *board, struct tms9914_priv *priv, uint8_t status); +uint8_t tms9914_serial_poll_status(gpib_board_t *board, struct tms9914_priv *priv); +int tms9914_line_status(const gpib_board_t *board, struct tms9914_priv *priv); +unsigned int tms9914_t1_delay(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int nano_sec); +void tms9914_return_to_local(const gpib_board_t *board, struct tms9914_priv *priv); + +// utility functions +void tms9914_board_reset(struct tms9914_priv *priv); +void tms9914_online(gpib_board_t *board, struct tms9914_priv *priv); +void tms9914_release_holdoff(struct tms9914_priv *priv); +void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode); + +// wrappers for io functions +uint8_t tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num); +void tms9914_ioport_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num); +uint8_t tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num); +void tms9914_iomem_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num); + +// interrupt service routine +irqreturn_t tms9914_interrupt(gpib_board_t *board, struct tms9914_priv *priv); +irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_priv *priv, + int status1, int status2); + +// tms9914 has 8 registers +enum { + ms9914_num_registers = 8, +}; + +/* tms9914 register numbers (might need to be multiplied by + * a board-dependent offset to get actually io address offset) + */ +// write registers +enum { + IMR0 = 0, /* interrupt mask 0 */ + IMR1 = 1, /* interrupt mask 1 */ + AUXCR = 3, /* auxiliary command */ + ADR = 4, // address register + SPMR = 5, // serial poll mode register + PPR = 6, /* parallel poll */ + CDOR = 7, /* data out register */ +}; + +// read registers +enum { + ISR0 = 0, /* interrupt status 0 */ + ISR1 = 1, /* interrupt status 1 */ + ADSR = 2, /* address status */ + BSR = 3, /* bus status */ + CPTR = 6, /* command pass thru */ + DIR = 7, /* data in register */ +}; + +//bit definitions common to tms9914 compatible registers + +/* ISR0 - Register bits */ +enum isr0_bits { + HR_MAC = (1 << 0), /* My Address Change */ + HR_RLC = (1 << 1), /* Remote/Local change */ + HR_SPAS = (1 << 2), /* Serial Poll active State */ + HR_END = (1 << 3), /* END (EOI or EOS) */ + HR_BO = (1 << 4), /* Byte Out */ + HR_BI = (1 << 5), /* Byte In */ +}; + +/* IMR0 - Register bits */ +enum imr0_bits { + HR_MACIE = (1 << 0), /* */ + HR_RLCIE = (1 << 1), /* */ + HR_SPASIE = (1 << 2), /* */ + HR_ENDIE = (1 << 3), /* */ + HR_BOIE = (1 << 4), /* */ + HR_BIIE = (1 << 5), /* */ +}; + +/* ISR1 - Register bits */ +enum isr1_bits { + HR_IFC = (1 << 0), /* IFC asserted */ + HR_SRQ = (1 << 1), /* SRQ asserted */ + HR_MA = (1 << 2), /* My Address */ + HR_DCAS = (1 << 3), /* Device Clear active State */ + HR_APT = (1 << 4), /* Address pass Through */ + HR_UNC = (1 << 5), /* Unrecognized Command */ + HR_ERR = (1 << 6), /* Data Transmission Error */ + HR_GET = (1 << 7), /* Group execute Trigger */ +}; + +/* IMR1 - Register bits */ +enum imr1_bits { + HR_IFCIE = (1 << 0), /* */ + HR_SRQIE = (1 << 1), /* */ + HR_MAIE = (1 << 2), /* */ + HR_DCASIE = (1 << 3), /* */ + HR_APTIE = (1 << 4), /* */ + HR_UNCIE = (1 << 5), /* */ + HR_ERRIE = (1 << 6), /* */ + HR_GETIE = (1 << 7), /* */ +}; + +/* ADSR - Register bits */ +enum adsr_bits { + HR_ULPA = (1 << 0), /* Store last address LSB */ + HR_TA = (1 << 1), /* Talker Adressed */ + HR_LA = (1 << 2), /* Listener adressed */ + HR_TPAS = (1 << 3), /* talker primary address state */ + HR_LPAS = (1 << 4), /* listener " */ + HR_ATN = (1 << 5), /* ATN active */ + HR_LLO = (1 << 6), /* LLO active */ + HR_REM = (1 << 7), /* REM active */ +}; + +/* ADR - Register bits */ +enum adr_bits { + ADDRESS_MASK = 0x1f, /* mask to specify lower 5 bits for ADR */ + HR_DAT = (1 << 5), /* disable talker */ + HR_DAL = (1 << 6), /* disable listener */ + HR_EDPA = (1 << 7), /* enable dual primary addressing */ +}; + +enum bus_status_bits { + BSR_REN_BIT = 0x1, + BSR_IFC_BIT = 0x2, + BSR_SRQ_BIT = 0x4, + BSR_EOI_BIT = 0x8, + BSR_NRFD_BIT = 0x10, + BSR_NDAC_BIT = 0x20, + BSR_DAV_BIT = 0x40, + BSR_ATN_BIT = 0x80, +}; + +/*---------------------------------------------------------*/ +/* TMS 9914 Auxiliary Commands */ +/*---------------------------------------------------------*/ + +enum aux_cmd_bits { + AUX_CS = 0x80, /* set bit instead of clearing it, used with commands marked 'd' below */ + AUX_CHIP_RESET = 0x0, /* d Chip reset */ + AUX_INVAL = 0x1, // release dac holdoff, invalid command byte + AUX_VAL = (AUX_INVAL | AUX_CS), // release dac holdoff, valid command byte + AUX_RHDF = 0x2, /* X Release RFD holdoff */ + AUX_HLDA = 0x3, /* d holdoff on all data */ + AUX_HLDE = 0x4, /* d holdoff on EOI only */ + AUX_NBAF = 0x5, /* X Set new byte available false */ + AUX_FGET = 0x6, /* d force GET */ + AUX_RTL = 0x7, /* d return to local */ + AUX_SEOI = 0x8, /* X send EOI with next byte */ + AUX_LON = 0x9, /* d Listen only */ + AUX_TON = 0xa, /* d Talk only */ + AUX_GTS = 0xb, /* X goto standby */ + AUX_TCA = 0xc, /* X take control asynchronously */ + AUX_TCS = 0xd, /* X take " synchronously */ + AUX_RPP = 0xe, /* d Request parallel poll */ + AUX_SIC = 0xf, /* d send interface clear */ + AUX_SRE = 0x10, /* d send remote enable */ + AUX_RQC = 0x11, /* X request control */ + AUX_RLC = 0x12, /* X release control */ + AUX_DAI = 0x13, /* d disable all interrupts */ + AUX_PTS = 0x14, /* X pass through next secondary */ + AUX_STDL = 0x15, /* d short T1 delay */ + AUX_SHDW = 0x16, /* d shadow handshake */ + AUX_VSTDL = 0x17, /* d very short T1 delay (smj9914 extension) */ + AUX_RSV2 = 0x18, /* d request service bit 2 (smj9914 extension) */ +}; + +#endif //_TMS9914_H diff --git a/drivers/staging/gpib/include/tnt4882_registers.h b/drivers/staging/gpib/include/tnt4882_registers.h new file mode 100644 index 0000000000000000000000000000000000000000..1b1441cd03d50ec23dca803be5853601b0d8addc --- /dev/null +++ b/drivers/staging/gpib/include/tnt4882_registers.h @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002, 2004 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _TNT4882_REGISTERS_H +#define _TNT4882_REGISTERS_H + +// tnt4882 register offsets +enum { + ACCWR = 0x5, + // offset of auxiliary command register in 9914 mode + AUXCR = 0x6, + INTRT = 0x7, + // register number for auxiliary command register when swap bit is set (9914 mode) + SWAPPED_AUXCR = 0xa, + HSSEL = 0xd, // handshake select register + CNT2 = 0x9, + CNT3 = 0xb, + CFG = 0x10, + SASR = 0x1b, + IMR0 = 0x1d, + IMR3 = 0x12, + CNT0 = 0x14, + CNT1 = 0x16, + KEYREG = 0x17, // key control register (7210 mode only) + CSR = KEYREG, + FIFOB = 0x18, + FIFOA = 0x19, + CCR = 0x1a, // carry cycle register + CMDR = 0x1c, // command register + TIMER = 0x1e, // timer register + + STS1 = 0x10, /* T488 Status Register 1 */ + STS2 = 0x1c, /* T488 Status Register 2 */ + ISR0 = IMR0, + ISR3 = 0x1a, /* T488 Interrupt Status Register 3 */ + BCR = 0x1f, /* bus control/status register */ + BSR = BCR, +}; + +enum { + tnt_pagein_offset = 0x11, +}; + +/*============================================================*/ + +/* TURBO-488 registers bit definitions */ + +enum bus_control_status_bits { + BCSR_REN_BIT = 0x1, + BCSR_IFC_BIT = 0x2, + BCSR_SRQ_BIT = 0x4, + BCSR_EOI_BIT = 0x8, + BCSR_NRFD_BIT = 0x10, + BCSR_NDAC_BIT = 0x20, + BCSR_DAV_BIT = 0x40, + BCSR_ATN_BIT = 0x80, +}; + +/* CFG -- Configuration Register (write only) */ +enum cfg_bits { + TNT_COMMAND = 0x80, /* bytes are command bytes instead of data bytes + * (tnt4882 one-chip and newer only?) + */ + TNT_TLCHE = (1 << 6), /* halt transfer on imr0, imr1, or imr2 interrupt */ + TNT_IN = (1 << 5), /* transfer is GPIB read */ + TNT_A_B = (1 << 4), /* order to use fifos 1=fifo A first(big endian), + * 0=fifo b first(little endian) + */ + TNT_CCEN = (1 << 3), /* enable carry cycle */ + TNT_TMOE = (1 << 2), /* enable CPU bus time limit */ + TNT_TIM_BYTN = (1 << 1), /* tmot reg is: 1=125ns clocks, 0=num bytes */ + TNT_B_16BIT = (1 << 0), /* 1=FIFO is 16-bit register, 0=8-bit */ +}; + +/* CMDR -- Command Register */ +enum cmdr_bits { + CLRSC = 0x2, /* clear the system controller bit */ + SETSC = 0x3, /* set the system controller bit */ + GO = 0x4, /* start fifos */ + STOP = 0x8, /* stop fifos */ + RESET_FIFO = 0x10, /* reset the FIFOs */ + SOFT_RESET = 0x22, /* issue a software reset */ + HARD_RESET = 0x40 /* 500x only? */ +}; + +/* HSSEL -- handshake select register (write only) */ +enum hssel_bits { + TNT_ONE_CHIP_BIT = 0x1, + NODMA = 0x10, + TNT_GO2SIDS_BIT = 0x20, +}; + +/* IMR0 -- Interrupt Mode Register 0 */ +enum imr0_bits { + TNT_SYNCIE_BIT = 0x1, /* handshake sync */ + TNT_TOIE_BIT = 0x2, /* timeout */ + TNT_ATNIE_BIT = 0x4, /* ATN interrupt */ + TNT_IFCIE_BIT = 0x8, /* interface clear interrupt */ + TNT_BTO_BIT = 0x10, /* byte timeout */ + TNT_NLEN_BIT = 0x20, /* treat new line as EOS char */ + TNT_STBOIE_BIT = 0x40, /* status byte out */ + TNT_IMR0_ALWAYS_BITS = 0x80, /* always set this bit on write */ +}; + +/* ISR0 -- Interrupt Status Register 0 */ +enum isr0_bits { + TNT_SYNC_BIT = 0x1, /* handshake sync */ + TNT_TO_BIT = 0x2, /* timeout */ + TNT_ATNI_BIT = 0x4, /* ATN interrupt */ + TNT_IFCI_BIT = 0x8, /* interface clear interrupt */ + TNT_EOS_BIT = 0x10, /* end of string */ + TNT_NL_BIT = 0x20, /* new line receive */ + TNT_STBO_BIT = 0x40, /* status byte out */ + TNT_NBA_BIT = 0x80, /* new byte available */ +}; + +/* ISR3 -- Interrupt Status Register 3 (read only) */ +enum isr3_bits { + HR_DONE = (1 << 0), /* transfer done */ + HR_TLCI = (1 << 1), /* isr0, isr1, or isr2 interrupt asserted */ + HR_NEF = (1 << 2), /* NOT empty fifo */ + HR_NFF = (1 << 3), /* NOT full fifo */ + HR_STOP = (1 << 4), /* fifo empty or STOP command issued */ + HR_SRQI_CIC = (1 << 5), /* SRQ asserted and we are CIC (500x only?)*/ + HR_INTR = (1 << 7), /* isr3 interrupt active */ +}; + +enum keyreg_bits { + MSTD = 0x20, // enable 350ns T1 delay +}; + +/* STS1 -- Status Register 1 (read only) */ +enum sts1_bits { + S_DONE = 0x80, /* DMA done */ + S_SC = 0x40, /* is system controller */ + S_IN = 0x20, /* DMA in (to memory) */ + S_DRQ = 0x10, /* DRQ line (for diagnostics) */ + S_STOP = 0x08, /* DMA stopped */ + S_NDAV = 0x04, /* inverse of DAV */ + S_HALT = 0x02, /* status of transfer machine */ + S_GSYNC = 0x01, /* indicates if GPIB is in sync w I/O */ +}; + +/* STS2 -- Status Register 2 */ +enum sts2_bits { + AFFN = (1 << 3), /* "A full FIFO NOT" (0=FIFO full) */ + AEFN = (1 << 2), /* "A empty FIFO NOT" (0=FIFO empty) */ + BFFN = (1 << 1), /* "B full FIFO NOT" (0=FIFO full) */ + BEFN = (1 << 0), /* "B empty FIFO NOT" (0=FIFO empty) */ +}; + +// Auxiliary commands +enum tnt4882_aux_cmds { + AUX_9914 = 0x15, // switch to 9914 mode + AUX_REQT = 0x18, + AUX_REQF = 0x19, + AUX_PAGEIN = 0x50, /* page in alternate registers */ + AUX_HLDI = 0x51, // rfd holdoff immediately + AUX_CLEAR_END = 0x55, + AUX_7210 = 0x99, // switch to 7210 mode +}; + +enum tnt4882_aux_regs { + AUXRG = 0x40, + AUXRI = 0xe0, +}; + +enum auxg_bits { + /* no talking when no listeners bit (prevents bus errors when data written at wrong time) */ + NTNL_BIT = 0x8, + RPP2_BIT = 0x4, /* set/clear local rpp message */ + CHES_BIT = 0x1, /*clear holdoff on end select bit*/ +}; + +enum auxi_bits { + SISB = 0x1, // static interrupt bits (don't clear isr1, isr2 on read) + PP2 = 0x4, // ignore remote parallel poll configuration + USTD = 0x8, // ultra short (1100 nanosec) T1 delay +}; + +enum sasr_bits { + ACRDY_BIT = 0x4, /* acceptor ready state */ + ADHS_BIT = 0x8, /* acceptor data holdoff state */ + ANHS2_BIT = 0x10, /* acceptor not ready holdoff immediately state */ + ANHS1_BIT = 0x20, /* acceptor not ready holdoff state */ + AEHS_BIT = 0x40, /* acceptor end holdoff state */ +}; + +#endif // _TNT4882_REGISTERS_H diff --git a/drivers/staging/gpib/ines/Makefile b/drivers/staging/gpib/ines/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cdcaa59a4e39c5f3c0a4bfd5f16122d6a872ef38 --- /dev/null +++ b/drivers/staging/gpib/ines/Makefile @@ -0,0 +1,4 @@ +ccflags-$(CONFIG_GPIB_PCMCIA) := -DGPIB_PCMCIA +obj-m += ines_gpib.o + + diff --git a/drivers/staging/gpib/ines/ines.h b/drivers/staging/gpib/ines/ines.h new file mode 100644 index 0000000000000000000000000000000000000000..7e8302619998fe05611221a7a6af4d126d105e87 --- /dev/null +++ b/drivers/staging/gpib/ines/ines.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * Header for ines GPIB boards + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _INES_GPIB_H +#define _INES_GPIB_H + +#include "nec7210.h" +#include "gpibP.h" +#include "plx9050.h" +#include "amcc5920.h" +#include "quancom_pci.h" +#include + +enum ines_pci_chip { + PCI_CHIP_NONE, + PCI_CHIP_PLX9050, + PCI_CHIP_AMCC5920, + PCI_CHIP_QUANCOM, + PCI_CHIP_QUICKLOGIC5030, +}; + +struct ines_priv { + struct nec7210_priv nec7210_priv; + struct pci_dev *pci_device; + // base address for plx9052 pci chip + unsigned long plx_iobase; + // base address for amcc5920 pci chip + unsigned long amcc_iobase; + unsigned int irq; + enum ines_pci_chip pci_chip_type; + u8 extend_mode_bits; +}; + +// interfaces +extern gpib_interface_t ines_pci_interface; +extern gpib_interface_t ines_pci_accel_interface; +extern gpib_interface_t ines_pcmcia_interface; +extern gpib_interface_t ines_pcmcia_accel_interface; +extern gpib_interface_t ines_pcmcia_unaccel_interface; + +// interface functions +int ines_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read); +int ines_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written); +int ines_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read); +int ines_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written); +int ines_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written); +int ines_take_control(gpib_board_t *board, int synchronous); +int ines_go_to_standby(gpib_board_t *board); +void ines_request_system_control(gpib_board_t *board, int request_control); +void ines_interface_clear(gpib_board_t *board, int assert); +void ines_remote_enable(gpib_board_t *board, int enable); +int ines_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits); +void ines_disable_eos(gpib_board_t *board); +unsigned int ines_update_status(gpib_board_t *board, unsigned int clear_mask); +int ines_primary_address(gpib_board_t *board, unsigned int address); +int ines_secondary_address(gpib_board_t *board, unsigned int address, int enable); +int ines_parallel_poll(gpib_board_t *board, uint8_t *result); +void ines_parallel_poll_configure(gpib_board_t *board, uint8_t config); +void ines_parallel_poll_response(gpib_board_t *board, int ist); +void ines_serial_poll_response(gpib_board_t *board, uint8_t status); +uint8_t ines_serial_poll_status(gpib_board_t *board); +int ines_line_status(const gpib_board_t *board); +unsigned int ines_t1_delay(gpib_board_t *board, unsigned int nano_sec); +void ines_return_to_local(gpib_board_t *board); + +// interrupt service routines +irqreturn_t ines_pci_interrupt(int irq, void *arg); +irqreturn_t ines_interrupt(gpib_board_t *board); + +// utility functions +void ines_free_private(gpib_board_t *board); +int ines_generic_attach(gpib_board_t *board); +void ines_online(struct ines_priv *priv, const gpib_board_t *board, int use_accel); +void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count); + +/* inb/outb wrappers */ +static inline unsigned int ines_inb(struct ines_priv *priv, unsigned int register_number) +{ + return inb((unsigned long)(priv->nec7210_priv.iobase) + + register_number * priv->nec7210_priv.offset); +} + +static inline void ines_outb(struct ines_priv *priv, unsigned int value, + unsigned int register_number) +{ + outb(value, (unsigned long)(priv->nec7210_priv.iobase) + + register_number * priv->nec7210_priv.offset); +} + +// pcmcia init/cleanup + +int ines_pcmcia_init_module(void); +void ines_pcmcia_cleanup_module(void); + +enum ines_regs { + // read + FIFO_STATUS = 0x8, + ISR3 = 0x9, + ISR4 = 0xa, + IN_FIFO_COUNT = 0x10, + OUT_FIFO_COUNT = 0x11, + EXTEND_STATUS = 0xf, + + // write + XDMA_CONTROL = 0x8, + IMR3 = ISR3, + IMR4 = ISR4, + IN_FIFO_WATERMARK = IN_FIFO_COUNT, + OUT_FIFO_WATERMARK = OUT_FIFO_COUNT, + EXTEND_MODE = 0xf, + + // read-write + XFER_COUNT_LOWER = 0xb, + XFER_COUNT_UPPER = 0xc, + BUS_CONTROL_MONITOR = 0x13, +}; + +enum isr3_imr3_bits { + HW_TIMEOUT_BIT = 0x1, + XFER_COUNT_BIT = 0x2, + CMD_RECEIVED_BIT = 0x4, + TCT_RECEIVED_BIT = 0x8, + IFC_ACTIVE_BIT = 0x10, + ATN_ACTIVE_BIT = 0x20, + FIFO_ERROR_BIT = 0x40, +}; + +enum isr4_imr4_bits { + IN_FIFO_WATERMARK_BIT = 0x1, + OUT_FIFO_WATERMARK_BIT = 0x2, + IN_FIFO_FULL_BIT = 0x4, + OUT_FIFO_EMPTY_BIT = 0x8, + IN_FIFO_READY_BIT = 0x10, + OUT_FIFO_READY_BIT = 0x20, + IN_FIFO_EXIT_WATERMARK_BIT = 0x40, + OUT_FIFO_EXIT_WATERMARK_BIT = 0x80, +}; + +enum extend_mode_bits { + TR3_TRIG_ENABLE_BIT = 0x1, // enable generation of trigger pulse T/R3 pin + // clear message available status bit when chip writes byte with EOI true + MAV_ENABLE_BIT = 0x2, + EOS1_ENABLE_BIT = 0x4, // enable eos register 1 + EOS2_ENABLE_BIT = 0x8, // enable eos register 2 + EOIDIS_BIT = 0x10, // disable EOI interrupt when doing rfd holdoff on end? + XFER_COUNTER_ENABLE_BIT = 0x20, + XFER_COUNTER_OUTPUT_BIT = 0x40, // use counter for output, clear for input + // when xfer counter hits 0, assert EOI on write or RFD holdoff on read + LAST_BYTE_HANDLING_BIT = 0x80, +}; + +enum extend_status_bits { + OUTPUT_MESSAGE_IN_PROGRESS_BIT = 0x1, + SCSEL_BIT = 0x2, // statue of SCSEL pin + LISTEN_DISABLED = 0x4, + IN_FIFO_EMPTY_BIT = 0x8, + OUT_FIFO_FULL_BIT = 0x10, +}; + +// ines adds fifo enable bits to address mode register +enum ines_admr_bits { + IN_FIFO_ENABLE_BIT = 0x8, + OUT_FIFO_ENABLE_BIT = 0x4, +}; + +enum xdma_control_bits { + DMA_OUTPUT_BIT = 0x1, // use dma for output, clear for input + ENABLE_SYNC_DMA_BIT = 0x2, + DMA_ACCESS_EVERY_CYCLE = 0x4,// dma accesses fifo every cycle, clear for every other cycle + DMA_16BIT = 0x8, // clear for 8 bit transfers +}; + +enum bus_control_monitor_bits { + BCM_DAV_BIT = 0x1, + BCM_NRFD_BIT = 0x2, + BCM_NDAC_BIT = 0x4, + BCM_IFC_BIT = 0x8, + BCM_ATN_BIT = 0x10, + BCM_SRQ_BIT = 0x20, + BCM_REN_BIT = 0x40, + BCM_EOI_BIT = 0x80, +}; + +enum ines_aux_reg_bits { + INES_AUXD = 0x40, +}; + +enum ines_aux_cmds { + INES_RFD_HLD_IMMEDIATE = 0x4, + INES_AUX_CLR_OUT_FIFO = 0x5, + INES_AUX_CLR_IN_FIFO = 0x6, + INES_AUX_XMODE = 0xa, +}; + +enum ines_auxd_bits { + INES_FOLLOWING_T1_MASK = 0x3, + INES_FOLLOWING_T1_500ns = 0x0, + INES_FOLLOWING_T1_350ns = 0x1, + INES_FOLLOWING_T1_250ns = 0x2, + INES_INITIAL_TI_MASK = 0xc, + INES_INITIAL_T1_2000ns = 0x0, + INES_INITIAL_T1_1100ns = 0x4, + INES_INITIAL_T1_700ns = 0x8, + INES_T6_2us = 0x0, + INES_T6_50us = 0x10, +}; + +#endif // _INES_GPIB_H diff --git a/drivers/staging/gpib/ines/ines_gpib.c b/drivers/staging/gpib/ines/ines_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..9d8387c3bf019bd36a68da540a3ea5d27f40f7cf --- /dev/null +++ b/drivers/staging/gpib/ines/ines_gpib.c @@ -0,0 +1,1464 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 1999 Axel Dziemba (axel.dziemba@ines.de) + * (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#include "ines.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gpib_pci_ids.h" + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for Ines iGPIB 72010"); + +int ines_line_status(const gpib_board_t *board) +{ + int status = ValidALL; + int bcm_bits; + struct ines_priv *ines_priv; + struct nec7210_priv *nec_priv; + + ines_priv = board->private_data; + nec_priv = &ines_priv->nec7210_priv; + + bcm_bits = ines_inb(ines_priv, BUS_CONTROL_MONITOR); + + if (bcm_bits & BCM_REN_BIT) + status |= BusREN; + if (bcm_bits & BCM_IFC_BIT) + status |= BusIFC; + if (bcm_bits & BCM_SRQ_BIT) + status |= BusSRQ; + if (bcm_bits & BCM_EOI_BIT) + status |= BusEOI; + if (bcm_bits & BCM_NRFD_BIT) + status |= BusNRFD; + if (bcm_bits & BCM_NDAC_BIT) + status |= BusNDAC; + if (bcm_bits & BCM_DAV_BIT) + status |= BusDAV; + if (bcm_bits & BCM_ATN_BIT) + status |= BusATN; + + return status; +} + +void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count) +{ + if (count > 0xffff) { + pr_err("ines: bug! tried to set xfer counter > 0xffff\n"); + return; + } + ines_outb(priv, (count >> 8) & 0xff, XFER_COUNT_UPPER); + ines_outb(priv, count & 0xff, XFER_COUNT_LOWER); +} + +unsigned int ines_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct ines_priv *ines_priv = board->private_data; + struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; + unsigned int retval; + + retval = nec7210_t1_delay(board, nec_priv, nano_sec); + + if (nano_sec <= 250) { + write_byte(nec_priv, INES_AUXD | INES_FOLLOWING_T1_250ns | + INES_INITIAL_T1_2000ns, AUXMR); + retval = 250; + } else if (nano_sec <= 350) { + write_byte(nec_priv, INES_AUXD | INES_FOLLOWING_T1_350ns | + INES_INITIAL_T1_2000ns, AUXMR); + retval = 350; + } else { + write_byte(nec_priv, INES_AUXD | INES_FOLLOWING_T1_500ns | + INES_INITIAL_T1_2000ns, AUXMR); + retval = 500; + } + + return retval; +} + +static inline unsigned short num_in_fifo_bytes(struct ines_priv *ines_priv) +{ + return ines_inb(ines_priv, IN_FIFO_COUNT); +} + +static ssize_t pio_read(gpib_board_t *board, struct ines_priv *ines_priv, uint8_t *buffer, + size_t length, size_t *nbytes) +{ + ssize_t retval = 0; + unsigned int num_fifo_bytes, i; + struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; + + *nbytes = 0; + while (*nbytes < length) { + if (wait_event_interruptible(board->wait, + num_in_fifo_bytes(ines_priv) || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_warn("gpib: pio read wait interrupted\n"); + return -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + return -ETIMEDOUT; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) + return -EINTR; + + num_fifo_bytes = num_in_fifo_bytes(ines_priv); + if (num_fifo_bytes + *nbytes > length) { + pr_warn("ines: counter allowed %li extra byte(s)\n", + (long)(num_fifo_bytes - (length - *nbytes))); + num_fifo_bytes = length - *nbytes; + } + for (i = 0; i < num_fifo_bytes; i++) + buffer[(*nbytes)++] = read_byte(nec_priv, DIR); + if (test_bit(RECEIVED_END_BN, &nec_priv->state) && + num_in_fifo_bytes(ines_priv) == 0) + break; + if (need_resched()) + schedule(); + } + /* make sure RECEIVED_END is in sync */ + ines_interrupt(board); + return retval; +} + +int ines_accel_read(gpib_board_t *board, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + ssize_t retval = 0; + struct ines_priv *ines_priv = board->private_data; + struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; + int counter_setting; + + *end = 0; + *bytes_read = 0; + if (length == 0) + return 0; + + clear_bit(DEV_CLEAR_BN, &nec_priv->state); + + write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR); + + //clear in fifo + nec7210_set_reg_bits(nec_priv, ADMR, IN_FIFO_ENABLE_BIT, 0); + nec7210_set_reg_bits(nec_priv, ADMR, IN_FIFO_ENABLE_BIT, IN_FIFO_ENABLE_BIT); + + ines_priv->extend_mode_bits |= LAST_BYTE_HANDLING_BIT; + ines_priv->extend_mode_bits &= ~XFER_COUNTER_OUTPUT_BIT & ~XFER_COUNTER_ENABLE_BIT; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + + counter_setting = length - num_in_fifo_bytes(ines_priv); + if (counter_setting > 0) { + ines_set_xfer_counter(ines_priv, length); + ines_priv->extend_mode_bits |= XFER_COUNTER_ENABLE_BIT; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + + // holdoff on END + nec7210_set_handshake_mode(board, nec_priv, HR_HLDE); + /* release rfd holdoff */ + write_byte(nec_priv, AUX_FH, AUXMR); + } + + retval = pio_read(board, ines_priv, buffer, length, bytes_read); + ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + if (retval < 0) { + write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR); + return retval; + } + if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) + *end = 1; + + return retval; +} + +static const int out_fifo_size = 0xff; + +static inline unsigned short num_out_fifo_bytes(struct ines_priv *ines_priv) +{ + return ines_inb(ines_priv, OUT_FIFO_COUNT); +} + +static int ines_write_wait(gpib_board_t *board, struct ines_priv *ines_priv, + unsigned int fifo_threshold) +{ + struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; + + // wait until byte is ready to be sent + if (wait_event_interruptible(board->wait, + num_out_fifo_bytes(ines_priv) < fifo_threshold || + test_bit(BUS_ERROR_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted\n"); + return -ERESTARTSYS; + } + if (test_bit(BUS_ERROR_BN, &nec_priv->state)) + return -EIO; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) + return -EINTR; + if (test_bit(TIMO_NUM, &board->status)) + return -ETIMEDOUT; + + return 0; +} + +int ines_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + size_t count = 0; + ssize_t retval = 0; + struct ines_priv *ines_priv = board->private_data; + struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; + unsigned int num_bytes, i; + + *bytes_written = 0; + //clear out fifo + nec7210_set_reg_bits(nec_priv, ADMR, OUT_FIFO_ENABLE_BIT, 0); + nec7210_set_reg_bits(nec_priv, ADMR, OUT_FIFO_ENABLE_BIT, OUT_FIFO_ENABLE_BIT); + + ines_priv->extend_mode_bits |= XFER_COUNTER_OUTPUT_BIT; + ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT; + ines_priv->extend_mode_bits &= ~LAST_BYTE_HANDLING_BIT; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + + ines_set_xfer_counter(ines_priv, length); + if (send_eoi) + ines_priv->extend_mode_bits |= LAST_BYTE_HANDLING_BIT; + ines_priv->extend_mode_bits |= XFER_COUNTER_ENABLE_BIT; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + + while (count < length) { + retval = ines_write_wait(board, ines_priv, out_fifo_size); + if (retval < 0) + break; + + num_bytes = out_fifo_size - num_out_fifo_bytes(ines_priv); + if (num_bytes + count > length) + num_bytes = length - count; + for (i = 0; i < num_bytes; i++) + write_byte(nec_priv, buffer[count++], CDOR); + } + if (retval < 0) { + ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + *bytes_written = length - num_out_fifo_bytes(ines_priv); + return retval; + } + // wait last byte has been sent + retval = ines_write_wait(board, ines_priv, 1); + ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + *bytes_written = length - num_out_fifo_bytes(ines_priv); + + return retval; +} + +irqreturn_t ines_pci_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + struct ines_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + + if (priv->pci_chip_type == PCI_CHIP_QUANCOM) { + if ((inb((unsigned long)nec_priv->iobase + + QUANCOM_IRQ_CONTROL_STATUS_REG) & + QUANCOM_IRQ_ASSERTED_BIT)) + outb(QUANCOM_IRQ_ENABLE_BIT, (unsigned long)(nec_priv->iobase) + + QUANCOM_IRQ_CONTROL_STATUS_REG); + } + + return ines_interrupt(board); +} + +irqreturn_t ines_interrupt(gpib_board_t *board) +{ + struct ines_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + unsigned int isr3_bits, isr4_bits; + unsigned long flags; + int wake = 0; + + spin_lock_irqsave(&board->spinlock, flags); + + nec7210_interrupt(board, nec_priv); + isr3_bits = ines_inb(priv, ISR3); + isr4_bits = ines_inb(priv, ISR4); + if (isr3_bits & IFC_ACTIVE_BIT) { + push_gpib_event(board, EventIFC); + wake++; + } + if (isr3_bits & FIFO_ERROR_BIT) + pr_err("ines gpib: fifo error\n"); + if (isr3_bits & XFER_COUNT_BIT) + wake++; + + if (isr4_bits & (IN_FIFO_WATERMARK_BIT | IN_FIFO_FULL_BIT | OUT_FIFO_WATERMARK_BIT | + OUT_FIFO_EMPTY_BIT)) + wake++; + + if (wake) + wake_up_interruptible(&board->wait); + spin_unlock_irqrestore(&board->spinlock, flags); + return IRQ_HANDLED; +} + +static int ines_pci_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int ines_pci_accel_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int ines_isa_attach(gpib_board_t *board, const gpib_board_config_t *config); + +static void ines_pci_detach(gpib_board_t *board); +static void ines_isa_detach(gpib_board_t *board); + +enum ines_pci_vendor_ids { + PCI_VENDOR_ID_INES_QUICKLOGIC = 0x16da +}; + +enum ines_pci_device_ids { + PCI_DEVICE_ID_INES_GPIB_AMCC = 0x8507, + PCI_DEVICE_ID_INES_GPIB_QL5030 = 0x11, +}; + +enum ines_pci_subdevice_ids { + PCI_SUBDEVICE_ID_INES_GPIB = 0x1072 +}; + +static struct pci_device_id ines_pci_table[] = { + {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX, + PCI_SUBDEVICE_ID_INES_GPIB, 0, 0, 0}, + {PCI_VENDOR_ID_AMCC, PCI_DEVICE_ID_INES_GPIB_AMCC, PCI_VENDOR_ID_AMCC, + PCI_SUBDEVICE_ID_INES_GPIB, 0, 0, 0}, + {PCI_VENDOR_ID_INES_QUICKLOGIC, PCI_DEVICE_ID_INES_GPIB_QL5030, + PCI_VENDOR_ID_INES_QUICKLOGIC, PCI_DEVICE_ID_INES_GPIB_QL5030, 0, 0, 0}, + {PCI_DEVICE(PCI_VENDOR_ID_QUANCOM, PCI_DEVICE_ID_QUANCOM_GPIB)}, + {0} +}; +MODULE_DEVICE_TABLE(pci, ines_pci_table); + +struct ines_pci_id { + unsigned int vendor_id; + unsigned int device_id; + int subsystem_vendor_id; + int subsystem_device_id; + unsigned int gpib_region; + unsigned int io_offset; + enum ines_pci_chip pci_chip_type; +}; + +struct ines_pci_id pci_ids[] = { + {vendor_id: PCI_VENDOR_ID_PLX, + device_id : PCI_DEVICE_ID_PLX_9050, + subsystem_vendor_id : PCI_VENDOR_ID_PLX, + subsystem_device_id : PCI_SUBDEVICE_ID_INES_GPIB, + gpib_region : 2, + io_offset : 1, + pci_chip_type : PCI_CHIP_PLX9050, + }, + {vendor_id: PCI_VENDOR_ID_AMCC, + device_id : PCI_DEVICE_ID_INES_GPIB_AMCC, + subsystem_vendor_id : PCI_VENDOR_ID_AMCC, + subsystem_device_id : PCI_SUBDEVICE_ID_INES_GPIB, + gpib_region : 1, + io_offset : 1, + pci_chip_type : PCI_CHIP_AMCC5920, + }, + {vendor_id: PCI_VENDOR_ID_INES_QUICKLOGIC, + device_id : PCI_DEVICE_ID_INES_GPIB_QL5030, + subsystem_vendor_id : PCI_VENDOR_ID_INES_QUICKLOGIC, + subsystem_device_id : PCI_DEVICE_ID_INES_GPIB_QL5030, + gpib_region : 1, + io_offset : 1, + pci_chip_type : PCI_CHIP_QUICKLOGIC5030, + }, + {vendor_id: PCI_VENDOR_ID_QUANCOM, + device_id : PCI_DEVICE_ID_QUANCOM_GPIB, + subsystem_vendor_id : -1, + subsystem_device_id : -1, + gpib_region : 0, + io_offset : 4, + pci_chip_type : PCI_CHIP_QUANCOM, + }, +}; + +static const int num_pci_chips = ARRAY_SIZE(pci_ids); + +// wrappers for interface functions +int ines_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read) +{ + struct ines_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + ssize_t retval; + int dummy; + + retval = nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); + if (retval < 0) { + write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR); + + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + + nec7210_read_data_in(board, nec_priv, &dummy); + } + return retval; +} + +int ines_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); +} + +int ines_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); +} + +int ines_take_control(gpib_board_t *board, int synchronous) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_take_control(board, &priv->nec7210_priv, synchronous); +} + +int ines_go_to_standby(gpib_board_t *board) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_go_to_standby(board, &priv->nec7210_priv); +} + +void ines_request_system_control(gpib_board_t *board, int request_control) +{ + struct ines_priv *priv = board->private_data; + + nec7210_request_system_control(board, &priv->nec7210_priv, request_control); +} + +void ines_interface_clear(gpib_board_t *board, int assert) +{ + struct ines_priv *priv = board->private_data; + + nec7210_interface_clear(board, &priv->nec7210_priv, assert); +} + +void ines_remote_enable(gpib_board_t *board, int enable) +{ + struct ines_priv *priv = board->private_data; + + nec7210_remote_enable(board, &priv->nec7210_priv, enable); +} + +int ines_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); +} + +void ines_disable_eos(gpib_board_t *board) +{ + struct ines_priv *priv = board->private_data; + + nec7210_disable_eos(board, &priv->nec7210_priv); +} + +unsigned int ines_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); +} + +int ines_primary_address(gpib_board_t *board, unsigned int address) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_primary_address(board, &priv->nec7210_priv, address); +} + +int ines_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); +} + +int ines_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_parallel_poll(board, &priv->nec7210_priv, result); +} + +void ines_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + struct ines_priv *priv = board->private_data; + + nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config); +} + +void ines_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct ines_priv *priv = board->private_data; + + nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); +} + +void ines_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct ines_priv *priv = board->private_data; + + nec7210_serial_poll_response(board, &priv->nec7210_priv, status); +} + +uint8_t ines_serial_poll_status(gpib_board_t *board) +{ + struct ines_priv *priv = board->private_data; + + return nec7210_serial_poll_status(board, &priv->nec7210_priv); +} + +void ines_return_to_local(gpib_board_t *board) +{ + struct ines_priv *priv = board->private_data; + + nec7210_return_to_local(board, &priv->nec7210_priv); +} + +gpib_interface_t ines_pci_unaccel_interface = { +name: "ines_pci_unaccel", +attach : ines_pci_attach, +detach : ines_pci_detach, +read : ines_read, +write : ines_write, +command : ines_command, +take_control : ines_take_control, +go_to_standby : ines_go_to_standby, +request_system_control : ines_request_system_control, +interface_clear : ines_interface_clear, +remote_enable : ines_remote_enable, +enable_eos : ines_enable_eos, +disable_eos : ines_disable_eos, +parallel_poll : ines_parallel_poll, +parallel_poll_configure : ines_parallel_poll_configure, +parallel_poll_response : ines_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ines_line_status, +update_status : ines_update_status, +primary_address : ines_primary_address, +secondary_address : ines_secondary_address, +serial_poll_response : ines_serial_poll_response, +serial_poll_status : ines_serial_poll_status, +t1_delay : ines_t1_delay, +return_to_local : ines_return_to_local, +}; + +gpib_interface_t ines_pci_interface = { +name: "ines_pci", +attach : ines_pci_accel_attach, +detach : ines_pci_detach, +read : ines_accel_read, +write : ines_accel_write, +command : ines_command, +take_control : ines_take_control, +go_to_standby : ines_go_to_standby, +request_system_control : ines_request_system_control, +interface_clear : ines_interface_clear, +remote_enable : ines_remote_enable, +enable_eos : ines_enable_eos, +disable_eos : ines_disable_eos, +parallel_poll : ines_parallel_poll, +parallel_poll_configure : ines_parallel_poll_configure, +parallel_poll_response : ines_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ines_line_status, +update_status : ines_update_status, +primary_address : ines_primary_address, +secondary_address : ines_secondary_address, +serial_poll_response : ines_serial_poll_response, +serial_poll_status : ines_serial_poll_status, +t1_delay : ines_t1_delay, +return_to_local : ines_return_to_local, +}; + +gpib_interface_t ines_pci_accel_interface = { +name: "ines_pci_accel", +attach : ines_pci_accel_attach, +detach : ines_pci_detach, +read : ines_accel_read, +write : ines_accel_write, +command : ines_command, +take_control : ines_take_control, +go_to_standby : ines_go_to_standby, +request_system_control : ines_request_system_control, +interface_clear : ines_interface_clear, +remote_enable : ines_remote_enable, +enable_eos : ines_enable_eos, +disable_eos : ines_disable_eos, +parallel_poll : ines_parallel_poll, +parallel_poll_configure : ines_parallel_poll_configure, +parallel_poll_response : ines_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ines_line_status, +update_status : ines_update_status, +primary_address : ines_primary_address, +secondary_address : ines_secondary_address, +serial_poll_response : ines_serial_poll_response, +serial_poll_status : ines_serial_poll_status, +t1_delay : ines_t1_delay, +return_to_local : ines_return_to_local, +}; + +gpib_interface_t ines_isa_interface = { +name: "ines_isa", +attach : ines_isa_attach, +detach : ines_isa_detach, +read : ines_accel_read, +write : ines_accel_write, +command : ines_command, +take_control : ines_take_control, +go_to_standby : ines_go_to_standby, +request_system_control : ines_request_system_control, +interface_clear : ines_interface_clear, +remote_enable : ines_remote_enable, +enable_eos : ines_enable_eos, +disable_eos : ines_disable_eos, +parallel_poll : ines_parallel_poll, +parallel_poll_configure : ines_parallel_poll_configure, +parallel_poll_response : ines_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ines_line_status, +update_status : ines_update_status, +primary_address : ines_primary_address, +secondary_address : ines_secondary_address, +serial_poll_response : ines_serial_poll_response, +serial_poll_status : ines_serial_poll_status, +t1_delay : ines_t1_delay, +return_to_local : ines_return_to_local, +}; + +static int ines_allocate_private(gpib_board_t *board) +{ + struct ines_priv *priv; + + board->private_data = kmalloc(sizeof(struct ines_priv), GFP_KERNEL); + if (!board->private_data) + return -1; + priv = board->private_data; + memset(priv, 0, sizeof(struct ines_priv)); + init_nec7210_private(&priv->nec7210_priv); + return 0; +} + +void ines_free_private(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +int ines_generic_attach(gpib_board_t *board) +{ + struct ines_priv *ines_priv; + struct nec7210_priv *nec_priv; + + board->status = 0; + + if (ines_allocate_private(board)) + return -ENOMEM; + ines_priv = board->private_data; + nec_priv = &ines_priv->nec7210_priv; + nec_priv->read_byte = nec7210_ioport_read_byte; + nec_priv->write_byte = nec7210_ioport_write_byte; + nec_priv->offset = 1; + nec_priv->type = IGPIB7210; + ines_priv->pci_chip_type = PCI_CHIP_NONE; + + return 0; +} + +void ines_online(struct ines_priv *ines_priv, const gpib_board_t *board, int use_accel) +{ + struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv; + + /* ines doesn't seem to use internal count register */ + write_byte(nec_priv, ICR | 0, AUXMR); + + write_byte(nec_priv, INES_AUX_XMODE, AUXMR); + write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR); + + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + + write_byte(nec_priv, INES_AUXD | 0, AUXMR); + ines_outb(ines_priv, 0, XDMA_CONTROL); + ines_priv->extend_mode_bits = 0; + ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE); + if (use_accel) { + ines_outb(ines_priv, 0x80, OUT_FIFO_WATERMARK); + ines_outb(ines_priv, 0x80, IN_FIFO_WATERMARK); + ines_outb(ines_priv, IFC_ACTIVE_BIT | ATN_ACTIVE_BIT | + FIFO_ERROR_BIT | XFER_COUNT_BIT, IMR3); + ines_outb(ines_priv, IN_FIFO_WATERMARK_BIT | IN_FIFO_FULL_BIT | + OUT_FIFO_WATERMARK_BIT | OUT_FIFO_EMPTY_BIT, IMR4); + } else { + nec7210_set_reg_bits(nec_priv, ADMR, IN_FIFO_ENABLE_BIT | OUT_FIFO_ENABLE_BIT, 0); + ines_outb(ines_priv, IFC_ACTIVE_BIT | FIFO_ERROR_BIT, IMR3); + ines_outb(ines_priv, 0, IMR4); + } + + nec7210_board_online(nec_priv, board); + if (use_accel) + nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, 0); +} + +static int ines_common_pci_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct ines_priv *ines_priv; + struct nec7210_priv *nec_priv; + int isr_flags = 0; + int retval; + struct ines_pci_id found_id; + unsigned int i; + struct pci_dev *pdev; + + memset(&found_id, 0, sizeof(found_id)); + + retval = ines_generic_attach(board); + if (retval) + return retval; + + ines_priv = board->private_data; + nec_priv = &ines_priv->nec7210_priv; + + // find board + ines_priv->pci_device = NULL; + for (i = 0; i < num_pci_chips && !ines_priv->pci_device; i++) { + pdev = NULL; + do { + if (pci_ids[i].subsystem_vendor_id >= 0 && + pci_ids[i].subsystem_device_id >= 0) + pdev = pci_get_subsys(pci_ids[i].vendor_id, pci_ids[i].device_id, + pci_ids[i].subsystem_vendor_id, + pci_ids[i].subsystem_device_id, pdev); + else + pdev = pci_get_device(pci_ids[i].vendor_id, pci_ids[i].device_id, + pdev); + if (!pdev) + break; + if (config->pci_bus >= 0 && config->pci_bus != pdev->bus->number) + continue; + if (config->pci_slot >= 0 && config->pci_slot != PCI_SLOT(pdev->devfn)) + continue; + found_id = pci_ids[i]; + ines_priv->pci_device = pdev; + break; + } while (1); + } + if (!ines_priv->pci_device) { + pr_err("gpib: could not find ines PCI board\n"); + return -1; + } + + if (pci_enable_device(ines_priv->pci_device)) { + pr_err("error enabling pci device\n"); + return -1; + } + + if (pci_request_regions(ines_priv->pci_device, "ines-gpib")) + return -1; + nec_priv->iobase = (void *)(pci_resource_start(ines_priv->pci_device, + found_id.gpib_region)); + + ines_priv->pci_chip_type = found_id.pci_chip_type; + nec_priv->offset = found_id.io_offset; + switch (ines_priv->pci_chip_type) { + case PCI_CHIP_PLX9050: + ines_priv->plx_iobase = pci_resource_start(ines_priv->pci_device, 1); + break; + case PCI_CHIP_AMCC5920: + ines_priv->amcc_iobase = pci_resource_start(ines_priv->pci_device, 0); + break; + case PCI_CHIP_QUANCOM: + break; + case PCI_CHIP_QUICKLOGIC5030: + break; + default: + pr_err("gpib: unspecified chip type? (bug)\n"); + nec_priv->iobase = 0; + pci_release_regions(ines_priv->pci_device); + return -1; + } + + nec7210_board_reset(nec_priv, board); +#ifdef QUANCOM_PCI + if (ines_priv->pci_chip_type == PCI_CHIP_QUANCOM) { + /* change interrupt polarity */ + nec_priv->auxb_bits |= HR_INV; + ines_outb(ines_priv, nec_priv->auxb_bits, AUXMR); + } +#endif + isr_flags |= IRQF_SHARED; + if (request_irq(ines_priv->pci_device->irq, ines_pci_interrupt, isr_flags, + "pci-gpib", board)) { + pr_err("gpib: can't request IRQ %d\n", ines_priv->pci_device->irq); + return -1; + } + ines_priv->irq = ines_priv->pci_device->irq; + + // enable interrupts on pci chip + switch (ines_priv->pci_chip_type) { + case PCI_CHIP_PLX9050: + outl(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR1_POLARITY_BIT | PLX9050_PCI_INTR_EN_BIT, + ines_priv->plx_iobase + PLX9050_INTCSR_REG); + break; + case PCI_CHIP_AMCC5920: + { + static const int region = 1; + static const int num_wait_states = 7; + u32 bits; + + bits = amcc_prefetch_bits(region, PREFETCH_DISABLED); + bits |= amcc_PTADR_mode_bit(region); + bits |= amcc_disable_write_fifo_bit(region); + bits |= amcc_wait_state_bits(region, num_wait_states); + outl(bits, ines_priv->amcc_iobase + AMCC_PASS_THRU_REG); + outl(AMCC_ADDON_INTR_ENABLE_BIT, ines_priv->amcc_iobase + AMCC_INTCS_REG); + } + break; + case PCI_CHIP_QUANCOM: + outb(QUANCOM_IRQ_ENABLE_BIT, (unsigned long)(nec_priv->iobase) + + QUANCOM_IRQ_CONTROL_STATUS_REG); + break; + case PCI_CHIP_QUICKLOGIC5030: + break; + default: + pr_err("gpib: unspecified chip type? (bug)\n"); + return -1; + } + + return 0; +} + +int ines_pci_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct ines_priv *ines_priv; + int retval; + + retval = ines_common_pci_attach(board, config); + if (retval < 0) + return retval; + + ines_priv = board->private_data; + ines_online(ines_priv, board, 0); + + return 0; +} + +int ines_pci_accel_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct ines_priv *ines_priv; + int retval; + + retval = ines_common_pci_attach(board, config); + if (retval < 0) + return retval; + + ines_priv = board->private_data; + ines_online(ines_priv, board, 1); + + return 0; +} + +static const int ines_isa_iosize = 0x20; + +int ines_isa_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct ines_priv *ines_priv; + struct nec7210_priv *nec_priv; + int isr_flags = 0; + int retval; + + retval = ines_generic_attach(board); + if (retval) + return retval; + + ines_priv = board->private_data; + nec_priv = &ines_priv->nec7210_priv; + + if (!request_region((unsigned long)config->ibbase, ines_isa_iosize, "ines_gpib")) { + pr_err("ines_gpib: ioports at 0x%p already in use\n", config->ibbase); + return -1; + } + nec_priv->iobase = config->ibbase; + nec_priv->offset = 1; + nec7210_board_reset(nec_priv, board); + if (request_irq(config->ibirq, ines_pci_interrupt, isr_flags, "ines_gpib", board)) { + pr_err("ines_gpib: failed to allocate IRQ %d\n", config->ibirq); + return -1; + } + ines_priv->irq = config->ibirq; + ines_online(ines_priv, board, 1); + return 0; +} + +void ines_pci_detach(gpib_board_t *board) +{ + struct ines_priv *ines_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (ines_priv) { + nec_priv = &ines_priv->nec7210_priv; + if (ines_priv->irq) { + // disable interrupts + switch (ines_priv->pci_chip_type) { + case PCI_CHIP_AMCC5920: + if (ines_priv->plx_iobase) + outl(0, ines_priv->plx_iobase + PLX9050_INTCSR_REG); + break; + case PCI_CHIP_QUANCOM: + if (nec_priv->iobase) + outb(0, (unsigned long)(nec_priv->iobase) + + QUANCOM_IRQ_CONTROL_STATUS_REG); + break; + default: + break; + } + free_irq(ines_priv->irq, board); + } + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + pci_release_regions(ines_priv->pci_device); + } + if (ines_priv->pci_device) + pci_dev_put(ines_priv->pci_device); + } + ines_free_private(board); +} + +void ines_isa_detach(gpib_board_t *board) +{ + struct ines_priv *ines_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (ines_priv) { + nec_priv = &ines_priv->nec7210_priv; + if (ines_priv->irq) + free_irq(ines_priv->irq, board); + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + release_region((unsigned long)(nec_priv->iobase), ines_isa_iosize); + } + } + ines_free_private(board); +} + +static int ines_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return 0; +} + +static struct pci_driver ines_pci_driver = { + .name = "ines_gpib", + .id_table = ines_pci_table, + .probe = &ines_pci_probe +}; + +#ifdef GPIB_PCMCIA + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +#define DEBUG(n, args...) do {if (pc_debug > (n)) pr_debug(args)} while (0) +#else +#define DEBUG(args...) +#endif + +static const int ines_pcmcia_iosize = 0x20; + +/* The event() function is this driver's Card Services event handler. + * It will be called by Card Services when an appropriate card status + * event is received. The config() and release() entry points are + * used to configure or release a socket, in response to card insertion + * and ejection events. They are invoked from the gpib event + * handler. + */ + +static int ines_gpib_config(struct pcmcia_device *link); +static void ines_gpib_release(struct pcmcia_device *link); +static int ines_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int ines_pcmcia_accel_attach(gpib_board_t *board, const gpib_board_config_t *config); +static void ines_pcmcia_detach(gpib_board_t *board); +static irqreturn_t ines_pcmcia_interrupt(int irq, void *arg); +static int ines_common_pcmcia_attach(gpib_board_t *board); +/* + * A linked list of "instances" of the gpib device. Each actual + * PCMCIA card corresponds to one device instance, and is described + * by one dev_link_t structure (defined in ds.h). + * + * You may not want to use a linked list for this -- for example, the + * memory card driver uses an array of dev_link_t pointers, where minor + * device numbers are used to derive the corresponding array index. + */ + +static struct pcmcia_device *curr_dev; + +/* + * A dev_link_t structure has fields for most things that are needed + * to keep track of a socket, but there will usually be some device + * specific information that also needs to be kept track of. The + * 'priv' pointer in a dev_link_t structure can be used to point to + * a device-specific private data structure, like this. + * + * A driver needs to provide a dev_node_t structure for each device + * on a card. In some cases, there is only one device per card (for + * example, ethernet cards, modems). In other cases, there may be + * many actual or logical devices (SCSI adapters, memory cards with + * multiple partitions). The dev_node_t structures need to be kept + * in a linked list starting at the 'dev' field of a dev_link_t + * structure. We allocate them in the card's private data structure, + * because they generally can't be allocated dynamically. + */ + +struct local_info { + struct pcmcia_device *p_dev; + gpib_board_t *dev; + u_short manfid; + u_short cardid; +}; + +/* + * gpib_attach() creates an "instance" of the driver, allocating + * local data structures for one device. The device is registered + * with Card Services. + * + * The dev_link structure is initialized, but we don't actually + * configure the card at this point -- we wait until we receive a + * card insertion event. + */ +static int ines_gpib_probe(struct pcmcia_device *link) +{ + struct local_info *info; + +// int ret, i; + + DEBUG(0, "%s(0x%p)\n", __func__ link); + + /* Allocate space for private device-specific data */ + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->p_dev = link; + link->priv = info; + + /* The io structure describes IO port mapping */ + link->resource[0]->end = 32; + link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->io_lines = 5; + + /* General socket configuration */ + link->config_flags = CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; + + /* Register with Card Services */ + curr_dev = link; + return ines_gpib_config(link); +} + +/* + * This deletes a driver "instance". The device is de-registered + * with Card Services. If it has been released, all local data + * structures are freed. Otherwise, the structures will be freed + * when the device is released. + */ +static void ines_gpib_remove(struct pcmcia_device *link) +{ + struct local_info *info = link->priv; + //struct gpib_board_t *dev = info->dev; + + DEBUG(0, "%s(0x%p)\n", __func__, link); + + if (info->dev) + ines_pcmcia_detach(info->dev); + ines_gpib_release(link); + + //free_netdev(dev); + kfree(info); +} + +static int ines_gpib_config_iteration(struct pcmcia_device *link, void *priv_data) +{ + return pcmcia_request_io(link); +} + +/* + * gpib_config() is scheduled to run after a CARD_INSERTION event + * is received, to configure the PCMCIA socket, and to make the + * device available to the system. + */ +static int ines_gpib_config(struct pcmcia_device *link) +{ + struct local_info *dev; + int retval; + void *virt; + + dev = link->priv; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + retval = pcmcia_loop_config(link, &ines_gpib_config_iteration, NULL); + if (retval) { + dev_warn(&link->dev, "no configuration found\n"); + ines_gpib_release(link); + return -ENODEV; + } + + pr_debug("ines_cs: manufacturer: 0x%x card: 0x%x\n", + link->manf_id, link->card_id); + + /* for the ines card we have to setup the configuration registers in + * attribute memory here + */ + link->resource[2]->flags |= WIN_MEMORY_TYPE_AM | WIN_DATA_WIDTH_8 | WIN_ENABLE; + link->resource[2]->end = 0x1000; + retval = pcmcia_request_window(link, link->resource[2], 250); + if (retval) { + dev_warn(&link->dev, "pcmcia_request_window failed\n"); + ines_gpib_release(link); + return -ENODEV; + } + retval = pcmcia_map_mem_page(link, link->resource[2], 0); + if (retval) { + dev_warn(&link->dev, "pcmcia_map_mem_page failed\n"); + ines_gpib_release(link); + return -ENODEV; + } + virt = ioremap(link->resource[2]->start, resource_size(link->resource[2])); + writeb((link->resource[2]->start >> 2) & 0xff, virt + 0xf0); // IOWindow base + iounmap((void *)virt); + + /* + * This actually configures the PCMCIA socket -- setting up + * the I/O windows and the interrupt mapping. + */ + retval = pcmcia_enable_device(link); + if (retval) { + ines_gpib_release(link); + return -ENODEV; + } + pr_info("ines gpib device loaded\n"); + return 0; +} /* gpib_config */ + +/* + * After a card is removed, gpib_release() will unregister the net + * device, and release the PCMCIA configuration. If the device is + * still open, this will be postponed until it is closed. + */ + +static void ines_gpib_release(struct pcmcia_device *link) +{ + DEBUG(0, "%s(0x%p)\n", __func__, link); + pcmcia_disable_device(link); +} /* gpib_release */ + +static int ines_gpib_suspend(struct pcmcia_device *link) +{ + //struct local_info *info = link->priv; + //struct gpib_board_t *dev = info->dev; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + if (link->open) + pr_err("Device still open ???\n"); + //netif_device_detach(dev); + + return 0; +} + +static int ines_gpib_resume(struct pcmcia_device *link) +{ + //struct local_info_t *info = link->priv; + //struct gpib_board_t *dev = info->dev; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + /*if (link->open) { + * ni_gpib_probe(dev); / really? + * printk("Gpib resumed ???\n"); + * //netif_device_attach(dev); + *} + */ + return ines_gpib_config(link); +} + +static struct pcmcia_device_id ines_pcmcia_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x01b4, 0x4730), + PCMCIA_DEVICE_NULL +}; +MODULE_DEVICE_TABLE(pcmcia, ines_pcmcia_ids); + +static struct pcmcia_driver ines_gpib_cs_driver = { + .owner = THIS_MODULE, + .name = "ines_gpib_cs", + .id_table = ines_pcmcia_ids, + .probe = ines_gpib_probe, + .remove = ines_gpib_remove, + .suspend = ines_gpib_suspend, + .resume = ines_gpib_resume, +}; + +int ines_pcmcia_init_module(void) +{ + pcmcia_register_driver(&ines_gpib_cs_driver); + return 0; +} + +void ines_pcmcia_cleanup_module(void) +{ + DEBUG(0, "ines_cs: unloading\n"); + pcmcia_unregister_driver(&ines_gpib_cs_driver); +} + +gpib_interface_t ines_pcmcia_unaccel_interface = { +name: "ines_pcmcia_unaccel", +attach : ines_pcmcia_attach, +detach : ines_pcmcia_detach, +read : ines_read, +write : ines_write, +command : ines_command, +take_control : ines_take_control, +go_to_standby : ines_go_to_standby, +request_system_control : ines_request_system_control, +interface_clear : ines_interface_clear, +remote_enable : ines_remote_enable, +enable_eos : ines_enable_eos, +disable_eos : ines_disable_eos, +parallel_poll : ines_parallel_poll, +parallel_poll_configure : ines_parallel_poll_configure, +parallel_poll_response : ines_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ines_line_status, +update_status : ines_update_status, +primary_address : ines_primary_address, +secondary_address : ines_secondary_address, +serial_poll_response : ines_serial_poll_response, +serial_poll_status : ines_serial_poll_status, +t1_delay : ines_t1_delay, +return_to_local : ines_return_to_local, +}; + +gpib_interface_t ines_pcmcia_accel_interface = { +name: "ines_pcmcia_accel", +attach : ines_pcmcia_accel_attach, +detach : ines_pcmcia_detach, +read : ines_accel_read, +write : ines_accel_write, +command : ines_command, +take_control : ines_take_control, +go_to_standby : ines_go_to_standby, +request_system_control : ines_request_system_control, +interface_clear : ines_interface_clear, +remote_enable : ines_remote_enable, +enable_eos : ines_enable_eos, +disable_eos : ines_disable_eos, +parallel_poll : ines_parallel_poll, +parallel_poll_configure : ines_parallel_poll_configure, +parallel_poll_response : ines_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ines_line_status, +update_status : ines_update_status, +primary_address : ines_primary_address, +secondary_address : ines_secondary_address, +serial_poll_response : ines_serial_poll_response, +serial_poll_status : ines_serial_poll_status, +t1_delay : ines_t1_delay, +return_to_local : ines_return_to_local, +}; + +gpib_interface_t ines_pcmcia_interface = { +name: "ines_pcmcia", +attach : ines_pcmcia_accel_attach, +detach : ines_pcmcia_detach, +read : ines_accel_read, +write : ines_accel_write, +command : ines_command, +take_control : ines_take_control, +go_to_standby : ines_go_to_standby, +request_system_control : ines_request_system_control, +interface_clear : ines_interface_clear, +remote_enable : ines_remote_enable, +enable_eos : ines_enable_eos, +disable_eos : ines_disable_eos, +parallel_poll : ines_parallel_poll, +parallel_poll_configure : ines_parallel_poll_configure, +parallel_poll_response : ines_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ines_line_status, +update_status : ines_update_status, +primary_address : ines_primary_address, +secondary_address : ines_secondary_address, +serial_poll_response : ines_serial_poll_response, +serial_poll_status : ines_serial_poll_status, +t1_delay : ines_t1_delay, +return_to_local : ines_return_to_local, +}; + +irqreturn_t ines_pcmcia_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + + return ines_interrupt(board); +} + +int ines_common_pcmcia_attach(gpib_board_t *board) +{ + struct ines_priv *ines_priv; + struct nec7210_priv *nec_priv; + int retval; + + if (!curr_dev) { + pr_err("no ines pcmcia cards found\n"); + return -1; + } + + retval = ines_generic_attach(board); + if (retval) + return retval; + + ines_priv = board->private_data; + nec_priv = &ines_priv->nec7210_priv; + + if (request_region(curr_dev->resource[0]->start, + resource_size(curr_dev->resource[0]), "ines_gpib") == 0) { + pr_err("ines_gpib: ioports at 0x%lx already in use\n", + (unsigned long)(curr_dev->resource[0]->start)); + return -1; + } + + nec_priv->iobase = (void *)(unsigned long)curr_dev->resource[0]->start; + + nec7210_board_reset(nec_priv, board); + + if (request_irq(curr_dev->irq, ines_pcmcia_interrupt, IRQF_SHARED, + "pcmcia-gpib", board)) { + pr_err("gpib: can't request IRQ %d\n", curr_dev->irq); + return -1; + } + ines_priv->irq = curr_dev->irq; + + return 0; +} + +int ines_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct ines_priv *ines_priv; + int retval; + + retval = ines_common_pcmcia_attach(board); + if (retval < 0) + return retval; + + ines_priv = board->private_data; + ines_online(ines_priv, board, 0); + + return 0; +} + +int ines_pcmcia_accel_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct ines_priv *ines_priv; + int retval; + + retval = ines_common_pcmcia_attach(board); + if (retval < 0) + return retval; + + ines_priv = board->private_data; + ines_online(ines_priv, board, 1); + + return 0; +} + +void ines_pcmcia_detach(gpib_board_t *board) +{ + struct ines_priv *ines_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (ines_priv) { + nec_priv = &ines_priv->nec7210_priv; + if (ines_priv->irq) + free_irq(ines_priv->irq, board); + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + release_region((unsigned long)(nec_priv->iobase), ines_pcmcia_iosize); + } + } + ines_free_private(board); +} + +#endif /* GPIB_PCMCIA */ + +static int __init ines_init_module(void) +{ + int err = 0; + + err = pci_register_driver(&ines_pci_driver); + if (err) { + pr_err("ines_gpib: pci_driver_register failed!\n"); + return err; + } + + gpib_register_driver(&ines_pci_interface, THIS_MODULE); + gpib_register_driver(&ines_pci_unaccel_interface, THIS_MODULE); + gpib_register_driver(&ines_pci_accel_interface, THIS_MODULE); + gpib_register_driver(&ines_isa_interface, THIS_MODULE); +#ifdef GPIB_PCMCIA + gpib_register_driver(&ines_pcmcia_interface, THIS_MODULE); + gpib_register_driver(&ines_pcmcia_unaccel_interface, THIS_MODULE); + gpib_register_driver(&ines_pcmcia_accel_interface, THIS_MODULE); + err += ines_pcmcia_init_module(); +#endif + if (err) + return -1; + + return 0; +} + +static void __exit ines_exit_module(void) +{ + gpib_unregister_driver(&ines_pci_interface); + gpib_unregister_driver(&ines_pci_unaccel_interface); + gpib_unregister_driver(&ines_pci_accel_interface); + gpib_unregister_driver(&ines_isa_interface); +#ifdef GPIB__PCMCIA + gpib_unregister_driver(&ines_pcmcia_interface); + gpib_unregister_driver(&ines_pcmcia_unaccel_interface); + gpib_unregister_driver(&ines_pcmcia_accel_interface); + ines_pcmcia_cleanup_module(); +#endif + + pci_unregister_driver(&ines_pci_driver); +} + +module_init(ines_init_module); +module_exit(ines_exit_module); diff --git a/drivers/staging/gpib/lpvo_usb_gpib/Makefile b/drivers/staging/gpib/lpvo_usb_gpib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..137511acce63521d570d1f4a6ce798003187e5cd --- /dev/null +++ b/drivers/staging/gpib/lpvo_usb_gpib/Makefile @@ -0,0 +1,3 @@ + +obj-m += lpvo_usb_gpib.o + diff --git a/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c b/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..796c3a5be54513ab0f40694bb7229760a0b3e606 --- /dev/null +++ b/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c @@ -0,0 +1,2136 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * This code has been developed at the Department of Physics (University * + * of Florence, Italy) to support in linux-gpib the open usb-gpib adapter * + * implemented at the University of Ljubljana (lpvo.fe.uni-lj.si/gpib) * + * * + * copyright : (C) 2011 Marcello Carla' * + ***************************************************************************/ + +/* base module includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpibP.h" + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for LPVO usb devices"); + +#define NAME "lpvo_usb_gpib" + +/* + * Table of devices that work with this driver. + * + * Currently, only one device is known to be used in the + * lpvo_usb_gpib adapter (FTDI 0403:6001). + * If your adapter uses a different chip, insert a line + * in the following table with proper , . + * + * To have your chip automatically handled by the driver, + * update files "/usr/local/etc/modprobe.d/lpvo_usb_gpib.conf" + * and /usr/local/etc/udev/rules.d/99-lpvo_usb_gpib.rules. + * + */ + +static const struct usb_device_id skel_table[] = { + { USB_DEVICE(0x0403, 0x6001) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, skel_table); + +/* + * *** Diagnostics and Debug *** + * + * The module parameter "debug" controls the sending of debug messages to + * syslog. By default it is set to 0 or 1 according to GPIB_CONFIG_KERNEL_DEBUG. + * debug = 0: only register/deregister messages are generated + * 1: every action is logged + * 2: extended logging; each single exchanged byte is documented + * (about twice the log volume of [1]) + * To switch debug level: + * At module loading: modprobe lpvo_usb_gpib debug={0,1,2} + * On the fly: echo {0,1,2} > /sys/modules/lpvo_usb_gpib/parameters/debug + */ + +static int debug; +module_param(debug, int, 0644); + +#define DIA_LOG(level, format, ...) \ + do { if (debug >= (level)) \ + pr_alert("%s:%s - " format, NAME, __func__, ## __VA_ARGS__); } \ + while (0) + +/* standard and extended command sets of the usb-gpib adapter */ + +#define USB_GPIB_ON "\nIB\n" +#define USB_GPIB_OFF "\nIBO\n" +#define USB_GPIB_IBm0 "\nIBm0\n" /* do not assert REN with IFC */ +#define USB_GPIB_IBm1 "\nIBm1\n" /* assert REN with IFC */ +#define USB_GPIB_IBCL "\nIBZ\n" +#define USB_GPIB_STATUS "\nIBS\n" +#define USB_GPIB_READ "\nIB?\n" +#define USB_GPIB_READ_1 "\nIBB\n" +#define USB_GPIB_EOI "\nIBe0\n" +#define USB_GPIB_FTMO "\nIBf0\n" /* disable first byte timeout */ +#define USB_GPIB_TTMOZ "\nIBt0\n" /* disable byte timeout */ + +/* incomplete commands */ + +#define USB_GPIB_BTMO "\nIBt" /* set byte timeout */ +#define USB_GPIB_TTMO "\nIBT" /* set total timeout */ + +#define USB_GPIB_DEBUG_ON "\nIBDE\xAA\n" +#define USB_GPIB_SET_LISTEN "\nIBDT0\n" +#define USB_GPIB_SET_TALK "\nIBDT1\n" +#define USB_GPIB_SET_LINES "\nIBDC\n" +#define USB_GPIB_SET_DATA "\nIBDM\n" +#define USB_GPIB_READ_LINES "\nIBD?C\n" +#define USB_GPIB_READ_DATA "\nIBD?M\n" +#define USB_GPIB_READ_BUS "\nIBD??\n" + +/* command sequences */ + +#define USB_GPIB_UNTALK "\nIBC_\n" +#define USB_GPIB_UNLISTEN "\nIBC?\n" + +/* special characters used by the adapter */ + +#define DLE ('\020') +#define STX ('\02') +#define ETX ('\03') +#define ACK ('\06') +#define NODATA ('\03') +#define NODAV ('\011') + +#define IB_BUS_REN 0x01 +#define IB_BUS_IFC 0x02 +#define IB_BUS_NDAC 0x04 +#define IB_BUS_NRFD 0x08 +#define IB_BUS_DAV 0x10 +#define IB_BUS_EOI 0x20 +#define IB_BUS_ATN 0x40 +#define IB_BUS_SRQ 0x80 + +#define INBUF_SIZE 128 + +struct char_buf { /* used by one_char() routine */ + char *inbuf; + int last; + int nchar; +}; + +struct usb_gpib_priv { /* private data to the device */ + u8 eos; /* eos character */ + short eos_flags; /* eos mode */ + int timeout; /* current value for timeout */ + void *dev; /* the usb device private data structure */ +}; + +#define GPIB_DEV (((struct usb_gpib_priv *)board->private_data)->dev) + +#define SHOW_STATUS(board) { \ + DIA_LOG(2, "# - board %p\n", board); \ + DIA_LOG(2, "# - buffer_length %d\n", board->buffer_length); \ + DIA_LOG(2, "# - status %lx\n", board->status); \ + DIA_LOG(2, "# - use_count %d\n", board->use_count); \ + DIA_LOG(2, "# - pad %x\n", board->pad); \ + DIA_LOG(2, "# - sad %x\n", board->sad); \ + DIA_LOG(2, "# - timeout %d\n", board->usec_timeout); \ + DIA_LOG(2, "# - ppc %d\n", board->parallel_poll_configuration); \ + DIA_LOG(2, "# - t1delay %d\n", board->t1_nano_sec); \ + DIA_LOG(2, "# - online %d\n", board->online); \ + DIA_LOG(2, "# - autopoll %d\n", board->autospollers); \ + DIA_LOG(2, "# - autopoll task %p\n", board->autospoll_task); \ + DIA_LOG(2, "# - minor %d\n", board->minor); \ + DIA_LOG(2, "# - master %d\n", board->master); \ + DIA_LOG(2, "# - list %d\n", board->ist); \ + } +/* + * n = 0; + * list_for_each (l, &board->device_list) n++; + * TTY_LOG ("%s:%s - devices in list %d\n", a, b, n); + */ + +/* + * TTY_LOG - write a message to the current work terminal (if any) + */ + +#define TTY_LOG(format, ...) { \ + char buf[128]; \ + struct tty_struct *tty = get_current_tty(); \ + if (tty) { \ + snprintf(buf, 128, format, __VA_ARGS__); \ + tty->driver->ops->write(tty, buf, strlen(buf)); \ + tty->driver->ops->write(tty, "\r", 1); \ + } \ + } + +/* + * GLOBAL VARIABLES: required for + * pairing among gpib minor and usb minor. + * MAX_DEV is the max number of usb-gpib adapters; free + * to change as you like, but no more than 32 + */ + +#define MAX_DEV 8 +static struct usb_interface *lpvo_usb_interfaces[MAX_DEV]; /* registered interfaces */ +static int usb_minors[MAX_DEV]; /* usb minors */ +static int assigned_usb_minors; /* mask of filled slots */ +static struct mutex minors_lock; /* operations on usb_minors are to be protected */ + +/* + * usb-skeleton prototypes + */ + +struct usb_skel; +static ssize_t skel_do_write(struct usb_skel *, const char *, size_t); +static ssize_t skel_do_read(struct usb_skel *, char *, size_t); +static int skel_do_open(gpib_board_t *, int); +static int skel_do_release(gpib_board_t *); + +/* + * usec_diff : take difference in MICROsec between two 'timespec' + * (unix time in sec and NANOsec) + */ + +inline int usec_diff(struct timespec64 *a, struct timespec64 *b) +{ + return ((a->tv_sec - b->tv_sec) * 1000000 + + (a->tv_nsec - b->tv_nsec) / 1000); +} + +/* + * *** these routines are specific to the usb-gpib adapter *** + */ + +/** + * write_loop() - Send a byte sequence to the adapter + * + * @dev: the private device structure + * @msg: the byte sequence. + * @leng: the byte sequence length. + * + */ + +static int write_loop(void *dev, char *msg, int leng) +{ +// int nchar = 0, val; + +// do { + + return skel_do_write(dev, msg, leng); + +// if (val < 1) { +// printk (KERN_ALERT "%s:%s - write error: %d %d/%d\n", +// NAME, __func__, val, nchar, leng); +// return -EIO; +// } +// nchar +=val; +// } while (nchar < leng); +// return leng; +} + +static char printable(char x) +{ + if (x < 32 || x > 126) + return ' '; + return x; +} + +/** + * send_command() - Send a byte sequence and return a single byte reply. + * + * @board: the gpib_board_struct data area for this gpib interface + * @msg: the byte sequence. + * @leng the byte sequence length; can be given as zero and is + * computed automatically, but if 'msg' contains a zero byte, + * it has to be given explicitly. + */ + +static int send_command(gpib_board_t *board, char *msg, int leng) +{ + char buffer[64]; + int nchar, j; + int retval; + struct timespec64 before, after; + + ktime_get_real_ts64 (&before); + + if (!leng) + leng = strlen(msg); + retval = write_loop(GPIB_DEV, msg, leng); + if (retval < 0) + return retval; + + nchar = skel_do_read(GPIB_DEV, buffer, 64); + + if (nchar < 0) { + DIA_LOG(0, " return from read: %d\n", nchar); + return nchar; + } else if (nchar != 1) { + for (j = 0 ; j < leng ; j++) { + DIA_LOG(0, " Irregular reply to command: %d %x %c\n", + j, msg[j], printable(msg[j])); + } + for (j = 0 ; j < nchar ; j++) { + DIA_LOG(0, " Irregular command reply: %d %x %c\n", + j, buffer[j] & 0xff, printable(buffer[j])); + } + return -EIO; + } + ktime_get_real_ts64 (&after); + + DIA_LOG(1, "Sent %d - done %d us.\n", leng, usec_diff(&after, &before)); + + return buffer[0] & 0xff; +} + +/* + * + * set_control_line() - Set the value of a single gpib control line + * + * @board: the gpib_board_struct data area for this gpib interface + * @line: line mask + * @value: line new value (0/1) + * + */ + +static int set_control_line(gpib_board_t *board, int line, int value) +{ + char msg[] = USB_GPIB_SET_LINES; + int retval; + int leng = strlen(msg); + + DIA_LOG(1, "setting line %x to %x\n", line, value); + + retval = send_command(board, USB_GPIB_READ_LINES, 0); + + DIA_LOG(1, "old line values: %x\n", retval); + + if (retval == -EIO) + return retval; + + msg[leng - 2] = value ? (retval & ~line) : retval | line; + + retval = send_command(board, msg, 0); + + DIA_LOG(1, "operation result: %x\n", retval); + + return retval; +} + +/* + * one_char() - read one single byte from input buffer + * + * @board: the gpib_board_struct data area for this gpib interface + * @char_buf: the routine private data structure + */ + +static int one_char(gpib_board_t *board, struct char_buf *b) +{ + struct timespec64 before, after; + + if (b->nchar) { + DIA_LOG(2, "-> %x\n", b->inbuf[b->last - b->nchar]); + return b->inbuf[b->last - b->nchar--]; + } + ktime_get_real_ts64 (&before); + b->nchar = skel_do_read(GPIB_DEV, b->inbuf, INBUF_SIZE); + b->last = b->nchar; + ktime_get_real_ts64 (&after); + + DIA_LOG(2, "read %d bytes in %d usec\n", + b->nchar, usec_diff(&after, &before)); + + if (b->nchar > 0) { + DIA_LOG(2, "--> %x\n", b->inbuf[b->last - b->nchar]); + return b->inbuf[b->last - b->nchar--]; + } else if (b->nchar == 0) { + dev_alert(board->gpib_dev, "%s:%s - read returned EOF\n", NAME, __func__); + return -EIO; + } + dev_alert(board->gpib_dev, "%s:%s - read error %d\n", NAME, __func__, b->nchar); + TTY_LOG("\n *** %s *** Read Error - %s\n", NAME, + "Reset the adapter with 'gpib_config'\n"); + return -EIO; +} + +/** + * set_timeout() - set single byte / total timeouts on the adapter + * + * @board: the gpib_board_struct data area for this gpib interface + * + * For sake of speed, the operation is performed only if it + * modifies the current (saved) value. Minimum allowed timeout + * is 30 ms (T30ms -> 8); timeout disable (TNONE -> 0) currently + * not supported. + */ + +static void set_timeout(gpib_board_t *board) +{ + int n, val; + char command[sizeof(USB_GPIB_TTMO) + 6]; + struct usb_gpib_priv *data = board->private_data; + + if (data->timeout == board->usec_timeout) + return; + + n = (board->usec_timeout + 32767) / 32768; + if (n < 2) + n = 2; + + DIA_LOG(1, "Set timeout to %d us -> %d\n", board->usec_timeout, n); + + sprintf(command, "%s%d\n", USB_GPIB_BTMO, n > 255 ? 255 : n); + val = send_command(board, command, 0); + + if (val == ACK) { + if (n > 65535) + n = 65535; + sprintf(command, "%s%d\n", USB_GPIB_TTMO, n); + val = send_command(board, command, 0); + } + + if (val != ACK) { + dev_alert(board->gpib_dev, "%s:%s - error in timeout set: <%s>\n", + NAME, __func__, command); + } else { + data->timeout = board->usec_timeout; + } +} + +/* + * now the standard interface functions - attach and detach + */ + +/** + * usb_gpib_attach() - activate the usb-gpib converter board + * + * @board: the gpib_board_struct data area for this gpib interface + * @config: firmware data, if any (from gpib_config -I ) + * + * The channel name is ttyUSBn, with n=0 by default. Other values for n + * passed with gpib_config -b . + * + * In this routine I trust that when an error code is returned + * detach() will be called. Always. + */ + +static int usb_gpib_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + int retval, j; + int base = (long)config->ibbase; + char *device_path; + int match; + struct usb_device *udev; + + DIA_LOG(0, "Board %p -t %s -m %d -a %p -u %d -l %d -b %d\n", + board, board->interface->name, board->minor, config->device_path, + config->pci_bus, config->pci_slot, base); + + board->private_data = NULL; /* to be sure - we can detach before setting */ + + /* identify device to be attached */ + + mutex_lock(&minors_lock); + + if (config->device_path) { + /* if config->device_path given, try that first */ + dev_alert(board->gpib_dev, "%s:%s - Looking for device_path: %s\n", + NAME, __func__, config->device_path); + for (j = 0 ; j < MAX_DEV ; j++) { + if ((assigned_usb_minors & 1 << j) == 0) + continue; + udev = usb_get_dev(interface_to_usbdev(lpvo_usb_interfaces[j])); + device_path = kobject_get_path(&udev->dev.kobj, GFP_KERNEL); + match = gpib_match_device_path(&lpvo_usb_interfaces[j]->dev, + config->device_path); + DIA_LOG(1, "dev. %d: minor %d path: %s --> %d\n", j, + lpvo_usb_interfaces[j]->minor, device_path, match); + kfree(device_path); + if (match) + break; + } + } else if (config->pci_bus != -1 && config->pci_slot != -1) { + /* second: look for bus and slot */ + for (j = 0 ; j < MAX_DEV ; j++) { + if ((assigned_usb_minors & 1 << j) == 0) + continue; + udev = usb_get_dev(interface_to_usbdev(lpvo_usb_interfaces[j])); + DIA_LOG(1, "dev. %d: bus %d -> %d dev: %d -> %d\n", j, + udev->bus->busnum, config->pci_bus, udev->devnum, config->pci_slot); + if (config->pci_bus == udev->bus->busnum && + config->pci_slot == udev->devnum) + break; + } + } else { /* last chance: usb_minor, given as ibbase */ + for (j = 0 ; j < MAX_DEV ; j++) { + if (usb_minors[j] == base && assigned_usb_minors & 1 << j) + break; + } + } + mutex_unlock(&minors_lock); + + if (j == MAX_DEV) { + dev_alert(board->gpib_dev, "%s:%s - Requested device is not registered.\n", + NAME, __func__); + return -EIO; + } + + board->private_data = kzalloc(sizeof(struct usb_gpib_priv), GFP_KERNEL); + if (!board->private_data) + return -ENOMEM; + + retval = skel_do_open(board, usb_minors[j]); + + DIA_LOG(1, "Skel open: %d\n", retval); + + if (retval) { + TTY_LOG("%s:%s - skel open failed.\n", NAME, __func__); + kfree(board->private_data); + board->private_data = NULL; + return -ENODEV; + } + + SHOW_STATUS(board); + + retval = send_command(board, USB_GPIB_ON, 0); + DIA_LOG(1, "USB_GPIB_ON returns %x\n", retval); + if (retval != ACK) + return -EIO; + + /* We must setup debug mode because we need the extended instruction + * set to cope with the Core (gpib_common) point of view + */ + + retval = send_command(board, USB_GPIB_DEBUG_ON, 0); + DIA_LOG(1, "USB_GPIB_DEBUG_ON returns %x\n", retval); + if (retval != ACK) + return -EIO; + + /* We must keep REN off after an IFC because so it is + * assumed by the Core + */ + + retval = send_command(board, USB_GPIB_IBm0, 0); + DIA_LOG(1, "USB_GPIB_IBm0 returns %x\n", retval); + if (retval != ACK) + return -EIO; + + retval = set_control_line(board, IB_BUS_REN, 0); + if (retval != ACK) + return -EIO; + + retval = send_command(board, USB_GPIB_FTMO, 0); + DIA_LOG(1, "USB_GPIB_FTMO returns %x\n", retval); + if (retval != ACK) + return -EIO; + + SHOW_STATUS(board); + TTY_LOG("Module '%s' has been sucesfully configured\n", NAME); + return 0; +} + +/** + * usb_gpib_detach() - deactivate the usb-gpib converter board + * + * @board: the gpib_board data area for this gpib interface + * + */ + +static void usb_gpib_detach(gpib_board_t *board) +{ + int retval; + + SHOW_STATUS(board); + + DIA_LOG(0, "detaching %p\n", board); + + if (board->private_data) { + if (GPIB_DEV) { + write_loop(GPIB_DEV, USB_GPIB_OFF, strlen(USB_GPIB_OFF)); + msleep(100); + DIA_LOG(1, "%s", "GPIB off\n"); + retval = skel_do_release(board); + DIA_LOG(1, "skel release -> %d\n", retval); + } + kfree(board->private_data); + board->private_data = NULL; + } + + DIA_LOG(0, "done %p\n", board); + TTY_LOG("Module '%s' has been detached\n", NAME); +} + +/* + * Other functions follow in alphabetical order + */ +/* command */ +static int usb_gpib_command(gpib_board_t *board, + u8 *buffer, + size_t length, + size_t *bytes_written) +{ + int i, retval; + char command[6] = "IBc\n"; + + DIA_LOG(1, "enter %p\n", board); + + set_timeout(board); + + *bytes_written = 0; + for (i = 0 ; i < length ; i++) { + command[3] = buffer[i]; + retval = send_command(board, command, 5); + DIA_LOG(2, "%d ==> %x %x\n", i, buffer[i], retval); + if (retval != 0x06) + return retval; + ++(*bytes_written); + } + return 0; +} + +/** + * disable_eos() - Disable END on eos byte (END on EOI only) + * + * @board: the gpib_board data area for this gpib interface + * + * With the lpvo adapter eos can only be handled via software. + * Cannot do nothing here, but remember for future use. + */ + +static void usb_gpib_disable_eos(gpib_board_t *board) +{ + ((struct usb_gpib_priv *)board->private_data)->eos_flags &= ~REOS; + DIA_LOG(1, "done: %x\n", + ((struct usb_gpib_priv *)board->private_data)->eos_flags); +} + +/** + * enable_eos() - Enable END for reads when eos byte is received. + * + * @board: the gpib_board data area for this gpib interface + * @eos_byte: the 'eos' byte + * @compare_8_bits: if zero ignore eigthth bit when comparing + * + */ + +static int usb_gpib_enable_eos(gpib_board_t *board, + u8 eos_byte, + int compare_8_bits) +{ + struct usb_gpib_priv *pd = (struct usb_gpib_priv *)board->private_data; + + DIA_LOG(1, "enter with %x\n", eos_byte); + pd->eos = eos_byte; + pd->eos_flags = REOS; + if (compare_8_bits) + pd->eos_flags |= BIN; + return 0; +} + +/** + * go_to_standby() - De-assert ATN + * + * @board: the gpib_board data area for this gpib interface + */ + +static int usb_gpib_go_to_standby(gpib_board_t *board) +{ + int retval = set_control_line(board, IB_BUS_ATN, 0); + + DIA_LOG(1, "done with %x\n", retval); + + if (retval == ACK) + return 0; + return -EIO; +} + +/** + * interface_clear() - Assert or de-assert IFC + * + * @board: the gpib_board data area for this gpib interface + * assert: 1: assert IFC; 0: de-assert IFC + * + * Currently on the assert request we issue the lpvo IBZ + * command that cycles IFC low for 100 usec, then we ignore + * the de-assert request. + */ + +static void usb_gpib_interface_clear(gpib_board_t *board, int assert) +{ + int retval = 0; + + DIA_LOG(1, "enter with %d\n", assert); + + if (assert) { + retval = send_command(board, USB_GPIB_IBCL, 0); + + set_bit(CIC_NUM, &board->status); + } + + DIA_LOG(1, "done with %d %d\n", assert, retval); +} + +/** + * line_status() - Read the status of the bus lines. + * + * @board: the gpib_board data area for this gpib interface + * + * We can read all lines. + */ + +#define WQT wait_queue_entry_t +#define WQH head +#define WQE entry + +static int usb_gpib_line_status(const gpib_board_t *board) +{ + int buffer; + int line_status = ValidALL; /* all lines will be read */ + struct list_head *p, *q; + WQT *item; + unsigned long flags; + int sleep = 0; + + DIA_LOG(1, "%s\n", "request"); + + /* if we are on the wait queue (board->wait), do not hurry + * reading status line; instead, pause a little + */ + + spin_lock_irqsave((spinlock_t *)&board->wait.lock, flags); + q = (struct list_head *)&board->wait.WQH; + list_for_each(p, q) { + item = container_of(p, WQT, WQE); + if (item->private == current) { + sleep = 20; + break; + } + /* pid is: ((struct task_struct *) item->private)->pid); */ + } + spin_unlock_irqrestore((spinlock_t *)&board->wait.lock, flags); + if (sleep) { + DIA_LOG(1, "we are on the wait queue - sleep %d ms\n", sleep); + msleep(sleep); + } + + buffer = send_command((gpib_board_t *)board, USB_GPIB_STATUS, 0); + + if (buffer < 0) { + dev_alert(board->gpib_dev, "%s:%s - line status read failed with %d\n", + NAME, __func__, buffer); + return -1; + } + + if ((buffer & 0x01) == 0) + line_status |= BusREN; + if ((buffer & 0x02) == 0) + line_status |= BusIFC; + if ((buffer & 0x04) == 0) + line_status |= BusNDAC; + if ((buffer & 0x08) == 0) + line_status |= BusNRFD; + if ((buffer & 0x10) == 0) + line_status |= BusDAV; + if ((buffer & 0x20) == 0) + line_status |= BusEOI; + if ((buffer & 0x40) == 0) + line_status |= BusATN; + if ((buffer & 0x80) == 0) + line_status |= BusSRQ; + + DIA_LOG(1, "done with %x %x\n", buffer, line_status); + + return line_status; +} + +/* parallel_poll */ + +static int usb_gpib_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + /* request parallel poll asserting ATN | EOI; + * we suppose ATN already asserted + */ + + int retval; + + DIA_LOG(1, "enter %p\n", board); + + retval = set_control_line(board, IB_BUS_EOI, 1); + if (retval != ACK) { + dev_alert(board->gpib_dev, "%s:%s - assert EOI failed\n", NAME, __func__); + return -EIO; + } + + *result = send_command(board, USB_GPIB_READ_DATA, 0); + + DIA_LOG(1, "done with %x\n", *result); + + retval = set_control_line(board, IB_BUS_EOI, 0); + if (retval != 0x06) { + dev_alert(board->gpib_dev, "%s:%s - unassert EOI failed\n", NAME, __func__); + return -EIO; + } + + return 0; +} + +/* read */ + +static int usb_gpib_read(gpib_board_t *board, + u8 *buffer, + size_t length, + int *end, + size_t *bytes_read) +{ +#define MAX_READ_EXCESS 16384 + + struct char_buf b = {NULL, 0}; + + int retval; + char c, nc; + int ic; + struct timespec64 before, after; + int read_count = MAX_READ_EXCESS; + struct usb_gpib_priv *pd = (struct usb_gpib_priv *)board->private_data; + + DIA_LOG(1, "enter %p -> %zu\n", board, length); + + *bytes_read = 0; /* by default, things go wrong */ + *end = 0; + + set_timeout(board); + + /* single byte read has a special handling */ + + if (length == 1) { + char inbuf[2] = {0, 0}; + + /* read a single character */ + + ktime_get_real_ts64 (&before); + + retval = write_loop(GPIB_DEV, USB_GPIB_READ_1, strlen(USB_GPIB_READ_1)); + if (retval < 0) + return retval; + + retval = skel_do_read(GPIB_DEV, inbuf, 1); + retval += skel_do_read(GPIB_DEV, inbuf + 1, 1); + + ktime_get_real_ts64 (&after); + + DIA_LOG(1, "single read: %x %x %x in %d\n", retval, + inbuf[0], inbuf[1], + usec_diff(&after, &before)); + + /* good char / last char? */ + + if (retval == 2 && inbuf[1] == ACK) { + buffer[0] = inbuf[0]; + *bytes_read = 1; + return 0; + } + if (retval < 2) + return -EIO; + else + return -ETIME; + return 0; + } + + /* allocate buffer for multibyte read */ + + b.inbuf = kmalloc(INBUF_SIZE, GFP_KERNEL); + if (!b.inbuf) + return -ENOMEM; + + /* send read command and check sequence */ + + retval = write_loop(GPIB_DEV, USB_GPIB_READ, strlen(USB_GPIB_READ)); + if (retval < 0) + goto read_return; + + if (one_char(board, &b) != DLE || one_char(board, &b) != STX) { + dev_alert(board->gpib_dev, "%s:%s - wrong sequence\n", + NAME, __func__); + retval = -EIO; + goto read_return; + } + + /* get data flow */ + + while (1) { + ic = one_char(board, &b); + if (ic == -EIO) { + retval = -EIO; + goto read_return; + } + c = ic; + + if (c == DLE) + nc = one_char(board, &b); + if (c != DLE || nc == DLE) { + /* data byte - store into buffer */ + + if (*bytes_read == length) + break; /* data overflow */ + if (c == DLE) + c = nc; + buffer[(*bytes_read)++] = c; + if (c == pd->eos) { + *end = 1; + break; + } + + } else { + /* we are in the closing sequence */ + + if (c == ETX) { + c = one_char(board, &b); + if (c == ACK) { + *end = 1; + retval = 0; + goto read_return; + } else { + dev_alert(board->gpib_dev, "%s:%s - %s %x\n", + NAME, __func__, + "Wrong end of message", c); + retval = -ETIME; + goto read_return; + } + } else { + dev_alert(board->gpib_dev, "%s:%s - %s\n", NAME, __func__, + "lone in stream"); + retval = -EIO; + goto read_return; + } + } + } + + /* we had a data overflow - flush excess data */ + + while (read_count--) { + if (one_char(board, &b) != DLE) + continue; + c = one_char(board, &b); + if (c == DLE) + continue; + if (c == ETX) { + c = one_char(board, &b); + if (c == ACK) { + if (MAX_READ_EXCESS - read_count > 1) + dev_alert(board->gpib_dev, "%s:%s - %s\n", NAME, __func__, + "small buffer - maybe some data lost"); + retval = 0; + goto read_return; + } + break; + } + } + + dev_alert(board->gpib_dev, "%s:%s - no input end - GPIB board in odd state\n", + NAME, __func__); + retval = -EIO; + +read_return: + kfree(b.inbuf); + + DIA_LOG(1, "done with byte/status: %d %x %d\n", + (int)*bytes_read, retval, *end); + + if (retval == 0 || retval == -ETIME) { + if (send_command(board, USB_GPIB_UNTALK, sizeof(USB_GPIB_UNTALK)) == 0x06) + return retval; + return -EIO; + } + + return retval; +} + +/* remote_enable */ + +static void usb_gpib_remote_enable(gpib_board_t *board, int enable) +{ + int retval; + + retval = set_control_line(board, IB_BUS_REN, enable ? 1 : 0); + if (retval != ACK) + dev_alert(board->gpib_dev, "%s:%s - could not set REN line: %x\n", + NAME, __func__, retval); + + DIA_LOG(1, "done with %x\n", retval); +} + +/* request_system_control */ + +static void usb_gpib_request_system_control(gpib_board_t *board, + int request_control) +{ + if (request_control) + set_bit(CIC_NUM, &board->status); + else + clear_bit(CIC_NUM, &board->status); + + DIA_LOG(1, "done with %d -> %lx\n", request_control, board->status); +} + +/* take_control */ +/* beware: the sync flag is ignored; what is its real meaning? */ + +static int usb_gpib_take_control(gpib_board_t *board, int sync) +{ + int retval; + + retval = set_control_line(board, IB_BUS_ATN, 1); + + DIA_LOG(1, "done with %d %x\n", sync, retval); + + if (retval == ACK) + return 0; + return -EIO; +} + +/* update_status */ + +static unsigned int usb_gpib_update_status(gpib_board_t *board, + unsigned int clear_mask) +{ + /* There is nothing we can do here, I guess */ + + board->status &= ~clear_mask; + + DIA_LOG(1, "done with %x %lx\n", clear_mask, board->status); + + return board->status; +} + +/* write */ +/* beware: DLE characters are not escaped - can only send ASCII data */ + +static int usb_gpib_write(gpib_board_t *board, + u8 *buffer, + size_t length, + int send_eoi, + size_t *bytes_written) +{ + int retval; + char *msg; + + DIA_LOG(1, "enter %p -> %zu\n", board, length); + + set_timeout(board); + + msg = kmalloc(length + 8, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + memcpy(msg, "\nIB\020\002", 5); + memcpy(msg + 5, buffer, length); + memcpy(msg + 5 + length, "\020\003\n", 3); + + retval = send_command(board, msg, length + 8); + kfree(msg); + + DIA_LOG(1, "<%.*s> -> %x\n", (int)length, buffer, retval); + + if (retval != ACK) + return -EPIPE; + + *bytes_written = length; + + if (send_command(board, USB_GPIB_UNLISTEN, sizeof(USB_GPIB_UNLISTEN)) + != 0x06) + return -EPIPE; + + return length; +} + +/* + * *** following functions not implemented yet *** + */ + +/* parallel_poll configure */ + +static void usb_gpib_parallel_poll_configure(gpib_board_t *board, + uint8_t configuration) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); +} + +/* parallel_poll_response */ + +static void usb_gpib_parallel_poll_response(gpib_board_t *board, int ist) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); +} + +/* primary_address */ + +static int usb_gpib_primary_address(gpib_board_t *board, unsigned int address) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); + return 0; +} + +/* return_to_local */ + +static void usb_gpib_return_to_local(gpib_board_t *board) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); +} + +/* secondary_address */ + +static int usb_gpib_secondary_address(gpib_board_t *board, + unsigned int address, + int enable) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); + return 0; +} + +/* serial_poll_response */ + +static void usb_gpib_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); +} + +/* serial_poll_status */ + +static uint8_t usb_gpib_serial_poll_status(gpib_board_t *board) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); + return 0; +} + +/* t1_delay */ + +static unsigned int usb_gpib_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__); + return 0; +} + +/* + * *** module dispatch table and init/exit functions *** + */ + +gpib_interface_t usb_gpib_interface = { +name: NAME, +attach : usb_gpib_attach, +detach : usb_gpib_detach, +read : usb_gpib_read, +write : usb_gpib_write, +command : usb_gpib_command, +take_control : usb_gpib_take_control, +go_to_standby : usb_gpib_go_to_standby, +request_system_control : usb_gpib_request_system_control, +interface_clear : usb_gpib_interface_clear, +remote_enable : usb_gpib_remote_enable, +enable_eos : usb_gpib_enable_eos, +disable_eos : usb_gpib_disable_eos, +parallel_poll : usb_gpib_parallel_poll, +parallel_poll_configure : usb_gpib_parallel_poll_configure, +parallel_poll_response : usb_gpib_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : usb_gpib_line_status, +update_status : usb_gpib_update_status, +primary_address : usb_gpib_primary_address, +secondary_address : usb_gpib_secondary_address, +serial_poll_response : usb_gpib_serial_poll_response, +serial_poll_status : usb_gpib_serial_poll_status, +t1_delay : usb_gpib_t1_delay, +return_to_local : usb_gpib_return_to_local, +skip_check_for_command_acceptors : 1 +}; + +/* + * usb_gpib_init_module(), usb_gpib_exit_module() + * + * This functions are called every time a new device is detected + * and registered or is removed and unregistered. + * We must take note of created and destroyed usb minors to be used + * when usb_gpib_attach() and usb_gpib_detach() will be called on + * request by gpib_config. + */ + +static int usb_gpib_init_module(struct usb_interface *interface) +{ + int j, mask, rv; + + rv = mutex_lock_interruptible(&minors_lock); + if (rv < 0) + return rv; + + if (!assigned_usb_minors) { + gpib_register_driver(&usb_gpib_interface, THIS_MODULE); + } else { + /* check if minor is already registered - maybe useless, but if + * it happens the code is inconsistent somewhere + */ + + for (j = 0 ; j < MAX_DEV ; j++) { + if (usb_minors[j] == interface->minor && assigned_usb_minors & 1 << j) { + pr_alert("%s:%s - CODE BUG: USB minor %d registered at %d.\n", + NAME, __func__, interface->minor, j); + rv = -1; + goto exit; + } + } + } + + /* find a free slot */ + + for (j = 0 ; j < MAX_DEV ; j++) { + mask = 1 << j; + if ((assigned_usb_minors & mask) == 0) { + usb_minors[j] = interface->minor; + lpvo_usb_interfaces[j] = interface; + assigned_usb_minors |= mask; + DIA_LOG(0, "usb minor %d registered at %d\n", interface->minor, j); + rv = 0; + goto exit; + } + } + pr_alert("%s:%s - No slot available for interface %p minor %d\n", + NAME, __func__, interface, interface->minor); + rv = -1; + +exit: + mutex_unlock(&minors_lock); + return rv; +} + +static void usb_gpib_exit_module(int minor) +{ + int j; + + mutex_lock(&minors_lock); + for (j = 0 ; j < MAX_DEV ; j++) { + if (usb_minors[j] == minor && assigned_usb_minors & 1 << j) { + assigned_usb_minors &= ~(1 << j); + usb_minors[j] = -1; + if (assigned_usb_minors == 0) + gpib_unregister_driver(&usb_gpib_interface); + goto exit; + } + } + pr_alert("%s:%s - CODE BUG: USB minor %d not found.\n", NAME, __func__, minor); + +exit: + mutex_unlock(&minors_lock); +} + +/* + * Default latency time (16 msec) is too long. + * We must use 1 msec (best); anyhow, no more than 5 msec. + * + * Defines and function taken and modified from the kernel tree + * (see ftdi_sio.h and ftdi_sio.c). + * + */ + +#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ +#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER +#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40 +#define WDR_TIMEOUT 5000 /* default urb timeout */ +#define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */ + +#define LATENCY_TIMER 1 /* use a small latency timer: 1 ... 5 msec */ +#define LATENCY_CHANNEL 0 /* channel selection in multichannel devices */ +static int write_latency_timer(struct usb_device *udev) +{ + int rv = usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), + FTDI_SIO_SET_LATENCY_TIMER_REQUEST, + FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, + LATENCY_TIMER, LATENCY_CHANNEL, + NULL, 0, WDR_TIMEOUT); + if (rv < 0) + pr_alert("Unable to write latency timer: %i\n", rv); + return rv; +} + +/***************************************************************************** + * * + * The following code is a modified version of the USB Skeleton driver * + * written by Greg Kroah-Hartman and available in the kernel tree. * + * * + * Functions skel_open() and skel_release() have been rewritten and named * + * skel_do_open() and skel_do_release() to process the attach and detach * + * requests coming from gpib_config. * + * * + * Functions skel_read() and skel_write() have been split into a * + * skel_do_read() and skel_do_write(), that cover the kernel stuff of read * + * and write operations, and the original skel_read() and skel_write(), * + * that handle communication with user space and call their _do_ companion. * + * * + * Only the _do_ versions are used by the lpvo_usb_gpib driver; other ones * + * can be (optionally) maintained in the compilation to have direct access * + * to a gpib controller for debug and diagnostics. * + * * + * To avoid collisions in names, devices in user space have been renamed * + * lpvo_raw1, lpvo_raw2 .... and the usb driver has been renamed with the * + * gpib module name. * + * * + *****************************************************************************/ + +/* + * USB Skeleton driver - 2.2 + * + * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) + * + * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c + * but has been rewritten to be easier to read and use. + */ + +#include +#include +#include +#include + +/* Get a minor range for your devices from the usb maintainer */ +#define USB_SKEL_MINOR_BASE 192 + +/* private defines */ + +#define MAX_TRANSFER (PAGE_SIZE - 512) +/* MAX_TRANSFER is chosen so that the VM is not stressed by + * allocations > PAGE_SIZE and the number of packets in a page + * is an integer 512 is the largest possible packet on EHCI + */ + +#define WRITES_IN_FLIGHT 1 /* we do not want more than one pending write */ +#define USER_DEVICE 1 /* compile for device(s) in user space */ + +/* Structure to hold all of our device specific stuff */ +struct usb_skel { + struct usb_device *udev; /* the usb device for this device */ + struct usb_interface *interface; /* the interface for this device */ + struct semaphore limit_sem; /* limiting the number of writes in progress */ + struct usb_anchor submitted; /* in case need to retract our submissions */ + struct urb *bulk_in_urb; /* the urb to read data with */ + unsigned char *bulk_in_buffer; /* the buffer to receive data */ + size_t bulk_in_size; /* the size of the receive buffer */ + size_t bulk_in_filled; /* number of bytes in the buffer */ + size_t bulk_in_copied; /* already copied to user space */ + __u8 bulk_in_endpoint_addr; /* the address of the bulk in endpoint */ + __u8 bulk_out_endpoint_addr; /* the address of the bulk out endpoint */ + int errors; /* the last request tanked */ + bool ongoing_read; /* a read is going on */ + spinlock_t err_lock; /* lock for errors */ + struct kref kref; + struct mutex io_mutex; /* synchronize I/O with disconnect */ + wait_queue_head_t bulk_in_wait; /* to wait for an ongoing read */ +}; + +#define to_skel_dev(d) container_of(d, struct usb_skel, kref) + +static struct usb_driver skel_driver; +static void skel_draw_down(struct usb_skel *dev); + +static void skel_delete(struct kref *kref) +{ + struct usb_skel *dev = to_skel_dev(kref); + + usb_free_urb(dev->bulk_in_urb); + usb_put_dev(dev->udev); + kfree(dev->bulk_in_buffer); + kfree(dev); +} + +/* + * skel_do_open() - to be called by usb_gpib_attach + */ + +static int skel_do_open(gpib_board_t *board, int subminor) +{ + struct usb_skel *dev; + struct usb_interface *interface; + int retval = 0; + + DIA_LOG(0, "Required minor: %d\n", subminor); + + interface = usb_find_interface(&skel_driver, subminor); + if (!interface) { + pr_err("%s - error, can't find device for minor %d\n", + __func__, subminor); + retval = -ENODEV; + goto exit; + } + + dev = usb_get_intfdata(interface); + if (!dev) { + retval = -ENODEV; + goto exit; + } + + retval = usb_autopm_get_interface(interface); + if (retval) + goto exit; + + /* increment our usage count for the device */ + kref_get(&dev->kref); + + /* save our object in the file's private structure */ + GPIB_DEV = dev; + +exit: + return retval; +} + +/* + * skel_do_release() - to be called by usb_gpib_detach + */ + +static int skel_do_release(gpib_board_t *board) +{ + struct usb_skel *dev; + + dev = GPIB_DEV; + if (!dev) + return -ENODEV; + + /* allow the device to be autosuspended */ + mutex_lock(&dev->io_mutex); + if (dev->interface) + usb_autopm_put_interface(dev->interface); + mutex_unlock(&dev->io_mutex); + + /* decrement the count on our device */ + kref_put(&dev->kref, skel_delete); + return 0; +} + +/* + * read functions + */ + +static void skel_read_bulk_callback(struct urb *urb) +{ + struct usb_skel *dev; + unsigned long flags; + + dev = urb->context; + + spin_lock_irqsave(&dev->err_lock, flags); + /* sync/async unlink faults aren't errors */ + if (urb->status) { + if (!(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) + dev_err(&dev->interface->dev, + "%s - nonzero read bulk status received: %d\n", + __func__, urb->status); + + dev->errors = urb->status; + } else { + dev->bulk_in_filled = urb->actual_length; + } + dev->ongoing_read = 0; + spin_unlock_irqrestore(&dev->err_lock, flags); + + wake_up_interruptible(&dev->bulk_in_wait); +} + +static int skel_do_read_io(struct usb_skel *dev, size_t count) +{ + int rv; + + /* prepare a read */ + usb_fill_bulk_urb(dev->bulk_in_urb, + dev->udev, + usb_rcvbulkpipe(dev->udev, + dev->bulk_in_endpoint_addr), + dev->bulk_in_buffer, + min(dev->bulk_in_size, count), + skel_read_bulk_callback, + dev); + /* tell everybody to leave the URB alone */ + spin_lock_irq(&dev->err_lock); + dev->ongoing_read = 1; + spin_unlock_irq(&dev->err_lock); + + /* submit bulk in urb, which means no data to deliver */ + dev->bulk_in_filled = 0; + dev->bulk_in_copied = 0; + + /* do it */ + rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL); + if (rv < 0) { + dev_err(&dev->interface->dev, + "%s - failed submitting read urb, error %d\n", + __func__, rv); + rv = (rv == -ENOMEM) ? rv : -EIO; + spin_lock_irq(&dev->err_lock); + dev->ongoing_read = 0; + spin_unlock_irq(&dev->err_lock); + } + + return rv; +} + +/* + * skel_do_read() - read operations from lpvo_usb_gpib + */ + +static ssize_t skel_do_read(struct usb_skel *dev, char *buffer, size_t count) +{ + int rv; + bool ongoing_io; + + /* if we cannot read at all, return EOF */ + + if (!dev->bulk_in_urb || !count) + return 0; + + DIA_LOG(1, "enter for %zu.\n", count); + +restart: /* added to comply with ftdi timeout technique */ + + /* no concurrent readers */ + + DIA_LOG(2, "restart with %zd %zd.\n", dev->bulk_in_filled, dev->bulk_in_copied); + + rv = mutex_lock_interruptible(&dev->io_mutex); + if (rv < 0) + return rv; + + if (!dev->interface) { /* disconnect() was called */ + rv = -ENODEV; + goto exit; + } + +retry: + /* if IO is under way, we must not touch things */ + spin_lock_irq(&dev->err_lock); + ongoing_io = dev->ongoing_read; + spin_unlock_irq(&dev->err_lock); + + DIA_LOG(2, "retry with %d.\n", ongoing_io); + + if (ongoing_io) { +// /* nonblocking IO shall not wait */ +// /* no file, no O_NONBLOCK; maybe provide when from user space */ +// if (file->f_flags & O_NONBLOCK) { +// rv = -EAGAIN; +// goto exit; +// } + + /* + * IO may take forever + * hence wait in an interruptible state + */ + rv = wait_event_interruptible(dev->bulk_in_wait, (!dev->ongoing_read)); + if (rv < 0) + goto exit; + } + + /* errors must be reported */ + rv = dev->errors; + if (rv < 0) { + /* any error is reported once */ + dev->errors = 0; + /* to preserve notifications about reset */ + rv = (rv == -EPIPE) ? rv : -EIO; + /* report it */ + goto exit; + } + + /* + * if the buffer is filled we may satisfy the read + * else we need to start IO + */ + + if (dev->bulk_in_filled) { + /* we had read data */ + + size_t available = dev->bulk_in_filled - dev->bulk_in_copied; +// size_t chunk = min(available, count); /* compute chunk later */ + size_t chunk; + + DIA_LOG(2, "we have data: %zu %zu.\n", dev->bulk_in_filled, dev->bulk_in_copied); + + if (!available) { + /* + * all data has been used + * actual IO needs to be done + */ + /* it seems that requests for less than dev->bulk_in_size + * are not accepted + */ + rv = skel_do_read_io(dev, dev->bulk_in_size); + if (rv < 0) + goto exit; + else + goto retry; + } + + /* + * data is available - chunk tells us how much shall be copied + */ + + /* Condition dev->bulk_in_copied > 0 maybe will never happen. In case, + * signal the event and copy using the original procedure, i.e., copy + * first two bytes also + */ + + if (dev->bulk_in_copied) { + int j; + + for (j = 0 ; j < dev->bulk_in_filled ; j++) { + pr_alert("copy -> %x %zu %x\n", + j, dev->bulk_in_copied, dev->bulk_in_buffer[j]); + } + chunk = min(available, count); + memcpy(buffer, dev->bulk_in_buffer + dev->bulk_in_copied, chunk); + rv = chunk; + dev->bulk_in_copied += chunk; + + /* copy discarding first two bytes that contain ftdi chip status */ + + } else { + /* account for two bytes to be discarded */ + chunk = min(available, count + 2); + if (chunk < 2) { + pr_alert("BAD READ - chunk: %zu\n", chunk); + rv = -EIO; + goto exit; + } + + memcpy(buffer, dev->bulk_in_buffer + 2, chunk - 2); + rv = chunk; + dev->bulk_in_copied += chunk; + } + + /* + * if we are asked for more than we have, + * we start IO but don't wait + * + * No, no read ahead allowed; if the case, more data will be + * asked for by the lpvo_usb_gpib layer. + */ +// if (available < count) +// skel_do_read_io(dev, dev->bulk_in_size); + } else { + DIA_LOG(1, "no data - start read - copied: %zd.\n", dev->bulk_in_copied); + + /* no data in the buffer */ + rv = skel_do_read_io(dev, dev->bulk_in_size); + if (rv < 0) + goto exit; + else + goto retry; + } +exit: + mutex_unlock(&dev->io_mutex); + if (rv == 2) + goto restart; /* ftdi chip returns two status bytes after a latency anyhow */ + DIA_LOG(1, "exit with %d.\n", rv); + if (rv > 0) + return rv - 2; /* account for 2 discarded bytes in a valid buffer */ + return rv; +} + +/* + * write functions + */ + +static void skel_write_bulk_callback(struct urb *urb) +{ + struct usb_skel *dev; + unsigned long flags; + + dev = urb->context; + + /* sync/async unlink faults aren't errors */ + if (urb->status) { + if (!(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) + dev_err(&dev->interface->dev, + "%s - nonzero write bulk status received: %d\n", + __func__, urb->status); + + spin_lock_irqsave(&dev->err_lock, flags); + dev->errors = urb->status; + spin_unlock_irqrestore(&dev->err_lock, flags); + } + + /* free up our allocated buffer */ + usb_free_coherent(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + up(&dev->limit_sem); +} + +/* + * skel_do_write() - write operations from lpvo_usb_gpib + */ + +static ssize_t skel_do_write(struct usb_skel *dev, const char *buffer, size_t count) +{ + int retval = 0; + struct urb *urb = NULL; + char *buf = NULL; + size_t writesize = min_t(size_t, count, (size_t)MAX_TRANSFER); + + /* verify that we actually have some data to write */ + if (count == 0) + goto exit; + + /* + * limit the number of URBs in flight to stop a user from using up all + * RAM + */ + /* Only one URB is used, because we can't have a pending write() and go on */ + +// if (!(file->f_flags & O_NONBLOCK)) { /* no NONBLOCK provided */ + if (down_interruptible(&dev->limit_sem)) { + retval = -ERESTARTSYS; + goto exit; + } +// } else { +// if (down_trylock(&dev->limit_sem)) { +// retval = -EAGAIN; +// goto exit; +// } +// } + + spin_lock_irq(&dev->err_lock); + retval = dev->errors; + if (retval < 0) { + /* any error is reported once */ + dev->errors = 0; + /* to preserve notifications about reset */ + retval = (retval == -EPIPE) ? retval : -EIO; + } + spin_unlock_irq(&dev->err_lock); + if (retval < 0) + goto error; + + /* create a urb, and a buffer for it, and copy the data to the urb */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + retval = -ENOMEM; + goto error; + } + + buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL, + &urb->transfer_dma); + if (!buf) { + retval = -ENOMEM; + goto error; + } + + memcpy(buf, buffer, count); + + /* this lock makes sure we don't submit URBs to gone devices */ + mutex_lock(&dev->io_mutex); + if (!dev->interface) { /* disconnect() was called */ + mutex_unlock(&dev->io_mutex); + retval = -ENODEV; + goto error; + } + + /* initialize the urb properly */ + usb_fill_bulk_urb(urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpoint_addr), + buf, writesize, skel_write_bulk_callback, dev); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_anchor_urb(urb, &dev->submitted); + + /* send the data out the bulk port */ + retval = usb_submit_urb(urb, GFP_KERNEL); + mutex_unlock(&dev->io_mutex); + if (retval) { + dev_err(&dev->interface->dev, + "%s - failed submitting write urb, error %d\n", + __func__, retval); + goto error_unanchor; + } + + /* + * release our reference to this urb, the USB core will eventually free + * it entirely + */ + usb_free_urb(urb); + + return writesize; + +error_unanchor: + usb_unanchor_urb(urb); +error: + if (urb) { + usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma); + usb_free_urb(urb); + } + up(&dev->limit_sem); + +exit: + return retval; +} + +/* + * services for the user space devices + */ + +#if USER_DEVICE /* conditional compilation of user space device */ + +static int skel_flush(struct file *file, fl_owner_t id) +{ + struct usb_skel *dev; + int res; + + dev = file->private_data; + if (!dev) + return -ENODEV; + + /* wait for io to stop */ + mutex_lock(&dev->io_mutex); + skel_draw_down(dev); + + /* read out errors, leave subsequent opens a clean slate */ + spin_lock_irq(&dev->err_lock); + res = dev->errors ? (dev->errors == -EPIPE ? -EPIPE : -EIO) : 0; + dev->errors = 0; + spin_unlock_irq(&dev->err_lock); + + mutex_unlock(&dev->io_mutex); + + return res; +} + +static int skel_open(struct inode *inode, struct file *file) +{ + struct usb_skel *dev; + struct usb_interface *interface; + int subminor; + int retval = 0; + + subminor = iminor(inode); + + interface = usb_find_interface(&skel_driver, subminor); + if (!interface) { + pr_err("%s - error, can't find device for minor %d\n", + __func__, subminor); + retval = -ENODEV; + goto exit; + } + + dev = usb_get_intfdata(interface); + if (!dev) { + retval = -ENODEV; + goto exit; + } + + retval = usb_autopm_get_interface(interface); + if (retval) + goto exit; + + /* increment our usage count for the device */ + kref_get(&dev->kref); + + /* save our object in the file's private structure */ + file->private_data = dev; + +exit: + return retval; +} + +static int skel_release(struct inode *inode, struct file *file) +{ + struct usb_skel *dev; + + dev = file->private_data; + if (!dev) + return -ENODEV; + + /* allow the device to be autosuspended */ + mutex_lock(&dev->io_mutex); + if (dev->interface) + usb_autopm_put_interface(dev->interface); + mutex_unlock(&dev->io_mutex); + + /* decrement the count on our device */ + kref_put(&dev->kref, skel_delete); + return 0; +} + +/* + * user space access to read function + */ + +static ssize_t skel_read(struct file *file, char *buffer, size_t count, + loff_t *ppos) +{ + struct usb_skel *dev; + char *buf; + ssize_t rv; + + dev = file->private_data; + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + rv = skel_do_read(dev, buf, count); + + pr_alert("%s - return with %zu\n", __func__, rv); + + if (rv > 0) { + if (copy_to_user(buffer, buf, rv)) { + kfree(buf); + return -EFAULT; + } + } + kfree(buf); + return rv; +} + +/* + * user space access to write function + */ + +static ssize_t skel_write(struct file *file, const char *user_buffer, + size_t count, loff_t *ppos) +{ + struct usb_skel *dev; + char *buf; + ssize_t rv; + + dev = file->private_data; + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, user_buffer, count)) { + kfree(buf); + return -EFAULT; + } + + rv = skel_do_write(dev, buf, count); + kfree(buf); + return rv; +} +#endif + +static const struct file_operations skel_fops = { + .owner = THIS_MODULE, +#if USER_DEVICE + .read = skel_read, + .write = skel_write, + .open = skel_open, + .release = skel_release, + .flush = skel_flush, + .llseek = noop_llseek, +#endif +}; + +/* + * usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with the driver core + */ +#if USER_DEVICE +static struct usb_class_driver skel_class = { + .name = "lpvo_raw%d", + .fops = &skel_fops, + .minor_base = USB_SKEL_MINOR_BASE, +}; +#endif + +static int skel_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_skel *dev; + struct usb_endpoint_descriptor *bulk_in, *bulk_out; + int retval; + char *device_path; + + mutex_init(&minors_lock); /* required for handling minor numbers table */ + + /* allocate memory for our device state and initialize it */ + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + kref_init(&dev->kref); + sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); + mutex_init(&dev->io_mutex); + spin_lock_init(&dev->err_lock); + init_usb_anchor(&dev->submitted); + init_waitqueue_head(&dev->bulk_in_wait); + + dev->udev = usb_get_dev(interface_to_usbdev(interface)); + dev->interface = interface; + + /* set up the endpoint information */ + /* use only the first bulk-in and bulk-out endpoints */ + retval = usb_find_common_endpoints(interface->cur_altsetting, + &bulk_in, &bulk_out, NULL, NULL); + if (retval) { + dev_err(&interface->dev, + "Could not find both bulk-in and bulk-out endpoints\n"); + goto error; + } + + dev->bulk_in_size = usb_endpoint_maxp(bulk_in); + dev->bulk_in_endpoint_addr = bulk_in->bEndpointAddress; + dev->bulk_in_buffer = kmalloc(dev->bulk_in_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { + retval = -ENOMEM; + goto error; + } + dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->bulk_in_urb) { + retval = -ENOMEM; + goto error; + } + + dev->bulk_out_endpoint_addr = bulk_out->bEndpointAddress; + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, dev); + + /* let the world know */ + + device_path = kobject_get_path(&dev->udev->dev.kobj, GFP_KERNEL); + pr_alert("%s:%s - New lpvo_usb_device -> bus: %d dev: %d path: %s\n", NAME, __func__, + dev->udev->bus->busnum, dev->udev->devnum, device_path); + kfree(device_path); + +#if USER_DEVICE + /* we can register the device now, as it is ready */ + retval = usb_register_dev(interface, &skel_class); + if (retval) { + /* something prevented us from registering this driver */ + dev_err(&interface->dev, + "Not able to get a minor for this device.\n"); + usb_set_intfdata(interface, NULL); + goto error; + } + + /* let the user know what node this device is now attached to */ + dev_info(&interface->dev, + "lpvo_usb_gpib device now attached to lpvo_raw%d", + interface->minor); +#endif + + write_latency_timer(dev->udev); /* adjust the latency timer */ + + usb_gpib_init_module(interface); /* last, init the lpvo for this minor */ + + return 0; + +error: + /* this frees allocated memory */ + kref_put(&dev->kref, skel_delete); + + return retval; +} + +static void skel_disconnect(struct usb_interface *interface) +{ + struct usb_skel *dev; + int minor = interface->minor; + + usb_gpib_exit_module(minor); /* first, disactivate the lpvo */ + + dev = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); + +#if USER_DEVICE + /* give back our minor */ + usb_deregister_dev(interface, &skel_class); +#endif + + /* prevent more I/O from starting */ + mutex_lock(&dev->io_mutex); + dev->interface = NULL; + mutex_unlock(&dev->io_mutex); + + usb_kill_anchored_urbs(&dev->submitted); + + /* decrement our usage count */ + kref_put(&dev->kref, skel_delete); + + dev_info(&interface->dev, "USB lpvo_raw #%d now disconnected", minor); +} + +static void skel_draw_down(struct usb_skel *dev) +{ + int time; + + time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000); + if (!time) + usb_kill_anchored_urbs(&dev->submitted); + usb_kill_urb(dev->bulk_in_urb); +} + +static int skel_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct usb_skel *dev = usb_get_intfdata(intf); + + if (!dev) + return 0; + skel_draw_down(dev); + return 0; +} + +static int skel_resume(struct usb_interface *intf) +{ + return 0; +} + +static int skel_pre_reset(struct usb_interface *intf) +{ + struct usb_skel *dev = usb_get_intfdata(intf); + + mutex_lock(&dev->io_mutex); + skel_draw_down(dev); + + return 0; +} + +static int skel_post_reset(struct usb_interface *intf) +{ + struct usb_skel *dev = usb_get_intfdata(intf); + + /* we are sure no URBs are active - no locking needed */ + dev->errors = -EPIPE; + mutex_unlock(&dev->io_mutex); + + return 0; +} + +static struct usb_driver skel_driver = { + .name = NAME, + .probe = skel_probe, + .disconnect = skel_disconnect, + .suspend = skel_suspend, + .resume = skel_resume, + .pre_reset = skel_pre_reset, + .post_reset = skel_post_reset, + .id_table = skel_table, + .supports_autosuspend = 1, +}; + +module_usb_driver(skel_driver); diff --git a/drivers/staging/gpib/nec7210/Makefile b/drivers/staging/gpib/nec7210/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8d4d90f211092d28581bdb1fd33ec05d2f72385f --- /dev/null +++ b/drivers/staging/gpib/nec7210/Makefile @@ -0,0 +1,4 @@ + +obj-m += nec7210.o + + diff --git a/drivers/staging/gpib/nec7210/board.h b/drivers/staging/gpib/nec7210/board.h new file mode 100644 index 0000000000000000000000000000000000000000..ac3fe38ade57269296ed7438781a412c63dd2cf6 --- /dev/null +++ b/drivers/staging/gpib/nec7210/board.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2001, 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_PCIIA_BOARD_H +#define _GPIB_PCIIA_BOARD_H + +#include "gpibP.h" +#include +#include +#include +#include + +#include "nec7210.h" + +#endif //_GPIB_PCIIA_BOARD_H + diff --git a/drivers/staging/gpib/nec7210/nec7210.c b/drivers/staging/gpib/nec7210/nec7210.c new file mode 100644 index 0000000000000000000000000000000000000000..1d995103549746f460b036f5571b6931f87d3c9b --- /dev/null +++ b/drivers/staging/gpib/nec7210/nec7210.c @@ -0,0 +1,1134 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2001, 2002 by Frank Mori Hess + ***************************************************************************/ + +#include "board.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB library code for NEC uPD7210"); + +int nec7210_enable_eos(gpib_board_t *board, struct nec7210_priv *priv, uint8_t eos_byte, + int compare_8_bits) +{ + write_byte(priv, eos_byte, EOSR); + priv->auxa_bits |= HR_REOS; + if (compare_8_bits) + priv->auxa_bits |= HR_BIN; + else + priv->auxa_bits &= ~HR_BIN; + write_byte(priv, priv->auxa_bits, AUXMR); + return 0; +} +EXPORT_SYMBOL(nec7210_enable_eos); + +void nec7210_disable_eos(gpib_board_t *board, struct nec7210_priv *priv) +{ + priv->auxa_bits &= ~HR_REOS; + write_byte(priv, priv->auxa_bits, AUXMR); +} +EXPORT_SYMBOL(nec7210_disable_eos); + +int nec7210_parallel_poll(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *result) +{ + int ret; + + clear_bit(COMMAND_READY_BN, &priv->state); + + // execute parallel poll + write_byte(priv, AUX_EPP, AUXMR); + // wait for result FIXME: support timeouts + ret = wait_event_interruptible(board->wait, test_bit(COMMAND_READY_BN, &priv->state)); + if (ret) { + dev_dbg(board->gpib_dev, "gpib: parallel poll interrupted\n"); + return -ERESTARTSYS; + } + *result = read_byte(priv, CPTR); + + return 0; +} +EXPORT_SYMBOL(nec7210_parallel_poll); + +void nec7210_parallel_poll_configure(gpib_board_t *board, + struct nec7210_priv *priv, unsigned int configuration) +{ + write_byte(priv, PPR | configuration, AUXMR); +} +EXPORT_SYMBOL(nec7210_parallel_poll_configure); + +void nec7210_parallel_poll_response(gpib_board_t *board, struct nec7210_priv *priv, int ist) +{ + if (ist) + write_byte(priv, AUX_SPPF, AUXMR); + else + write_byte(priv, AUX_CPPF, AUXMR); +} +EXPORT_SYMBOL(nec7210_parallel_poll_response); +/* This is really only adequate for chips that do a 488.2 style reqt/reqf + * based on bit 6 of the SPMR (see chapter 11.3.3 of 488.2). For simpler chips that simply + * set rsv directly based on bit 6, we either need to do more hardware setup to expose + * the 488.2 capability (for example with NI chips), or we need to implement the + * 488.2 set srv state machine in the driver (if that is even viable). + */ +void nec7210_serial_poll_response(gpib_board_t *board, struct nec7210_priv *priv, uint8_t status) +{ + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + if (status & request_service_bit) { + priv->srq_pending = 1; + clear_bit(SPOLL_NUM, &board->status); + + } else { + priv->srq_pending = 0; + } + write_byte(priv, status, SPMR); + spin_unlock_irqrestore(&board->spinlock, flags); +} +EXPORT_SYMBOL(nec7210_serial_poll_response); + +uint8_t nec7210_serial_poll_status(gpib_board_t *board, struct nec7210_priv *priv) +{ + return read_byte(priv, SPSR); +} +EXPORT_SYMBOL(nec7210_serial_poll_status); + +int nec7210_primary_address(const gpib_board_t *board, struct nec7210_priv *priv, + unsigned int address) +{ + // put primary address in address0 + write_byte(priv, address & ADDRESS_MASK, ADR); + return 0; +} +EXPORT_SYMBOL(nec7210_primary_address); + +int nec7210_secondary_address(const gpib_board_t *board, struct nec7210_priv *priv, + unsigned int address, int enable) +{ + if (enable) { + // put secondary address in address1 + write_byte(priv, HR_ARS | (address & ADDRESS_MASK), ADR); + // go to address mode 2 + priv->reg_bits[ADMR] &= ~HR_ADM0; + priv->reg_bits[ADMR] |= HR_ADM1; + } else { + // disable address1 register + write_byte(priv, HR_ARS | HR_DT | HR_DL, ADR); + // go to address mode 1 + priv->reg_bits[ADMR] |= HR_ADM0; + priv->reg_bits[ADMR] &= ~HR_ADM1; + } + write_byte(priv, priv->reg_bits[ADMR], ADMR); + return 0; +} +EXPORT_SYMBOL(nec7210_secondary_address); + +static void update_talker_state(struct nec7210_priv *priv, unsigned int address_status_bits) +{ + if ((address_status_bits & HR_TA)) { + if ((address_status_bits & HR_NATN)) { + if (address_status_bits & HR_SPMS) + priv->talker_state = serial_poll_active; + else + priv->talker_state = talker_active; + } else { + priv->talker_state = talker_addressed; + } + } else { + priv->talker_state = talker_idle; + } +} + +static void update_listener_state(struct nec7210_priv *priv, unsigned int address_status_bits) +{ + if (address_status_bits & HR_LA) { + if ((address_status_bits & HR_NATN)) + priv->listener_state = listener_active; + else + priv->listener_state = listener_addressed; + } else { + priv->listener_state = listener_idle; + } +} + +unsigned int nec7210_update_status_nolock(gpib_board_t *board, struct nec7210_priv *priv) +{ + int address_status_bits; + u8 spoll_status; + + if (!priv) + return 0; + + address_status_bits = read_byte(priv, ADSR); + if (address_status_bits & HR_CIC) + set_bit(CIC_NUM, &board->status); + else + clear_bit(CIC_NUM, &board->status); + // check for talker/listener addressed + update_talker_state(priv, address_status_bits); + if (priv->talker_state == talker_active || priv->talker_state == talker_addressed) + set_bit(TACS_NUM, &board->status); + else + clear_bit(TACS_NUM, &board->status); + update_listener_state(priv, address_status_bits); + if (priv->listener_state == listener_active || + priv->listener_state == listener_addressed) + set_bit(LACS_NUM, &board->status); + else + clear_bit(LACS_NUM, &board->status); + if (address_status_bits & HR_NATN) + clear_bit(ATN_NUM, &board->status); + else + set_bit(ATN_NUM, &board->status); + spoll_status = nec7210_serial_poll_status(board, priv); + if (priv->srq_pending && (spoll_status & request_service_bit) == 0) { + priv->srq_pending = 0; + set_bit(SPOLL_NUM, &board->status); + } +// dev_dbg(board->gpib_dev, "status 0x%x, state 0x%x\n", board->status, priv->state); + + /* we rely on the interrupt handler to set the + * rest of the status bits + */ + + return board->status; +} +EXPORT_SYMBOL(nec7210_update_status_nolock); + +unsigned int nec7210_update_status(gpib_board_t *board, struct nec7210_priv *priv, + unsigned int clear_mask) +{ + unsigned long flags; + unsigned int retval; + + spin_lock_irqsave(&board->spinlock, flags); + board->status &= ~clear_mask; + retval = nec7210_update_status_nolock(board, priv); + spin_unlock_irqrestore(&board->spinlock, flags); + + return retval; +} +EXPORT_SYMBOL(nec7210_update_status); + +unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg, + unsigned int mask, unsigned int bits) +{ + priv->reg_bits[reg] &= ~mask; + priv->reg_bits[reg] |= mask & bits; + write_byte(priv, priv->reg_bits[reg], reg); + return priv->reg_bits[reg]; +} +EXPORT_SYMBOL(nec7210_set_reg_bits); + +void nec7210_set_handshake_mode(gpib_board_t *board, struct nec7210_priv *priv, int mode) +{ + unsigned long flags; + + mode &= HR_HANDSHAKE_MASK; + + spin_lock_irqsave(&board->spinlock, flags); + if ((priv->auxa_bits & HR_HANDSHAKE_MASK) != mode) { + priv->auxa_bits &= ~HR_HANDSHAKE_MASK; + priv->auxa_bits |= mode; + write_byte(priv, priv->auxa_bits, AUXMR); + } + spin_unlock_irqrestore(&board->spinlock, flags); +} +EXPORT_SYMBOL(nec7210_set_handshake_mode); + +uint8_t nec7210_read_data_in(gpib_board_t *board, struct nec7210_priv *priv, int *end) +{ + unsigned long flags; + u8 data; + + spin_lock_irqsave(&board->spinlock, flags); + data = read_byte(priv, DIR); + clear_bit(READ_READY_BN, &priv->state); + if (test_and_clear_bit(RECEIVED_END_BN, &priv->state)) + *end = 1; + else + *end = 0; + spin_unlock_irqrestore(&board->spinlock, flags); + + return data; +} +EXPORT_SYMBOL(nec7210_read_data_in); + +int nec7210_take_control(gpib_board_t *board, struct nec7210_priv *priv, int syncronous) +{ + int i; + const int timeout = 100; + int retval = 0; + unsigned int adsr_bits = 0; + + if (syncronous) + write_byte(priv, AUX_TCS, AUXMR); + else + write_byte(priv, AUX_TCA, AUXMR); + // busy wait until ATN is asserted + for (i = 0; i < timeout; i++) { + adsr_bits = read_byte(priv, ADSR); + if ((adsr_bits & HR_NATN) == 0) + break; + udelay(1); + } + if (i == timeout) + return -ETIMEDOUT; + + clear_bit(WRITE_READY_BN, &priv->state); + + return retval; +} +EXPORT_SYMBOL(nec7210_take_control); + +int nec7210_go_to_standby(gpib_board_t *board, struct nec7210_priv *priv) +{ + int i; + const int timeout = 1000; + unsigned int adsr_bits = 0; + int retval = 0; + + write_byte(priv, AUX_GTS, AUXMR); + // busy wait until ATN is released + for (i = 0; i < timeout; i++) { + adsr_bits = read_byte(priv, ADSR); + if (adsr_bits & HR_NATN) + break; + udelay(1); + } + // if busy wait has failed, try sleeping + if (i == timeout) { + for (i = 0; i < HZ; i++) { + set_current_state(TASK_INTERRUPTIBLE); + if (schedule_timeout(1)) + return -ERESTARTSYS; + adsr_bits = read_byte(priv, ADSR); + if (adsr_bits & HR_NATN) + break; + } + if (i == HZ) { + pr_err("nec7210: error waiting for NATN\n"); + return -ETIMEDOUT; + } + } + + clear_bit(COMMAND_READY_BN, &priv->state); + return retval; +} +EXPORT_SYMBOL(nec7210_go_to_standby); + +void nec7210_request_system_control(gpib_board_t *board, struct nec7210_priv *priv, + int request_control) +{ + if (request_control == 0) { + write_byte(priv, AUX_CREN, AUXMR); + write_byte(priv, AUX_CIFC, AUXMR); + write_byte(priv, AUX_DSC, AUXMR); + } +} +EXPORT_SYMBOL(nec7210_request_system_control); + +void nec7210_interface_clear(gpib_board_t *board, struct nec7210_priv *priv, int assert) +{ + if (assert) + write_byte(priv, AUX_SIFC, AUXMR); + else + write_byte(priv, AUX_CIFC, AUXMR); +} +EXPORT_SYMBOL(nec7210_interface_clear); + +void nec7210_remote_enable(gpib_board_t *board, struct nec7210_priv *priv, int enable) +{ + if (enable) + write_byte(priv, AUX_SREN, AUXMR); + else + write_byte(priv, AUX_CREN, AUXMR); +} +EXPORT_SYMBOL(nec7210_remote_enable); + +void nec7210_release_rfd_holdoff(gpib_board_t *board, struct nec7210_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + if (test_bit(RFD_HOLDOFF_BN, &priv->state) && + test_bit(READ_READY_BN, &priv->state) == 0) { + write_byte(priv, AUX_FH, AUXMR); + clear_bit(RFD_HOLDOFF_BN, &priv->state); + } + spin_unlock_irqrestore(&board->spinlock, flags); +} +EXPORT_SYMBOL(nec7210_release_rfd_holdoff); + +unsigned int nec7210_t1_delay(gpib_board_t *board, struct nec7210_priv *priv, + unsigned int nano_sec) +{ + unsigned int retval; + + if (nano_sec <= 500) { + priv->auxb_bits |= HR_TRI; + retval = 500; + } else { + priv->auxb_bits &= ~HR_TRI; + retval = 2000; + } + write_byte(priv, priv->auxb_bits, AUXMR); + + return retval; +} +EXPORT_SYMBOL(nec7210_t1_delay); + +void nec7210_return_to_local(const gpib_board_t *board, struct nec7210_priv *priv) +{ + write_byte(priv, AUX_RTL, AUXMR); +} +EXPORT_SYMBOL(nec7210_return_to_local); + +static inline short nec7210_atn_has_changed(gpib_board_t *board, struct nec7210_priv *priv) +{ + short address_status_bits = read_byte(priv, ADSR); + + if (address_status_bits & HR_NATN) { + if (test_bit(ATN_NUM, &board->status)) + return 1; + else + return 0; + } else { + if (test_bit(ATN_NUM, &board->status)) + return 0; + else + return 1; + } + return -1; +} + +int nec7210_command(gpib_board_t *board, struct nec7210_priv *priv, uint8_t + *buffer, size_t length, size_t *bytes_written) +{ + int retval = 0; + unsigned long flags; + + *bytes_written = 0; + + clear_bit(BUS_ERROR_BN, &priv->state); + + while (*bytes_written < length) { + if (wait_event_interruptible(board->wait, + test_bit(COMMAND_READY_BN, &priv->state) || + test_bit(BUS_ERROR_BN, &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib command wait interrupted\n"); + retval = -ERESTARTSYS; + break; + } + if (test_bit(TIMO_NUM, &board->status)) + break; + if (test_and_clear_bit(BUS_ERROR_BN, &priv->state)) { + pr_err("nec7210: bus error on command byte\n"); + break; + } + + spin_lock_irqsave(&board->spinlock, flags); + clear_bit(COMMAND_READY_BN, &priv->state); + write_byte(priv, buffer[*bytes_written], CDOR); + spin_unlock_irqrestore(&board->spinlock, flags); + + ++(*bytes_written); + + if (need_resched()) + schedule(); + } + // wait for last byte to get sent + if (wait_event_interruptible(board->wait, test_bit(COMMAND_READY_BN, &priv->state) || + test_bit(BUS_ERROR_BN, &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib command wait interrupted\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) { + dev_dbg(board->gpib_dev, "gpib command timed out\n"); + retval = -ETIMEDOUT; + } + if (test_and_clear_bit(BUS_ERROR_BN, &priv->state)) { + pr_err("nec7210: bus error on command byte\n"); + retval = -EIO; + } + + return retval; +} +EXPORT_SYMBOL(nec7210_command); + +static int pio_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + ssize_t retval = 0; + + *bytes_read = 0; + *end = 0; + + while (*bytes_read < length) { + if (wait_event_interruptible(board->wait, + test_bit(READ_READY_BN, &priv->state) || + test_bit(DEV_CLEAR_BN, &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "nec7210: pio read wait interrupted\n"); + retval = -ERESTARTSYS; + break; + } + if (test_bit(READ_READY_BN, &priv->state)) { + if (*bytes_read == 0) { + /* We set the handshake mode here because we know + * no new bytes will arrive (it has already arrived + * and is awaiting being read out of the chip) while we are changing + * modes. This ensures we can reliably keep track + * of the holdoff state. + */ + nec7210_set_handshake_mode(board, priv, HR_HLDA); + } + buffer[(*bytes_read)++] = nec7210_read_data_in(board, priv, end); + if (*end) + break; + } + if (test_bit(TIMO_NUM, &board->status)) { + dev_dbg(board->gpib_dev, "interrupted by timeout\n"); + retval = -ETIMEDOUT; + break; + } + if (test_bit(DEV_CLEAR_BN, &priv->state)) { + dev_dbg(board->gpib_dev, "interrupted by device clear\n"); + retval = -EINTR; + break; + } + + if (*bytes_read < length) + nec7210_release_rfd_holdoff(board, priv); + + if (need_resched()) + schedule(); + } + return retval; +} + +#ifdef NEC_DMA +static ssize_t __dma_read(gpib_board_t *board, struct nec7210_priv *priv, size_t length) +{ + ssize_t retval = 0; + size_t count = 0; + unsigned long flags, dma_irq_flags; + + if (length == 0) + return 0; + + spin_lock_irqsave(&board->spinlock, flags); + + dma_irq_flags = claim_dma_lock(); + disable_dma(priv->dma_channel); + /* program dma controller */ + clear_dma_ff(priv->dma_channel); + set_dma_count(priv->dma_channel, length); + set_dma_addr(priv->dma_channel, priv->dma_buffer_addr); + set_dma_mode(priv->dma_channel, DMA_MODE_READ); + release_dma_lock(dma_irq_flags); + + enable_dma(priv->dma_channel); + + set_bit(DMA_READ_IN_PROGRESS_BN, &priv->state); + clear_bit(READ_READY_BN, &priv->state); + + // enable nec7210 dma + nec7210_set_reg_bits(priv, IMR2, HR_DMAI, HR_DMAI); + + spin_unlock_irqrestore(&board->spinlock, flags); + + // wait for data to transfer + if (wait_event_interruptible(board->wait, + test_bit(DMA_READ_IN_PROGRESS_BN, &priv->state) == 0 || + test_bit(DEV_CLEAR_BN, &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "nec7210: dma read wait interrupted\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_bit(DEV_CLEAR_BN, &priv->state)) + retval = -EINTR; + + // disable nec7210 dma + nec7210_set_reg_bits(priv, IMR2, HR_DMAI, 0); + + // record how many bytes we transferred + flags = claim_dma_lock(); + clear_dma_ff(priv->dma_channel); + disable_dma(priv->dma_channel); + count += length - get_dma_residue(priv->dma_channel); + release_dma_lock(flags); + + return retval ? retval : count; +} + +static ssize_t dma_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length) +{ + size_t remain = length; + size_t transfer_size; + ssize_t retval = 0; + + while (remain > 0) { + transfer_size = (priv->dma_buffer_length < remain) ? + priv->dma_buffer_length : remain; + retval = __dma_read(board, priv, transfer_size); + if (retval < 0) + break; + memcpy(buffer, priv->dma_buffer, transfer_size); + remain -= retval; + buffer += retval; + if (test_bit(RECEIVED_END_BN, &priv->state)) + break; + } + + if (retval < 0) + return retval; + + return length - remain; +} +#endif + +int nec7210_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + ssize_t retval = 0; + + *end = 0; + *bytes_read = 0; + + if (length == 0) + return 0; + + clear_bit(DEV_CLEAR_BN, &priv->state); // XXX wrong + + nec7210_release_rfd_holdoff(board, priv); + + retval = pio_read(board, priv, buffer, length, end, bytes_read); + + return retval; +} +EXPORT_SYMBOL(nec7210_read); + +static int pio_write_wait(gpib_board_t *board, struct nec7210_priv *priv, + short wake_on_lacs, short wake_on_atn, short wake_on_bus_error) +{ + // wait until byte is ready to be sent + if (wait_event_interruptible(board->wait, + (test_bit(TACS_NUM, &board->status) && + test_bit(WRITE_READY_BN, &priv->state)) || + test_bit(DEV_CLEAR_BN, &priv->state) || + (wake_on_bus_error && test_bit(BUS_ERROR_BN, &priv->state)) || + (wake_on_lacs && test_bit(LACS_NUM, &board->status)) || + (wake_on_atn && test_bit(ATN_NUM, &board->status)) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted\n"); + return -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) { + dev_dbg(board->gpib_dev, "nec7210: write timed out\n"); + return -ETIMEDOUT; + } + if (test_bit(DEV_CLEAR_BN, &priv->state)) { + dev_dbg(board->gpib_dev, "nec7210: write interrupted by clear\n"); + return -EINTR; + } + if (wake_on_bus_error && test_and_clear_bit(BUS_ERROR_BN, &priv->state)) { + dev_dbg(board->gpib_dev, "nec7210: bus error on write\n"); + return -EIO; + } + return 0; +} + +static int pio_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length, size_t *bytes_written) +{ + size_t last_count = 0; + ssize_t retval = 0; + unsigned long flags; + const int max_bus_errors = (length > 1000) ? length : 1000; + int bus_error_count = 0; + *bytes_written = 0; + + clear_bit(BUS_ERROR_BN, &priv->state); + + while (*bytes_written < length) { + if (need_resched()) + schedule(); + + retval = pio_write_wait(board, priv, 0, 0, priv->type == NEC7210); + if (retval == -EIO) { + /* resend last byte on bus error */ + *bytes_written = last_count; + dev_dbg(board->gpib_dev, "resending %c\n", buffer[*bytes_written]); + /* we can get unrecoverable bus errors, + * so give up after a while + */ + bus_error_count++; + if (bus_error_count > max_bus_errors) + return retval; + continue; + } else { + if (retval < 0) + return retval; + } + spin_lock_irqsave(&board->spinlock, flags); + clear_bit(BUS_ERROR_BN, &priv->state); + clear_bit(WRITE_READY_BN, &priv->state); + last_count = *bytes_written; + write_byte(priv, buffer[(*bytes_written)++], CDOR); + spin_unlock_irqrestore(&board->spinlock, flags); + } + retval = pio_write_wait(board, priv, 1, 1, priv->type == NEC7210); + return retval; +} + +#ifdef NEC_DMA +static ssize_t __dma_write(gpib_board_t *board, struct nec7210_priv *priv, dma_addr_t address, + size_t length) +{ + unsigned long flags, dma_irq_flags; + int residue = 0; + int retval = 0; + + spin_lock_irqsave(&board->spinlock, flags); + + /* program dma controller */ + dma_irq_flags = claim_dma_lock(); + disable_dma(priv->dma_channel); + clear_dma_ff(priv->dma_channel); + set_dma_count(priv->dma_channel, length); + set_dma_addr(priv->dma_channel, address); + set_dma_mode(priv->dma_channel, DMA_MODE_WRITE); + enable_dma(priv->dma_channel); + release_dma_lock(dma_irq_flags); + + // enable board's dma for output + nec7210_set_reg_bits(priv, IMR2, HR_DMAO, HR_DMAO); + + clear_bit(WRITE_READY_BN, &priv->state); + set_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state); + + spin_unlock_irqrestore(&board->spinlock, flags); + + // suspend until message is sent + if (wait_event_interruptible(board->wait, + test_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state) == 0 || + test_bit(BUS_ERROR_BN, &priv->state) || + test_bit(DEV_CLEAR_BN, &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted!\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + if (test_and_clear_bit(DEV_CLEAR_BN, &priv->state)) + retval = -EINTR; + if (test_and_clear_bit(BUS_ERROR_BN, &priv->state)) + retval = -EIO; + + // disable board's dma + nec7210_set_reg_bits(priv, IMR2, HR_DMAO, 0); + + dma_irq_flags = claim_dma_lock(); + clear_dma_ff(priv->dma_channel); + disable_dma(priv->dma_channel); + residue = get_dma_residue(priv->dma_channel); + release_dma_lock(dma_irq_flags); + + if (residue) + retval = -EPIPE; + + return retval ? retval : length; +} + +static ssize_t dma_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, + size_t length) +{ + size_t remain = length; + size_t transfer_size; + ssize_t retval = 0; + + while (remain > 0) { + transfer_size = (priv->dma_buffer_length < remain) ? + priv->dma_buffer_length : remain; + memcpy(priv->dma_buffer, buffer, transfer_size); + retval = __dma_write(board, priv, priv->dma_buffer_addr, transfer_size); + if (retval < 0) + break; + remain -= retval; + buffer += retval; + } + + if (retval < 0) + return retval; + + return length - remain; +} +#endif +int nec7210_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + int retval = 0; + + *bytes_written = 0; + + clear_bit(DEV_CLEAR_BN, &priv->state); //XXX + + if (send_eoi) + length-- ; /* save the last byte for sending EOI */ + + if (length > 0) { + // isa dma transfer + if (0 /*priv->dma_channel*/) { +/* + * dma writes are unreliable since they can't recover from bus errors + * (which happen when ATN is asserted in the middle of a write) + */ +#ifdef NEC_DMA + retval = dma_write(board, priv, buffer, length); + if (retval < 0) + return retval; + count += retval; +#endif + } else { // PIO transfer + size_t num_bytes; + + retval = pio_write(board, priv, buffer, length, &num_bytes); + + *bytes_written += num_bytes; + if (retval < 0) + return retval; + } + } + if (send_eoi) { + size_t num_bytes; + + /* We need to wait to make sure we will immediately be able to write the data byte + * into the chip before sending the associated AUX_SEOI command. This is really + * only needed for length==1 since otherwise the earlier calls to pio_write + * will have dont the wait already. + */ + retval = pio_write_wait(board, priv, 0, 0, priv->type == NEC7210); + if (retval < 0) + return retval; + /*send EOI */ + write_byte(priv, AUX_SEOI, AUXMR); + + retval = pio_write(board, priv, &buffer[*bytes_written], 1, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + } + + return retval; +} +EXPORT_SYMBOL(nec7210_write); + +/* + * interrupt service routine + */ +irqreturn_t nec7210_interrupt(gpib_board_t *board, struct nec7210_priv *priv) +{ + int status1, status2; + + // read interrupt status (also clears status) + status1 = read_byte(priv, ISR1); + status2 = read_byte(priv, ISR2); + + return nec7210_interrupt_have_status(board, priv, status1, status2); +} +EXPORT_SYMBOL(nec7210_interrupt); + +irqreturn_t nec7210_interrupt_have_status(gpib_board_t *board, + struct nec7210_priv *priv, int status1, int status2) +{ +#ifdef NEC_DMA + unsigned long dma_flags; +#endif + int retval = IRQ_NONE; + + // record service request in status + if (status2 & HR_SRQI) + set_bit(SRQI_NUM, &board->status); + + // change in lockout status + if (status2 & HR_LOKC) { + if (status2 & HR_LOK) + set_bit(LOK_NUM, &board->status); + else + clear_bit(LOK_NUM, &board->status); + } + + // change in remote status + if (status2 & HR_REMC) { + if (status2 & HR_REM) + set_bit(REM_NUM, &board->status); + else + clear_bit(REM_NUM, &board->status); + } + + // record reception of END + if (status1 & HR_END) { + set_bit(RECEIVED_END_BN, &priv->state); + if ((priv->auxa_bits & HR_HANDSHAKE_MASK) == HR_HLDE) + set_bit(RFD_HOLDOFF_BN, &priv->state); + } + + // get incoming data in PIO mode + if ((status1 & HR_DI)) { + set_bit(READ_READY_BN, &priv->state); + if ((priv->auxa_bits & HR_HANDSHAKE_MASK) == HR_HLDA) + set_bit(RFD_HOLDOFF_BN, &priv->state); + } +#ifdef NEC_DMA + // check for dma read transfer complete + if (test_bit(DMA_READ_IN_PROGRESS_BN, &priv->state)) { + dma_flags = claim_dma_lock(); + disable_dma(priv->dma_channel); + clear_dma_ff(priv->dma_channel); + if ((status1 & HR_END) || get_dma_residue(priv->dma_channel) == 0) + clear_bit(DMA_READ_IN_PROGRESS_BN, &priv->state); + else + enable_dma(priv->dma_channel); + release_dma_lock(dma_flags); + } +#endif + if ((status1 & HR_DO)) { + if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state) == 0) + set_bit(WRITE_READY_BN, &priv->state); +#ifdef NEC_DMA + if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state)) { // write data, isa dma mode + // check if dma transfer is complete + dma_flags = claim_dma_lock(); + disable_dma(priv->dma_channel); + clear_dma_ff(priv->dma_channel); + if (get_dma_residue(priv->dma_channel) == 0) { + clear_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state); + // XXX race? byte may still be in CDOR reg + } else { + clear_bit(WRITE_READY_BN, &priv->state); + enable_dma(priv->dma_channel); + } + release_dma_lock(dma_flags); + } +#endif + } + + // outgoing command can be sent + if (status2 & HR_CO) + set_bit(COMMAND_READY_BN, &priv->state); + + // command pass through received + if (status1 & HR_CPT) { + unsigned int command; + + command = read_byte(priv, CPTR) & gpib_command_mask; + write_byte(priv, AUX_NVAL, AUXMR); +// printk("gpib: command pass through 0x%x\n", command); + } + + if (status1 & HR_ERR) + set_bit(BUS_ERROR_BN, &priv->state); + + if (status1 & HR_DEC) { + unsigned short address_status_bits = read_byte(priv, ADSR); + + // ignore device clear events if we are controller in charge + if ((address_status_bits & HR_CIC) == 0) { + push_gpib_event(board, EventDevClr); + set_bit(DEV_CLEAR_BN, &priv->state); + } + } + + if (status1 & HR_DET) + push_gpib_event(board, EventDevTrg); + + // Addressing status has changed + if (status2 & HR_ADSC) + set_bit(ADR_CHANGE_BN, &priv->state); + + if ((status1 & priv->reg_bits[IMR1]) || + (status2 & (priv->reg_bits[IMR2] & IMR2_ENABLE_INTR_MASK)) || + nec7210_atn_has_changed(board, priv)) { + nec7210_update_status_nolock(board, priv); + dev_dbg(board->gpib_dev, "minor %i, stat %lx, isr1 0x%x, imr1 0x%x, isr2 0x%x, imr2 0x%x\n", + board->minor, board->status, status1, priv->reg_bits[IMR1], status2, + priv->reg_bits[IMR2]); + wake_up_interruptible(&board->wait); /* wake up sleeping process */ + retval = IRQ_HANDLED; + } + + return retval; +} +EXPORT_SYMBOL(nec7210_interrupt_have_status); + +void nec7210_board_reset(struct nec7210_priv *priv, const gpib_board_t *board) +{ + /* 7210 chip reset */ + write_byte(priv, AUX_CR, AUXMR); + + /* disable all interrupts */ + priv->reg_bits[IMR1] = 0; + write_byte(priv, priv->reg_bits[IMR1], IMR1); + priv->reg_bits[IMR2] = 0; + write_byte(priv, priv->reg_bits[IMR2], IMR2); + write_byte(priv, 0, SPMR); + + /* clear registers by reading */ + read_byte(priv, CPTR); + read_byte(priv, ISR1); + read_byte(priv, ISR2); + + /* parallel poll unconfigure */ + write_byte(priv, PPR | HR_PPU, AUXMR); + + priv->reg_bits[ADMR] = HR_TRM0 | HR_TRM1; + + priv->auxa_bits = AUXRA | HR_HLDA; + write_byte(priv, priv->auxa_bits, AUXMR); + + write_byte(priv, AUXRE | 0, AUXMR); + + /* set INT pin to active high, enable command pass through of unknown commands */ + priv->auxb_bits = AUXRB | HR_CPTE; + write_byte(priv, priv->auxb_bits, AUXMR); + write_byte(priv, AUXRE, AUXMR); +} +EXPORT_SYMBOL(nec7210_board_reset); + +void nec7210_board_online(struct nec7210_priv *priv, const gpib_board_t *board) +{ + /* set GPIB address */ + nec7210_primary_address(board, priv, board->pad); + nec7210_secondary_address(board, priv, board->sad, board->sad >= 0); + + // enable interrupts + priv->reg_bits[IMR1] = HR_ERRIE | HR_DECIE | HR_ENDIE | + HR_DETIE | HR_CPTIE | HR_DOIE | HR_DIIE; + priv->reg_bits[IMR2] = IMR2_ENABLE_INTR_MASK; + write_byte(priv, priv->reg_bits[IMR1], IMR1); + write_byte(priv, priv->reg_bits[IMR2], IMR2); + + write_byte(priv, AUX_PON, AUXMR); +} +EXPORT_SYMBOL(nec7210_board_online); + +#ifdef CONFIG_HAS_IOPORT +/* wrappers for io */ +uint8_t nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num) +{ + return inb((unsigned long)(priv->iobase) + register_num * priv->offset); +} +EXPORT_SYMBOL(nec7210_ioport_read_byte); + +void nec7210_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num) +{ + if (register_num == AUXMR) + /* locking makes absolutely sure noone accesses the + * AUXMR register faster than once per microsecond + */ + nec7210_locking_ioport_write_byte(priv, data, register_num); + else + outb(data, (unsigned long)(priv->iobase) + register_num * priv->offset); +} +EXPORT_SYMBOL(nec7210_ioport_write_byte); + +/* locking variants of io wrappers, for chips that page-in registers */ +uint8_t nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num) +{ + u8 retval; + unsigned long flags; + + spin_lock_irqsave(&priv->register_page_lock, flags); + retval = inb((unsigned long)(priv->iobase) + register_num * priv->offset); + spin_unlock_irqrestore(&priv->register_page_lock, flags); + return retval; +} +EXPORT_SYMBOL(nec7210_locking_ioport_read_byte); + +void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, uint8_t data, + unsigned int register_num) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->register_page_lock, flags); + if (register_num == AUXMR) + udelay(1); + outb(data, (unsigned long)(priv->iobase) + register_num * priv->offset); + spin_unlock_irqrestore(&priv->register_page_lock, flags); +} +EXPORT_SYMBOL(nec7210_locking_ioport_write_byte); +#endif + +uint8_t nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num) +{ + return readb(priv->iobase + register_num * priv->offset); +} +EXPORT_SYMBOL(nec7210_iomem_read_byte); + +void nec7210_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, unsigned int register_num) +{ + if (register_num == AUXMR) + /* locking makes absolutely sure noone accesses the + * AUXMR register faster than once per microsecond + */ + nec7210_locking_iomem_write_byte(priv, data, register_num); + else + writeb(data, priv->iobase + register_num * priv->offset); +} +EXPORT_SYMBOL(nec7210_iomem_write_byte); + +uint8_t nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num) +{ + u8 retval; + unsigned long flags; + + spin_lock_irqsave(&priv->register_page_lock, flags); + retval = readb(priv->iobase + register_num * priv->offset); + spin_unlock_irqrestore(&priv->register_page_lock, flags); + return retval; +} +EXPORT_SYMBOL(nec7210_locking_iomem_read_byte); + +void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, uint8_t data, + unsigned int register_num) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->register_page_lock, flags); + if (register_num == AUXMR) + udelay(1); + writeb(data, priv->iobase + register_num * priv->offset); + spin_unlock_irqrestore(&priv->register_page_lock, flags); +} +EXPORT_SYMBOL(nec7210_locking_iomem_write_byte); + +static int __init nec7210_init_module(void) +{ + return 0; +} + +static void __exit nec7210_exit_module(void) +{ +} + +module_init(nec7210_init_module); +module_exit(nec7210_exit_module); diff --git a/drivers/staging/gpib/ni_usb/Makefile b/drivers/staging/gpib/ni_usb/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e22b3b21a62c6b9533d16fbad99e5f4d26c1ffad --- /dev/null +++ b/drivers/staging/gpib/ni_usb/Makefile @@ -0,0 +1,4 @@ + +obj-m += ni_usb_gpib.o + + diff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..b7b6fb1be379032b894e2b0cb7d0325c83bf4b07 --- /dev/null +++ b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c @@ -0,0 +1,2640 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * driver for National Instruments usb to gpib adapters + * copyright : (C) 2004 by Frank Mori Hess + ***************************************************************************/ + +#include +#include +#include +#include "ni_usb_gpib.h" +#include "gpibP.h" +#include "nec7210.h" +#include "tnt4882_registers.h" + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for National Instruments USB devices"); + +#define MAX_NUM_NI_USB_INTERFACES 128 +static struct usb_interface *ni_usb_driver_interfaces[MAX_NUM_NI_USB_INTERFACES]; + +static int ni_usb_parse_status_block(const u8 *buffer, struct ni_usb_status_block *status); +static int ni_usb_set_interrupt_monitor(gpib_board_t *board, unsigned int monitored_bits); +static void ni_usb_stop(struct ni_usb_priv *ni_priv); + +static DEFINE_MUTEX(ni_usb_hotplug_lock); + +//calculates a reasonable timeout in that can be passed to usb functions +static inline unsigned long ni_usb_timeout_msecs(unsigned int usec) +{ + if (usec == 0) + return 0; + return 2000 + usec / 500; +}; + +// returns timeout code byte for use in ni-usb-b instructions +static unsigned short ni_usb_timeout_code(unsigned int usec) +{ + if (usec == 0) + return 0xf0; + else if (usec <= 10) + return 0xf1; + else if (usec <= 30) + return 0xf2; + else if (usec <= 100) + return 0xf3; + else if (usec <= 300) + return 0xf4; + else if (usec <= 1000) + return 0xf5; + else if (usec <= 3000) + return 0xf6; + else if (usec <= 10000) + return 0xf7; + else if (usec <= 30000) + return 0xf8; + else if (usec <= 100000) + return 0xf9; + else if (usec <= 300000) + return 0xfa; + else if (usec <= 1000000) + return 0xfb; + else if (usec <= 3000000) + return 0xfc; + else if (usec <= 10000000) + return 0xfd; + else if (usec <= 30000000) + return 0xfe; + else if (usec <= 100000000) + return 0xff; + else if (usec <= 300000000) + return 0x01; + /* NI driver actually uses 0xff for timeout T1000s, which is a bug in their code. + * I've verified on a usb-b that a code of 0x2 is correct for a 1000 sec timeout + */ + else if (usec <= 1000000000) + return 0x02; + pr_err("%s: bug? usec is greater than 1e9\n", __func__); + return 0xf0; +} + +static void ni_usb_bulk_complete(struct urb *urb) +{ + struct ni_usb_urb_ctx *context = urb->context; + +// printk("debug: %s: status=0x%x, error_count=%i, actual_length=%i\n", __func__, +// urb->status, urb->error_count, urb->actual_length); + up(&context->complete); +} + +static void ni_usb_timeout_handler(struct timer_list *t) +{ + struct ni_usb_priv *ni_priv = from_timer(ni_priv, t, bulk_timer); + struct ni_usb_urb_ctx *context = &ni_priv->context; + + context->timed_out = 1; + up(&context->complete); +}; + +// I'm using nonblocking loosely here, it only means -EAGAIN can be returned in certain cases +static int ni_usb_nonblocking_send_bulk_msg(struct ni_usb_priv *ni_priv, void *data, + int data_length, int *actual_data_length, + int timeout_msecs) +{ + struct usb_device *usb_dev; + int retval; + unsigned int out_pipe; + struct ni_usb_urb_ctx *context = &ni_priv->context; + + *actual_data_length = 0; + mutex_lock(&ni_priv->bulk_transfer_lock); + if (!ni_priv->bus_interface) { + mutex_unlock(&ni_priv->bulk_transfer_lock); + return -ENODEV; + } + if (ni_priv->bulk_urb) { + mutex_unlock(&ni_priv->bulk_transfer_lock); + return -EAGAIN; + } + ni_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ni_priv->bulk_urb) { + mutex_unlock(&ni_priv->bulk_transfer_lock); + return -ENOMEM; + } + usb_dev = interface_to_usbdev(ni_priv->bus_interface); + out_pipe = usb_sndbulkpipe(usb_dev, ni_priv->bulk_out_endpoint); + sema_init(&context->complete, 0); + context->timed_out = 0; + usb_fill_bulk_urb(ni_priv->bulk_urb, usb_dev, out_pipe, data, data_length, + &ni_usb_bulk_complete, context); + + if (timeout_msecs) + mod_timer(&ni_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs)); + + retval = usb_submit_urb(ni_priv->bulk_urb, GFP_KERNEL); + if (retval) { + del_timer_sync(&ni_priv->bulk_timer); + usb_free_urb(ni_priv->bulk_urb); + ni_priv->bulk_urb = NULL; + dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n", + __func__, retval); + mutex_unlock(&ni_priv->bulk_transfer_lock); + return retval; + } + mutex_unlock(&ni_priv->bulk_transfer_lock); + down(&context->complete); // wait for ni_usb_bulk_complete + if (context->timed_out) { + usb_kill_urb(ni_priv->bulk_urb); + dev_err(&usb_dev->dev, "%s: killed urb due to timeout\n", __func__); + retval = -ETIMEDOUT; + } else { + retval = ni_priv->bulk_urb->status; + } + + del_timer_sync(&ni_priv->bulk_timer); + *actual_data_length = ni_priv->bulk_urb->actual_length; + mutex_lock(&ni_priv->bulk_transfer_lock); + usb_free_urb(ni_priv->bulk_urb); + ni_priv->bulk_urb = NULL; + mutex_unlock(&ni_priv->bulk_transfer_lock); + return retval; +} + +static int ni_usb_send_bulk_msg(struct ni_usb_priv *ni_priv, void *data, int data_length, + int *actual_data_length, int timeout_msecs) +{ + int retval; + int timeout_msecs_remaining = timeout_msecs; + + retval = ni_usb_nonblocking_send_bulk_msg(ni_priv, data, data_length, actual_data_length, + timeout_msecs_remaining); + while (retval == -EAGAIN && (timeout_msecs == 0 || timeout_msecs_remaining > 0)) { + usleep_range(1000, 1500); + retval = ni_usb_nonblocking_send_bulk_msg(ni_priv, data, data_length, + actual_data_length, + timeout_msecs_remaining); + if (timeout_msecs != 0) + --timeout_msecs_remaining; + } + if (timeout_msecs != 0 && timeout_msecs_remaining <= 0) + return -ETIMEDOUT; + return retval; +} + +// I'm using nonblocking loosely here, it only means -EAGAIN can be returned in certain cases +static int ni_usb_nonblocking_receive_bulk_msg(struct ni_usb_priv *ni_priv, + void *data, int data_length, + int *actual_data_length, int timeout_msecs, + int interruptible) +{ + struct usb_device *usb_dev; + int retval; + unsigned int in_pipe; + struct ni_usb_urb_ctx *context = &ni_priv->context; + + *actual_data_length = 0; + mutex_lock(&ni_priv->bulk_transfer_lock); + if (!ni_priv->bus_interface) { + mutex_unlock(&ni_priv->bulk_transfer_lock); + return -ENODEV; + } + if (ni_priv->bulk_urb) { + mutex_unlock(&ni_priv->bulk_transfer_lock); + return -EAGAIN; + } + ni_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ni_priv->bulk_urb) { + mutex_unlock(&ni_priv->bulk_transfer_lock); + return -ENOMEM; + } + usb_dev = interface_to_usbdev(ni_priv->bus_interface); + in_pipe = usb_rcvbulkpipe(usb_dev, ni_priv->bulk_in_endpoint); + sema_init(&context->complete, 0); + context->timed_out = 0; + usb_fill_bulk_urb(ni_priv->bulk_urb, usb_dev, in_pipe, data, data_length, + &ni_usb_bulk_complete, context); + + if (timeout_msecs) + mod_timer(&ni_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs)); + + //printk("%s: submitting urb\n", __func__); + retval = usb_submit_urb(ni_priv->bulk_urb, GFP_KERNEL); + if (retval) { + del_timer_sync(&ni_priv->bulk_timer); + usb_free_urb(ni_priv->bulk_urb); + ni_priv->bulk_urb = NULL; + dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n", + __func__, retval); + mutex_unlock(&ni_priv->bulk_transfer_lock); + return retval; + } + mutex_unlock(&ni_priv->bulk_transfer_lock); + if (interruptible) { + if (down_interruptible(&context->complete)) { + /* If we got interrupted by a signal while + * waiting for the usb gpib to respond, we + * should send a stop command so it will + * finish up with whatever it was doing and + * send its response now. + */ + ni_usb_stop(ni_priv); + retval = -ERESTARTSYS; + /* now do an uninterruptible wait, it shouldn't take long + * for the board to respond now. + */ + down(&context->complete); + } + } else { + down(&context->complete); + } + if (context->timed_out) { + usb_kill_urb(ni_priv->bulk_urb); + dev_err(&usb_dev->dev, "%s: killed urb due to timeout\n", __func__); + retval = -ETIMEDOUT; + } else { + if (ni_priv->bulk_urb->status) + retval = ni_priv->bulk_urb->status; + } + del_timer_sync(&ni_priv->bulk_timer); + *actual_data_length = ni_priv->bulk_urb->actual_length; + mutex_lock(&ni_priv->bulk_transfer_lock); + usb_free_urb(ni_priv->bulk_urb); + ni_priv->bulk_urb = NULL; + mutex_unlock(&ni_priv->bulk_transfer_lock); + return retval; +} + +static int ni_usb_receive_bulk_msg(struct ni_usb_priv *ni_priv, void *data, + int data_length, int *actual_data_length, int timeout_msecs, + int interruptible) +{ + int retval; + int timeout_msecs_remaining = timeout_msecs; + + retval = ni_usb_nonblocking_receive_bulk_msg(ni_priv, data, data_length, + actual_data_length, timeout_msecs_remaining, + interruptible); + while (retval == -EAGAIN && (timeout_msecs == 0 || timeout_msecs_remaining > 0)) { + usleep_range(1000, 1500); + retval = ni_usb_nonblocking_receive_bulk_msg(ni_priv, data, data_length, + actual_data_length, + timeout_msecs_remaining, + interruptible); + if (timeout_msecs != 0) + --timeout_msecs_remaining; + } + if (timeout_msecs && timeout_msecs_remaining <= 0) + return -ETIMEDOUT; + return retval; +} + +static int ni_usb_receive_control_msg(struct ni_usb_priv *ni_priv, __u8 request, + __u8 requesttype, __u16 value, __u16 index, + void *data, __u16 size, int timeout_msecs) +{ + struct usb_device *usb_dev; + int retval; + unsigned int in_pipe; + + mutex_lock(&ni_priv->control_transfer_lock); + if (!ni_priv->bus_interface) { + mutex_unlock(&ni_priv->control_transfer_lock); + return -ENODEV; + } + usb_dev = interface_to_usbdev(ni_priv->bus_interface); + in_pipe = usb_rcvctrlpipe(usb_dev, 0); + retval = usb_control_msg(usb_dev, in_pipe, request, requesttype, value, index, data, + size, timeout_msecs); + mutex_unlock(&ni_priv->control_transfer_lock); + return retval; +} + +static void ni_usb_soft_update_status(gpib_board_t *board, unsigned int ni_usb_ibsta, + unsigned int clear_mask) +{ + static const unsigned int ni_usb_ibsta_mask = SRQI | ATN | CIC | REM | LACS | TACS | LOK; + + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + unsigned int need_monitoring_bits = ni_usb_ibsta_monitor_mask; + unsigned long flags; + + board->status &= ~clear_mask; + board->status &= ~ni_usb_ibsta_mask; + board->status |= ni_usb_ibsta & ni_usb_ibsta_mask; + //FIXME should generate events on DTAS and DCAS + + spin_lock_irqsave(&board->spinlock, flags); +/* remove set status bits from monitored set why ?***/ + ni_priv->monitored_ibsta_bits &= ~ni_usb_ibsta; + need_monitoring_bits &= ~ni_priv->monitored_ibsta_bits; /* mm - monitored set */ + spin_unlock_irqrestore(&board->spinlock, flags); + dev_dbg(&usb_dev->dev, "%s: need_monitoring_bits=0x%x\n", __func__, need_monitoring_bits); + + if (need_monitoring_bits & ~ni_usb_ibsta) + ni_usb_set_interrupt_monitor(board, ni_usb_ibsta_monitor_mask); + else if (need_monitoring_bits & ni_usb_ibsta) + wake_up_interruptible(&board->wait); + + dev_dbg(&usb_dev->dev, "%s: ni_usb_ibsta=0x%x\n", __func__, ni_usb_ibsta); +} + +static int ni_usb_parse_status_block(const u8 *buffer, struct ni_usb_status_block *status) +{ + u16 count; + + status->id = buffer[0]; + status->ibsta = (buffer[1] << 8) | buffer[2]; + status->error_code = buffer[3]; + count = buffer[4] | (buffer[5] << 8); + count = ~count; + count++; + status->count = count; + return 8; +}; + +static void ni_usb_dump_raw_block(const u8 *raw_data, int length) +{ + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 8, 1, raw_data, length, true); +} + +static int ni_usb_parse_register_read_block(const u8 *raw_data, unsigned int *results, + int num_results) +{ + int i = 0; + int j; + int unexpected = 0; + static const int results_per_chunk = 3; + + for (j = 0; j < num_results;) { + int k; + + if (raw_data[i++] != NIUSB_REGISTER_READ_DATA_START_ID) { + pr_err("%s: parse error: wrong start id\n", __func__); + unexpected = 1; + } + for (k = 0; k < results_per_chunk && j < num_results; ++k) + results[j++] = raw_data[i++]; + } + while (i % 4) + i++; + if (raw_data[i++] != NIUSB_REGISTER_READ_DATA_END_ID) { + pr_err("%s: parse error: wrong end id\n", __func__); + unexpected = 1; + } + if (raw_data[i++] % results_per_chunk != num_results % results_per_chunk) { + pr_err("%s: parse error: wrong count=%i for NIUSB_REGISTER_READ_DATA_END\n", + __func__, (int)raw_data[i - 1]); + unexpected = 1; + } + while (i % 4) { + if (raw_data[i++] != 0) { + pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n", + __func__, i - 1, (int)raw_data[i - 1]); + unexpected = 1; + } + } + if (unexpected) + ni_usb_dump_raw_block(raw_data, i); + return i; +} + +static int ni_usb_parse_termination_block(const u8 *buffer) +{ + int i = 0; + + if (buffer[i++] != NIUSB_TERM_ID || + buffer[i++] != 0x0 || + buffer[i++] != 0x0 || + buffer[i++] != 0x0) { + pr_err("%s: received unexpected termination block\n", __func__); + pr_err(" expected: 0x%x 0x%x 0x%x 0x%x\n", + NIUSB_TERM_ID, 0x0, 0x0, 0x0); + pr_err(" received: 0x%x 0x%x 0x%x 0x%x\n", + buffer[i - 4], buffer[i - 3], buffer[i - 2], buffer[i - 1]); + } + return i; +}; + +static int parse_board_ibrd_readback(const u8 *raw_data, struct ni_usb_status_block *status, + u8 *parsed_data, int parsed_data_length, + int *actual_bytes_read) +{ + static const int ibrd_data_block_length = 0xf; + static const int ibrd_extended_data_block_length = 0x1e; + int data_block_length = 0; + int i = 0; + int j = 0; + int k; + unsigned int adr1_bits; + int num_data_blocks = 0; + struct ni_usb_status_block register_write_status; + int unexpected = 0; + + while (raw_data[i] == NIUSB_IBRD_DATA_ID || raw_data[i] == NIUSB_IBRD_EXTENDED_DATA_ID) { + if (raw_data[i] == NIUSB_IBRD_DATA_ID) { + data_block_length = ibrd_data_block_length; + } else if (raw_data[i] == NIUSB_IBRD_EXTENDED_DATA_ID) { + data_block_length = ibrd_extended_data_block_length; + if (raw_data[++i] != 0) { + pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n", + __func__, i, (int)raw_data[i]); + unexpected = 1; + } + } else { + pr_err("%s: logic bug!\n", __func__); + return -EINVAL; + } + ++i; + for (k = 0; k < data_block_length; k++) { + if (j < parsed_data_length) + parsed_data[j++] = raw_data[i++]; + else + ++i; + } + ++num_data_blocks; + } + i += ni_usb_parse_status_block(&raw_data[i], status); + if (status->id != NIUSB_IBRD_STATUS_ID) { + pr_err("%s: bug: status->id=%i, != ibrd_status_id\n", __func__, status->id); + return -EIO; + } + adr1_bits = raw_data[i++]; + if (num_data_blocks) { + *actual_bytes_read = (num_data_blocks - 1) * data_block_length + raw_data[i++]; + } else { + ++i; + *actual_bytes_read = 0; + } + if (*actual_bytes_read > j) + pr_err("%s: bug: discarded data. actual_bytes_read=%i, j=%i\n", + __func__, *actual_bytes_read, j); + for (k = 0; k < 2; k++) + if (raw_data[i++] != 0) { + pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n", + __func__, i - 1, (int)raw_data[i - 1]); + unexpected = 1; + } + i += ni_usb_parse_status_block(&raw_data[i], ®ister_write_status); + if (register_write_status.id != NIUSB_REG_WRITE_ID) { + pr_err("%s: unexpected data: register write status id=0x%x, expected 0x%x\n", + __func__, register_write_status.id, NIUSB_REG_WRITE_ID); + unexpected = 1; + } + if (raw_data[i++] != 2) { + pr_err("%s: unexpected data: register write count=%i, expected 2\n", + __func__, (int)raw_data[i - 1]); + unexpected = 1; + } + for (k = 0; k < 3; k++) + if (raw_data[i++] != 0) { + pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n", + __func__, i - 1, (int)raw_data[i - 1]); + unexpected = 1; + } + i += ni_usb_parse_termination_block(&raw_data[i]); + if (unexpected) + ni_usb_dump_raw_block(raw_data, i); + return i; +} + +static int ni_usb_parse_reg_write_status_block(const u8 *raw_data, + struct ni_usb_status_block *status, + int *writes_completed) +{ + int i = 0; + + i += ni_usb_parse_status_block(raw_data, status); + *writes_completed = raw_data[i++]; + while (i % 4) + i++; + return i; +} + +static int ni_usb_write_registers(struct ni_usb_priv *ni_priv, + const struct ni_usb_register *writes, int num_writes, + unsigned int *ibsta) +{ + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int retval; + u8 *out_data, *in_data; + int out_data_length; + static const int in_data_length = 0x20; + int bytes_written = 0, bytes_read = 0; + int i = 0; + int j; + struct ni_usb_status_block status; + static const int bytes_per_write = 3; + int reg_writes_completed; + + out_data_length = num_writes * bytes_per_write + 0x10; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) { + dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__); + return -ENOMEM; + } + i += ni_usb_bulk_register_write_header(&out_data[i], num_writes); + for (j = 0; j < num_writes; j++) + i += ni_usb_bulk_register_write(&out_data[i], writes[j]); + while (i % 4) + out_data[i++] = 0x00; + i += ni_usb_bulk_termination(&out_data[i]); + if (i > out_data_length) + dev_err(&usb_dev->dev, "%s: bug! buffer overrun\n", __func__); + + mutex_lock(&ni_priv->addressed_transfer_lock); + + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000); + kfree(out_data); + if (retval) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + return retval; + } + + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__); + return -ENOMEM; + } + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0); + if (retval || bytes_read != 16) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + ni_usb_dump_raw_block(in_data, bytes_read); + kfree(in_data); + return retval; + } + + mutex_unlock(&ni_priv->addressed_transfer_lock); + + ni_usb_parse_reg_write_status_block(in_data, &status, ®_writes_completed); + //FIXME parse extra 09 status bits and termination + kfree(in_data); + if (status.id != NIUSB_REG_WRITE_ID) { + dev_err(&usb_dev->dev, "%s: parse error, id=0x%x != NIUSB_REG_WRITE_ID\n", + __func__, status.id); + return -EIO; + } + if (status.error_code) { + dev_err(&usb_dev->dev, "%s: nonzero error code 0x%x\n", + __func__, status.error_code); + return -EIO; + } + if (reg_writes_completed != num_writes) { + dev_err(&usb_dev->dev, "%s: reg_writes_completed=%i, num_writes=%i\n", + __func__, reg_writes_completed, num_writes); + return -EIO; + } + if (ibsta) + *ibsta = status.ibsta; + return 0; +} + +// interface functions +static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read) +{ + int retval, parse_retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + static const int out_data_length = 0x20; + int in_data_length; + int usb_bytes_written = 0, usb_bytes_read = 0; + int i = 0; + int complement_count; + int actual_length; + struct ni_usb_status_block status; + static const int max_read_length = 0xffff; + struct ni_usb_register reg; + + *bytes_read = 0; + if (length > max_read_length) { + length = max_read_length; + dev_err(&usb_dev->dev, "%s: read length too long\n", __func__); + } + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + out_data[i++] = 0x0a; + out_data[i++] = ni_priv->eos_mode >> 8; + out_data[i++] = ni_priv->eos_char; + out_data[i++] = ni_usb_timeout_code(board->usec_timeout); + complement_count = length - 1; + complement_count = ~complement_count; + out_data[i++] = complement_count & 0xff; + out_data[i++] = (complement_count >> 8) & 0xff; + out_data[i++] = 0x0; + out_data[i++] = 0x0; + i += ni_usb_bulk_register_write_header(&out_data[i], 2); + reg.device = NIUSB_SUBDEV_TNT4882; + reg.address = nec7210_to_tnt4882_offset(AUXMR); + reg.value = AUX_HLDI; + i += ni_usb_bulk_register_write(&out_data[i], reg); + reg.value = AUX_CLEAR_END; + i += ni_usb_bulk_register_write(&out_data[i], reg); + while (i % 4) // pad with zeros to 4-byte boundary + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + + mutex_lock(&ni_priv->addressed_transfer_lock); + + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &usb_bytes_written, 1000); + kfree(out_data); + if (retval || usb_bytes_written != i) { + if (retval == 0) + retval = -EIO; + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n", + __func__, retval, usb_bytes_written, i); + mutex_unlock(&ni_priv->addressed_transfer_lock); + return retval; + } + + in_data_length = (length / 30 + 1) * 0x20 + 0x20; + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + return -ENOMEM; + } + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &usb_bytes_read, + ni_usb_timeout_msecs(board->usec_timeout), 1); + + mutex_unlock(&ni_priv->addressed_transfer_lock); + + if (retval == -ERESTARTSYS) { + } else if (retval) { + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, usb_bytes_read=%i\n", + __func__, retval, usb_bytes_read); + kfree(in_data); + return retval; + } + parse_retval = parse_board_ibrd_readback(in_data, &status, buffer, length, &actual_length); + if (parse_retval != usb_bytes_read) { + if (parse_retval >= 0) + parse_retval = -EIO; + dev_err(&usb_dev->dev, "%s: retval=%i usb_bytes_read=%i\n", + __func__, parse_retval, usb_bytes_read); + kfree(in_data); + return parse_retval; + } + if (actual_length != length - status.count) { + dev_err(&usb_dev->dev, "%s: actual_length=%i expected=%li\n", + __func__, actual_length, (long)(length - status.count)); + ni_usb_dump_raw_block(in_data, usb_bytes_read); + } + kfree(in_data); + switch (status.error_code) { + case NIUSB_NO_ERROR: + retval = 0; + break; + case NIUSB_ABORTED_ERROR: + /* this is expected if ni_usb_receive_bulk_msg got + * interrupted by a signal and returned -ERESTARTSYS + */ + break; + case NIUSB_ATN_STATE_ERROR: + retval = -EIO; + dev_err(&usb_dev->dev, "%s: read when ATN set\n", __func__); + break; + case NIUSB_ADDRESSING_ERROR: + retval = -EIO; + break; + case NIUSB_TIMEOUT_ERROR: + retval = -ETIMEDOUT; + break; + case NIUSB_EOSMODE_ERROR: + dev_err(&usb_dev->dev, "%s: driver bug, we should have been able to avoid NIUSB_EOSMODE_ERROR.\n", + __func__); + retval = -EINVAL; + break; + default: + dev_err(&usb_dev->dev, "%s: unknown error code=%i\n", __func__, status.error_code); + retval = -EIO; + break; + } + ni_usb_soft_update_status(board, status.ibsta, 0); + if (status.ibsta & END) + *end = 1; + else + *end = 0; + *bytes_read = actual_length; + return retval; +} + +static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + int out_data_length; + static const int in_data_length = 0x10; + int usb_bytes_written = 0, usb_bytes_read = 0; + int i = 0, j; + int complement_count; + struct ni_usb_status_block status; + static const int max_write_length = 0xffff; + + *bytes_written = 0; + if (length > max_write_length) { + length = max_write_length; + send_eoi = 0; + dev_err(&usb_dev->dev, "%s: write length too long\n", __func__); + } + out_data_length = length + 0x10; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + out_data[i++] = 0x0d; + complement_count = length - 1; + complement_count = ~complement_count; + out_data[i++] = complement_count & 0xff; + out_data[i++] = (complement_count >> 8) & 0xff; + out_data[i++] = ni_usb_timeout_code(board->usec_timeout); + out_data[i++] = 0x0; + out_data[i++] = 0x0; + if (send_eoi) + out_data[i++] = 0x8; + else + out_data[i++] = 0x0; + out_data[i++] = 0x0; + for (j = 0; j < length; j++) + out_data[i++] = buffer[j]; + while (i % 4) // pad with zeros to 4-byte boundary + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + + mutex_lock(&ni_priv->addressed_transfer_lock); + + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &usb_bytes_written, + ni_usb_timeout_msecs(board->usec_timeout)); + kfree(out_data); + if (retval || usb_bytes_written != i) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n", + __func__, retval, usb_bytes_written, i); + return retval; + } + + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) + return -ENOMEM; + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &usb_bytes_read, + ni_usb_timeout_msecs(board->usec_timeout), 1); + + mutex_unlock(&ni_priv->addressed_transfer_lock); + + if ((retval && retval != -ERESTARTSYS) || usb_bytes_read != 12) { + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, usb_bytes_read=%i\n", + __func__, retval, usb_bytes_read); + kfree(in_data); + return retval; + } + ni_usb_parse_status_block(in_data, &status); + kfree(in_data); + switch (status.error_code) { + case NIUSB_NO_ERROR: + retval = 0; + break; + case NIUSB_ABORTED_ERROR: + /* this is expected if ni_usb_receive_bulk_msg got + * interrupted by a signal and returned -ERESTARTSYS + */ + break; + case NIUSB_ADDRESSING_ERROR: + dev_err(&usb_dev->dev, "%s: Addressing error retval %d error code=%i\n", + __func__, retval, status.error_code); + retval = -ENXIO; + break; + case NIUSB_NO_LISTENER_ERROR: + retval = -ECOMM; + break; + case NIUSB_TIMEOUT_ERROR: + retval = -ETIMEDOUT; + break; + default: + dev_err(&usb_dev->dev, "%s: unknown error code=%i\n", + __func__, status.error_code); + retval = -EPIPE; + break; + } + ni_usb_soft_update_status(board, status.ibsta, 0); + *bytes_written = length - status.count; + return retval; +} + +static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *command_bytes_written) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + int out_data_length; + static const int in_data_length = 0x10; + int bytes_written = 0, bytes_read = 0; + int i = 0, j; + unsigned int complement_count; + struct ni_usb_status_block status; + // usb-b gives error 4 if you try to send more than 16 command bytes at once + static const int max_command_length = 0x10; + + *command_bytes_written = 0; + if (length > max_command_length) + length = max_command_length; + out_data_length = length + 0x10; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + out_data[i++] = 0x0c; + complement_count = length - 1; + complement_count = ~complement_count; + out_data[i++] = complement_count; + out_data[i++] = 0x0; + out_data[i++] = ni_usb_timeout_code(board->usec_timeout); + for (j = 0; j < length; j++) + out_data[i++] = buffer[j]; + while (i % 4) // pad with zeros to 4-byte boundary + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + + mutex_lock(&ni_priv->addressed_transfer_lock); + + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, + ni_usb_timeout_msecs(board->usec_timeout)); + kfree(out_data); + if (retval || bytes_written != i) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + return retval; + } + + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + return -ENOMEM; + } + + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, + ni_usb_timeout_msecs(board->usec_timeout), 1); + + mutex_unlock(&ni_priv->addressed_transfer_lock); + + if ((retval && retval != -ERESTARTSYS) || bytes_read != 12) { + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + kfree(in_data); + return retval; + } + ni_usb_parse_status_block(in_data, &status); + kfree(in_data); + *command_bytes_written = length - status.count; + switch (status.error_code) { + case NIUSB_NO_ERROR: + break; + case NIUSB_ABORTED_ERROR: + /* this is expected if ni_usb_receive_bulk_msg got + * interrupted by a signal and returned -ERESTARTSYS + */ + break; + case NIUSB_NO_BUS_ERROR: + return -ENOTCONN; + case NIUSB_EOSMODE_ERROR: + dev_err(&usb_dev->dev, "%s: got eosmode error. Driver bug?\n", __func__); + return -EIO; + case NIUSB_TIMEOUT_ERROR: + return -ETIMEDOUT; + default: + dev_err(&usb_dev->dev, "%s: unknown error code=%i\n", __func__, status.error_code); + return -EIO; + } + ni_usb_soft_update_status(board, status.ibsta, 0); + return 0; +} + +static int ni_usb_command(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written) +{ + size_t count; + int retval; + + *bytes_written = 0; + while (*bytes_written < length) { + retval = ni_usb_command_chunk(board, buffer + *bytes_written, + length - *bytes_written, &count); + *bytes_written += count; + if (retval < 0) + return retval; + } + return 0; +} + +static int ni_usb_take_control(gpib_board_t *board, int synchronous) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + static const int out_data_length = 0x10; + static const int in_data_length = 0x10; + int bytes_written = 0, bytes_read = 0; + int i = 0; + struct ni_usb_status_block status; + + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + out_data[i++] = NIUSB_IBCAC_ID; + if (synchronous) + out_data[i++] = 0x1; + else + out_data[i++] = 0x0; + out_data[i++] = 0x0; + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + + mutex_lock(&ni_priv->addressed_transfer_lock); + + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000); + kfree(out_data); + if (retval || bytes_written != i) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + return retval; + } + + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__); + return -ENOMEM; + } + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 1); + + mutex_unlock(&ni_priv->addressed_transfer_lock); + + if ((retval && retval != -ERESTARTSYS) || bytes_read != 12) { + if (retval == 0) + retval = -EIO; + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + kfree(in_data); + return retval; + } + ni_usb_parse_status_block(in_data, &status); + kfree(in_data); + ni_usb_soft_update_status(board, status.ibsta, 0); + return retval; +} + +static int ni_usb_go_to_standby(gpib_board_t *board) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + static const int out_data_length = 0x10; + static const int in_data_length = 0x20; + int bytes_written = 0, bytes_read = 0; + int i = 0; + struct ni_usb_status_block status; + + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + + out_data[i++] = NIUSB_IBGTS_ID; + out_data[i++] = 0x0; + out_data[i++] = 0x0; + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + + mutex_lock(&ni_priv->addressed_transfer_lock); + + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000); + kfree(out_data); + if (retval || bytes_written != i) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + return retval; + } + + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__); + return -ENOMEM; + } + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0); + + mutex_unlock(&ni_priv->addressed_transfer_lock); + + if (retval || bytes_read != 12) { + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + kfree(in_data); + return retval; + } + ni_usb_parse_status_block(in_data, &status); + kfree(in_data); + if (status.id != NIUSB_IBGTS_ID) + dev_err(&usb_dev->dev, "%s: bug: status.id 0x%x != INUSB_IBGTS_ID\n", + __func__, status.id); + ni_usb_soft_update_status(board, status.ibsta, 0); + return 0; +} + +static void ni_usb_request_system_control(gpib_board_t *board, int request_control) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int i = 0; + struct ni_usb_register writes[4]; + unsigned int ibsta; + + if (request_control) { + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = CMDR; + writes[i].value = SETSC; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_CIFC; + i++; + } else { + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_CREN; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_CIFC; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_DSC; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = CMDR; + writes[i].value = CLRSC; + i++; + } + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return; // retval; + } + if (!request_control) + ni_priv->ren_state = 0; + ni_usb_soft_update_status(board, ibsta, 0); + return; // 0; +} + +//FIXME maybe the interface should have a "pulse interface clear" function that can return an error? +static void ni_usb_interface_clear(gpib_board_t *board, int assert) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + static const int out_data_length = 0x10; + static const int in_data_length = 0x10; + int bytes_written = 0, bytes_read = 0; + int i = 0; + struct ni_usb_status_block status; + + // FIXME: we are going to pulse when assert is true, and ignore otherwise + if (assert == 0) + return; + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) { + dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__); + return; + } + out_data[i++] = NIUSB_IBSIC_ID; + out_data[i++] = 0x0; + out_data[i++] = 0x0; + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000); + kfree(out_data); + if (retval || bytes_written != i) { + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + return; + } + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) + return; + + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0); + if (retval || bytes_read != 12) { + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + kfree(in_data); + return; + } + ni_usb_parse_status_block(in_data, &status); + kfree(in_data); + ni_usb_soft_update_status(board, status.ibsta, 0); +} + +static void ni_usb_remote_enable(gpib_board_t *board, int enable) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + struct ni_usb_register reg; + unsigned int ibsta; + + reg.device = NIUSB_SUBDEV_TNT4882; + reg.address = nec7210_to_tnt4882_offset(AUXMR); + if (enable) + reg.value = AUX_SREN; + else + reg.value = AUX_CREN; + retval = ni_usb_write_registers(ni_priv, ®, 1, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return; //retval; + } + ni_priv->ren_state = enable; + ni_usb_soft_update_status(board, ibsta, 0); + return;// 0; +} + +static int ni_usb_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct ni_usb_priv *ni_priv = board->private_data; + + ni_priv->eos_char = eos_byte; + ni_priv->eos_mode |= REOS; + if (compare_8_bits) + ni_priv->eos_mode |= BIN; + else + ni_priv->eos_mode &= ~BIN; + return 0; +} + +static void ni_usb_disable_eos(gpib_board_t *board) +{ + struct ni_usb_priv *ni_priv = board->private_data; + /* adapter gets unhappy if you don't zero all the bits + * for the eos mode and eos char (returns error 4 on reads). + */ + ni_priv->eos_mode = 0; + ni_priv->eos_char = 0; +} + +static unsigned int ni_usb_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + static const int buffer_length = 8; + u8 *buffer; + struct ni_usb_status_block status; + + //printk("%s: receive control pipe is %i\n", __func__, pipe); + buffer = kmalloc(buffer_length, GFP_KERNEL); + if (!buffer) + return board->status; + + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_WAIT_REQUEST, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x200, 0x0, buffer, buffer_length, 1000); + if (retval != buffer_length) { + dev_err(&usb_dev->dev, "%s: usb_control_msg returned %i\n", __func__, retval); + kfree(buffer); + return board->status; + } + ni_usb_parse_status_block(buffer, &status); + kfree(buffer); + ni_usb_soft_update_status(board, status.ibsta, clear_mask); + return board->status; +} + +// tells ni-usb to immediately stop an ongoing i/o operation +static void ni_usb_stop(struct ni_usb_priv *ni_priv) +{ + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int retval; + static const int buffer_length = 8; + u8 *buffer; + struct ni_usb_status_block status; + + //printk("%s: receive control pipe is %i\n", __func__, pipe); + buffer = kmalloc(buffer_length, GFP_KERNEL); + if (!buffer) + return; + + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_STOP_REQUEST, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, 0x0, buffer, buffer_length, 1000); + if (retval != buffer_length) { + dev_err(&usb_dev->dev, "%s: usb_control_msg returned %i\n", __func__, retval); + kfree(buffer); + return; + } + ni_usb_parse_status_block(buffer, &status); + kfree(buffer); +} + +static int ni_usb_primary_address(gpib_board_t *board, unsigned int address) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int i = 0; + struct ni_usb_register writes[2]; + unsigned int ibsta; + + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(ADR); + writes[i].value = address; + i++; + writes[i].device = NIUSB_SUBDEV_UNKNOWN2; + writes[i].address = 0x0; + writes[i].value = address; + i++; + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return retval; + } + ni_usb_soft_update_status(board, ibsta, 0); + return 0; +} + +static int ni_usb_write_sad(struct ni_usb_register *writes, int address, int enable) +{ + unsigned int adr_bits, admr_bits; + int i = 0; + + adr_bits = HR_ARS; + admr_bits = HR_TRM0 | HR_TRM1; + if (enable) { + adr_bits |= address; + admr_bits |= HR_ADM1; + } else { + adr_bits |= HR_DT | HR_DL; + admr_bits |= HR_ADM0; + } + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(ADR); + writes[i].value = adr_bits; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(ADMR); + writes[i].value = admr_bits; + i++; + writes[i].device = NIUSB_SUBDEV_UNKNOWN2; + writes[i].address = 0x1; + writes[i].value = enable ? MSA(address) : 0x0; + i++; + return i; +} + +static int ni_usb_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int i = 0; + struct ni_usb_register writes[3]; + unsigned int ibsta; + + i += ni_usb_write_sad(writes, address, enable); + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return retval; + } + ni_usb_soft_update_status(board, ibsta, 0); + return 0; +} + +static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + static const int out_data_length = 0x10; + static const int in_data_length = 0x20; + int bytes_written = 0, bytes_read = 0; + int i = 0; + int j = 0; + struct ni_usb_status_block status; + + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + + out_data[i++] = NIUSB_IBRPP_ID; + out_data[i++] = 0xf0; //FIXME: this should be the parallel poll timeout code + out_data[i++] = 0x0; + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + /*FIXME: 1000 should use parallel poll timeout (not supported yet)*/ + retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000); + + kfree(out_data); + if (retval || bytes_written != i) { + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + return retval; + } + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) + return -ENOMEM; + + /*FIXME: should use parallel poll timeout (not supported yet)*/ + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, + &bytes_read, 1000, 1); + + if (retval && retval != -ERESTARTSYS) { + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + kfree(in_data); + return retval; + } + j += ni_usb_parse_status_block(in_data, &status); + *result = in_data[j++]; + kfree(in_data); + ni_usb_soft_update_status(board, status.ibsta, 0); + return retval; +} + +static void ni_usb_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int i = 0; + struct ni_usb_register writes[1]; + unsigned int ibsta; + + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = PPR | config; + i++; + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return;// retval; + } + ni_usb_soft_update_status(board, ibsta, 0); + return;// 0; +} + +static void ni_usb_parallel_poll_response(gpib_board_t *board, int ist) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int i = 0; + struct ni_usb_register writes[1]; + unsigned int ibsta; + + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + if (ist) + writes[i].value = AUX_SPPF; + else + writes[i].value = AUX_CPPF; + i++; + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return;// retval; + } + ni_usb_soft_update_status(board, ibsta, 0); + return;// 0; +} + +static void ni_usb_serial_poll_response(gpib_board_t *board, u8 status) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int i = 0; + struct ni_usb_register writes[1]; + unsigned int ibsta; + + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(SPMR); + writes[i].value = status; + i++; + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return;// retval; + } + ni_usb_soft_update_status(board, ibsta, 0); + return;// 0; +} + +static uint8_t ni_usb_serial_poll_status(gpib_board_t *board) +{ + return 0; +} + +static void ni_usb_return_to_local(gpib_board_t *board) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int i = 0; + struct ni_usb_register writes[1]; + unsigned int ibsta; + + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_RTL; + i++; + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return;// retval; + } + ni_usb_soft_update_status(board, ibsta, 0); + return;// 0; +} + +static int ni_usb_line_status(const gpib_board_t *board) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + u8 *out_data, *in_data; + static const int out_data_length = 0x20; + static const int in_data_length = 0x20; + int bytes_written = 0, bytes_read = 0; + int i = 0; + unsigned int bsr_bits; + int line_status = ValidALL; + // NI windows driver reads 0xd(HSSEL), 0xc (ARD0), 0x1f (BSR) + + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) + return -ENOMEM; + + /* line status gets called during ibwait */ + retval = mutex_trylock(&ni_priv->addressed_transfer_lock); + + if (retval == 0) { + kfree(out_data); + return -EBUSY; + } + i += ni_usb_bulk_register_read_header(&out_data[i], 1); + i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_TNT4882, BSR); + while (i % 4) + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + retval = ni_usb_nonblocking_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000); + kfree(out_data); + if (retval || bytes_written != i) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + if (retval != -EAGAIN) + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n", + __func__, retval, bytes_written, i); + return retval; + } + + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) { + mutex_unlock(&ni_priv->addressed_transfer_lock); + dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__); + return -ENOMEM; + } + retval = ni_usb_nonblocking_receive_bulk_msg(ni_priv, in_data, in_data_length, + &bytes_read, 1000, 0); + + mutex_unlock(&ni_priv->addressed_transfer_lock); + + if (retval) { + if (retval != -EAGAIN) + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + kfree(in_data); + return retval; + } + + ni_usb_parse_register_read_block(in_data, &bsr_bits, 1); + kfree(in_data); + if (bsr_bits & BCSR_REN_BIT) + line_status |= BusREN; + if (bsr_bits & BCSR_IFC_BIT) + line_status |= BusIFC; + if (bsr_bits & BCSR_SRQ_BIT) + line_status |= BusSRQ; + if (bsr_bits & BCSR_EOI_BIT) + line_status |= BusEOI; + if (bsr_bits & BCSR_NRFD_BIT) + line_status |= BusNRFD; + if (bsr_bits & BCSR_NDAC_BIT) + line_status |= BusNDAC; + if (bsr_bits & BCSR_DAV_BIT) + line_status |= BusDAV; + if (bsr_bits & BCSR_ATN_BIT) + line_status |= BusATN; + return line_status; +} + +static int ni_usb_setup_t1_delay(struct ni_usb_register *reg, unsigned int nano_sec, + unsigned int *actual_ns) +{ + int i = 0; + + *actual_ns = 2000; + + reg[i].device = NIUSB_SUBDEV_TNT4882; + reg[i].address = nec7210_to_tnt4882_offset(AUXMR); + if (nano_sec <= 1100) { + reg[i].value = AUXRI | USTD | SISB; + *actual_ns = 1100; + } else { + reg[i].value = AUXRI | SISB; + } + i++; + reg[i].device = NIUSB_SUBDEV_TNT4882; + reg[i].address = nec7210_to_tnt4882_offset(AUXMR); + if (nano_sec <= 500) { + reg[i].value = AUXRB | HR_TRI; + *actual_ns = 500; + } else { + reg[i].value = AUXRB; + } + i++; + reg[i].device = NIUSB_SUBDEV_TNT4882; + reg[i].address = KEYREG; + if (nano_sec <= 350) { + reg[i].value = MSTD; + *actual_ns = 350; + } else { + reg[i].value = 0x0; + } + i++; + return i; +} + +static unsigned int ni_usb_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + struct ni_usb_register writes[3]; + unsigned int ibsta; + unsigned int actual_ns; + int i; + + i = ni_usb_setup_t1_delay(writes, nano_sec, &actual_ns); + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return -1; //FIXME should change return type to int for error reporting + } + board->t1_nano_sec = actual_ns; + ni_usb_soft_update_status(board, ibsta, 0); + return actual_ns; +} + +static int ni_usb_allocate_private(gpib_board_t *board) +{ + struct ni_usb_priv *ni_priv; + + board->private_data = kmalloc(sizeof(struct ni_usb_priv), GFP_KERNEL); + if (!board->private_data) + return -ENOMEM; + ni_priv = board->private_data; + memset(ni_priv, 0, sizeof(struct ni_usb_priv)); + mutex_init(&ni_priv->bulk_transfer_lock); + mutex_init(&ni_priv->control_transfer_lock); + mutex_init(&ni_priv->interrupt_transfer_lock); + mutex_init(&ni_priv->addressed_transfer_lock); + return 0; +} + +static void ni_usb_free_private(struct ni_usb_priv *ni_priv) +{ + usb_free_urb(ni_priv->interrupt_urb); + kfree(ni_priv); +} + +#define NUM_INIT_WRITES 26 +static int ni_usb_setup_init(gpib_board_t *board, struct ni_usb_register *writes) +{ + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + unsigned int mask, actual_ns; + int i = 0; + + writes[i].device = NIUSB_SUBDEV_UNKNOWN3; + writes[i].address = 0x10; + writes[i].value = 0x0; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = CMDR; + writes[i].value = SOFT_RESET; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + mask = AUXRA | HR_HLDA; + if (ni_priv->eos_mode & BIN) + mask |= HR_BIN; + writes[i].value = mask; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = AUXCR; + writes[i].value = mask; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = HSSEL; + writes[i].value = TNT_ONE_CHIP_BIT; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_CR; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = IMR0; + writes[i].value = TNT_IMR0_ALWAYS_BITS; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(IMR1); + writes[i].value = 0x0; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(IMR2); + writes[i].value = 0x0; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = IMR3; + writes[i].value = 0x0; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_HLDI; + i++; + + i += ni_usb_setup_t1_delay(&writes[i], board->t1_nano_sec, &actual_ns); + + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUXRG | NTNL_BIT; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = CMDR; + if (board->master) + mask = SETSC; // set system controller + else + mask = CLRSC; // clear system controller + writes[i].value = mask; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_CIFC; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(ADR); + writes[i].value = board->pad; + i++; + writes[i].device = NIUSB_SUBDEV_UNKNOWN2; + writes[i].address = 0x0; + writes[i].value = board->pad; + i++; + + i += ni_usb_write_sad(&writes[i], board->sad, board->sad >= 0); + + writes[i].device = NIUSB_SUBDEV_UNKNOWN2; + writes[i].address = 0x2; // could this be a timeout ? + writes[i].value = 0xfd; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = 0xf; // undocumented address + writes[i].value = 0x11; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_PON; + i++; + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_CPPF; + i++; + if (i > NUM_INIT_WRITES) { + dev_err(&usb_dev->dev, "%s: bug!, buffer overrun, i=%i\n", __func__, i); + return 0; + } + return i; +} + +static int ni_usb_init(gpib_board_t *board) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + struct ni_usb_register *writes; + unsigned int ibsta; + int writes_len; + + writes = kmalloc_array(NUM_INIT_WRITES, sizeof(*writes), GFP_KERNEL); + if (!writes) + return -ENOMEM; + + writes_len = ni_usb_setup_init(board, writes); + if (writes_len) + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); + else + return -EFAULT; + kfree(writes); + if (retval) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return retval; + } + ni_usb_soft_update_status(board, ibsta, 0); + return 0; +} + +static void ni_usb_interrupt_complete(struct urb *urb) +{ + gpib_board_t *board = urb->context; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int retval; + struct ni_usb_status_block status; + unsigned long flags; + +// printk("debug: %s: status=0x%x, error_count=%i, actual_length=%i\n", __func__, +// urb->status, urb->error_count, urb->actual_length); + + switch (urb->status) { + /* success */ + case 0: + break; + /* unlinked, don't resubmit */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + return; + default: /* other error, resubmit */ + retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_ATOMIC); + if (retval) + dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__); + return; + } + + ni_usb_parse_status_block(urb->transfer_buffer, &status); +// printk("debug: ibsta=0x%x\n", status.ibsta); + + spin_lock_irqsave(&board->spinlock, flags); + ni_priv->monitored_ibsta_bits &= ~status.ibsta; +// printk("debug: monitored_ibsta_bits=0x%x\n", ni_priv->monitored_ibsta_bits); + spin_unlock_irqrestore(&board->spinlock, flags); + + wake_up_interruptible(&board->wait); + + retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_ATOMIC); + if (retval) + dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__); +} + +static int ni_usb_set_interrupt_monitor(gpib_board_t *board, unsigned int monitored_bits) +{ + int retval; + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + static const int buffer_length = 8; + u8 *buffer; + struct ni_usb_status_block status; + unsigned long flags; + //printk("%s: receive control pipe is %i\n", __func__, pipe); + buffer = kmalloc(buffer_length, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + spin_lock_irqsave(&board->spinlock, flags); + ni_priv->monitored_ibsta_bits = ni_usb_ibsta_monitor_mask & monitored_bits; +// dev_err(&usb_dev->dev, "debug: %s: monitored_ibsta_bits=0x%x\n", +// __func__, ni_priv->monitored_ibsta_bits); + spin_unlock_irqrestore(&board->spinlock, flags); + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_WAIT_REQUEST, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x300, ni_usb_ibsta_monitor_mask & monitored_bits, + buffer, buffer_length, 1000); + if (retval != buffer_length) { + dev_err(&usb_dev->dev, "%s: usb_control_msg returned %i\n", __func__, retval); + kfree(buffer); + return -1; + } + ni_usb_parse_status_block(buffer, &status); + kfree(buffer); + return 0; +} + +static int ni_usb_setup_urbs(gpib_board_t *board) +{ + struct ni_usb_priv *ni_priv = board->private_data; + struct usb_device *usb_dev; + int int_pipe; + int retval; + + if (ni_priv->interrupt_in_endpoint < 0) + return 0; + + mutex_lock(&ni_priv->interrupt_transfer_lock); + if (!ni_priv->bus_interface) { + mutex_unlock(&ni_priv->interrupt_transfer_lock); + return -ENODEV; + } + ni_priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ni_priv->interrupt_urb) { + mutex_unlock(&ni_priv->interrupt_transfer_lock); + return -ENOMEM; + } + usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int_pipe = usb_rcvintpipe(usb_dev, ni_priv->interrupt_in_endpoint); + usb_fill_int_urb(ni_priv->interrupt_urb, usb_dev, int_pipe, ni_priv->interrupt_buffer, + sizeof(ni_priv->interrupt_buffer), &ni_usb_interrupt_complete, board, 1); + retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_KERNEL); + mutex_unlock(&ni_priv->interrupt_transfer_lock); + if (retval) { + dev_err(&usb_dev->dev, "%s: failed to submit first interrupt urb, retval=%i\n", + __func__, retval); + return retval; + } + return 0; +} + +static void ni_usb_cleanup_urbs(struct ni_usb_priv *ni_priv) +{ + if (ni_priv && ni_priv->bus_interface) { + if (ni_priv->interrupt_urb) + usb_kill_urb(ni_priv->interrupt_urb); + if (ni_priv->bulk_urb) + usb_kill_urb(ni_priv->bulk_urb); + } +} + +static int ni_usb_b_read_serial_number(struct ni_usb_priv *ni_priv) +{ + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int retval; + u8 *out_data; + u8 *in_data; + static const int out_data_length = 0x20; + static const int in_data_length = 0x20; + int bytes_written = 0, bytes_read = 0; + int i = 0; + static const int num_reads = 4; + unsigned int results[4]; + int j; + unsigned int serial_number; + +// printk("%s: %s\n", __func__); + in_data = kmalloc(in_data_length, GFP_KERNEL); + if (!in_data) + return -ENOMEM; + + out_data = kmalloc(out_data_length, GFP_KERNEL); + if (!out_data) { + kfree(in_data); + return -ENOMEM; + } + i += ni_usb_bulk_register_read_header(&out_data[i], num_reads); + i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_1_REG); + i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_2_REG); + i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_3_REG); + i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_4_REG); + while (i % 4) + out_data[i++] = 0x0; + i += ni_usb_bulk_termination(&out_data[i]); + retval = ni_usb_send_bulk_msg(ni_priv, out_data, out_data_length, &bytes_written, 1000); + if (retval) { + dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%li\n", + __func__, + retval, bytes_written, (long)out_data_length); + goto serial_out; + } + retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0); + if (retval) { + dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n", + __func__, retval, bytes_read); + ni_usb_dump_raw_block(in_data, bytes_read); + goto serial_out; + } + if (ARRAY_SIZE(results) < num_reads) { + dev_err(&usb_dev->dev, "Setup bug\n"); + retval = -EINVAL; + goto serial_out; + } + ni_usb_parse_register_read_block(in_data, results, num_reads); + serial_number = 0; + for (j = 0; j < num_reads; ++j) + serial_number |= (results[j] & 0xff) << (8 * j); + dev_info(&usb_dev->dev, "%s: board serial number is 0x%x\n", __func__, serial_number); + retval = 0; +serial_out: + kfree(in_data); + kfree(out_data); + return retval; +} + +static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv) +{ + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + static const int buffer_size = 0x10; + static const int timeout = 50; + static const int msec_sleep_duration = 100; + int i; int retval; + int j; + int unexpected = 0; + unsigned int serial_number; + u8 *buffer; + + buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_SERIAL_NUMBER_REQUEST, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, 0x0, buffer, buffer_size, 1000); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n", + __func__, NI_USB_SERIAL_NUMBER_REQUEST, retval); + goto ready_out; + } + j = 0; + if (buffer[j] != NI_USB_SERIAL_NUMBER_REQUEST) { + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x%x\n", + __func__, j, (int)buffer[j], NI_USB_SERIAL_NUMBER_REQUEST); + unexpected = 1; + } + if (unexpected) + ni_usb_dump_raw_block(buffer, retval); + // NI-USB-HS+ pads the serial with 0x0 to make 16 bytes + if (retval != 5 && retval != 16) { + dev_err(&usb_dev->dev, "%s: received unexpected number of bytes = %i, expected 5 or 16\n", + __func__, retval); + ni_usb_dump_raw_block(buffer, retval); + } + serial_number = 0; + serial_number |= buffer[++j]; + serial_number |= (buffer[++j] << 8); + serial_number |= (buffer[++j] << 16); + serial_number |= (buffer[++j] << 24); + dev_info(&usb_dev->dev, "%s: board serial number is 0x%x\n", __func__, serial_number); + for (i = 0; i < timeout; ++i) { + int ready = 0; + + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_POLL_READY_REQUEST, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, 0x0, buffer, buffer_size, 100); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n", + __func__, NI_USB_POLL_READY_REQUEST, retval); + goto ready_out; + } + j = 0; + unexpected = 0; + if (buffer[j] != NI_USB_POLL_READY_REQUEST) { // [0] + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x%x\n", + __func__, j, (int)buffer[j], NI_USB_POLL_READY_REQUEST); + unexpected = 1; + } + ++j; + if (buffer[j] != 0x1 && buffer[j] != 0x0) { // [1] HS+ sends 0x0 + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + if (buffer[++j] != 0x0) { // [2] + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x%x\n", + __func__, j, (int)buffer[j], 0x0); + unexpected = 1; + } + ++j; + // MC usb-488 (and sometimes NI-USB-HS?) sends 0x8 here; MC usb-488A sends 0x7 here + // NI-USB-HS+ sends 0x0 + if (buffer[j] != 0x1 && buffer[j] != 0x8 && buffer[j] != 0x7 && buffer[j] != 0x0) { + // [3] + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0, 0x1, 0x7 or 0x8\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + ++j; + // NI-USB-HS+ sends 0 here + if (buffer[j] != 0x30 && buffer[j] != 0x0) { // [4] + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x30\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + ++j; + // MC usb-488 (and sometimes NI-USB-HS?) and NI-USB-HS+ sends 0x0 here + if (buffer[j] != 0x1 && buffer[j] != 0x0) { // [5] + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + if (buffer[++j] != 0x0) { // [6] + ready = 1; + // NI-USB-HS+ sends 0xf here + if (buffer[j] != 0x2 && buffer[j] != 0xe && buffer[j] != 0xf && + buffer[j] != 0x16) { + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x2, 0xe, 0xf or 0x16\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + } + if (buffer[++j] != 0x0) { // [7] + ready = 1; + // MC usb-488 sends 0x5 here; MC usb-488A sends 0x6 here + if (buffer[j] != 0x3 && buffer[j] != 0x5 && buffer[j] != 0x6 && + buffer[j] != 0x8) { + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x3 or 0x5, 0x6 or 0x08\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + } + ++j; + if (buffer[j] != 0x0 && buffer[j] != 0x2) { // [8] MC usb-488 sends 0x2 here + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x2\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + ++j; + // MC usb-488A and NI-USB-HS sends 0x3 here; NI-USB-HS+ sends 0x30 here + if (buffer[j] != 0x0 && buffer[j] != 0x3 && buffer[j] != 0x30) { // [9] + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0, 0x3 or 0x30\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + if (buffer[++j] != 0x0) { + ready = 1; + if (buffer[j] != 0x96 && buffer[j] != 0x7 && buffer[j] != 0x6e) { +// [10] MC usb-488 sends 0x7 here + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x96, 0x07 or 0x6e\n", + __func__, j, (int)buffer[j]); + unexpected = 1; + } + } + if (unexpected) + ni_usb_dump_raw_block(buffer, retval); + if (ready) + break; + retval = msleep_interruptible(msec_sleep_duration); + if (retval) { + dev_err(&usb_dev->dev, "ni_usb_gpib: msleep interrupted\n"); + retval = -ERESTARTSYS; + goto ready_out; + } + } + retval = 0; + +ready_out: + kfree(buffer); + dev_dbg(&usb_dev->dev, "%s: exit retval=%d\n", __func__, retval); + return retval; +} + +/* This does some extra init for HS+ models, as observed on Windows. One of the + * control requests causes the LED to stop blinking. + * I'm not sure what the other 2 requests do. None of these requests are actually required + * for the adapter to work, maybe they do some init for the analyzer interface + * (which we don't use). + */ +static int ni_usb_hs_plus_extra_init(struct ni_usb_priv *ni_priv) +{ + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int retval; + u8 *buffer; + static const int buffer_size = 16; + int transfer_size; + + buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + do { + transfer_size = 16; + + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_HS_PLUS_0x48_REQUEST, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, 0x0, buffer, transfer_size, 1000); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n", + __func__, NI_USB_HS_PLUS_0x48_REQUEST, retval); + break; + } + // expected response data: 48 f3 30 00 00 00 00 00 00 00 00 00 00 00 00 00 + if (buffer[0] != NI_USB_HS_PLUS_0x48_REQUEST) + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[0]=0x%x, expected 0x%x\n", + __func__, (int)buffer[0], NI_USB_HS_PLUS_0x48_REQUEST); + + transfer_size = 2; + + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_HS_PLUS_LED_REQUEST, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x1, 0x0, buffer, transfer_size, 1000); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n", + __func__, NI_USB_HS_PLUS_LED_REQUEST, retval); + break; + } + // expected response data: 4b 00 + if (buffer[0] != NI_USB_HS_PLUS_LED_REQUEST) + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[0]=0x%x, expected 0x%x\n", + __func__, (int)buffer[0], NI_USB_HS_PLUS_LED_REQUEST); + + transfer_size = 9; + + retval = ni_usb_receive_control_msg(ni_priv, NI_USB_HS_PLUS_0xf8_REQUEST, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_INTERFACE, + 0x0, 0x1, buffer, transfer_size, 1000); + if (retval < 0) { + dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n", + __func__, NI_USB_HS_PLUS_0xf8_REQUEST, retval); + break; + } + // expected response data: f8 01 00 00 00 01 00 00 00 + if (buffer[0] != NI_USB_HS_PLUS_0xf8_REQUEST) + dev_err(&usb_dev->dev, "%s: unexpected data: buffer[0]=0x%x, expected 0x%x\n", + __func__, (int)buffer[0], NI_USB_HS_PLUS_0xf8_REQUEST); + + } while (0); + + // cleanup + kfree(buffer); + return retval; +} + +static inline int ni_usb_device_match(struct usb_interface *interface, + const gpib_board_config_t *config) +{ + if (gpib_match_device_path(&interface->dev, config->device_path) == 0) + return 0; + return 1; +} + +static int ni_usb_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + int retval; + int i; + struct ni_usb_priv *ni_priv; + int product_id; + struct usb_device *usb_dev; + + mutex_lock(&ni_usb_hotplug_lock); + retval = ni_usb_allocate_private(board); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + ni_priv = board->private_data; + for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) { + if (ni_usb_driver_interfaces[i] && + !usb_get_intfdata(ni_usb_driver_interfaces[i]) && + ni_usb_device_match(ni_usb_driver_interfaces[i], config)) { + ni_priv->bus_interface = ni_usb_driver_interfaces[i]; + usb_set_intfdata(ni_usb_driver_interfaces[i], board); + usb_dev = interface_to_usbdev(ni_priv->bus_interface); + dev_info(&usb_dev->dev, + "bus %d dev num %d attached to gpib minor %d, NI usb interface %i\n", + usb_dev->bus->busnum, usb_dev->devnum, board->minor, i); + break; + } + } + if (i == MAX_NUM_NI_USB_INTERFACES) { + mutex_unlock(&ni_usb_hotplug_lock); + pr_err("No supported NI usb gpib adapters found, have you loaded its firmware?\n"); + return -ENODEV; + } + if (usb_reset_configuration(interface_to_usbdev(ni_priv->bus_interface))) + dev_err(&usb_dev->dev, "ni_usb_gpib: usb_reset_configuration() failed.\n"); + + product_id = le16_to_cpu(usb_dev->descriptor.idProduct); + ni_priv->product_id = product_id; + + timer_setup(&ni_priv->bulk_timer, ni_usb_timeout_handler, 0); + + switch (product_id) { + case USB_DEVICE_ID_NI_USB_B: + ni_priv->bulk_out_endpoint = NIUSB_B_BULK_OUT_ENDPOINT; + ni_priv->bulk_in_endpoint = NIUSB_B_BULK_IN_ENDPOINT; + ni_priv->interrupt_in_endpoint = NIUSB_B_INTERRUPT_IN_ENDPOINT; + ni_usb_b_read_serial_number(ni_priv); + break; + case USB_DEVICE_ID_NI_USB_HS: + case USB_DEVICE_ID_MC_USB_488: + case USB_DEVICE_ID_KUSB_488A: + ni_priv->bulk_out_endpoint = NIUSB_HS_BULK_OUT_ENDPOINT; + ni_priv->bulk_in_endpoint = NIUSB_HS_BULK_IN_ENDPOINT; + ni_priv->interrupt_in_endpoint = NIUSB_HS_INTERRUPT_IN_ENDPOINT; + retval = ni_usb_hs_wait_for_ready(ni_priv); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + break; + case USB_DEVICE_ID_NI_USB_HS_PLUS: + ni_priv->bulk_out_endpoint = NIUSB_HS_PLUS_BULK_OUT_ENDPOINT; + ni_priv->bulk_in_endpoint = NIUSB_HS_PLUS_BULK_IN_ENDPOINT; + ni_priv->interrupt_in_endpoint = NIUSB_HS_PLUS_INTERRUPT_IN_ENDPOINT; + retval = ni_usb_hs_wait_for_ready(ni_priv); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + retval = ni_usb_hs_plus_extra_init(ni_priv); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + break; + default: + mutex_unlock(&ni_usb_hotplug_lock); + dev_err(&usb_dev->dev, "\tDriver bug: unknown endpoints for usb device id %x\n", + product_id); + return -EINVAL; + } + + retval = ni_usb_setup_urbs(board); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + retval = ni_usb_set_interrupt_monitor(board, 0); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + + board->t1_nano_sec = 500; + + retval = ni_usb_init(board); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + retval = ni_usb_set_interrupt_monitor(board, ni_usb_ibsta_monitor_mask); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + + mutex_unlock(&ni_usb_hotplug_lock); + dev_info(&usb_dev->dev, "%s: attached\n", __func__); + return retval; +} + +static int ni_usb_shutdown_hardware(struct ni_usb_priv *ni_priv) +{ + struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface); + int retval; + int i = 0; + struct ni_usb_register writes[2]; + static const int writes_length = ARRAY_SIZE(writes); + unsigned int ibsta; + +// printk("%s: %s\n", __func__); + writes[i].device = NIUSB_SUBDEV_TNT4882; + writes[i].address = nec7210_to_tnt4882_offset(AUXMR); + writes[i].value = AUX_CR; + i++; + writes[i].device = NIUSB_SUBDEV_UNKNOWN3; + writes[i].address = 0x10; + writes[i].value = 0x0; + i++; + if (i > writes_length) { + dev_err(&usb_dev->dev, "%s: bug!, buffer overrun, i=%i\n", __func__, i); + return -EINVAL; + } + retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta); + if (retval) { + dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval); + return retval; + } + return 0; +} + +static void ni_usb_detach(gpib_board_t *board) +{ + struct ni_usb_priv *ni_priv; + + mutex_lock(&ni_usb_hotplug_lock); +// under windows, software unplug does chip_reset nec7210 aux command, +// then writes 0x0 to address 0x10 of device 3 + ni_priv = board->private_data; + if (ni_priv) { + if (ni_priv->bus_interface) { + ni_usb_set_interrupt_monitor(board, 0); + ni_usb_shutdown_hardware(ni_priv); + usb_set_intfdata(ni_priv->bus_interface, NULL); + } + mutex_lock(&ni_priv->bulk_transfer_lock); + mutex_lock(&ni_priv->control_transfer_lock); + mutex_lock(&ni_priv->interrupt_transfer_lock); + ni_usb_cleanup_urbs(ni_priv); + ni_usb_free_private(ni_priv); + } + mutex_unlock(&ni_usb_hotplug_lock); +} + +gpib_interface_t ni_usb_gpib_interface = { +name: "ni_usb_b", +attach : ni_usb_attach, +detach : ni_usb_detach, +read : ni_usb_read, +write : ni_usb_write, +command : ni_usb_command, +take_control : ni_usb_take_control, +go_to_standby : ni_usb_go_to_standby, +request_system_control : ni_usb_request_system_control, +interface_clear : ni_usb_interface_clear, +remote_enable : ni_usb_remote_enable, +enable_eos : ni_usb_enable_eos, +disable_eos : ni_usb_disable_eos, +parallel_poll : ni_usb_parallel_poll, +parallel_poll_configure : ni_usb_parallel_poll_configure, +parallel_poll_response : ni_usb_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : ni_usb_line_status, +update_status : ni_usb_update_status, +primary_address : ni_usb_primary_address, +secondary_address : ni_usb_secondary_address, +serial_poll_response : ni_usb_serial_poll_response, +serial_poll_status : ni_usb_serial_poll_status, +t1_delay : ni_usb_t1_delay, +return_to_local : ni_usb_return_to_local, +skip_check_for_command_acceptors : 1 +}; + +// Table with the USB-devices: just now only testing IDs +static struct usb_device_id ni_usb_driver_device_table[] = { + {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_NI_USB_B)}, + {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_NI_USB_HS)}, + // gpib-usb-hs+ has a second interface for the analyzer, which we ignore + {USB_DEVICE_INTERFACE_NUMBER(USB_VENDOR_ID_NI, USB_DEVICE_ID_NI_USB_HS_PLUS, 0)}, + {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_KUSB_488A)}, + {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_MC_USB_488)}, + {} /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, ni_usb_driver_device_table); + +static int ni_usb_driver_probe(struct usb_interface *interface, const struct usb_device_id *id) +{ + struct usb_device *usb_dev = interface_to_usbdev(interface); + int i; + char *path; + static const int path_length = 1024; + + mutex_lock(&ni_usb_hotplug_lock); + usb_get_dev(usb_dev); + for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) { + if (!ni_usb_driver_interfaces[i]) { + ni_usb_driver_interfaces[i] = interface; + usb_set_intfdata(interface, NULL); + break; + } + } + if (i == MAX_NUM_NI_USB_INTERFACES) { + usb_put_dev(usb_dev); + mutex_unlock(&ni_usb_hotplug_lock); + dev_err(&usb_dev->dev, "%s: ni_usb_driver_interfaces[] full\n", __func__); + return -1; + } + path = kmalloc(path_length, GFP_KERNEL); + if (!path) { + usb_put_dev(usb_dev); + mutex_unlock(&ni_usb_hotplug_lock); + return -ENOMEM; + } + usb_make_path(usb_dev, path, path_length); + dev_info(&usb_dev->dev, "ni_usb_gpib: probe succeeded for path: %s\n", path); + kfree(path); + mutex_unlock(&ni_usb_hotplug_lock); + return 0; +} + +static void ni_usb_driver_disconnect(struct usb_interface *interface) +{ + struct usb_device *usb_dev = interface_to_usbdev(interface); + int i; + + mutex_lock(&ni_usb_hotplug_lock); + for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) { + if (ni_usb_driver_interfaces[i] == interface) { + gpib_board_t *board = usb_get_intfdata(interface); + + if (board) { + struct ni_usb_priv *ni_priv = board->private_data; + + if (ni_priv) { + mutex_lock(&ni_priv->bulk_transfer_lock); + mutex_lock(&ni_priv->control_transfer_lock); + mutex_lock(&ni_priv->interrupt_transfer_lock); + ni_usb_cleanup_urbs(ni_priv); + ni_priv->bus_interface = NULL; + mutex_unlock(&ni_priv->interrupt_transfer_lock); + mutex_unlock(&ni_priv->control_transfer_lock); + mutex_unlock(&ni_priv->bulk_transfer_lock); + } + } + ni_usb_driver_interfaces[i] = NULL; + break; + } + } + if (i == MAX_NUM_NI_USB_INTERFACES) + dev_err(&usb_dev->dev, "%s: unable to find interface in ni_usb_driver_interfaces[]? bug?\n", + __func__); + usb_put_dev(usb_dev); + mutex_unlock(&ni_usb_hotplug_lock); +} + +static int ni_usb_driver_suspend(struct usb_interface *interface, pm_message_t message) +{ + struct usb_device *usb_dev = interface_to_usbdev(interface); + gpib_board_t *board; + int i, retval; + + mutex_lock(&ni_usb_hotplug_lock); + + for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) { + if (ni_usb_driver_interfaces[i] == interface) { + board = usb_get_intfdata(interface); + if (board) + break; + } + } + if (i == MAX_NUM_NI_USB_INTERFACES) { + mutex_unlock(&ni_usb_hotplug_lock); + return 0; + } + + struct ni_usb_priv *ni_priv = board->private_data; + + if (ni_priv) { + ni_usb_set_interrupt_monitor(board, 0); + retval = ni_usb_shutdown_hardware(ni_priv); + if (retval) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + if (ni_priv->interrupt_urb) { + mutex_lock(&ni_priv->interrupt_transfer_lock); + ni_usb_cleanup_urbs(ni_priv); + mutex_unlock(&ni_priv->interrupt_transfer_lock); + } + dev_info(&usb_dev->dev, + "bus %d dev num %d gpib minor %d, ni usb interface %i suspended\n", + usb_dev->bus->busnum, usb_dev->devnum, board->minor, i); + } + + mutex_unlock(&ni_usb_hotplug_lock); + return 0; +} + +static int ni_usb_driver_resume(struct usb_interface *interface) +{ + struct usb_device *usb_dev = interface_to_usbdev(interface); + + gpib_board_t *board; + int i, retval; + + mutex_lock(&ni_usb_hotplug_lock); + + for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) { + if (ni_usb_driver_interfaces[i] == interface) { + board = usb_get_intfdata(interface); + if (board) + break; + } + } + if (i == MAX_NUM_NI_USB_INTERFACES) { + mutex_unlock(&ni_usb_hotplug_lock); + return 0; + } + + struct ni_usb_priv *ni_priv = board->private_data; + + if (ni_priv) { + if (ni_priv->interrupt_urb) { + mutex_lock(&ni_priv->interrupt_transfer_lock); + retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_KERNEL); + if (retval) { + dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb, retval=%i\n", + __func__, retval); + mutex_unlock(&ni_priv->interrupt_transfer_lock); + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + mutex_unlock(&ni_priv->interrupt_transfer_lock); + } else { + dev_err(&usb_dev->dev, "%s: bug! int urb not set up\n", __func__); + mutex_unlock(&ni_usb_hotplug_lock); + return -EINVAL; + } + + switch (ni_priv->product_id) { + case USB_DEVICE_ID_NI_USB_B: + ni_usb_b_read_serial_number(ni_priv); + break; + case USB_DEVICE_ID_NI_USB_HS: + case USB_DEVICE_ID_MC_USB_488: + case USB_DEVICE_ID_KUSB_488A: + retval = ni_usb_hs_wait_for_ready(ni_priv); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + break; + case USB_DEVICE_ID_NI_USB_HS_PLUS: + retval = ni_usb_hs_wait_for_ready(ni_priv); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + retval = ni_usb_hs_plus_extra_init(ni_priv); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + break; + default: + mutex_unlock(&ni_usb_hotplug_lock); + dev_err(&usb_dev->dev, "\tDriver bug: unknown endpoints for usb device id\n"); + return -EINVAL; + } + + retval = ni_usb_set_interrupt_monitor(board, 0); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + + retval = ni_usb_init(board); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + retval = ni_usb_set_interrupt_monitor(board, ni_usb_ibsta_monitor_mask); + if (retval < 0) { + mutex_unlock(&ni_usb_hotplug_lock); + return retval; + } + if (board->master) + ni_usb_interface_clear(board, 1); // this is a pulsed action + if (ni_priv->ren_state) + ni_usb_remote_enable(board, 1); + + dev_info(&usb_dev->dev, + "bus %d dev num %d gpib minor %d, ni usb interface %i resumed\n", + usb_dev->bus->busnum, usb_dev->devnum, board->minor, i); + } + + mutex_unlock(&ni_usb_hotplug_lock); + return 0; +} + +static struct usb_driver ni_usb_bus_driver = { + .name = "ni_usb_gpib", + .probe = ni_usb_driver_probe, + .disconnect = ni_usb_driver_disconnect, + .suspend = ni_usb_driver_suspend, + .resume = ni_usb_driver_resume, + .id_table = ni_usb_driver_device_table, +}; + +static int __init ni_usb_init_module(void) +{ + int i; + + pr_info("ni_usb_gpib driver loading\n"); + for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) + ni_usb_driver_interfaces[i] = NULL; + usb_register(&ni_usb_bus_driver); + gpib_register_driver(&ni_usb_gpib_interface, THIS_MODULE); + + return 0; +} + +static void __exit ni_usb_exit_module(void) +{ + pr_info("ni_usb_gpib driver unloading\n"); + gpib_unregister_driver(&ni_usb_gpib_interface); + usb_deregister(&ni_usb_bus_driver); +} + +module_init(ni_usb_init_module); +module_exit(ni_usb_exit_module); diff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.h b/drivers/staging/gpib/ni_usb/ni_usb_gpib.h new file mode 100644 index 0000000000000000000000000000000000000000..9b21dfa0f3f6d12480a86bdf3a9ecade24eaeb8a --- /dev/null +++ b/drivers/staging/gpib/ni_usb/ni_usb_gpib.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2004 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _NI_USB_GPIB_H +#define _NI_USB_GPIB_H + +#include +#include +#include +#include +#include "gpibP.h" + +enum { + USB_VENDOR_ID_NI = 0x3923 +}; + +enum { + USB_DEVICE_ID_NI_USB_B = 0x702a, + USB_DEVICE_ID_NI_USB_B_PREINIT = 0x702b, // device id before firmware is loaded + USB_DEVICE_ID_NI_USB_HS = 0x709b, + USB_DEVICE_ID_NI_USB_HS_PLUS = 0x7618, + USB_DEVICE_ID_KUSB_488A = 0x725c, + USB_DEVICE_ID_MC_USB_488 = 0x725d +}; + +enum ni_usb_device { + NIUSB_SUBDEV_TNT4882 = 1, + NIUSB_SUBDEV_UNKNOWN2 = 2, + NIUSB_SUBDEV_UNKNOWN3 = 3, +}; + +enum endpoint_addresses { + NIUSB_B_BULK_OUT_ENDPOINT = 0x2, + NIUSB_B_BULK_IN_ENDPOINT = 0x2, + NIUSB_B_BULK_IN_ALT_ENDPOINT = 0x6, + NIUSB_B_INTERRUPT_IN_ENDPOINT = 0x4, +}; + +enum hs_enpoint_addresses { + NIUSB_HS_BULK_OUT_ENDPOINT = 0x2, + NIUSB_HS_BULK_OUT_ALT_ENDPOINT = 0x6, + NIUSB_HS_BULK_IN_ENDPOINT = 0x4, + NIUSB_HS_BULK_IN_ALT_ENDPOINT = 0x8, + NIUSB_HS_INTERRUPT_IN_ENDPOINT = 0x1, +}; + +enum hs_plus_endpoint_addresses { + NIUSB_HS_PLUS_BULK_OUT_ENDPOINT = 0x1, + NIUSB_HS_PLUS_BULK_OUT_ALT_ENDPOINT = 0x4, + NIUSB_HS_PLUS_BULK_IN_ENDPOINT = 0x2, + NIUSB_HS_PLUS_BULK_IN_ALT_ENDPOINT = 0x5, + NIUSB_HS_PLUS_INTERRUPT_IN_ENDPOINT = 0x3, +}; + +struct ni_usb_urb_ctx { + struct semaphore complete; + unsigned timed_out : 1; +}; + +// struct which defines private_data for ni_usb devices +struct ni_usb_priv { + struct usb_interface *bus_interface; + int bulk_out_endpoint; + int bulk_in_endpoint; + int interrupt_in_endpoint; + u8 eos_char; + unsigned short eos_mode; + unsigned int monitored_ibsta_bits; + struct urb *bulk_urb; + struct urb *interrupt_urb; + u8 interrupt_buffer[0x11]; + struct mutex addressed_transfer_lock; // protect transfer lock + struct mutex bulk_transfer_lock; // protect bulk message sends + struct mutex control_transfer_lock; // protect control messages + struct mutex interrupt_transfer_lock; // protect interrupt messages + struct timer_list bulk_timer; + struct ni_usb_urb_ctx context; + int product_id; + unsigned short ren_state; +}; + +struct ni_usb_status_block { + short id; + unsigned short ibsta; + short error_code; + unsigned short count; +}; + +struct ni_usb_register { + enum ni_usb_device device; + short address; + unsigned short value; +}; + +enum ni_usb_bulk_ids { + NIUSB_IBCAC_ID = 0x1, + NIUSB_UNKNOWN3_ID = 0x3, // device level function id? + NIUSB_TERM_ID = 0x4, + NIUSB_IBGTS_ID = 0x6, + NIUSB_IBRPP_ID = 0x7, + NIUSB_REG_READ_ID = 0x8, + NIUSB_REG_WRITE_ID = 0x9, + NIUSB_IBSIC_ID = 0xf, + NIUSB_REGISTER_READ_DATA_START_ID = 0x34, + NIUSB_REGISTER_READ_DATA_END_ID = 0x35, + NIUSB_IBRD_DATA_ID = 0x36, + NIUSB_IBRD_EXTENDED_DATA_ID = 0x37, + NIUSB_IBRD_STATUS_ID = 0x38 +}; + +enum ni_usb_error_codes { + NIUSB_NO_ERROR = 0, + /* NIUSB_ABORTED_ERROR occurs when I/O is interrupted early by + * doing a NI_USB_STOP_REQUEST on the control endpoint. + */ + NIUSB_ABORTED_ERROR = 1, + // NIUSB_READ_ATN_ERROR occurs when you do a board read while + // ATN is set + NIUSB_ATN_STATE_ERROR = 2, + // NIUSB_ADDRESSING_ERROR occurs when you do a board + // read/write as CIC but are not in LACS/TACS + NIUSB_ADDRESSING_ERROR = 3, + /* NIUSB_EOSMODE_ERROR occurs on reads if any eos mode or char + * bits are set when REOS is not set. + * Have also seen error 4 if you try to send more than 16 + * command bytes at once on a usb-b. + */ + NIUSB_EOSMODE_ERROR = 4, + // NIUSB_NO_BUS_ERROR occurs when you try to write a command + // byte but there are no devices connected to the gpib bus + NIUSB_NO_BUS_ERROR = 5, + // NIUSB_NO_LISTENER_ERROR occurs when you do a board write as + // CIC with no listener + NIUSB_NO_LISTENER_ERROR = 8, + // get NIUSB_TIMEOUT_ERROR on board read/write timeout + NIUSB_TIMEOUT_ERROR = 10, +}; + +enum ni_usb_control_requests { + NI_USB_STOP_REQUEST = 0x20, + NI_USB_WAIT_REQUEST = 0x21, + NI_USB_POLL_READY_REQUEST = 0x40, + NI_USB_SERIAL_NUMBER_REQUEST = 0x41, + NI_USB_HS_PLUS_0x48_REQUEST = 0x48, + NI_USB_HS_PLUS_LED_REQUEST = 0x4b, + NI_USB_HS_PLUS_0xf8_REQUEST = 0xf8 +}; + +static const unsigned int ni_usb_ibsta_monitor_mask = + SRQI | LOK | REM | CIC | ATN | TACS | LACS | DTAS | DCAS; + +static inline int nec7210_to_tnt4882_offset(int offset) +{ + return 2 * offset; +}; + +static inline int ni_usb_bulk_termination(u8 *buffer) +{ + int i = 0; + + buffer[i++] = NIUSB_TERM_ID; + buffer[i++] = 0x0; + buffer[i++] = 0x0; + buffer[i++] = 0x0; + return i; +} + +enum ni_usb_unknown3_register { + SERIAL_NUMBER_4_REG = 0x8, + SERIAL_NUMBER_3_REG = 0x9, + SERIAL_NUMBER_2_REG = 0xa, + SERIAL_NUMBER_1_REG = 0xb, +}; + +static inline int ni_usb_bulk_register_write_header(u8 *buffer, int num_writes) +{ + int i = 0; + + buffer[i++] = NIUSB_REG_WRITE_ID; + buffer[i++] = num_writes; + buffer[i++] = 0x0; + return i; +} + +static inline int ni_usb_bulk_register_write(u8 *buffer, struct ni_usb_register reg) +{ + int i = 0; + + buffer[i++] = reg.device; + buffer[i++] = reg.address; + buffer[i++] = reg.value; + return i; +} + +static inline int ni_usb_bulk_register_read_header(u8 *buffer, int num_reads) +{ + int i = 0; + + buffer[i++] = NIUSB_REG_READ_ID; + buffer[i++] = num_reads; + return i; +} + +static inline int ni_usb_bulk_register_read(u8 *buffer, int device, int address) +{ + int i = 0; + + buffer[i++] = device; + buffer[i++] = address; + return i; +} + +#endif // _NI_USB_GPIB_H diff --git a/drivers/staging/gpib/pc2/Makefile b/drivers/staging/gpib/pc2/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8148425e0f8760a771474c5578baf802927feba1 --- /dev/null +++ b/drivers/staging/gpib/pc2/Makefile @@ -0,0 +1,5 @@ + +obj-m += pc2_gpib.o + + + diff --git a/drivers/staging/gpib/pc2/pc2_gpib.c b/drivers/staging/gpib/pc2/pc2_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..7b3b34f4734168eb01859ae1bfe428dcb6fb8783 --- /dev/null +++ b/drivers/staging/gpib/pc2/pc2_gpib.c @@ -0,0 +1,656 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2001, 2002 by Frank Mori Hess + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nec7210.h" +#include "gpibP.h" + +// struct which defines private_data for pc2 driver +struct pc2_priv { + struct nec7210_priv nec7210_priv; + unsigned int irq; + // io address that clears interrupt for pc2a (0x2f0 + irq) + unsigned int clear_intr_addr; +}; + +// pc2 uses 8 consecutive io addresses +static const int pc2_iosize = 8; +static const int pc2a_iosize = 8; +static const int pc2_2a_iosize = 16; + +// offset between io addresses of successive nec7210 registers +static const int pc2a_reg_offset = 0x400; +static const int pc2_reg_offset = 1; + +//interrupt service routine +static irqreturn_t pc2_interrupt(int irq, void *arg); +static irqreturn_t pc2a_interrupt(int irq, void *arg); + +// pc2 specific registers and bits + +// interrupt clear register address +static const int pc2a_clear_intr_iobase = 0x2f0; +static inline unsigned int CLEAR_INTR_REG(unsigned int irq) +{ + return pc2a_clear_intr_iobase + irq; +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for PC2/PC2a and compatible devices"); + +static int pc2_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int pc2a_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int pc2a_cb7210_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int pc2_2a_attach(gpib_board_t *board, const gpib_board_config_t *config); + +static void pc2_detach(gpib_board_t *board); +static void pc2a_detach(gpib_board_t *board); +static void pc2_2a_detach(gpib_board_t *board); + +/* + * GPIB interrupt service routines + */ + +irqreturn_t pc2_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + struct pc2_priv *priv = board->private_data; + unsigned long flags; + irqreturn_t retval; + + spin_lock_irqsave(&board->spinlock, flags); + retval = nec7210_interrupt(board, &priv->nec7210_priv); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +irqreturn_t pc2a_interrupt(int irq, void *arg) +{ + gpib_board_t *board = arg; + struct pc2_priv *priv = board->private_data; + int status1, status2; + unsigned long flags; + irqreturn_t retval; + + spin_lock_irqsave(&board->spinlock, flags); + // read interrupt status (also clears status) + status1 = read_byte(&priv->nec7210_priv, ISR1); + status2 = read_byte(&priv->nec7210_priv, ISR2); + /* clear interrupt circuit */ + if (priv->irq) + outb(0xff, CLEAR_INTR_REG(priv->irq)); + retval = nec7210_interrupt_have_status(board, &priv->nec7210_priv, status1, status2); + spin_unlock_irqrestore(&board->spinlock, flags); + return retval; +} + +// wrappers for interface functions +static int pc2_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); +} + +static int pc2_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); +} + +static int pc2_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); +} + +static int pc2_take_control(gpib_board_t *board, int synchronous) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_take_control(board, &priv->nec7210_priv, synchronous); +} + +static int pc2_go_to_standby(gpib_board_t *board) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_go_to_standby(board, &priv->nec7210_priv); +} + +static void pc2_request_system_control(gpib_board_t *board, int request_control) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_request_system_control(board, &priv->nec7210_priv, request_control); +} + +static void pc2_interface_clear(gpib_board_t *board, int assert) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_interface_clear(board, &priv->nec7210_priv, assert); +} + +static void pc2_remote_enable(gpib_board_t *board, int enable) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_remote_enable(board, &priv->nec7210_priv, enable); +} + +static int pc2_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); +} + +static void pc2_disable_eos(gpib_board_t *board) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_disable_eos(board, &priv->nec7210_priv); +} + +static unsigned int pc2_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); +} + +static int pc2_primary_address(gpib_board_t *board, unsigned int address) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_primary_address(board, &priv->nec7210_priv, address); +} + +static int pc2_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); +} + +static int pc2_parallel_poll(gpib_board_t *board, uint8_t *result) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_parallel_poll(board, &priv->nec7210_priv, result); +} + +static void pc2_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config); +} + +static void pc2_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); +} + +static void pc2_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_serial_poll_response(board, &priv->nec7210_priv, status); +} + +static uint8_t pc2_serial_poll_status(gpib_board_t *board) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_serial_poll_status(board, &priv->nec7210_priv); +} + +static unsigned int pc2_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct pc2_priv *priv = board->private_data; + + return nec7210_t1_delay(board, &priv->nec7210_priv, nano_sec); +} + +static void pc2_return_to_local(gpib_board_t *board) +{ + struct pc2_priv *priv = board->private_data; + + nec7210_return_to_local(board, &priv->nec7210_priv); +} + +gpib_interface_t pc2_interface = { +name: "pcII", +attach : pc2_attach, +detach : pc2_detach, +read : pc2_read, +write : pc2_write, +command : pc2_command, +take_control : pc2_take_control, +go_to_standby : pc2_go_to_standby, +request_system_control : pc2_request_system_control, +interface_clear : pc2_interface_clear, +remote_enable : pc2_remote_enable, +enable_eos : pc2_enable_eos, +disable_eos : pc2_disable_eos, +parallel_poll : pc2_parallel_poll, +parallel_poll_configure : pc2_parallel_poll_configure, +parallel_poll_response : pc2_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : NULL, +update_status : pc2_update_status, +primary_address : pc2_primary_address, +secondary_address : pc2_secondary_address, +serial_poll_response : pc2_serial_poll_response, +serial_poll_status : pc2_serial_poll_status, +t1_delay : pc2_t1_delay, +return_to_local : pc2_return_to_local, +}; + +gpib_interface_t pc2a_interface = { +name: "pcIIa", +attach : pc2a_attach, +detach : pc2a_detach, +read : pc2_read, +write : pc2_write, +command : pc2_command, +take_control : pc2_take_control, +go_to_standby : pc2_go_to_standby, +request_system_control : pc2_request_system_control, +interface_clear : pc2_interface_clear, +remote_enable : pc2_remote_enable, +enable_eos : pc2_enable_eos, +disable_eos : pc2_disable_eos, +parallel_poll : pc2_parallel_poll, +parallel_poll_configure : pc2_parallel_poll_configure, +parallel_poll_response : pc2_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : NULL, +update_status : pc2_update_status, +primary_address : pc2_primary_address, +secondary_address : pc2_secondary_address, +serial_poll_response : pc2_serial_poll_response, +serial_poll_status : pc2_serial_poll_status, +t1_delay : pc2_t1_delay, +return_to_local : pc2_return_to_local, +}; + +gpib_interface_t pc2a_cb7210_interface = { +name: "pcIIa_cb7210", +attach : pc2a_cb7210_attach, +detach : pc2a_detach, +read : pc2_read, +write : pc2_write, +command : pc2_command, +take_control : pc2_take_control, +go_to_standby : pc2_go_to_standby, +request_system_control : pc2_request_system_control, +interface_clear : pc2_interface_clear, +remote_enable : pc2_remote_enable, +enable_eos : pc2_enable_eos, +disable_eos : pc2_disable_eos, +parallel_poll : pc2_parallel_poll, +parallel_poll_configure : pc2_parallel_poll_configure, +parallel_poll_response : pc2_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : NULL, //XXX +update_status : pc2_update_status, +primary_address : pc2_primary_address, +secondary_address : pc2_secondary_address, +serial_poll_response : pc2_serial_poll_response, +serial_poll_status : pc2_serial_poll_status, +t1_delay : pc2_t1_delay, +return_to_local : pc2_return_to_local, +}; + +gpib_interface_t pc2_2a_interface = { +name: "pcII_IIa", +attach : pc2_2a_attach, +detach : pc2_2a_detach, +read : pc2_read, +write : pc2_write, +command : pc2_command, +take_control : pc2_take_control, +go_to_standby : pc2_go_to_standby, +request_system_control : pc2_request_system_control, +interface_clear : pc2_interface_clear, +remote_enable : pc2_remote_enable, +enable_eos : pc2_enable_eos, +disable_eos : pc2_disable_eos, +parallel_poll : pc2_parallel_poll, +parallel_poll_configure : pc2_parallel_poll_configure, +parallel_poll_response : pc2_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : NULL, +update_status : pc2_update_status, +primary_address : pc2_primary_address, +secondary_address : pc2_secondary_address, +serial_poll_response : pc2_serial_poll_response, +serial_poll_status : pc2_serial_poll_status, +t1_delay : pc2_t1_delay, +return_to_local : pc2_return_to_local, +}; + +static int allocate_private(gpib_board_t *board) +{ + struct pc2_priv *priv; + + board->private_data = kmalloc(sizeof(struct pc2_priv), GFP_KERNEL); + if (!board->private_data) + return -1; + priv = board->private_data; + memset(priv, 0, sizeof(struct pc2_priv)); + init_nec7210_private(&priv->nec7210_priv); + return 0; +} + +static void free_private(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +static int pc2_generic_attach(gpib_board_t *board, const gpib_board_config_t *config, + enum nec7210_chipset chipset) +{ + struct pc2_priv *pc2_priv; + struct nec7210_priv *nec_priv; + + board->status = 0; + if (allocate_private(board)) + return -ENOMEM; + pc2_priv = board->private_data; + nec_priv = &pc2_priv->nec7210_priv; + nec_priv->read_byte = nec7210_ioport_read_byte; + nec_priv->write_byte = nec7210_ioport_write_byte; + nec_priv->type = chipset; + +#ifndef PC2_DMA + /* board->dev hasn't been initialized, so forget about DMA until this driver + * is adapted to use isa_register_driver. + */ + if (config->ibdma) + pr_err("DMA disabled for pc2 gpib, driver needs to be adapted to use isa_register_driver to get a struct device*"); +#else + if (config->ibdma) { + nec_priv->dma_buffer_length = 0x1000; + nec_priv->dma_buffer = dma_alloc_coherent(board->dev, + nec_priv->dma_buffer_length, & + nec_priv->dma_buffer_addr, GFP_ATOMIC); + if (!nec_priv->dma_buffer) + return -ENOMEM; + + // request isa dma channel + if (request_dma(config->ibdma, "pc2")) { + pr_err("gpib: can't request DMA %d\n", config->ibdma); + return -1; + } + nec_priv->dma_channel = config->ibdma; + } +#endif + + return 0; +} + +int pc2_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + int isr_flags = 0; + struct pc2_priv *pc2_priv; + struct nec7210_priv *nec_priv; + int retval; + + retval = pc2_generic_attach(board, config, NEC7210); + if (retval) + return retval; + + pc2_priv = board->private_data; + nec_priv = &pc2_priv->nec7210_priv; + nec_priv->offset = pc2_reg_offset; + + if (request_region((unsigned long)config->ibbase, pc2_iosize, "pc2") == 0) { + pr_err("gpib: ioports are already in use\n"); + return -1; + } + nec_priv->iobase = config->ibbase; + + nec7210_board_reset(nec_priv, board); + + // install interrupt handler + if (config->ibirq) { + if (request_irq(config->ibirq, pc2_interrupt, isr_flags, "pc2", board)) { + pr_err("gpib: can't request IRQ %d\n", config->ibirq); + return -1; + } + } + pc2_priv->irq = config->ibirq; + /* poll so we can detect assertion of ATN */ + if (gpib_request_pseudo_irq(board, pc2_interrupt)) { + pr_err("pc2_gpib: failed to allocate pseudo_irq\n"); + return -1; + } + /* set internal counter register for 8 MHz input clock */ + write_byte(nec_priv, ICR | 8, AUXMR); + + nec7210_board_online(nec_priv, board); + + return 0; +} + +void pc2_detach(gpib_board_t *board) +{ + struct pc2_priv *pc2_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (pc2_priv) { + nec_priv = &pc2_priv->nec7210_priv; +#ifdef PC2_DMA + if (nec_priv->dma_channel) + free_dma(nec_priv->dma_channel); +#endif + gpib_free_pseudo_irq(board); + if (pc2_priv->irq) + free_irq(pc2_priv->irq, board); + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + release_region((unsigned long)(nec_priv->iobase), pc2_iosize); + } + if (nec_priv->dma_buffer) { + dma_free_coherent(board->dev, nec_priv->dma_buffer_length, + nec_priv->dma_buffer, nec_priv->dma_buffer_addr); + nec_priv->dma_buffer = NULL; + } + } + free_private(board); +} + +static int pc2a_common_attach(gpib_board_t *board, const gpib_board_config_t *config, + unsigned int num_registers, enum nec7210_chipset chipset) +{ + unsigned int i, j; + struct pc2_priv *pc2_priv; + struct nec7210_priv *nec_priv; + int retval; + + retval = pc2_generic_attach(board, config, chipset); + if (retval) + return retval; + + pc2_priv = board->private_data; + nec_priv = &pc2_priv->nec7210_priv; + nec_priv->offset = pc2a_reg_offset; + + switch ((unsigned long)(config->ibbase)) { + case 0x02e1: + case 0x22e1: + case 0x42e1: + case 0x62e1: + break; + default: + pr_err("PCIIa base range invalid, must be one of 0x[0246]2e1, but is 0x%p\n", + config->ibbase); + return -1; + } + + if (config->ibirq) { + if (config->ibirq < 2 || config->ibirq > 7) { + pr_err("pc2_gpib: illegal interrupt level %i\n", config->ibirq); + return -1; + } + } else { + pr_err("pc2_gpib: interrupt disabled, using polling mode (slow)\n"); + } +#ifdef CHECK_IOPORTS + unsigned int err = 0; + + for (i = 0; i < num_registers; i++) { + if (check_region((unsigned long)config->ibbase + i * pc2a_reg_offset, 1)) + err++; + } + if (config->ibirq && check_region(pc2a_clear_intr_iobase + config->ibirq, 1)) + err++; + if (err) { + pr_err("gpib: ioports are already in use"); + return -1; + } +#endif + for (i = 0; i < num_registers; i++) { + if (!request_region((unsigned long)config->ibbase + + i * pc2a_reg_offset, 1, "pc2a")) { + pr_err("gpib: ioports are already in use"); + for (j = 0; j < i; j++) + release_region((unsigned long)(config->ibbase) + + j * pc2a_reg_offset, 1); + return -1; + } + } + nec_priv->iobase = config->ibbase; + if (config->ibirq) { + if (!request_region(pc2a_clear_intr_iobase + config->ibirq, 1, "pc2a")) { + pr_err("gpib: ioports are already in use"); + return -1; + } + pc2_priv->clear_intr_addr = pc2a_clear_intr_iobase + config->ibirq; + if (request_irq(config->ibirq, pc2a_interrupt, 0, "pc2a", board)) { + pr_err("gpib: can't request IRQ %d\n", config->ibirq); + return -1; + } + } + pc2_priv->irq = config->ibirq; + /* poll so we can detect assertion of ATN */ + if (gpib_request_pseudo_irq(board, pc2_interrupt)) { + pr_err("pc2_gpib: failed to allocate pseudo_irq\n"); + return -1; + } + + // make sure interrupt is clear + if (pc2_priv->irq) + outb(0xff, CLEAR_INTR_REG(pc2_priv->irq)); + + nec7210_board_reset(nec_priv, board); + + /* set internal counter register for 8 MHz input clock */ + write_byte(nec_priv, ICR | 8, AUXMR); + + nec7210_board_online(nec_priv, board); + + return 0; +} + +int pc2a_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + return pc2a_common_attach(board, config, pc2a_iosize, NEC7210); +} + +int pc2a_cb7210_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + return pc2a_common_attach(board, config, pc2a_iosize, CB7210); +} + +int pc2_2a_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + return pc2a_common_attach(board, config, pc2_2a_iosize, NAT4882); +} + +static void pc2a_common_detach(gpib_board_t *board, unsigned int num_registers) +{ + int i; + struct pc2_priv *pc2_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (pc2_priv) { + nec_priv = &pc2_priv->nec7210_priv; +#ifdef PC2_DMA + if (nec_priv->dma_channel) + free_dma(nec_priv->dma_channel); +#endif + gpib_free_pseudo_irq(board); + if (pc2_priv->irq) + free_irq(pc2_priv->irq, board); + if (nec_priv->iobase) { + nec7210_board_reset(nec_priv, board); + for (i = 0; i < num_registers; i++) + release_region((unsigned long)nec_priv->iobase + + i * pc2a_reg_offset, 1); + } + if (pc2_priv->clear_intr_addr) + release_region(pc2_priv->clear_intr_addr, 1); + if (nec_priv->dma_buffer) { + dma_free_coherent(board->dev, nec_priv->dma_buffer_length, + nec_priv->dma_buffer, + nec_priv->dma_buffer_addr); + nec_priv->dma_buffer = NULL; + } + } + free_private(board); +} + +void pc2a_detach(gpib_board_t *board) +{ + pc2a_common_detach(board, pc2a_iosize); +} + +void pc2_2a_detach(gpib_board_t *board) +{ + pc2a_common_detach(board, pc2_2a_iosize); +} + +static int __init pc2_init_module(void) +{ + gpib_register_driver(&pc2_interface, THIS_MODULE); + gpib_register_driver(&pc2a_interface, THIS_MODULE); + gpib_register_driver(&pc2a_cb7210_interface, THIS_MODULE); + gpib_register_driver(&pc2_2a_interface, THIS_MODULE); + + return 0; +} + +static void __exit pc2_exit_module(void) +{ + gpib_unregister_driver(&pc2_interface); + gpib_unregister_driver(&pc2a_interface); + gpib_unregister_driver(&pc2a_cb7210_interface); + gpib_unregister_driver(&pc2_2a_interface); +} + +module_init(pc2_init_module); +module_exit(pc2_exit_module); + diff --git a/drivers/staging/gpib/tms9914/Makefile b/drivers/staging/gpib/tms9914/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..81b7e3cf104c0ed5528aaa20d2155c20067de23f --- /dev/null +++ b/drivers/staging/gpib/tms9914/Makefile @@ -0,0 +1,6 @@ + +obj-m += tms9914.o + + + + diff --git a/drivers/staging/gpib/tms9914/tms9914.c b/drivers/staging/gpib/tms9914/tms9914.c new file mode 100644 index 0000000000000000000000000000000000000000..152b243b845b50927814786cf220e43c75b2cd4f --- /dev/null +++ b/drivers/staging/gpib/tms9914/tms9914.c @@ -0,0 +1,910 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * copyright : (C) 2001, 2002 by Frank Mori Hess + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpibP.h" +#include "tms9914.h" + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB library for tms9914"); + +static unsigned int update_status_nolock(gpib_board_t *board, struct tms9914_priv *priv); + +int tms9914_take_control(gpib_board_t *board, struct tms9914_priv *priv, int synchronous) +{ + int i; + const int timeout = 100; + + if (synchronous) + write_byte(priv, AUX_TCS, AUXCR); + else + write_byte(priv, AUX_TCA, AUXCR); + // busy wait until ATN is asserted + for (i = 0; i < timeout; i++) { + if ((read_byte(priv, ADSR) & HR_ATN)) + break; + udelay(1); + } + if (i == timeout) + return -ETIMEDOUT; + + clear_bit(WRITE_READY_BN, &priv->state); + + return 0; +} +EXPORT_SYMBOL_GPL(tms9914_take_control); + +/* The agilent 82350B has a buggy implementation of tcs which interferes with the + * operation of tca. It appears to be based on the controller state machine + * described in the TI 9900 TMS9914A data manual published in 1982. This + * manual describes tcs as putting the controller into a CWAS + * state where it waits indefinitely for ANRS and ignores tca. Since a + * functioning tca is far more important than tcs, we work around the + * problem by never issuing tcs. + * + * I don't know if this problem exists in the real tms9914a or just in the fpga + * of the 82350B. For now, only the agilent_82350b uses this workaround. + * The rest of the tms9914 based drivers still use tms9914_take_control + * directly (which does issue tcs). + */ +int tms9914_take_control_workaround(gpib_board_t *board, struct tms9914_priv *priv, int synchronous) +{ + if (synchronous) + return -ETIMEDOUT; + return tms9914_take_control(board, priv, synchronous); +} +EXPORT_SYMBOL_GPL(tms9914_take_control_workaround); + +int tms9914_go_to_standby(gpib_board_t *board, struct tms9914_priv *priv) +{ + int i; + const int timeout = 1000; + + write_byte(priv, AUX_GTS, AUXCR); + // busy wait until ATN is released + for (i = 0; i < timeout; i++) { + if ((read_byte(priv, ADSR) & HR_ATN) == 0) + break; + udelay(1); + } + if (i == timeout) { + pr_err("error waiting for NATN\n"); + return -ETIMEDOUT; + } + + clear_bit(COMMAND_READY_BN, &priv->state); + + return 0; +} +EXPORT_SYMBOL_GPL(tms9914_go_to_standby); + +void tms9914_interface_clear(gpib_board_t *board, struct tms9914_priv *priv, int assert) +{ + if (assert) { + write_byte(priv, AUX_SIC | AUX_CS, AUXCR); + + set_bit(CIC_NUM, &board->status); + } else { + write_byte(priv, AUX_SIC, AUXCR); + } +} +EXPORT_SYMBOL_GPL(tms9914_interface_clear); + +void tms9914_remote_enable(gpib_board_t *board, struct tms9914_priv *priv, int enable) +{ + if (enable) + write_byte(priv, AUX_SRE | AUX_CS, AUXCR); + else + write_byte(priv, AUX_SRE, AUXCR); +} +EXPORT_SYMBOL_GPL(tms9914_remote_enable); + +void tms9914_request_system_control(gpib_board_t *board, struct tms9914_priv *priv, + int request_control) +{ + if (request_control) { + write_byte(priv, AUX_RQC, AUXCR); + } else { + clear_bit(CIC_NUM, &board->status); + write_byte(priv, AUX_RLC, AUXCR); + } +} +EXPORT_SYMBOL_GPL(tms9914_request_system_control); + +unsigned int tms9914_t1_delay(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int nano_sec) +{ + static const int clock_period = 200; // assuming 5Mhz input clock + int num_cycles; + + num_cycles = 12; + + if (nano_sec <= 8 * clock_period) { + write_byte(priv, AUX_STDL | AUX_CS, AUXCR); + num_cycles = 8; + } else { + write_byte(priv, AUX_STDL, AUXCR); + } + + if (nano_sec <= 4 * clock_period) { + write_byte(priv, AUX_VSTDL | AUX_CS, AUXCR); + num_cycles = 4; + } else { + write_byte(priv, AUX_VSTDL, AUXCR); + } + + return num_cycles * clock_period; +} +EXPORT_SYMBOL_GPL(tms9914_t1_delay); + +void tms9914_return_to_local(const gpib_board_t *board, struct tms9914_priv *priv) +{ + write_byte(priv, AUX_RTL, AUXCR); +} +EXPORT_SYMBOL_GPL(tms9914_return_to_local); + +void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode) +{ + switch (mode) { + case TMS9914_HOLDOFF_NONE: + write_byte(priv, AUX_HLDE, AUXCR); + write_byte(priv, AUX_HLDA, AUXCR); + break; + case TMS9914_HOLDOFF_EOI: + write_byte(priv, AUX_HLDE | AUX_CS, AUXCR); + write_byte(priv, AUX_HLDA, AUXCR); + break; + case TMS9914_HOLDOFF_ALL: + write_byte(priv, AUX_HLDE, AUXCR); + write_byte(priv, AUX_HLDA | AUX_CS, AUXCR); + break; + default: + pr_err("%s: bug! bad holdoff mode %i\n", __func__, mode); + break; + } + priv->holdoff_mode = mode; +} +EXPORT_SYMBOL_GPL(tms9914_set_holdoff_mode); + +void tms9914_release_holdoff(struct tms9914_priv *priv) +{ + if (priv->holdoff_active) { + write_byte(priv, AUX_RHDF, AUXCR); + priv->holdoff_active = 0; + } +} +EXPORT_SYMBOL_GPL(tms9914_release_holdoff); + +int tms9914_enable_eos(gpib_board_t *board, struct tms9914_priv *priv, uint8_t eos_byte, + int compare_8_bits) +{ + priv->eos = eos_byte; + priv->eos_flags = REOS; + if (compare_8_bits) + priv->eos_flags |= BIN; + return 0; +} +EXPORT_SYMBOL(tms9914_enable_eos); + +void tms9914_disable_eos(gpib_board_t *board, struct tms9914_priv *priv) +{ + priv->eos_flags &= ~REOS; +} +EXPORT_SYMBOL(tms9914_disable_eos); + +int tms9914_parallel_poll(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *result) +{ + // execute parallel poll + write_byte(priv, AUX_CS | AUX_RPP, AUXCR); + udelay(2); + *result = read_byte(priv, CPTR); + // clear parallel poll state + write_byte(priv, AUX_RPP, AUXCR); + return 0; +} +EXPORT_SYMBOL(tms9914_parallel_poll); + +static void set_ppoll_reg(struct tms9914_priv *priv, int enable, + unsigned int dio_line, int sense, int ist) +{ + u8 dio_byte; + + if (enable && ((sense && ist) || (!sense && !ist))) { + dio_byte = 1 << (dio_line - 1); + write_byte(priv, dio_byte, PPR); + } else { + write_byte(priv, 0, PPR); + } +} + +void tms9914_parallel_poll_configure(gpib_board_t *board, + struct tms9914_priv *priv, uint8_t config) +{ + priv->ppoll_enable = (config & PPC_DISABLE) == 0; + priv->ppoll_line = (config & PPC_DIO_MASK) + 1; + priv->ppoll_sense = (config & PPC_SENSE) != 0; + set_ppoll_reg(priv, priv->ppoll_enable, priv->ppoll_line, priv->ppoll_sense, board->ist); +} +EXPORT_SYMBOL(tms9914_parallel_poll_configure); + +void tms9914_parallel_poll_response(gpib_board_t *board, + struct tms9914_priv *priv, int ist) +{ + set_ppoll_reg(priv, priv->ppoll_enable, priv->ppoll_line, priv->ppoll_sense, ist); +} +EXPORT_SYMBOL(tms9914_parallel_poll_response); + +void tms9914_serial_poll_response(gpib_board_t *board, struct tms9914_priv *priv, uint8_t status) +{ + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + write_byte(priv, status, SPMR); + priv->spoll_status = status; + if (status & request_service_bit) + write_byte(priv, AUX_RSV2 | AUX_CS, AUXCR); + else + write_byte(priv, AUX_RSV2, AUXCR); + spin_unlock_irqrestore(&board->spinlock, flags); +} +EXPORT_SYMBOL(tms9914_serial_poll_response); + +uint8_t tms9914_serial_poll_status(gpib_board_t *board, struct tms9914_priv *priv) +{ + u8 status; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + status = priv->spoll_status; + spin_unlock_irqrestore(&board->spinlock, flags); + + return status; +} +EXPORT_SYMBOL(tms9914_serial_poll_status); + +int tms9914_primary_address(gpib_board_t *board, struct tms9914_priv *priv, unsigned int address) +{ + // put primary address in address0 + write_byte(priv, address & ADDRESS_MASK, ADR); + return 0; +} +EXPORT_SYMBOL(tms9914_primary_address); + +int tms9914_secondary_address(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int address, int enable) +{ + if (enable) + priv->imr1_bits |= HR_APTIE; + else + priv->imr1_bits &= ~HR_APTIE; + + write_byte(priv, priv->imr1_bits, IMR1); + return 0; +} +EXPORT_SYMBOL(tms9914_secondary_address); + +unsigned int tms9914_update_status(gpib_board_t *board, struct tms9914_priv *priv, + unsigned int clear_mask) +{ + unsigned long flags; + unsigned int retval; + + spin_lock_irqsave(&board->spinlock, flags); + retval = update_status_nolock(board, priv); + board->status &= ~clear_mask; + spin_unlock_irqrestore(&board->spinlock, flags); + + return retval; +} +EXPORT_SYMBOL(tms9914_update_status); + +static void update_talker_state(struct tms9914_priv *priv, unsigned int address_status_bits) +{ + if (address_status_bits & HR_TA) { + if (address_status_bits & HR_ATN) + priv->talker_state = talker_addressed; + else + /* this could also be serial_poll_active, but the tms9914 provides no + * way to distinguish, so we'll assume talker_active + */ + priv->talker_state = talker_active; + } else { + priv->talker_state = talker_idle; + } +} + +static void update_listener_state(struct tms9914_priv *priv, unsigned int address_status_bits) +{ + if (address_status_bits & HR_LA) { + if (address_status_bits & HR_ATN) + priv->listener_state = listener_addressed; + else + priv->listener_state = listener_active; + } else { + priv->listener_state = listener_idle; + } +} + +static unsigned int update_status_nolock(gpib_board_t *board, struct tms9914_priv *priv) +{ + int address_status; + int bsr_bits; + + address_status = read_byte(priv, ADSR); + + // check for remote/local + if (address_status & HR_REM) + set_bit(REM_NUM, &board->status); + else + clear_bit(REM_NUM, &board->status); + // check for lockout + if (address_status & HR_LLO) + set_bit(LOK_NUM, &board->status); + else + clear_bit(LOK_NUM, &board->status); + // check for ATN + if (address_status & HR_ATN) + set_bit(ATN_NUM, &board->status); + else + clear_bit(ATN_NUM, &board->status); + // check for talker/listener addressed + update_talker_state(priv, address_status); + if (priv->talker_state == talker_active || priv->talker_state == talker_addressed) + set_bit(TACS_NUM, &board->status); + else + clear_bit(TACS_NUM, &board->status); + + update_listener_state(priv, address_status); + if (priv->listener_state == listener_active || priv->listener_state == listener_addressed) + set_bit(LACS_NUM, &board->status); + else + clear_bit(LACS_NUM, &board->status); + // Check for SRQI - not reset elsewhere except in autospoll + if (board->status & SRQI) { + bsr_bits = read_byte(priv, BSR); + if (!(bsr_bits & BSR_SRQ_BIT)) + clear_bit(SRQI_NUM, &board->status); + } + + dev_dbg(board->gpib_dev, "status 0x%lx, state 0x%lx\n", board->status, priv->state); + + return board->status; +} + +int tms9914_line_status(const gpib_board_t *board, struct tms9914_priv *priv) +{ + int bsr_bits; + int status = ValidALL; + + bsr_bits = read_byte(priv, BSR); + + if (bsr_bits & BSR_REN_BIT) + status |= BusREN; + if (bsr_bits & BSR_IFC_BIT) + status |= BusIFC; + if (bsr_bits & BSR_SRQ_BIT) + status |= BusSRQ; + if (bsr_bits & BSR_EOI_BIT) + status |= BusEOI; + if (bsr_bits & BSR_NRFD_BIT) + status |= BusNRFD; + if (bsr_bits & BSR_NDAC_BIT) + status |= BusNDAC; + if (bsr_bits & BSR_DAV_BIT) + status |= BusDAV; + if (bsr_bits & BSR_ATN_BIT) + status |= BusATN; + + return status; +} +EXPORT_SYMBOL(tms9914_line_status); + +static int check_for_eos(struct tms9914_priv *priv, uint8_t byte) +{ + static const u8 seven_bit_compare_mask = 0x7f; + + if ((priv->eos_flags & REOS) == 0) + return 0; + + if (priv->eos_flags & BIN) { + if (priv->eos == byte) + return 1; + } else { + if ((priv->eos & seven_bit_compare_mask) == (byte & seven_bit_compare_mask)) + return 1; + } + return 0; +} + +static int wait_for_read_byte(gpib_board_t *board, struct tms9914_priv *priv) +{ + if (wait_event_interruptible(board->wait, + test_bit(READ_READY_BN, &priv->state) || + test_bit(DEV_CLEAR_BN, &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_debug("gpib: pio read wait interrupted\n"); + return -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + return -ETIMEDOUT; + + if (test_bit(DEV_CLEAR_BN, &priv->state)) + return -EINTR; + return 0; +} + +static inline uint8_t tms9914_read_data_in(gpib_board_t *board, struct tms9914_priv *priv, int *end) +{ + unsigned long flags; + u8 data; + + spin_lock_irqsave(&board->spinlock, flags); + clear_bit(READ_READY_BN, &priv->state); + data = read_byte(priv, DIR); + if (test_and_clear_bit(RECEIVED_END_BN, &priv->state)) + *end = 1; + else + *end = 0; + switch (priv->holdoff_mode) { + case TMS9914_HOLDOFF_EOI: + if (*end) + priv->holdoff_active = 1; + break; + case TMS9914_HOLDOFF_ALL: + priv->holdoff_active = 1; + break; + case TMS9914_HOLDOFF_NONE: + break; + default: + pr_err("%s: bug! bad holdoff mode %i\n", __func__, priv->holdoff_mode); + break; + } + spin_unlock_irqrestore(&board->spinlock, flags); + + return data; +} + +static int pio_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + ssize_t retval = 0; + + *bytes_read = 0; + *end = 0; + while (*bytes_read < length && *end == 0) { + tms9914_release_holdoff(priv); + retval = wait_for_read_byte(board, priv); + if (retval < 0) + return retval; + buffer[(*bytes_read)++] = tms9914_read_data_in(board, priv, end); + + if (check_for_eos(priv, buffer[*bytes_read - 1])) + *end = 1; + } + + return retval; +} + +int tms9914_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, int *end, size_t *bytes_read) +{ + ssize_t retval = 0; + size_t num_bytes; + + *end = 0; + *bytes_read = 0; + if (length == 0) + return 0; + + clear_bit(DEV_CLEAR_BN, &priv->state); + + // transfer data (except for last byte) + if (length > 1) { + if (priv->eos_flags & REOS) + tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL); + else + tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_EOI); + // PIO transfer + retval = pio_read(board, priv, buffer, length - 1, end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + return retval; + buffer += num_bytes; + length -= num_bytes; + } + // read last bytes if we havn't received an END yet + if (*end == 0) { + // make sure we holdoff after last byte read + tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL); + retval = pio_read(board, priv, buffer, length, end, &num_bytes); + *bytes_read += num_bytes; + if (retval < 0) + return retval; + } + return 0; +} +EXPORT_SYMBOL(tms9914_read); + +static int pio_write_wait(gpib_board_t *board, struct tms9914_priv *priv) +{ + // wait until next byte is ready to be sent + if (wait_event_interruptible(board->wait, + test_bit(WRITE_READY_BN, &priv->state) || + test_bit(BUS_ERROR_BN, &priv->state) || + test_bit(DEV_CLEAR_BN, &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted!\n"); + return -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + return -ETIMEDOUT; + if (test_bit(BUS_ERROR_BN, &priv->state)) + return -EIO; + if (test_bit(DEV_CLEAR_BN, &priv->state)) + return -EINTR; + + return 0; +} + +static int pio_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, size_t *bytes_written) +{ + ssize_t retval = 0; + unsigned long flags; + + *bytes_written = 0; + while (*bytes_written < length) { + retval = pio_write_wait(board, priv); + if (retval < 0) + break; + + spin_lock_irqsave(&board->spinlock, flags); + clear_bit(WRITE_READY_BN, &priv->state); + write_byte(priv, buffer[(*bytes_written)++], CDOR); + spin_unlock_irqrestore(&board->spinlock, flags); + } + retval = pio_write_wait(board, priv); + if (retval < 0) + return retval; + + return length; +} + +int tms9914_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written) +{ + ssize_t retval = 0; + + *bytes_written = 0; + if (length == 0) + return 0; + + clear_bit(BUS_ERROR_BN, &priv->state); + clear_bit(DEV_CLEAR_BN, &priv->state); + + if (send_eoi) + length-- ; /* save the last byte for sending EOI */ + + if (length > 0) { + size_t num_bytes; + // PIO transfer + retval = pio_write(board, priv, buffer, length, &num_bytes); + *bytes_written += num_bytes; + if (retval < 0) + return retval; + } + if (send_eoi) { + size_t num_bytes; + /*send EOI */ + write_byte(priv, AUX_SEOI, AUXCR); + + retval = pio_write(board, priv, &buffer[*bytes_written], 1, &num_bytes); + *bytes_written += num_bytes; + } + return retval; +} +EXPORT_SYMBOL(tms9914_write); + +static void check_my_address_state(gpib_board_t *board, struct tms9914_priv *priv, int cmd_byte) +{ + if (cmd_byte == MLA(board->pad)) { + priv->primary_listen_addressed = 1; + // become active listener + if (board->sad < 0) + write_byte(priv, AUX_LON | AUX_CS, AUXCR); + } else if (board->sad >= 0 && priv->primary_listen_addressed && + cmd_byte == MSA(board->sad)) { + // become active listener + write_byte(priv, AUX_LON | AUX_CS, AUXCR); + } else if (cmd_byte != MLA(board->pad) && (cmd_byte & 0xe0) == LAD) { + priv->primary_listen_addressed = 0; + } else if (cmd_byte == UNL) { + priv->primary_listen_addressed = 0; + write_byte(priv, AUX_LON, AUXCR); + } else if (cmd_byte == MTA(board->pad)) { + priv->primary_talk_addressed = 1; + if (board->sad < 0) + //make active talker + write_byte(priv, AUX_TON | AUX_CS, AUXCR); + } else if (board->sad >= 0 && priv->primary_talk_addressed && + cmd_byte == MSA(board->sad)) { + // become active talker + write_byte(priv, AUX_TON | AUX_CS, AUXCR); + } else if (cmd_byte != MTA(board->pad) && (cmd_byte & 0xe0) == TAD) { + // Other Talk Address + priv->primary_talk_addressed = 0; + write_byte(priv, AUX_TON, AUXCR); + } else if (cmd_byte == UNT) { + priv->primary_talk_addressed = 0; + write_byte(priv, AUX_TON, AUXCR); + } +} + +int tms9914_command(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, + size_t length, size_t *bytes_written) +{ + int retval = 0; + unsigned long flags; + + *bytes_written = 0; + while (*bytes_written < length) { + if (wait_event_interruptible(board->wait, + test_bit(COMMAND_READY_BN, + &priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_debug("gpib command wait interrupted\n"); + break; + } + if (test_bit(TIMO_NUM, &board->status)) + break; + + spin_lock_irqsave(&board->spinlock, flags); + clear_bit(COMMAND_READY_BN, &priv->state); + write_byte(priv, buffer[*bytes_written], CDOR); + spin_unlock_irqrestore(&board->spinlock, flags); + + check_my_address_state(board, priv, buffer[*bytes_written]); + + ++(*bytes_written); + } + // wait until last command byte is written + if (wait_event_interruptible(board->wait, + test_bit(COMMAND_READY_BN, + &priv->state) || test_bit(TIMO_NUM, &board->status))) + retval = -ERESTARTSYS; + if (test_bit(TIMO_NUM, &board->status)) + retval = -ETIMEDOUT; + + return retval; +} +EXPORT_SYMBOL(tms9914_command); + +irqreturn_t tms9914_interrupt(gpib_board_t *board, struct tms9914_priv *priv) +{ + int status0, status1; + + // read interrupt status (also clears status) + status0 = read_byte(priv, ISR0); + status1 = read_byte(priv, ISR1); + return tms9914_interrupt_have_status(board, priv, status0, status1); +} +EXPORT_SYMBOL(tms9914_interrupt); + +irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_priv *priv, + int status0, int status1) +{ + // record reception of END + if (status0 & HR_END) + set_bit(RECEIVED_END_BN, &priv->state); + // get incoming data in PIO mode + if ((status0 & HR_BI)) + set_bit(READ_READY_BN, &priv->state); + if ((status0 & HR_BO)) { + if (read_byte(priv, ADSR) & HR_ATN) + set_bit(COMMAND_READY_BN, &priv->state); + else + set_bit(WRITE_READY_BN, &priv->state); + } + + if (status0 & HR_SPAS) { + priv->spoll_status &= ~request_service_bit; + write_byte(priv, priv->spoll_status, SPMR); + //FIXME: set SPOLL status bit + } + // record service request in status + if (status1 & HR_SRQ) + set_bit(SRQI_NUM, &board->status); + // have been addressed (with secondary addressing disabled) + if (status1 & HR_MA) + // clear dac holdoff + write_byte(priv, AUX_VAL, AUXCR); + // unrecognized command received + if (status1 & HR_UNC) { + unsigned short command_byte = read_byte(priv, CPTR) & gpib_command_mask; + + switch (command_byte) { + case PPConfig: + priv->ppoll_configure_state = 1; + /* AUX_PTS generates another UNC interrupt on the next command byte + * if it is in the secondary address group (such as PPE and PPD). + */ + write_byte(priv, AUX_PTS, AUXCR); + write_byte(priv, AUX_VAL, AUXCR); + break; + case PPU: + tms9914_parallel_poll_configure(board, priv, command_byte); + write_byte(priv, AUX_VAL, AUXCR); + break; + default: + if (is_PPE(command_byte) || is_PPD(command_byte)) { + if (priv->ppoll_configure_state) { + tms9914_parallel_poll_configure(board, priv, command_byte); + write_byte(priv, AUX_VAL, AUXCR); + } else {// bad parallel poll configure byte + // clear dac holdoff + write_byte(priv, AUX_INVAL, AUXCR); + } + } else { + // printk("tms9914: unrecognized gpib command pass thru 0x%x\n", + // command_byte); + // clear dac holdoff + write_byte(priv, AUX_INVAL, AUXCR); + } + break; + } + + if (in_primary_command_group(command_byte) && command_byte != PPConfig) + priv->ppoll_configure_state = 0; + } + + if (status1 & HR_ERR) { + dev_dbg(board->gpib_dev, "gpib bus error\n"); + set_bit(BUS_ERROR_BN, &priv->state); + } + + if (status1 & HR_IFC) { + push_gpib_event(board, EventIFC); + clear_bit(CIC_NUM, &board->status); + } + + if (status1 & HR_GET) { + push_gpib_event(board, EventDevTrg); + // clear dac holdoff + write_byte(priv, AUX_VAL, AUXCR); + } + + if (status1 & HR_DCAS) { + push_gpib_event(board, EventDevClr); + // clear dac holdoff + write_byte(priv, AUX_VAL, AUXCR); + set_bit(DEV_CLEAR_BN, &priv->state); + } + + // check for being addressed with secondary addressing + if (status1 & HR_APT) { + if (board->sad < 0) + pr_err("tms9914: bug, APT interrupt without secondary addressing?\n"); + if ((read_byte(priv, CPTR) & gpib_command_mask) == MSA(board->sad)) + write_byte(priv, AUX_VAL, AUXCR); + else + write_byte(priv, AUX_INVAL, AUXCR); + } + + if ((status0 & priv->imr0_bits) || (status1 & priv->imr1_bits)) { +// dev_dbg(board->gpib_dev, "isr0 0x%x, imr0 0x%x, isr1 0x%x, imr1 0x%x\n", +// status0, priv->imr0_bits, status1, priv->imr1_bits); + update_status_nolock(board, priv); + wake_up_interruptible(&board->wait); + } + return IRQ_HANDLED; +} +EXPORT_SYMBOL(tms9914_interrupt_have_status); + +void tms9914_board_reset(struct tms9914_priv *priv) +{ + /* chip reset */ + write_byte(priv, AUX_CHIP_RESET | AUX_CS, AUXCR); + + /* disable all interrupts */ + priv->imr0_bits = 0; + write_byte(priv, priv->imr0_bits, IMR0); + priv->imr1_bits = 0; + write_byte(priv, priv->imr1_bits, IMR1); + write_byte(priv, AUX_DAI | AUX_CS, AUXCR); + + /* clear registers by reading */ + read_byte(priv, CPTR); + read_byte(priv, ISR0); + read_byte(priv, ISR1); + + write_byte(priv, 0, SPMR); + + /* parallel poll unconfigure */ + write_byte(priv, 0, PPR); + // request for data holdoff + tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL); +} +EXPORT_SYMBOL_GPL(tms9914_board_reset); + +void tms9914_online(gpib_board_t *board, struct tms9914_priv *priv) +{ + /* set GPIB address */ + tms9914_primary_address(board, priv, board->pad); + tms9914_secondary_address(board, priv, board->sad, board->sad >= 0); + + // enable tms9914 interrupts + priv->imr0_bits |= HR_MACIE | HR_RLCIE | HR_ENDIE | HR_BOIE | HR_BIIE | + HR_SPASIE; + priv->imr1_bits |= HR_MAIE | HR_SRQIE | HR_UNCIE | HR_ERRIE | HR_IFCIE | + HR_GETIE | HR_DCASIE; + write_byte(priv, priv->imr0_bits, IMR0); + write_byte(priv, priv->imr1_bits, IMR1); + write_byte(priv, AUX_DAI, AUXCR); + + // turn off reset state + write_byte(priv, AUX_CHIP_RESET, AUXCR); +} +EXPORT_SYMBOL_GPL(tms9914_online); + +#ifdef CONFIG_HAS_IOPORT +// wrapper for inb +uint8_t tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num) +{ + return inb((unsigned long)(priv->iobase) + register_num * priv->offset); +} +EXPORT_SYMBOL_GPL(tms9914_ioport_read_byte); + +// wrapper for outb +void tms9914_ioport_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +{ + outb(data, (unsigned long)(priv->iobase) + register_num * priv->offset); + if (register_num == AUXCR) + udelay(1); +} +EXPORT_SYMBOL_GPL(tms9914_ioport_write_byte); +#endif + +// wrapper for readb +uint8_t tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num) +{ + return readb(priv->iobase + register_num * priv->offset); +} +EXPORT_SYMBOL_GPL(tms9914_iomem_read_byte); + +// wrapper for writeb +void tms9914_iomem_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num) +{ + writeb(data, priv->iobase + register_num * priv->offset); + if (register_num == AUXCR) + udelay(1); +} +EXPORT_SYMBOL_GPL(tms9914_iomem_write_byte); + +static int __init tms9914_init_module(void) +{ + return 0; +} + +static void __exit tms9914_exit_module(void) +{ +} + +module_init(tms9914_init_module); +module_exit(tms9914_exit_module); + diff --git a/drivers/staging/gpib/tnt4882/Makefile b/drivers/staging/gpib/tnt4882/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f767c990db7a09e0fdac2a9c12ace2dcf4bbacb7 --- /dev/null +++ b/drivers/staging/gpib/tnt4882/Makefile @@ -0,0 +1,7 @@ +ccflags-$(CONFIG_GPIB_PCMCIA) := -DGPIB_PCMCIA +obj-m += tnt4882.o + +tnt4882-objs := tnt4882_gpib.o mite.o + + + diff --git a/drivers/staging/gpib/tnt4882/mite.c b/drivers/staging/gpib/tnt4882/mite.c new file mode 100644 index 0000000000000000000000000000000000000000..0edf34d243e9e897806bfc2b575b14dc98dda97d --- /dev/null +++ b/drivers/staging/gpib/tnt4882/mite.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2 + +/* + * Hardware driver for NI Mite PCI interface chip, + * adapted from COMEDI + * + * Copyright (C) 1997-8 David A. Schleef + * Copyright (C) 2002 Frank Mori Hess + * + * The PCI-MIO E series driver was originally written by + * Tomasz Motylewski <...>, and ported to comedi by ds. + * + * References for specifications: + * + * 321747b.pdf Register Level Programmer Manual (obsolete) + * 321747c.pdf Register Level Programmer Manual (new) + * DAQ-STC reference manual + * + * Other possibly relevant info: + * + * 320517c.pdf User manual (obsolete) + * 320517f.pdf User manual (new) + * 320889a.pdf delete + * 320906c.pdf maximum signal ratings + * 321066a.pdf about 16x + * 321791a.pdf discontinuation of at-mio-16e-10 rev. c + * 321808a.pdf about at-mio-16e-10 rev P + * 321837a.pdf discontinuation of at-mio-16de-10 rev d + * 321838a.pdf about at-mio-16de-10 rev N + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mite.h" + +#define PCI_MITE_SIZE 4096 +#define PCI_DAQ_SIZE 4096 + +struct mite_struct *mite_devices; + +#define TOP_OF_PAGE(x) ((x) | (~(PAGE_MASK))) + +void mite_init(void) +{ + struct pci_dev *pcidev; + struct mite_struct *mite; + + for (pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, NULL); + pcidev; + pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, pcidev)) { + mite = kzalloc(sizeof(*mite), GFP_KERNEL); + if (!mite) + return; + + mite->pcidev = pcidev; + pci_dev_get(mite->pcidev); + mite->next = mite_devices; + mite_devices = mite; + } +} + +int mite_setup(struct mite_struct *mite) +{ + u32 addr; + + if (pci_enable_device(mite->pcidev)) { + pr_err("mite: error enabling mite.\n"); + return -EIO; + } + pci_set_master(mite->pcidev); + if (pci_request_regions(mite->pcidev, "mite")) { + pr_err("mite: failed to request mite io regions.\n"); + return -EIO; + } + addr = pci_resource_start(mite->pcidev, 0); + mite->mite_phys_addr = addr; + mite->mite_io_addr = ioremap(addr, pci_resource_len(mite->pcidev, 0)); + if (!mite->mite_io_addr) { + pr_err("mite: failed to remap mite io memory address.\n"); + return -ENOMEM; + } + pr_info("mite: 0x%08lx mapped to %p\n", mite->mite_phys_addr, mite->mite_io_addr); + addr = pci_resource_start(mite->pcidev, 1); + mite->daq_phys_addr = addr; + mite->daq_io_addr = ioremap(mite->daq_phys_addr, pci_resource_len(mite->pcidev, 1)); + if (!mite->daq_io_addr) { + pr_err("mite: failed to remap daq io memory address.\n"); + return -ENOMEM; + } + pr_info("mite: daq: 0x%08lx mapped to %p\n", mite->daq_phys_addr, mite->daq_io_addr); + writel(mite->daq_phys_addr | WENAB, mite->mite_io_addr + MITE_IODWBSR); + mite->used = 1; + return 0; +} + +void mite_cleanup(void) +{ + struct mite_struct *mite, *next; + + for (mite = mite_devices; mite; mite = next) { + next = mite->next; + if (mite->pcidev) + pci_dev_put(mite->pcidev); + kfree(mite); + } +} + +void mite_unsetup(struct mite_struct *mite) +{ + if (!mite) + return; + if (mite->mite_io_addr) { + iounmap(mite->mite_io_addr); + mite->mite_io_addr = NULL; + } + if (mite->daq_io_addr) { + iounmap(mite->daq_io_addr); + mite->daq_io_addr = NULL; + } + if (mite->mite_phys_addr) { + pci_release_regions(mite->pcidev); + pci_disable_device(mite->pcidev); + mite->mite_phys_addr = 0; + } + mite->used = 0; +} + +void mite_list_devices(void) +{ + struct mite_struct *mite, *next; + + pr_info("Available NI PCI device IDs:"); + if (mite_devices) + for (mite = mite_devices; mite; mite = next) { + next = mite->next; + pr_info(" 0x%04x", mite_device_id(mite)); + if (mite->used) + pr_info("(used)"); + } + pr_info("\n"); +} + +int mite_bytes_transferred(struct mite_struct *mite, int chan) +{ + int dar, fcr; + + dar = readl(mite->mite_io_addr + MITE_DAR + CHAN_OFFSET(chan)); + fcr = readl(mite->mite_io_addr + MITE_FCR + CHAN_OFFSET(chan)) & 0x000000FF; + return dar - fcr; +} + +int mite_dma_tcr(struct mite_struct *mite) +{ + int tcr; + int lkar; + + lkar = readl(mite->mite_io_addr + CHAN_OFFSET(0) + MITE_LKAR); + tcr = readl(mite->mite_io_addr + CHAN_OFFSET(0) + MITE_TCR); + MDPRINTK("lkar=0x%08x tcr=%d\n", lkar, tcr); + + return tcr; +} + +void mite_dma_disarm(struct mite_struct *mite) +{ + int chor; + + /* disarm */ + chor = CHOR_ABORT; + writel(chor, mite->mite_io_addr + CHAN_OFFSET(0) + MITE_CHOR); +} + +void mite_dump_regs(struct mite_struct *mite) +{ + void *addr = 0; + unsigned long temp = 0; + + pr_info("mite address is =0x%p\n", mite->mite_io_addr); + + addr = mite->mite_io_addr + MITE_CHOR + CHAN_OFFSET(0); + pr_info("mite status[CHOR]at 0x%p =0x%08lx\n", addr, temp = readl(addr)); + //mite_decode(mite_CHOR_strings,temp); + addr = mite->mite_io_addr + MITE_CHCR + CHAN_OFFSET(0); + pr_info("mite status[CHCR]at 0x%p =0x%08lx\n", addr, temp = readl(addr)); + //mite_decode(mite_CHCR_strings,temp); + addr = mite->mite_io_addr + MITE_TCR + CHAN_OFFSET(0); + pr_info("mite status[TCR] at 0x%p =0x%08x\n", addr, readl(addr)); + addr = mite->mite_io_addr + MITE_MCR + CHAN_OFFSET(0); + pr_info("mite status[MCR] at 0x%p =0x%08lx\n", addr, temp = readl(addr)); + //mite_decode(mite_MCR_strings,temp); + addr = mite->mite_io_addr + MITE_MAR + CHAN_OFFSET(0); + pr_info("mite status[MAR] at 0x%p =0x%08x\n", addr, readl(addr)); + addr = mite->mite_io_addr + MITE_DCR + CHAN_OFFSET(0); + pr_info("mite status[DCR] at 0x%p =0x%08lx\n", addr, temp = readl(addr)); + //mite_decode(mite_CR_strings,temp); + addr = mite->mite_io_addr + MITE_DAR + CHAN_OFFSET(0); + pr_info("mite status[DAR] at 0x%p =0x%08x\n", addr, readl(addr)); + addr = mite->mite_io_addr + MITE_LKCR + CHAN_OFFSET(0); + pr_info("mite status[LKCR]at 0x%p =0x%08lx\n", addr, temp = readl(addr)); + //mite_decode(mite_CR_strings,temp); + addr = mite->mite_io_addr + MITE_LKAR + CHAN_OFFSET(0); + pr_info("mite status[LKAR]at 0x%p =0x%08x\n", addr, readl(addr)); + + addr = mite->mite_io_addr + MITE_CHSR + CHAN_OFFSET(0); + pr_info("mite status[CHSR]at 0x%p =0x%08lx\n", addr, temp = readl(addr)); + //mite_decode(mite_CHSR_strings,temp); + addr = mite->mite_io_addr + MITE_FCR + CHAN_OFFSET(0); + pr_info("mite status[FCR] at 0x%p =0x%08x\n\n", addr, readl(addr)); +} + diff --git a/drivers/staging/gpib/tnt4882/mite.h b/drivers/staging/gpib/tnt4882/mite.h new file mode 100644 index 0000000000000000000000000000000000000000..6454d069b8cc4e3d3519d492e9fc537fc14f4478 --- /dev/null +++ b/drivers/staging/gpib/tnt4882/mite.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: GPL-2 */ + +/* + * Hardware driver for NI Mite PCI interface chip + * + * Copyright (C) 1999 David A. Schleef + */ + +#ifndef _MITE_H_ +#define _MITE_H_ + +#include + +#define PCI_VENDOR_ID_NATINST 0x1093 + +//#define DEBUG_MITE + +#ifdef DEBUG_MITE +#define MDPRINTK(format, args...) pr_debug(format, ## args) +#else +#define MDPRINTK(args...) +#endif + +#define MITE_RING_SIZE 3000 +struct mite_dma_chain { + u32 count; + u32 addr; + u32 next; +}; + +struct mite_struct { + struct mite_struct *next; + int used; + + struct pci_dev *pcidev; + unsigned long mite_phys_addr; + void *mite_io_addr; + unsigned long daq_phys_addr; + void *daq_io_addr; + + int DMA_CheckNearEnd; + + struct mite_dma_chain ring[MITE_RING_SIZE]; +}; + +extern struct mite_struct *mite_devices; + +extern inline unsigned int mite_irq(struct mite_struct *mite) +{ + return mite->pcidev->irq; +}; + +extern inline unsigned int mite_device_id(struct mite_struct *mite) +{ + return mite->pcidev->device; +}; + +void mite_init(void); +void mite_cleanup(void); +int mite_setup(struct mite_struct *mite); +void mite_unsetup(struct mite_struct *mite); +void mite_list_devices(void); + +int mite_dma_tcr(struct mite_struct *mite); + +void mite_dma_arm(struct mite_struct *mite); +void mite_dma_disarm(struct mite_struct *mite); + +void mite_dump_regs(struct mite_struct *mite); +void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan, int dir); +int mite_bytes_transferred(struct mite_struct *mite, int chan); + +#define CHAN_OFFSET(x) (0x100 * (x)) + +/* DMA base for chan 0 is 0x500, chan 1 is 0x600 */ + +#define MITE_CHOR 0x500 +#define CHOR_DMARESET BIT(31) +#define CHOR_SET_SEND_TC BIT(11) +#define CHOR_CLR_SEND_TC BIT(10) +#define CHOR_SET_LPAUSE BIT(9) +#define CHOR_CLR_LPAUSE BIT(8) +#define CHOR_CLRDONE BIT(7) +#define CHOR_CLRRB BIT(6) +#define CHOR_CLRLC BIT(5) +#define CHOR_FRESET BIT(4) +#define CHOR_ABORT BIT(3) +#define CHOR_STOP BIT(2) +#define CHOR_CONT BIT(1) +#define CHOR_START BIT(0) +#define CHOR_PON (CHOR_CLR_SEND_TC | CHOR_CLR_LPAUSE) + +#define MITE_CHCR 0x504 +#define CHCR_SET_DMA_IE BIT(31) +#define CHCR_CLR_DMA_IE BIT(30) +#define CHCR_SET_LINKP_IE BIT(29) +#define CHCR_CLR_LINKP_IE BIT(28) +#define CHCR_SET_SAR_IE BIT(27) +#define CHCR_CLR_SAR_IE BIT(26) +#define CHCR_SET_DONE_IE BIT(25) +#define CHCR_CLR_DONE_IE BIT(24) +#define CHCR_SET_MRDY_IE BIT(23) +#define CHCR_CLR_MRDY_IE BIT(22) +#define CHCR_SET_DRDY_IE BIT(21) +#define CHCR_CLR_DRDY_IE BIT(20) +#define CHCR_SET_LC_IE BIT(19) +#define CHCR_CLR_LC_IE BIT(18) +#define CHCR_SET_CONT_RB_IE BIT(17) +#define CHCR_CLR_CONT_RB_IE BIT(16) +#define CHCR_FIFODIS BIT(15) +#define CHCR_FIFO_ON 0 +#define CHCR_BURSTEN BIT(14) +#define CHCR_NO_BURSTEN 0 +#define CHCR_NFTP(x) ((x) << 11) +#define CHCR_NFTP0 CHCR_NFTP(0) +#define CHCR_NFTP1 CHCR_NFTP(1) +#define CHCR_NFTP2 CHCR_NFTP(2) +#define CHCR_NFTP4 CHCR_NFTP(3) +#define CHCR_NFTP8 CHCR_NFTP(4) +#define CHCR_NFTP16 CHCR_NFTP(5) +#define CHCR_NETP(x) ((x) << 11) +#define CHCR_NETP0 CHCR_NETP(0) +#define CHCR_NETP1 CHCR_NETP(1) +#define CHCR_NETP2 CHCR_NETP(2) +#define CHCR_NETP4 CHCR_NETP(3) +#define CHCR_NETP8 CHCR_NETP(4) +#define CHCR_CHEND1 BIT(5) +#define CHCR_CHEND0 BIT(4) +#define CHCR_DIR BIT(3) +#define CHCR_DEV_TO_MEM CHCR_DIR +#define CHCR_MEM_TO_DEV 0 +#define CHCR_NORMAL ((0) << 0) +#define CHCR_CONTINUE ((1) << 0) +#define CHCR_RINGBUFF ((2) << 0) +#define CHCR_LINKSHORT ((4) << 0) +#define CHCR_LINKLONG ((5) << 0) +#define CHCRPON (CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE | \ + CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE | \ + CHCR_CLR_LC_IE | CHCR_CLR_CONT_IE) + +#define MITE_TCR 0x508 + +/* CR bits */ +#define CR_RL(x) ((x) << 21) +#define CR_RL0 CR_RL(0) +#define CR_RL1 CR_RL(1) +#define CR_RL2 CR_RL(2) +#define CR_RL4 CR_RL(3) +#define CR_RL8 CR_RL(4) +#define CR_RL16 CR_RL(5) +#define CR_RL32 CR_RL(6) +#define CR_RL64 CR_RL(7) +#define CR_RD(x) ((x) << 19) +#define CR_RD0 CR_RD(0) +#define CR_RD32 CR_RD(1) +#define CR_RD512 CR_RD(2) +#define CR_RD8192 CR_RD(3) +#define CR_REQS(x) ((x) << 16) +#define CR_REQSDRQ0 CR_REQS(4) +#define CR_REQSDRQ1 CR_REQS(5) +#define CR_REQSDRQ2 CR_REQS(6) +#define CR_REQSDRQ3 CR_REQS(7) +#define CR_ASEQX(x) ((x) << 10) +#define CR_ASEQX0 CR_ASEQX(0) +#define CR_ASEQDONT CR_ASEQX0 +#define CR_ASEQXP1 CR_ASEQX(1) +#define CR_ASEQUP CR_ASEQXP1 +#define CR_ASEQXP2 CR_ASEQX(2) +#define CR_ASEQDOWN CR_ASEQXP2 +#define CR_ASEQXP4 CR_ASEQX(3) +#define CR_ASEQXP8 CR_ASEQX(4) +#define CR_ASEQXP16 CR_ASEQX(5) +#define CR_ASEQXP32 CR_ASEQX(6) +#define CR_ASEQXP64 CR_ASEQX(7) +#define CR_ASEQXM1 CR_ASEQX(9) +#define CR_ASEQXM2 CR_ASEQX(10) +#define CR_ASEQXM4 CR_ASEQX(11) +#define CR_ASEQXM8 CR_ASEQX(12) +#define CR_ASEQXM16 CR_ASEQX(13) +#define CR_ASEQXM32 CR_ASEQX(14) +#define CR_ASEQXM64 CR_ASEQX(15) +#define CR_PSIZEBYTE BIT(8) +#define CR_PSIZEHALF (2 << 8) +#define CR_PSIZEWORD (3 << 8) +#define CR_PORTCPU (0 << 6) +#define CR_PORTIO BIT(6) +#define CR_PORTVXI (2 << 6) +#define CR_PORTMXI (3 << 6) +#define CR_AMDEVICE BIT(0) + +#define CHSR_INT 0x80000000 +#define CHSR_DONE 0x02000000 +#define CHSR_LINKC 0x00080000 + +#define MITE_MCR 0x50c +#define MCRPON 0 + +#define MITE_MAR 0x510 + +#define MITE_DCR 0x514 +#define DCR_NORMAL BIT(29) +#define DCRPON 0 + +#define MITE_DAR 0x518 + +#define MITE_LKCR 0x51c + +#define MITE_LKAR 0x520 +#define MITE_LLKAR 0x524 +#define MITE_BAR 0x528 +#define MITE_BCR 0x52c +#define MITE_SAR 0x530 +#define MITE_WSCR 0x534 +#define MITE_WSER 0x538 +#define MITE_CHSR 0x53c +#define MITE_FCR 0x540 + +#define MITE_FIFO 0x80 +#define MITE_FIFOEND 0xff + +#define MITE_AMRAM 0x00 +#define MITE_AMDEVICE 0x01 +#define MITE_AMHOST_A32_SINGLE 0x09 +#define MITE_AMHOST_A24_SINGLE 0x39 +#define MITE_AMHOST_A16_SINGLE 0x29 +#define MITE_AMHOST_A32_BLOCK 0x0b +#define MITE_AMHOST_A32D64_BLOCK 0x08 +#define MITE_AMHOST_A24_BLOCK 0x3b + +enum mite_registers { + MITE_IODWBSR = 0xc0, //IO Device Window Base Size Register + MITE_CSIGR = 0x460, //chip signature + MITE_IODWBSR_1 = 0xc4, // IO Device Window Base Size Register 1 (used by 6602 boards) + MITE_IODWCR_1 = 0xf4 +}; + +enum MITE_IODWBSR_bits { + WENAB = 0x80, // window enable + WENAB_6602 = 0x8c // window enable for 6602 boards +}; + +#endif + diff --git a/drivers/staging/gpib/tnt4882/tnt4882_gpib.c b/drivers/staging/gpib/tnt4882/tnt4882_gpib.c new file mode 100644 index 0000000000000000000000000000000000000000..e49a952fa0d83829bcec2e98e12f2131d7003db5 --- /dev/null +++ b/drivers/staging/gpib/tnt4882/tnt4882_gpib.c @@ -0,0 +1,1874 @@ +// SPDX-License-Identifier: GPL-2.0 + +/*************************************************************************** + * National Instruments boards using tnt4882 or compatible chips (at-gpib, etc). + * copyright : (C) 2001, 2002 by Frank Mori Hess + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nec7210.h" +#include "gpibP.h" +#include "mite.h" +#include "tnt4882_registers.h" + +static const int ISAPNP_VENDOR_ID_NI = ISAPNP_VENDOR('N', 'I', 'C'); +static const int ISAPNP_ID_NI_ATGPIB_TNT = 0xc601; +enum { + PCI_DEVICE_ID_NI_GPIB = 0xc801, + PCI_DEVICE_ID_NI_GPIB_PLUS = 0xc811, + PCI_DEVICE_ID_NI_GPIB_PLUS2 = 0x71ad, + PCI_DEVICE_ID_NI_PXIGPIB = 0xc821, + PCI_DEVICE_ID_NI_PMCGPIB = 0xc831, + PCI_DEVICE_ID_NI_PCIEGPIB = 0x70cf, + PCI_DEVICE_ID_NI_PCIE2GPIB = 0x710e, +// Measurement Computing PCI-488 same design as PCI-GPIB with TNT5004 + PCI_DEVICE_ID_MC_PCI488 = 0x7259, + PCI_DEVICE_ID_CEC_NI_GPIB = 0x7258 +}; + +// struct which defines private_data for tnt4882 devices +struct tnt4882_priv { + struct nec7210_priv nec7210_priv; + struct mite_struct *mite; + struct pnp_dev *pnp_dev; + unsigned int irq; + unsigned short imr0_bits; + unsigned short imr3_bits; + unsigned short auxg_bits; // bits written to auxiliary register G + void (*io_writeb)(unsigned int value, void *address); + void (*io_writew)(unsigned int value, void *address); + unsigned int (*io_readb)(void *address); + unsigned int (*io_readw)(void *address); +}; + +// interface functions +static int tnt4882_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read); +static int tnt4882_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, + int *end, size_t *bytes_read); +static int tnt4882_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written); +static int tnt4882_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, size_t *bytes_written); +static int tnt4882_command(gpib_board_t *board, uint8_t *buffer, size_t length, + size_t *bytes_written); +static int tnt4882_command_unaccel(gpib_board_t *board, uint8_t *buffer, + size_t length, size_t *bytes_written); +static int tnt4882_take_control(gpib_board_t *board, int synchronous); +static int tnt4882_go_to_standby(gpib_board_t *board); +static void tnt4882_request_system_control(gpib_board_t *board, int request_control); +static void tnt4882_interface_clear(gpib_board_t *board, int assert); +static void tnt4882_remote_enable(gpib_board_t *board, int enable); +static int tnt4882_enable_eos(gpib_board_t *board, uint8_t eos_byte, int + compare_8_bits); +static void tnt4882_disable_eos(gpib_board_t *board); +static unsigned int tnt4882_update_status(gpib_board_t *board, unsigned int clear_mask); +static int tnt4882_primary_address(gpib_board_t *board, unsigned int address); +static int tnt4882_secondary_address(gpib_board_t *board, unsigned int address, + int enable); +static int tnt4882_parallel_poll(gpib_board_t *board, uint8_t *result); +static void tnt4882_parallel_poll_configure(gpib_board_t *board, uint8_t config); +static void tnt4882_parallel_poll_response(gpib_board_t *board, int ist); +static void tnt4882_serial_poll_response(gpib_board_t *board, uint8_t status); +static uint8_t tnt4882_serial_poll_status(gpib_board_t *board); +static int tnt4882_line_status(const gpib_board_t *board); +static unsigned int tnt4882_t1_delay(gpib_board_t *board, unsigned int nano_sec); +static void tnt4882_return_to_local(gpib_board_t *board); + +// interrupt service routines +static irqreturn_t tnt4882_internal_interrupt(gpib_board_t *board); +static irqreturn_t tnt4882_interrupt(int irq, void *arg); + +// utility functions +static int tnt4882_allocate_private(gpib_board_t *board); +static void tnt4882_free_private(gpib_board_t *board); +static void tnt4882_init(struct tnt4882_priv *tnt_priv, const gpib_board_t *board); +static void tnt4882_board_reset(struct tnt4882_priv *tnt_priv, gpib_board_t *board); + +// register offset for nec7210 compatible registers +static const int atgpib_reg_offset = 2; + +// number of ioports used +static const int atgpib_iosize = 32; + +/* paged io */ +static inline unsigned int tnt_paged_readb(struct tnt4882_priv *priv, unsigned long offset) +{ + priv->io_writeb(AUX_PAGEIN, priv->nec7210_priv.iobase + AUXMR * priv->nec7210_priv.offset); + udelay(1); + return priv->io_readb(priv->nec7210_priv.iobase + offset); +} + +static inline void tnt_paged_writeb(struct tnt4882_priv *priv, unsigned int value, + unsigned long offset) +{ + priv->io_writeb(AUX_PAGEIN, priv->nec7210_priv.iobase + AUXMR * priv->nec7210_priv.offset); + udelay(1); + priv->io_writeb(value, priv->nec7210_priv.iobase + offset); +} + +/* readb/writeb wrappers */ +static inline unsigned short tnt_readb(struct tnt4882_priv *priv, unsigned long offset) +{ + void *address = priv->nec7210_priv.iobase + offset; + unsigned long flags; + unsigned short retval; + spinlock_t *register_lock = &priv->nec7210_priv.register_page_lock; + + spin_lock_irqsave(register_lock, flags); + switch (offset) { + case CSR: + case SASR: + case ISR0: + case BSR: + switch (priv->nec7210_priv.type) { + case TNT4882: + case TNT5004: + retval = priv->io_readb(address); + break; + case NAT4882: + retval = tnt_paged_readb(priv, offset - tnt_pagein_offset); + break; + case NEC7210: + retval = 0; + break; + default: + pr_err("tnt4882: bug! unsupported ni_chipset\n"); + retval = 0; + break; + } + break; + default: + retval = priv->io_readb(address); + break; + } + spin_unlock_irqrestore(register_lock, flags); + return retval; +} + +static inline void tnt_writeb(struct tnt4882_priv *priv, unsigned short value, unsigned long offset) +{ + void *address = priv->nec7210_priv.iobase + offset; + unsigned long flags; + spinlock_t *register_lock = &priv->nec7210_priv.register_page_lock; + + spin_lock_irqsave(register_lock, flags); + switch (offset) { + case KEYREG: + case IMR0: + case BCR: + switch (priv->nec7210_priv.type) { + case TNT4882: + case TNT5004: + priv->io_writeb(value, address); + break; + case NAT4882: + tnt_paged_writeb(priv, value, offset - tnt_pagein_offset); + break; + case NEC7210: + break; + default: + pr_err("tnt4882: bug! unsupported ni_chipset\n"); + break; + } + break; + default: + priv->io_writeb(value, address); + break; + } + spin_unlock_irqrestore(register_lock, flags); +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIB driver for National Instruments boards using tnt4882 or compatible chips"); + +int tnt4882_line_status(const gpib_board_t *board) +{ + int status = ValidALL; + int bcsr_bits; + struct tnt4882_priv *tnt_priv; + + tnt_priv = board->private_data; + + bcsr_bits = tnt_readb(tnt_priv, BSR); + + if (bcsr_bits & BCSR_REN_BIT) + status |= BusREN; + if (bcsr_bits & BCSR_IFC_BIT) + status |= BusIFC; + if (bcsr_bits & BCSR_SRQ_BIT) + status |= BusSRQ; + if (bcsr_bits & BCSR_EOI_BIT) + status |= BusEOI; + if (bcsr_bits & BCSR_NRFD_BIT) + status |= BusNRFD; + if (bcsr_bits & BCSR_NDAC_BIT) + status |= BusNDAC; + if (bcsr_bits & BCSR_DAV_BIT) + status |= BusDAV; + if (bcsr_bits & BCSR_ATN_BIT) + status |= BusATN; + + return status; +} + +unsigned int tnt4882_t1_delay(gpib_board_t *board, unsigned int nano_sec) +{ + struct tnt4882_priv *tnt_priv = board->private_data; + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + unsigned int retval; + + retval = nec7210_t1_delay(board, nec_priv, nano_sec); + if (nec_priv->type == NEC7210) + return retval; + + if (nano_sec <= 350) { + tnt_writeb(tnt_priv, MSTD, KEYREG); + retval = 350; + } else { + tnt_writeb(tnt_priv, 0, KEYREG); + } + if (nano_sec > 500 && nano_sec <= 1100) { + write_byte(nec_priv, AUXRI | USTD, AUXMR); + retval = 1100; + } else { + write_byte(nec_priv, AUXRI, AUXMR); + } + return retval; +} + +static int fifo_word_available(struct tnt4882_priv *tnt_priv) +{ + int status2; + int retval; + + status2 = tnt_readb(tnt_priv, STS2); + retval = (status2 & AEFN) && (status2 & BEFN); + + return retval; +} + +static int fifo_byte_available(struct tnt4882_priv *tnt_priv) +{ + int status2; + int retval; + + status2 = tnt_readb(tnt_priv, STS2); + retval = (status2 & AEFN) || (status2 & BEFN); + + return retval; +} + +static int fifo_xfer_done(struct tnt4882_priv *tnt_priv) +{ + int status1; + int retval; + + status1 = tnt_readb(tnt_priv, STS1); + retval = status1 & (S_DONE | S_HALT); + + return retval; +} + +static int drain_fifo_words(struct tnt4882_priv *tnt_priv, uint8_t *buffer, int num_bytes) +{ + int count = 0; + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + + while (fifo_word_available(tnt_priv) && count + 2 <= num_bytes) { + short word; + + word = tnt_priv->io_readw(nec_priv->iobase + FIFOB); + buffer[count++] = word & 0xff; + buffer[count++] = (word >> 8) & 0xff; + } + return count; +} + +static void tnt4882_release_holdoff(gpib_board_t *board, struct tnt4882_priv *tnt_priv) +{ + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + unsigned short sasr_bits; + + sasr_bits = tnt_readb(tnt_priv, SASR); + + /*tnt4882 not in one-chip mode won't always release holdoff unless we + * are in the right mode when release handshake command is given + */ + if (sasr_bits & AEHS_BIT) /* holding off due to holdoff on end mode*/ { + nec7210_set_handshake_mode(board, nec_priv, HR_HLDE); + write_byte(nec_priv, AUX_FH, AUXMR); + } else if (sasr_bits & ANHS1_BIT) { /* held off due to holdoff on all data mode*/ + nec7210_set_handshake_mode(board, nec_priv, HR_HLDA); + write_byte(nec_priv, AUX_FH, AUXMR); + nec7210_set_handshake_mode(board, nec_priv, HR_HLDE); + } else { /* held off due to holdoff immediately command */ + nec7210_set_handshake_mode(board, nec_priv, HR_HLDE); + write_byte(nec_priv, AUX_FH, AUXMR); + } +} + +int tnt4882_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, + size_t *bytes_read) +{ + size_t count = 0; + ssize_t retval = 0; + struct tnt4882_priv *tnt_priv = board->private_data; + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + unsigned int bits; + s32 hw_count; + unsigned long flags; + + *bytes_read = 0; + // FIXME: really, DEV_CLEAR_BN should happen elsewhere to prevent race + clear_bit(DEV_CLEAR_BN, &nec_priv->state); + clear_bit(ADR_CHANGE_BN, &nec_priv->state); + + nec7210_set_reg_bits(nec_priv, IMR1, HR_ENDIE, HR_ENDIE); + if (nec_priv->type != TNT4882 && nec_priv->type != TNT5004) + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI); + else + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + tnt_writeb(tnt_priv, nec_priv->auxa_bits | HR_HLDA, CCR); + bits = TNT_B_16BIT | TNT_IN | TNT_CCEN; + tnt_writeb(tnt_priv, bits, CFG); + tnt_writeb(tnt_priv, RESET_FIFO, CMDR); + udelay(1); + // load 2's complement of count into hardware counters + hw_count = -length; + tnt_writeb(tnt_priv, hw_count & 0xff, CNT0); + tnt_writeb(tnt_priv, (hw_count >> 8) & 0xff, CNT1); + tnt_writeb(tnt_priv, (hw_count >> 16) & 0xff, CNT2); + tnt_writeb(tnt_priv, (hw_count >> 24) & 0xff, CNT3); + + tnt4882_release_holdoff(board, tnt_priv); + + tnt_writeb(tnt_priv, GO, CMDR); + udelay(1); + + spin_lock_irqsave(&board->spinlock, flags); + tnt_priv->imr3_bits |= HR_DONE | HR_NEF; + tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3); + spin_unlock_irqrestore(&board->spinlock, flags); + + while (count + 2 <= length && + test_bit(RECEIVED_END_BN, &nec_priv->state) == 0 && + fifo_xfer_done(tnt_priv) == 0) { + // wait until a word is ready + if (wait_event_interruptible(board->wait, + fifo_word_available(tnt_priv) || + fifo_xfer_done(tnt_priv) || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(ADR_CHANGE_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_err("tnt4882: read interrupted\n"); + retval = -ERESTARTSYS; + break; + } + if (test_bit(TIMO_NUM, &board->status)) { + //pr_info("tnt4882: minor %i read timed out\n", board->minor); + retval = -ETIMEDOUT; + break; + } + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) { + pr_err("tnt4882: device clear interrupted read\n"); + retval = -EINTR; + break; + } + if (test_bit(ADR_CHANGE_BN, &nec_priv->state)) { + pr_err("tnt4882: address change interrupted read\n"); + retval = -EINTR; + break; + } + + spin_lock_irqsave(&board->spinlock, flags); + count += drain_fifo_words(tnt_priv, &buffer[count], length - count); + tnt_priv->imr3_bits |= HR_NEF; + tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3); + spin_unlock_irqrestore(&board->spinlock, flags); + + if (need_resched()) + schedule(); + } + // wait for last byte + if (count < length) { + spin_lock_irqsave(&board->spinlock, flags); + tnt_priv->imr3_bits |= HR_DONE | HR_NEF; + tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3); + spin_unlock_irqrestore(&board->spinlock, flags); + + if (wait_event_interruptible(board->wait, + fifo_xfer_done(tnt_priv) || + test_bit(RECEIVED_END_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(ADR_CHANGE_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + pr_err("tnt4882: read interrupted\n"); + retval = -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) + //pr_info("tnt4882: read timed out\n"); + retval = -ETIMEDOUT; + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) { + pr_err("tnt4882: device clear interrupted read\n"); + retval = -EINTR; + } + if (test_bit(ADR_CHANGE_BN, &nec_priv->state)) { + pr_err("tnt4882: address change interrupted read\n"); + retval = -EINTR; + } + count += drain_fifo_words(tnt_priv, &buffer[count], length - count); + if (fifo_byte_available(tnt_priv) && count < length) + buffer[count++] = tnt_readb(tnt_priv, FIFOB); + } + if (count < length) + tnt_writeb(tnt_priv, STOP, CMDR); + udelay(1); + + nec7210_set_reg_bits(nec_priv, IMR1, HR_ENDIE, 0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0); + /* force handling of any pending interrupts (seems to be needed + * to keep interrupts from getting hosed, plus for syncing + * with RECEIVED_END below) + */ + tnt4882_internal_interrupt(board); + /* RECEIVED_END should be in sync now */ + if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) + *end = 1; + if (retval < 0) { + // force immediate holdoff + write_byte(nec_priv, AUX_HLDI, AUXMR); + + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + } + *bytes_read = count; + + return retval; +} + +static int fifo_space_available(struct tnt4882_priv *tnt_priv) +{ + int status2; + int retval; + + status2 = tnt_readb(tnt_priv, STS2); + retval = (status2 & AFFN) && (status2 & BFFN); + + return retval; +} + +static unsigned int tnt_transfer_count(struct tnt4882_priv *tnt_priv) +{ + unsigned int count = 0; + + count |= tnt_readb(tnt_priv, CNT0) & 0xff; + count |= (tnt_readb(tnt_priv, CNT1) << 8) & 0xff00; + count |= (tnt_readb(tnt_priv, CNT2) << 16) & 0xff0000; + count |= (tnt_readb(tnt_priv, CNT3) << 24) & 0xff000000; + // return two's complement + return -count; +}; + +static int write_wait(gpib_board_t *board, struct tnt4882_priv *tnt_priv, + int wait_for_done, int send_commands) +{ + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + + if (wait_event_interruptible(board->wait, + (!wait_for_done && fifo_space_available(tnt_priv)) || + fifo_xfer_done(tnt_priv) || + test_bit(BUS_ERROR_BN, &nec_priv->state) || + test_bit(DEV_CLEAR_BN, &nec_priv->state) || + test_bit(TIMO_NUM, &board->status))) { + dev_dbg(board->gpib_dev, "gpib write interrupted\n"); + return -ERESTARTSYS; + } + if (test_bit(TIMO_NUM, &board->status)) { + pr_info("tnt4882: write timed out\n"); + return -ETIMEDOUT; + } + if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state)) { + pr_err("tnt4882: write bus error\n"); + return (send_commands) ? -ENOTCONN : -ECOMM; + } + if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) { + pr_err("tnt4882: device clear interrupted write\n"); + return -EINTR; + } + return 0; +} + +static int generic_write(gpib_board_t *board, uint8_t *buffer, size_t length, + int send_eoi, int send_commands, size_t *bytes_written) +{ + size_t count = 0; + ssize_t retval = 0; + struct tnt4882_priv *tnt_priv = board->private_data; + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + unsigned int bits; + s32 hw_count; + unsigned long flags; + + *bytes_written = 0; + // FIXME: really, DEV_CLEAR_BN should happen elsewhere to prevent race + clear_bit(DEV_CLEAR_BN, &nec_priv->state); + + nec7210_set_reg_bits(nec_priv, IMR1, HR_ERRIE, HR_ERRIE); + + if (nec_priv->type != TNT4882 && nec_priv->type != TNT5004) + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO); + else + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0); + + tnt_writeb(tnt_priv, RESET_FIFO, CMDR); + udelay(1); + + bits = TNT_B_16BIT; + if (send_eoi) { + bits |= TNT_CCEN; + if (nec_priv->type != TNT4882 && nec_priv->type != TNT5004) + tnt_writeb(tnt_priv, AUX_SEOI, CCR); + } + if (send_commands) + bits |= TNT_COMMAND; + tnt_writeb(tnt_priv, bits, CFG); + + // load 2's complement of count into hardware counters + hw_count = -length; + tnt_writeb(tnt_priv, hw_count & 0xff, CNT0); + tnt_writeb(tnt_priv, (hw_count >> 8) & 0xff, CNT1); + tnt_writeb(tnt_priv, (hw_count >> 16) & 0xff, CNT2); + tnt_writeb(tnt_priv, (hw_count >> 24) & 0xff, CNT3); + + tnt_writeb(tnt_priv, GO, CMDR); + udelay(1); + + spin_lock_irqsave(&board->spinlock, flags); + tnt_priv->imr3_bits |= HR_DONE; + tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3); + spin_unlock_irqrestore(&board->spinlock, flags); + + while (count < length) { + // wait until byte is ready to be sent + retval = write_wait(board, tnt_priv, 0, send_commands); + if (retval < 0) + break; + if (fifo_xfer_done(tnt_priv)) + break; + spin_lock_irqsave(&board->spinlock, flags); + while (fifo_space_available(tnt_priv) && count < length) { + u16 word; + + word = buffer[count++] & 0xff; + if (count < length) + word |= (buffer[count++] << 8) & 0xff00; + tnt_priv->io_writew(word, nec_priv->iobase + FIFOB); + } +// avoid unnecessary HR_NFF interrupts +// tnt_priv->imr3_bits |= HR_NFF; +// tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3); + spin_unlock_irqrestore(&board->spinlock, flags); + + if (need_resched()) + schedule(); + } + // wait last byte has been sent + if (retval == 0) + retval = write_wait(board, tnt_priv, 1, send_commands); + + tnt_writeb(tnt_priv, STOP, CMDR); + udelay(1); + + nec7210_set_reg_bits(nec_priv, IMR1, HR_ERR, 0x0); + nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0x0); + /* force handling of any interrupts that happened + * while they were masked (this appears to be needed) + */ + tnt4882_internal_interrupt(board); + *bytes_written = length - tnt_transfer_count(tnt_priv); + return retval; +} + +int tnt4882_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + return generic_write(board, buffer, length, send_eoi, 0, bytes_written); +} + +int tnt4882_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) +{ + return generic_write(board, buffer, length, 0, 1, bytes_written); +} + +irqreturn_t tnt4882_internal_interrupt(gpib_board_t *board) +{ + struct tnt4882_priv *priv = board->private_data; + int isr0_bits, isr3_bits, imr3_bits; + unsigned long flags; + + spin_lock_irqsave(&board->spinlock, flags); + + nec7210_interrupt(board, &priv->nec7210_priv); + + isr0_bits = tnt_readb(priv, ISR0); + isr3_bits = tnt_readb(priv, ISR3); + imr3_bits = priv->imr3_bits; + + if (isr0_bits & TNT_IFCI_BIT) + push_gpib_event(board, EventIFC); + //XXX don't need this wakeup, one below should do? +// wake_up_interruptible(&board->wait); + + if (isr3_bits & HR_NFF) + priv->imr3_bits &= ~HR_NFF; + if (isr3_bits & HR_NEF) + priv->imr3_bits &= ~HR_NEF; + if (isr3_bits & HR_DONE) + priv->imr3_bits &= ~HR_DONE; + if (isr3_bits & (HR_INTR | HR_TLCI)) { + dev_dbg(board->gpib_dev, "tnt4882: minor %i isr0 0x%x imr0 0x%x isr3 0x%x imr3 0x%x\n", + board->minor, isr0_bits, priv->imr0_bits, isr3_bits, imr3_bits); + tnt_writeb(priv, priv->imr3_bits, IMR3); + wake_up_interruptible(&board->wait); + } + spin_unlock_irqrestore(&board->spinlock, flags); + return IRQ_HANDLED; +} + +irqreturn_t tnt4882_interrupt(int irq, void *arg) +{ + return tnt4882_internal_interrupt(arg); +} + +static int ni_tnt_isa_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int ni_nat4882_isa_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int ni_nec_isa_attach(gpib_board_t *board, const gpib_board_config_t *config); +static int ni_pci_attach(gpib_board_t *board, const gpib_board_config_t *config); + +static void ni_isa_detach(gpib_board_t *board); +static void ni_pci_detach(gpib_board_t *board); + +#ifdef GPIB_PCMCIA +static int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config); +static void ni_pcmcia_detach(gpib_board_t *board); +static int init_ni_gpib_cs(void); +static void __exit exit_ni_gpib_cs(void); +#endif + +// wrappers for interface functions +int tnt4882_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read) +{ + struct tnt4882_priv *priv = board->private_data; + struct nec7210_priv *nec_priv = &priv->nec7210_priv; + int retval; + int dummy; + + retval = nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); + + if (retval < 0) { // force immediate holdoff + write_byte(nec_priv, AUX_HLDI, AUXMR); + + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + + nec7210_read_data_in(board, nec_priv, &dummy); + } + return retval; +} + +int tnt4882_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, + size_t *bytes_written) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); +} + +int tnt4882_command_unaccel(gpib_board_t *board, uint8_t *buffer, + size_t length, size_t *bytes_written) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); +} + +int tnt4882_take_control(gpib_board_t *board, int synchronous) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_take_control(board, &priv->nec7210_priv, synchronous); +} + +int tnt4882_go_to_standby(gpib_board_t *board) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_go_to_standby(board, &priv->nec7210_priv); +} + +void tnt4882_request_system_control(gpib_board_t *board, int request_control) +{ + struct tnt4882_priv *priv = board->private_data; + + if (request_control) { + tnt_writeb(priv, SETSC, CMDR); + udelay(1); + } + nec7210_request_system_control(board, &priv->nec7210_priv, request_control); + if (!request_control) { + tnt_writeb(priv, CLRSC, CMDR); + udelay(1); + } +} + +void tnt4882_interface_clear(gpib_board_t *board, int assert) +{ + struct tnt4882_priv *priv = board->private_data; + + nec7210_interface_clear(board, &priv->nec7210_priv, assert); +} + +void tnt4882_remote_enable(gpib_board_t *board, int enable) +{ + struct tnt4882_priv *priv = board->private_data; + + nec7210_remote_enable(board, &priv->nec7210_priv, enable); +} + +int tnt4882_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); +} + +void tnt4882_disable_eos(gpib_board_t *board) +{ + struct tnt4882_priv *priv = board->private_data; + + nec7210_disable_eos(board, &priv->nec7210_priv); +} + +unsigned int tnt4882_update_status(gpib_board_t *board, unsigned int clear_mask) +{ + unsigned long flags; + u8 line_status; + unsigned int retval; + struct tnt4882_priv *priv = board->private_data; + + spin_lock_irqsave(&board->spinlock, flags); + board->status &= ~clear_mask; + retval = nec7210_update_status_nolock(board, &priv->nec7210_priv); + /* set / clear SRQ state since it is not cleared by interrupt */ + line_status = tnt_readb(priv, BSR); + if (line_status & BCSR_SRQ_BIT) + set_bit(SRQI_NUM, &board->status); + else + clear_bit(SRQI_NUM, &board->status); + spin_unlock_irqrestore(&board->spinlock, flags); + return board->status; +} + +int tnt4882_primary_address(gpib_board_t *board, unsigned int address) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_primary_address(board, &priv->nec7210_priv, address); +} + +int tnt4882_secondary_address(gpib_board_t *board, unsigned int address, int enable) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); +} + +int tnt4882_parallel_poll(gpib_board_t *board, uint8_t *result) + +{ + struct tnt4882_priv *tnt_priv = board->private_data; + + if (tnt_priv->nec7210_priv.type != NEC7210) { + tnt_priv->auxg_bits |= RPP2_BIT; + write_byte(&tnt_priv->nec7210_priv, tnt_priv->auxg_bits, AUXMR); + udelay(2); //FIXME use parallel poll timeout + *result = read_byte(&tnt_priv->nec7210_priv, CPTR); + tnt_priv->auxg_bits &= ~RPP2_BIT; + write_byte(&tnt_priv->nec7210_priv, tnt_priv->auxg_bits, AUXMR); + return 0; + } else { + return nec7210_parallel_poll(board, &tnt_priv->nec7210_priv, result); + } +} + +void tnt4882_parallel_poll_configure(gpib_board_t *board, uint8_t config) +{ + struct tnt4882_priv *priv = board->private_data; + + if (priv->nec7210_priv.type == TNT5004) { + /* configure locally */ + write_byte(&priv->nec7210_priv, AUXRI | 0x4, AUXMR); + if (config) + /* set response + clear sense */ + write_byte(&priv->nec7210_priv, PPR | config, AUXMR); + else + /* disable ppoll */ + write_byte(&priv->nec7210_priv, PPR | 0x10, AUXMR); + } else { + nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config); + } +} + +void tnt4882_parallel_poll_response(gpib_board_t *board, int ist) +{ + struct tnt4882_priv *priv = board->private_data; + + nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); +} + +/* this is just used by the old nec7210 isa interfaces, the newer + * boards use tnt4882_serial_poll_response2 + */ +void tnt4882_serial_poll_response(gpib_board_t *board, uint8_t status) +{ + struct tnt4882_priv *priv = board->private_data; + + nec7210_serial_poll_response(board, &priv->nec7210_priv, status); +} + +static void tnt4882_serial_poll_response2(gpib_board_t *board, uint8_t status, + int new_reason_for_service) +{ + struct tnt4882_priv *priv = board->private_data; + unsigned long flags; + const int MSS = status & request_service_bit; + const int reqt = MSS && new_reason_for_service; + const int reqf = MSS == 0; + + spin_lock_irqsave(&board->spinlock, flags); + if (reqt) { + priv->nec7210_priv.srq_pending = 1; + clear_bit(SPOLL_NUM, &board->status); + } else { + if (reqf) + priv->nec7210_priv.srq_pending = 0; + } + if (reqt) + /* It may seem like a race to issue reqt before updating + * the status byte, but it is not. The chip does not + * issue the reqt until the SPMR is written to at + * a later time. + */ + write_byte(&priv->nec7210_priv, AUX_REQT, AUXMR); + else if (reqf) + write_byte(&priv->nec7210_priv, AUX_REQF, AUXMR); + /* We need to always zero bit 6 of the status byte before writing it to + * the SPMR to insure we are using + * serial poll mode SP1, and not accidentally triggering mode SP3. + */ + write_byte(&priv->nec7210_priv, status & ~request_service_bit, SPMR); + spin_unlock_irqrestore(&board->spinlock, flags); +} + +uint8_t tnt4882_serial_poll_status(gpib_board_t *board) +{ + struct tnt4882_priv *priv = board->private_data; + + return nec7210_serial_poll_status(board, &priv->nec7210_priv); +} + +void tnt4882_return_to_local(gpib_board_t *board) +{ + struct tnt4882_priv *priv = board->private_data; + + nec7210_return_to_local(board, &priv->nec7210_priv); +} + +gpib_interface_t ni_pci_interface = { +name: "ni_pci", +attach : ni_pci_attach, +detach : ni_pci_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response2 : tnt4882_serial_poll_response2, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_pci_accel_interface = { +name: "ni_pci_accel", +attach : ni_pci_attach, +detach : ni_pci_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response2 : tnt4882_serial_poll_response2, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_isa_interface = { +name: "ni_isa", +attach : ni_tnt_isa_attach, +detach : ni_isa_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response2 : tnt4882_serial_poll_response2, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_nat4882_isa_interface = { +name: "ni_nat4882_isa", +attach : ni_nat4882_isa_attach, +detach : ni_isa_detach, +read : tnt4882_read, +write : tnt4882_write, +command : tnt4882_command_unaccel, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response2 : tnt4882_serial_poll_response2, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_nec_isa_interface = { +name: "ni_nec_isa", +attach : ni_nec_isa_attach, +detach : ni_isa_detach, +read : tnt4882_read, +write : tnt4882_write, +command : tnt4882_command_unaccel, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : NULL, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response : tnt4882_serial_poll_response, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_isa_accel_interface = { +name: "ni_isa_accel", +attach : ni_tnt_isa_attach, +detach : ni_isa_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response2 : tnt4882_serial_poll_response2, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_nat4882_isa_accel_interface = { +name: "ni_nat4882_isa_accel", +attach : ni_nat4882_isa_attach, +detach : ni_isa_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command_unaccel, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response2 : tnt4882_serial_poll_response2, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_nec_isa_accel_interface = { +name: "ni_nec_isa_accel", +attach : ni_nec_isa_attach, +detach : ni_isa_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command_unaccel, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : NULL, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response : tnt4882_serial_poll_response, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +#ifdef GPIB_PCMCIA +gpib_interface_t ni_pcmcia_interface = { +name: "ni_pcmcia", +attach : ni_pcmcia_attach, +detach : ni_pcmcia_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response : tnt4882_serial_poll_response, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; + +gpib_interface_t ni_pcmcia_accel_interface = { +name: "ni_pcmcia_accel", +attach : ni_pcmcia_attach, +detach : ni_pcmcia_detach, +read : tnt4882_accel_read, +write : tnt4882_accel_write, +command : tnt4882_command, +take_control : tnt4882_take_control, +go_to_standby : tnt4882_go_to_standby, +request_system_control : tnt4882_request_system_control, +interface_clear : tnt4882_interface_clear, +remote_enable : tnt4882_remote_enable, +enable_eos : tnt4882_enable_eos, +disable_eos : tnt4882_disable_eos, +parallel_poll : tnt4882_parallel_poll, +parallel_poll_configure : tnt4882_parallel_poll_configure, +parallel_poll_response : tnt4882_parallel_poll_response, +local_parallel_poll_mode : NULL, // XXX +line_status : tnt4882_line_status, +update_status : tnt4882_update_status, +primary_address : tnt4882_primary_address, +secondary_address : tnt4882_secondary_address, +serial_poll_response : tnt4882_serial_poll_response, +serial_poll_status : tnt4882_serial_poll_status, +t1_delay : tnt4882_t1_delay, +return_to_local : tnt4882_return_to_local, +}; +#endif + +void tnt4882_board_reset(struct tnt4882_priv *tnt_priv, gpib_board_t *board) +{ + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + + tnt_priv->imr0_bits = 0; + tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0); + tnt_priv->imr3_bits = 0; + tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3); + tnt_readb(tnt_priv, IMR0); + tnt_readb(tnt_priv, IMR3); + nec7210_board_reset(nec_priv, board); +} + +int tnt4882_allocate_private(gpib_board_t *board) +{ + struct tnt4882_priv *tnt_priv; + + board->private_data = kmalloc(sizeof(struct tnt4882_priv), GFP_KERNEL); + if (!board->private_data) + return -1; + tnt_priv = board->private_data; + memset(tnt_priv, 0, sizeof(struct tnt4882_priv)); + init_nec7210_private(&tnt_priv->nec7210_priv); + return 0; +} + +void tnt4882_free_private(gpib_board_t *board) +{ + kfree(board->private_data); + board->private_data = NULL; +} + +void tnt4882_init(struct tnt4882_priv *tnt_priv, const gpib_board_t *board) +{ + struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv; + + /* Turbo488 software reset */ + tnt_writeb(tnt_priv, SOFT_RESET, CMDR); + udelay(1); + + // turn off one-chip mode + tnt_writeb(tnt_priv, NODMA, HSSEL); + tnt_writeb(tnt_priv, 0, ACCWR); + // make sure we are in 7210 mode + tnt_writeb(tnt_priv, AUX_7210, AUXCR); + udelay(1); + // registers might be swapped, so write it to the swapped address too + tnt_writeb(tnt_priv, AUX_7210, SWAPPED_AUXCR); + udelay(1); + // turn on one-chip mode + if (nec_priv->type == TNT4882 || nec_priv->type == TNT5004) + tnt_writeb(tnt_priv, NODMA | TNT_ONE_CHIP_BIT, HSSEL); + else + tnt_writeb(tnt_priv, NODMA, HSSEL); + + nec7210_board_reset(nec_priv, board); + // read-clear isr0 + tnt_readb(tnt_priv, ISR0); + + // enable passing of nat4882 interrupts + tnt_priv->imr3_bits = HR_TLCI; + tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3); + + // enable interrupt + tnt_writeb(tnt_priv, 0x1, INTRT); + + // force immediate holdoff + write_byte(&tnt_priv->nec7210_priv, AUX_HLDI, AUXMR); + + set_bit(RFD_HOLDOFF_BN, &nec_priv->state); + + tnt_priv->auxg_bits = AUXRG | NTNL_BIT; + write_byte(&tnt_priv->nec7210_priv, tnt_priv->auxg_bits, AUXMR); + + nec7210_board_online(nec_priv, board); + // enable interface clear interrupt for event queue + tnt_priv->imr0_bits = TNT_IMR0_ALWAYS_BITS | TNT_ATNI_BIT | TNT_IFCIE_BIT; + tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0); +} + +int ni_pci_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct tnt4882_priv *tnt_priv; + struct nec7210_priv *nec_priv; + int isr_flags = IRQF_SHARED; + int retval; + struct mite_struct *mite; + + board->status = 0; + + if (tnt4882_allocate_private(board)) + return -ENOMEM; + tnt_priv = board->private_data; + tnt_priv->io_writeb = writeb_wrapper; + tnt_priv->io_readb = readb_wrapper; + tnt_priv->io_writew = writew_wrapper; + tnt_priv->io_readw = readw_wrapper; + nec_priv = &tnt_priv->nec7210_priv; + nec_priv->type = TNT4882; + nec_priv->read_byte = nec7210_locking_iomem_read_byte; + nec_priv->write_byte = nec7210_locking_iomem_write_byte; + nec_priv->offset = atgpib_reg_offset; + + if (!mite_devices) { + pr_err("no National Instruments PCI boards found\n"); + return -1; + } + + for (mite = mite_devices; mite; mite = mite->next) { + short found_board; + + if (mite->used) + continue; + if (config->pci_bus >= 0 && config->pci_bus != mite->pcidev->bus->number) + continue; + if (config->pci_slot >= 0 && config->pci_slot != PCI_SLOT(mite->pcidev->devfn)) + continue; + switch (mite_device_id(mite)) { + case PCI_DEVICE_ID_NI_GPIB: + case PCI_DEVICE_ID_NI_GPIB_PLUS: + case PCI_DEVICE_ID_NI_GPIB_PLUS2: + case PCI_DEVICE_ID_NI_PXIGPIB: + case PCI_DEVICE_ID_NI_PMCGPIB: + case PCI_DEVICE_ID_NI_PCIEGPIB: + case PCI_DEVICE_ID_NI_PCIE2GPIB: +// support for Measurement Computing PCI-488 + case PCI_DEVICE_ID_MC_PCI488: + case PCI_DEVICE_ID_CEC_NI_GPIB: + found_board = 1; + break; + default: + found_board = 0; + break; + } + if (found_board) + break; + } + if (!mite) { + pr_err("no NI PCI-GPIB boards found\n"); + return -1; + } + tnt_priv->mite = mite; + retval = mite_setup(tnt_priv->mite); + if (retval < 0) { + pr_err("tnt4882: error setting up mite.\n"); + return retval; + } + + nec_priv->iobase = tnt_priv->mite->daq_io_addr; + + // get irq + if (request_irq(mite_irq(tnt_priv->mite), tnt4882_interrupt, isr_flags, + "ni-pci-gpib", board)) { + pr_err("gpib: can't request IRQ %d\n", mite_irq(tnt_priv->mite)); + return -1; + } + tnt_priv->irq = mite_irq(tnt_priv->mite); + pr_info("tnt4882: irq %i\n", tnt_priv->irq); + + // TNT5004 detection + switch (tnt_readb(tnt_priv, CSR) & 0xf0) { + case 0x30: + nec_priv->type = TNT4882; + pr_info("tnt4882: TNT4882 chipset detected\n"); + break; + case 0x40: + nec_priv->type = TNT5004; + pr_info("tnt4882: TNT5004 chipset detected\n"); + break; + } + tnt4882_init(tnt_priv, board); + + return 0; +} + +void ni_pci_detach(gpib_board_t *board) +{ + struct tnt4882_priv *tnt_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (tnt_priv) { + nec_priv = &tnt_priv->nec7210_priv; + + if (nec_priv->iobase) + tnt4882_board_reset(tnt_priv, board); + if (tnt_priv->irq) + free_irq(tnt_priv->irq, board); + if (tnt_priv->mite) + mite_unsetup(tnt_priv->mite); + } + tnt4882_free_private(board); +} + +static int ni_isapnp_find(struct pnp_dev **dev) +{ + *dev = pnp_find_dev(NULL, ISAPNP_VENDOR_ID_NI, + ISAPNP_FUNCTION(ISAPNP_ID_NI_ATGPIB_TNT), NULL); + if (!*dev || !(*dev)->card) { + pr_err("tnt4882: failed to find isapnp board\n"); + return -ENODEV; + } + if (pnp_device_attach(*dev) < 0) { + pr_err("tnt4882: atgpib/tnt board already active, skipping\n"); + return -EBUSY; + } + if (pnp_activate_dev(*dev) < 0) { + pnp_device_detach(*dev); + pr_err("tnt4882: failed to activate() atgpib/tnt, aborting\n"); + return -EAGAIN; + } + if (!pnp_port_valid(*dev, 0) || !pnp_irq_valid(*dev, 0)) { + pnp_device_detach(*dev); + pr_err("tnt4882: invalid port or irq for atgpib/tnt, aborting\n"); + return -ENOMEM; + } + return 0; +} + +static int ni_isa_attach_common(gpib_board_t *board, const gpib_board_config_t *config, + enum nec7210_chipset chipset) +{ + struct tnt4882_priv *tnt_priv; + struct nec7210_priv *nec_priv; + int isr_flags = 0; + void *iobase; + int irq; + + board->status = 0; + + if (tnt4882_allocate_private(board)) + return -ENOMEM; + tnt_priv = board->private_data; + tnt_priv->io_writeb = outb_wrapper; + tnt_priv->io_readb = inb_wrapper; + tnt_priv->io_writew = outw_wrapper; + tnt_priv->io_readw = inw_wrapper; + nec_priv = &tnt_priv->nec7210_priv; + nec_priv->type = chipset; + nec_priv->read_byte = nec7210_locking_ioport_read_byte; + nec_priv->write_byte = nec7210_locking_ioport_write_byte; + nec_priv->offset = atgpib_reg_offset; + + // look for plug-n-play board + if (config->ibbase == 0) { + struct pnp_dev *dev; + int retval; + + retval = ni_isapnp_find(&dev); + if (retval < 0) + return retval; + tnt_priv->pnp_dev = dev; + iobase = (void *)(pnp_port_start(dev, 0)); + irq = pnp_irq(dev, 0); + } else { + iobase = config->ibbase; + irq = config->ibirq; + } + // allocate ioports + if (!request_region((unsigned long)(iobase), atgpib_iosize, "atgpib")) { + pr_err("tnt4882: failed to allocate ioports\n"); + return -1; + } + nec_priv->iobase = iobase; + + // get irq + if (request_irq(irq, tnt4882_interrupt, isr_flags, "atgpib", board)) { + pr_err("gpib: can't request IRQ %d\n", irq); + return -1; + } + tnt_priv->irq = irq; + + tnt4882_init(tnt_priv, board); + + return 0; +} + +int ni_tnt_isa_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + return ni_isa_attach_common(board, config, TNT4882); +} + +int ni_nat4882_isa_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + return ni_isa_attach_common(board, config, NAT4882); +} + +int ni_nec_isa_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + return ni_isa_attach_common(board, config, NEC7210); +} + +void ni_isa_detach(gpib_board_t *board) +{ + struct tnt4882_priv *tnt_priv = board->private_data; + struct nec7210_priv *nec_priv; + + if (tnt_priv) { + nec_priv = &tnt_priv->nec7210_priv; + if (nec_priv->iobase) + tnt4882_board_reset(tnt_priv, board); + if (tnt_priv->irq) + free_irq(tnt_priv->irq, board); + if (nec_priv->iobase) + release_region((unsigned long)(nec_priv->iobase), atgpib_iosize); + if (tnt_priv->pnp_dev) + pnp_device_detach(tnt_priv->pnp_dev); + } + tnt4882_free_private(board); +} + +static int tnt4882_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return 0; +} + +static const struct pci_device_id tnt4882_pci_table[] = { + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB)}, + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB_PLUS)}, + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB_PLUS2)}, + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PXIGPIB)}, + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PMCGPIB)}, + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PCIEGPIB)}, + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PCIE2GPIB)}, + // support for Measurement Computing PCI-488 + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_MC_PCI488)}, + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_CEC_NI_GPIB)}, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, tnt4882_pci_table); + +static struct pci_driver tnt4882_pci_driver = { + .name = "tnt4882", + .id_table = tnt4882_pci_table, + .probe = &tnt4882_pci_probe +}; + +static const struct pnp_device_id tnt4882_pnp_table[] = { + {.id = "NICC601"}, + {.id = ""} +}; +MODULE_DEVICE_TABLE(pnp, tnt4882_pnp_table); + +static int __init tnt4882_init_module(void) +{ + int result; + + result = pci_register_driver(&tnt4882_pci_driver); + if (result) { + pr_err("tnt4882: pci_driver_register failed!\n"); + return result; + } + + gpib_register_driver(&ni_isa_interface, THIS_MODULE); + gpib_register_driver(&ni_isa_accel_interface, THIS_MODULE); + gpib_register_driver(&ni_nat4882_isa_interface, THIS_MODULE); + gpib_register_driver(&ni_nat4882_isa_accel_interface, THIS_MODULE); + gpib_register_driver(&ni_nec_isa_interface, THIS_MODULE); + gpib_register_driver(&ni_nec_isa_accel_interface, THIS_MODULE); + gpib_register_driver(&ni_pci_interface, THIS_MODULE); + gpib_register_driver(&ni_pci_accel_interface, THIS_MODULE); +#ifdef GPIB_PCMCIA + gpib_register_driver(&ni_pcmcia_interface, THIS_MODULE); + gpib_register_driver(&ni_pcmcia_accel_interface, THIS_MODULE); + if (init_ni_gpib_cs() < 0) + return -1; +#endif + + mite_init(); + mite_list_devices(); + + return 0; +} + +static void __exit tnt4882_exit_module(void) +{ + gpib_unregister_driver(&ni_isa_interface); + gpib_unregister_driver(&ni_isa_accel_interface); + gpib_unregister_driver(&ni_nat4882_isa_interface); + gpib_unregister_driver(&ni_nat4882_isa_accel_interface); + gpib_unregister_driver(&ni_nec_isa_interface); + gpib_unregister_driver(&ni_nec_isa_accel_interface); + gpib_unregister_driver(&ni_pci_interface); + gpib_unregister_driver(&ni_pci_accel_interface); +#ifdef GPIB_PCMCIA + gpib_unregister_driver(&ni_pcmcia_interface); + gpib_unregister_driver(&ni_pcmcia_accel_interface); + exit_ni_gpib_cs(); +#endif + + mite_cleanup(); + + pci_unregister_driver(&tnt4882_pci_driver); +} + +#ifdef GPIB_PCMCIA + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If + * you do not define PCMCIA_DEBUG at all, all the debug code will be + * left out. If you compile with PCMCIA_DEBUG=0, the debug code will + * be present but disabled -- but it can then be enabled for specific + * modules at load time with a 'pc_debug=#' option to insmod. + */ +#define PCMCIA_DEBUG 1 +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +module_param(pc_debug, int, 0); +#define DEBUG(n, args...) \ + do {if (pc_debug > (n)) \ + pr_debug(args); } \ + while (0) +#else +#define DEBUG(args...) +#endif + +static int ni_gpib_config(struct pcmcia_device *link); +static void ni_gpib_release(struct pcmcia_device *link); +static int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config); +static void ni_pcmcia_detach(gpib_board_t *board); + +/* + * A linked list of "instances" of the dummy device. Each actual + * PCMCIA card corresponds to one device instance, and is described + * by one dev_link_t structure (defined in ds.h). + * + * You may not want to use a linked list for this -- for example, the + * memory card driver uses an array of dev_link_t pointers, where minor + * device numbers are used to derive the corresponding array index. + * + * I think this dev_list is obsolete but the pointer is needed to keep + * the module instance for the ni_pcmcia_attach function. + */ + +static struct pcmcia_device *curr_dev; + +struct local_info_t { + struct pcmcia_device *p_dev; + gpib_board_t *dev; + int stop; + struct bus_operations *bus; +}; + +/* + * ni_gpib_probe() creates an "instance" of the driver, allocating + * local data structures for one device. The device is registered + * with Card Services. + */ + +static int ni_gpib_probe(struct pcmcia_device *link) +{ + struct local_info_t *info; + //struct gpib_board_t *dev; + + DEBUG(0, "%s(0x%p)\n", __func__, link); + + /* Allocate space for private device-specific data */ + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->p_dev = link; + link->priv = info; + + /* + * General socket configuration defaults can go here. In this + * client, we assume very little, and rely on the CIS for almost + * everything. In most clients, many details (i.e., number, sizes, + * and attributes of IO windows) are fixed by the nature of the + * device, and can be hard-wired here. + */ + link->config_flags = CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; + + /* Register with Card Services */ + curr_dev = link; + return ni_gpib_config(link); +} + +/* + * This deletes a driver "instance". The device is de-registered + * with Card Services. If it has been released, all local data + * structures are freed. Otherwise, the structures will be freed + * when the device is released. + */ +static void ni_gpib_remove(struct pcmcia_device *link) +{ + struct local_info_t *info = link->priv; + //struct gpib_board_t *dev = info->dev; + + DEBUG(0, "%s(%p)\n", __func__, link); + + if (info->dev) + ni_pcmcia_detach(info->dev); + ni_gpib_release(link); + + //free_netdev(dev); + kfree(info); +} + +static int ni_gpib_config_iteration(struct pcmcia_device *link, void *priv_data) +{ + int retval; + + retval = pcmcia_request_io(link); + if (retval != 0) + return retval; + + return 0; +} + +/* + * ni_gpib_config() is scheduled to run after a CARD_INSERTION event + * is received, to configure the PCMCIA socket, and to make the + * device available to the system. + */ +static int ni_gpib_config(struct pcmcia_device *link) +{ + //struct local_info_t *info = link->priv; + //gpib_board_t *dev = info->dev; + int last_ret; + + DEBUG(0, "%s(0x%p)\n", __func__, link); + + last_ret = pcmcia_loop_config(link, &ni_gpib_config_iteration, NULL); + if (last_ret) { + dev_warn(&link->dev, "no configuration found\n"); + ni_gpib_release(link); + return last_ret; + } + + last_ret = pcmcia_enable_device(link); + if (last_ret) { + ni_gpib_release(link); + return last_ret; + } + return 0; +} /* ni_gpib_config */ + +/* + * After a card is removed, ni_gpib_release() will unregister the + * device, and release the PCMCIA configuration. If the device is + * still open, this will be postponed until it is closed. + */ +static void ni_gpib_release(struct pcmcia_device *link) +{ + DEBUG(0, "%s(0x%p)\n", __func__, link); + pcmcia_disable_device(link); +} /* ni_gpib_release */ + +static int ni_gpib_suspend(struct pcmcia_device *link) +{ + //struct local_info_t *info = link->priv; + //struct gpib_board_t *dev = info->dev; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + if (link->open) + pr_err("Device still open ???\n"); + //netif_device_detach(dev); + + return 0; +} + +static int ni_gpib_resume(struct pcmcia_device *link) +{ + //struct local_info_t *info = link->priv; + //struct gpib_board_t *dev = info->dev; + DEBUG(0, "%s(0x%p)\n", __func__, link); + + /*if (link->open) { + * ni_gpib_probe(dev); / really? + * printk("Gpib resumed ???\n"); + * //netif_device_attach(dev); + *} + */ + return ni_gpib_config(link); +} + +static struct pcmcia_device_id ni_pcmcia_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4882), + PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0c71), // NI PCMCIA-GPIB+ + PCMCIA_DEVICE_NULL +}; + +MODULE_DEVICE_TABLE(pcmcia, ni_pcmcia_ids); + +static struct pcmcia_driver ni_gpib_cs_driver = { + .name = "ni_gpib_cs", + .owner = THIS_MODULE, + .drv = { .name = "ni_gpib_cs", }, + .id_table = ni_pcmcia_ids, + .probe = ni_gpib_probe, + .remove = ni_gpib_remove, + .suspend = ni_gpib_suspend, + .resume = ni_gpib_resume, +}; + +int __init init_ni_gpib_cs(void) +{ + return pcmcia_register_driver(&ni_gpib_cs_driver); +} + +void __exit exit_ni_gpib_cs(void) +{ + DEBUG(0, "ni_gpib_cs: unloading\n"); + pcmcia_unregister_driver(&ni_gpib_cs_driver); +} + +static const int pcmcia_gpib_iosize = 32; + +int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config) +{ + struct local_info_t *info; + struct tnt4882_priv *tnt_priv; + struct nec7210_priv *nec_priv; + int isr_flags = IRQF_SHARED; + + DEBUG(0, "%s(0x%p)\n", __func__, board); + + if (!curr_dev) { + pr_err("gpib: no NI PCMCIA board found\n"); + return -1; + } + + info = curr_dev->priv; + info->dev = board; + + board->status = 0; + + if (tnt4882_allocate_private(board)) + return -ENOMEM; + tnt_priv = board->private_data; + tnt_priv->io_writeb = outb_wrapper; + tnt_priv->io_readb = inb_wrapper; + tnt_priv->io_writew = outw_wrapper; + tnt_priv->io_readw = inw_wrapper; + nec_priv = &tnt_priv->nec7210_priv; + nec_priv->type = TNT4882; + nec_priv->read_byte = nec7210_locking_ioport_read_byte; + nec_priv->write_byte = nec7210_locking_ioport_write_byte; + nec_priv->offset = atgpib_reg_offset; + + DEBUG(0, "ioport1 window attributes: 0x%lx\n", curr_dev->resource[0]->flags); + if (request_region(curr_dev->resource[0]->start, resource_size(curr_dev->resource[0]), + "tnt4882") == 0) { + pr_err("gpib: ioports starting at 0x%lx are already in use\n", + (unsigned long)curr_dev->resource[0]->start); + return -EIO; + } + + nec_priv->iobase = (void *)(unsigned long)curr_dev->resource[0]->start; + + // get irq + if (request_irq(curr_dev->irq, tnt4882_interrupt, isr_flags, "tnt4882", board)) { + pr_err("gpib: can't request IRQ %d\n", curr_dev->irq); + return -1; + } + tnt_priv->irq = curr_dev->irq; + + tnt4882_init(tnt_priv, board); + + return 0; +} + +void ni_pcmcia_detach(gpib_board_t *board) +{ + struct tnt4882_priv *tnt_priv = board->private_data; + struct nec7210_priv *nec_priv; + + DEBUG(0, "%s(0x%p)\n", __func__, board); + + if (tnt_priv) { + nec_priv = &tnt_priv->nec7210_priv; + if (tnt_priv->irq) + free_irq(tnt_priv->irq, board); + if (nec_priv->iobase) { + tnt4882_board_reset(tnt_priv, board); + release_region((unsigned long)nec_priv->iobase, pcmcia_gpib_iosize); + } + } + tnt4882_free_private(board); +} + +#endif // GPIB_PCMCIA + +module_init(tnt4882_init_module); +module_exit(tnt4882_exit_module); diff --git a/drivers/staging/gpib/uapi/gpib_ioctl.h b/drivers/staging/gpib/uapi/gpib_ioctl.h new file mode 100644 index 0000000000000000000000000000000000000000..6202865278ea7c9bf858d79b2bf2d84e8a662499 --- /dev/null +++ b/drivers/staging/gpib/uapi/gpib_ioctl.h @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_IOCTL_H +#define _GPIB_IOCTL_H + +#include +#include + +#define GPIB_CODE 160 + +typedef struct { + char name[100]; +} board_type_ioctl_t; + +/* argument for read/write/command ioctls */ +typedef struct { + uint64_t buffer_ptr; + unsigned int requested_transfer_count; + unsigned int completed_transfer_count; + int end; /* end flag return for reads, end io suppression request for cmd*/ + int handle; +} read_write_ioctl_t; + +typedef struct { + unsigned int handle; + unsigned int pad; + int sad; + unsigned is_board : 1; +} open_dev_ioctl_t; + +typedef struct { + unsigned int handle; +} close_dev_ioctl_t; + +typedef struct { + unsigned int pad; + int sad; + uint8_t status_byte; +} serial_poll_ioctl_t; + +typedef struct { + int eos; + int eos_flags; +} eos_ioctl_t; + +typedef struct { + int handle; + int wait_mask; + int clear_mask; + int set_mask; + int ibsta; + int pad; + int sad; + unsigned int usec_timeout; +} wait_ioctl_t; + +typedef struct { + uint64_t init_data_ptr; + int init_data_length; + int online; +} online_ioctl_t; + +typedef struct { + unsigned int num_bytes; + unsigned int pad; + int sad; +} spoll_bytes_ioctl_t; + +typedef struct { + unsigned int pad; + int sad; + int parallel_poll_configuration; + int autopolling; + int is_system_controller; + unsigned int t1_delay; + unsigned ist : 1; + unsigned no_7_bit_eos : 1; +} board_info_ioctl_t; + +typedef struct { + int pci_bus; + int pci_slot; +} select_pci_ioctl_t; + +typedef struct { + uint8_t config; + unsigned set_ist : 1; + unsigned clear_ist : 1; +} ppoll_config_ioctl_t; + +typedef struct { + unsigned int handle; + unsigned int pad; +} pad_ioctl_t; + +typedef struct { + unsigned int handle; + int sad; +} sad_ioctl_t; + +// select a piece of hardware to attach by its sysfs device path +typedef struct { + char device_path[0x1000]; +} select_device_path_ioctl_t; + +typedef short event_ioctl_t; +typedef int rsc_ioctl_t; +typedef unsigned int t1_delay_ioctl_t; +typedef short autospoll_ioctl_t; +typedef short local_ppoll_mode_ioctl_t; + +// update status byte and request service +typedef struct { + uint8_t status_byte; + int new_reason_for_service; +} request_service2_t; + +/* Standard functions. */ +enum gpib_ioctl { + IBRD = _IOWR(GPIB_CODE, 100, read_write_ioctl_t), + IBWRT = _IOWR(GPIB_CODE, 101, read_write_ioctl_t), + IBCMD = _IOWR(GPIB_CODE, 102, read_write_ioctl_t), + IBOPENDEV = _IOWR(GPIB_CODE, 3, open_dev_ioctl_t), + IBCLOSEDEV = _IOW(GPIB_CODE, 4, close_dev_ioctl_t), + IBWAIT = _IOWR(GPIB_CODE, 5, wait_ioctl_t), + IBRPP = _IOWR(GPIB_CODE, 6, uint8_t), + + IBSIC = _IOW(GPIB_CODE, 9, unsigned int), + IBSRE = _IOW(GPIB_CODE, 10, int), + IBGTS = _IO(GPIB_CODE, 11), + IBCAC = _IOW(GPIB_CODE, 12, int), + IBLINES = _IOR(GPIB_CODE, 14, short), + IBPAD = _IOW(GPIB_CODE, 15, pad_ioctl_t), + IBSAD = _IOW(GPIB_CODE, 16, sad_ioctl_t), + IBTMO = _IOW(GPIB_CODE, 17, unsigned int), + IBRSP = _IOWR(GPIB_CODE, 18, serial_poll_ioctl_t), + IBEOS = _IOW(GPIB_CODE, 19, eos_ioctl_t), + IBRSV = _IOW(GPIB_CODE, 20, uint8_t), + CFCBASE = _IOW(GPIB_CODE, 21, uint64_t), + CFCIRQ = _IOW(GPIB_CODE, 22, unsigned int), + CFCDMA = _IOW(GPIB_CODE, 23, unsigned int), + CFCBOARDTYPE = _IOW(GPIB_CODE, 24, board_type_ioctl_t), + + IBMUTEX = _IOW(GPIB_CODE, 26, int), + IBSPOLL_BYTES = _IOWR(GPIB_CODE, 27, spoll_bytes_ioctl_t), + IBPPC = _IOW(GPIB_CODE, 28, ppoll_config_ioctl_t), + IBBOARD_INFO = _IOR(GPIB_CODE, 29, board_info_ioctl_t), + + IBQUERY_BOARD_RSV = _IOR(GPIB_CODE, 31, int), + IBSELECT_PCI = _IOWR(GPIB_CODE, 32, select_pci_ioctl_t), + IBEVENT = _IOR(GPIB_CODE, 33, event_ioctl_t), + IBRSC = _IOW(GPIB_CODE, 34, rsc_ioctl_t), + IB_T1_DELAY = _IOW(GPIB_CODE, 35, t1_delay_ioctl_t), + IBLOC = _IO(GPIB_CODE, 36), + + IBAUTOSPOLL = _IOW(GPIB_CODE, 38, autospoll_ioctl_t), + IBONL = _IOW(GPIB_CODE, 39, online_ioctl_t), + IBPP2_SET = _IOW(GPIB_CODE, 40, local_ppoll_mode_ioctl_t), + IBPP2_GET = _IOR(GPIB_CODE, 41, local_ppoll_mode_ioctl_t), + IBSELECT_DEVICE_PATH = _IOW(GPIB_CODE, 43, select_device_path_ioctl_t), + // 44 was IBSELECT_SERIAL_NUMBER + IBRSV2 = _IOW(GPIB_CODE, 45, request_service2_t) +}; + +#endif /* _GPIB_IOCTL_H */ diff --git a/drivers/staging/gpib/uapi/gpib_user.h b/drivers/staging/gpib/uapi/gpib_user.h new file mode 100644 index 0000000000000000000000000000000000000000..0896a55a758feeae61da2047b001e482b530041b --- /dev/null +++ b/drivers/staging/gpib/uapi/gpib_user.h @@ -0,0 +1,363 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/*************************************************************************** + * copyright : (C) 2002 by Frank Mori Hess + ***************************************************************************/ + +#ifndef _GPIB_USER_H +#define _GPIB_USER_H + +#define GPIB_MAX_NUM_BOARDS 16 +#define GPIB_MAX_NUM_DESCRIPTORS 0x1000 + +enum ibsta_bit_numbers { + DCAS_NUM = 0, + DTAS_NUM = 1, + LACS_NUM = 2, + TACS_NUM = 3, + ATN_NUM = 4, + CIC_NUM = 5, + REM_NUM = 6, + LOK_NUM = 7, + CMPL_NUM = 8, + EVENT_NUM = 9, + SPOLL_NUM = 10, + RQS_NUM = 11, + SRQI_NUM = 12, + END_NUM = 13, + TIMO_NUM = 14, + ERR_NUM = 15 +}; + +/* IBSTA status bits (returned by all functions) */ +enum ibsta_bits { + DCAS = (1 << DCAS_NUM), /* device clear state */ + DTAS = (1 << DTAS_NUM), /* device trigger state */ + LACS = (1 << LACS_NUM), /* GPIB interface is addressed as Listener */ + TACS = (1 << TACS_NUM), /* GPIB interface is addressed as Talker */ + ATN = (1 << ATN_NUM), /* Attention is asserted */ + CIC = (1 << CIC_NUM), /* GPIB interface is Controller-in-Charge */ + REM = (1 << REM_NUM), /* remote state */ + LOK = (1 << LOK_NUM), /* lockout state */ + CMPL = (1 << CMPL_NUM), /* I/O is complete */ + EVENT = (1 << EVENT_NUM), /* DCAS, DTAS, or IFC has occurred */ + SPOLL = (1 << SPOLL_NUM), /* board serial polled by busmaster */ + RQS = (1 << RQS_NUM), /* Device requesting service */ + SRQI = (1 << SRQI_NUM), /* SRQ is asserted */ + END = (1 << END_NUM), /* EOI or EOS encountered */ + TIMO = (1 << TIMO_NUM), /* Time limit on I/O or wait function exceeded */ + ERR = (1 << ERR_NUM), /* Function call terminated on error */ + + device_status_mask = ERR | TIMO | END | CMPL | RQS, + board_status_mask = ERR | TIMO | END | CMPL | SPOLL | + EVENT | LOK | REM | CIC | ATN | TACS | LACS | DTAS | DCAS | SRQI, +}; + +/* IBERR error codes */ +enum iberr_code { + EDVR = 0, /* system error */ + ECIC = 1, /* not CIC */ + ENOL = 2, /* no listeners */ + EADR = 3, /* CIC and not addressed before I/O */ + EARG = 4, /* bad argument to function call */ + ESAC = 5, /* not SAC */ + EABO = 6, /* I/O operation was aborted */ + ENEB = 7, /* non-existent board (GPIB interface offline) */ + EDMA = 8, /* DMA hardware error detected */ + EOIP = 10, /* new I/O attempted with old I/O in progress */ + ECAP = 11, /* no capability for intended opeation */ + EFSO = 12, /* file system operation error */ + EBUS = 14, /* bus error */ + ESTB = 15, /* lost serial poll bytes */ + ESRQ = 16, /* SRQ stuck on */ + ETAB = 20 /* Table Overflow */ +}; + +/* Timeout values and meanings */ +enum gpib_timeout { + TNONE = 0, /* Infinite timeout (disabled) */ + T10us = 1, /* Timeout of 10 usec (ideal) */ + T30us = 2, /* Timeout of 30 usec (ideal) */ + T100us = 3, /* Timeout of 100 usec (ideal) */ + T300us = 4, /* Timeout of 300 usec (ideal) */ + T1ms = 5, /* Timeout of 1 msec (ideal) */ + T3ms = 6, /* Timeout of 3 msec (ideal) */ + T10ms = 7, /* Timeout of 10 msec (ideal) */ + T30ms = 8, /* Timeout of 30 msec (ideal) */ + T100ms = 9, /* Timeout of 100 msec (ideal) */ + T300ms = 10, /* Timeout of 300 msec (ideal) */ + T1s = 11, /* Timeout of 1 sec (ideal) */ + T3s = 12, /* Timeout of 3 sec (ideal) */ + T10s = 13, /* Timeout of 10 sec (ideal) */ + T30s = 14, /* Timeout of 30 sec (ideal) */ + T100s = 15, /* Timeout of 100 sec (ideal) */ + T300s = 16, /* Timeout of 300 sec (ideal) */ + T1000s = 17 /* Timeout of 1000 sec (maximum) */ +}; + +/* End-of-string (EOS) modes for use with ibeos */ + +enum eos_flags { + EOS_MASK = 0x1c00, + REOS = 0x0400, /* Terminate reads on EOS */ + XEOS = 0x800, /* assert EOI when EOS char is sent */ + BIN = 0x1000 /* Do 8-bit compare on EOS */ +}; + +/* GPIB Bus Control Lines bit vector */ +enum bus_control_line { + ValidDAV = 0x01, + ValidNDAC = 0x02, + ValidNRFD = 0x04, + ValidIFC = 0x08, + ValidREN = 0x10, + ValidSRQ = 0x20, + ValidATN = 0x40, + ValidEOI = 0x80, + ValidALL = 0xff, + BusDAV = 0x0100, /* DAV line status bit */ + BusNDAC = 0x0200, /* NDAC line status bit */ + BusNRFD = 0x0400, /* NRFD line status bit */ + BusIFC = 0x0800, /* IFC line status bit */ + BusREN = 0x1000, /* REN line status bit */ + BusSRQ = 0x2000, /* SRQ line status bit */ + BusATN = 0x4000, /* ATN line status bit */ + BusEOI = 0x8000 /* EOI line status bit */ +}; + +enum old_bus_control_line { + BUS_DAV = 0x0100, /* DAV line status bit */ + BUS_NDAC = 0x0200, /* NDAC line status bit */ + BUS_NRFD = 0x0400, /* NRFD line status bit */ + BUS_IFC = 0x0800, /* IFC line status bit */ + BUS_REN = 0x1000, /* REN line status bit */ + BUS_SRQ = 0x2000, /* SRQ line status bit */ + BUS_ATN = 0x4000, /* ATN line status bit */ + BUS_EOI = 0x8000 /* EOI line status bit */ +}; + +/* Possible GPIB command messages */ + +enum cmd_byte { + GTL = 0x1, /* go to local */ + SDC = 0x4, /* selected device clear */ + PPConfig = 0x5, +#ifndef PPC + PPC = PPConfig, /* parallel poll configure */ +#endif + GET = 0x8, /* group execute trigger */ + TCT = 0x9, /* take control */ + LLO = 0x11, /* local lockout */ + DCL = 0x14, /* device clear */ + PPU = 0x15, /* parallel poll unconfigure */ + SPE = 0x18, /* serial poll enable */ + SPD = 0x19, /* serial poll disable */ + CFE = 0x1f, /* configure enable */ + LAD = 0x20, /* value to be 'ored' in to obtain listen address */ + UNL = 0x3F, /* unlisten */ + TAD = 0x40, /* value to be 'ored' in to obtain talk address */ + UNT = 0x5F, /* untalk */ + SAD = 0x60, /* my secondary address (base) */ + PPE = 0x60, /* parallel poll enable (base) */ + PPD = 0x70 /* parallel poll disable */ +}; + +enum ppe_bits { + PPC_DISABLE = 0x10, + PPC_SENSE = 0x8, /* parallel poll sense bit */ + PPC_DIO_MASK = 0x7 +}; + +/* confine address to range 0 to 30. */ +static inline unsigned int gpib_address_restrict(unsigned int addr) +{ + addr &= 0x1f; + if (addr == 0x1f) + addr = 0; + return addr; +} + +static inline uint8_t MLA(unsigned int addr) +{ + return gpib_address_restrict(addr) | LAD; +} + +static inline uint8_t MTA(unsigned int addr) +{ + return gpib_address_restrict(addr) | TAD; +} + +static inline uint8_t MSA(unsigned int addr) +{ + return gpib_address_restrict(addr) | SAD; +} + +static inline uint8_t PPE_byte(unsigned int dio_line, int sense) +{ + uint8_t cmd; + + cmd = PPE; + if (sense) + cmd |= PPC_SENSE; + cmd |= (dio_line - 1) & 0x7; + return cmd; +} + +static inline uint8_t CFGn(unsigned int meters) +{ + return 0x6 | (meters & 0xf); +} + +/* mask of bits that actually matter in a command byte */ +enum { + gpib_command_mask = 0x7f, +}; + +static inline int is_PPE(uint8_t command) +{ + return (command & 0x70) == 0x60; +} + +static inline int is_PPD(uint8_t command) +{ + return (command & 0x70) == 0x70; +} + +static inline int in_addressed_command_group(uint8_t command) +{ + return (command & 0x70) == 0x0; +} + +static inline int in_universal_command_group(uint8_t command) +{ + return (command & 0x70) == 0x10; +} + +static inline int in_listen_address_group(uint8_t command) +{ + return (command & 0x60) == 0x20; +} + +static inline int in_talk_address_group(uint8_t command) +{ + return (command & 0x60) == 0x40; +} + +static inline int in_primary_command_group(uint8_t command) +{ + return in_addressed_command_group(command) || + in_universal_command_group(command) || + in_listen_address_group(command) || + in_talk_address_group(command); +} + +static inline int gpib_address_equal(unsigned int pad1, int sad1, unsigned int pad2, int sad2) +{ + if (pad1 == pad2) { + if (sad1 == sad2) + return 1; + if (sad1 < 0 && sad2 < 0) + return 1; + } + + return 0; +} + +enum ibask_option { + IbaPAD = 0x1, + IbaSAD = 0x2, + IbaTMO = 0x3, + IbaEOT = 0x4, + IbaPPC = 0x5, /* board only */ + IbaREADDR = 0x6, /* device only */ + IbaAUTOPOLL = 0x7, /* board only */ + IbaCICPROT = 0x8, /* board only */ + IbaIRQ = 0x9, /* board only */ + IbaSC = 0xa, /* board only */ + IbaSRE = 0xb, /* board only */ + IbaEOSrd = 0xc, + IbaEOSwrt = 0xd, + IbaEOScmp = 0xe, + IbaEOSchar = 0xf, + IbaPP2 = 0x10, /* board only */ + IbaTIMING = 0x11, /* board only */ + IbaDMA = 0x12, /* board only */ + IbaReadAdjust = 0x13, + IbaWriteAdjust = 0x14, + IbaEventQueue = 0x15, /* board only */ + IbaSPollBit = 0x16, /* board only */ + IbaSpollBit = 0x16, /* board only */ + IbaSendLLO = 0x17, /* board only */ + IbaSPollTime = 0x18, /* device only */ + IbaPPollTime = 0x19, /* board only */ + IbaEndBitIsNormal = 0x1a, + IbaUnAddr = 0x1b, /* device only */ + IbaHSCableLength = 0x1f, /* board only */ + IbaIst = 0x20, /* board only */ + IbaRsv = 0x21, /* board only */ + IbaBNA = 0x200, /* device only */ + /* linux-gpib extensions */ + Iba7BitEOS = 0x1000 /* board only. Returns 1 if board supports 7 bit eos compares*/ +}; + +enum ibconfig_option { + IbcPAD = 0x1, + IbcSAD = 0x2, + IbcTMO = 0x3, + IbcEOT = 0x4, + IbcPPC = 0x5, /* board only */ + IbcREADDR = 0x6, /* device only */ + IbcAUTOPOLL = 0x7, /* board only */ + IbcCICPROT = 0x8, /* board only */ + IbcIRQ = 0x9, /* board only */ + IbcSC = 0xa, /* board only */ + IbcSRE = 0xb, /* board only */ + IbcEOSrd = 0xc, + IbcEOSwrt = 0xd, + IbcEOScmp = 0xe, + IbcEOSchar = 0xf, + IbcPP2 = 0x10, /* board only */ + IbcTIMING = 0x11, /* board only */ + IbcDMA = 0x12, /* board only */ + IbcReadAdjust = 0x13, + IbcWriteAdjust = 0x14, + IbcEventQueue = 0x15, /* board only */ + IbcSPollBit = 0x16, /* board only */ + IbcSpollBit = 0x16, /* board only */ + IbcSendLLO = 0x17, /* board only */ + IbcSPollTime = 0x18, /* device only */ + IbcPPollTime = 0x19, /* board only */ + IbcEndBitIsNormal = 0x1a, + IbcUnAddr = 0x1b, /* device only */ + IbcHSCableLength = 0x1f, /* board only */ + IbcIst = 0x20, /* board only */ + IbcRsv = 0x21, /* board only */ + IbcBNA = 0x200 /* device only */ +}; + +enum t1_delays { + T1_DELAY_2000ns = 1, + T1_DELAY_500ns = 2, + T1_DELAY_350ns = 3 +}; + +enum { + request_service_bit = 0x40, +}; + +enum gpib_events { + EventNone = 0, + EventDevTrg = 1, + EventDevClr = 2, + EventIFC = 3 +}; + +enum gpib_stb { + IbStbRQS = 0x40, /* IEEE 488.1 & 2 */ + IbStbESB = 0x20, /* IEEE 488.2 only */ + IbStbMAV = 0x10 /* IEEE 488.2 only */ +}; + +#endif /* _GPIB_USER_H */ + +/* Check for errors */ diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index aa6f266b62a1417408e11b68f2f624b4c40bec7d..90ab32638d3f59570da774e95d59db1257cde37e 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -470,7 +470,7 @@ MODULE_DEVICE_TABLE(of, arche_apb_ctrl_of_match); static struct platform_driver arche_apb_ctrl_device_driver = { .probe = arche_apb_ctrl_probe, - .remove_new = arche_apb_ctrl_remove, + .remove = arche_apb_ctrl_remove, .shutdown = arche_apb_ctrl_shutdown, .driver = { .name = "arche-apb-ctrl", diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index b33977ccd5271064a1b588df6e529e1684c2d190..d48464390f58e23af3d1c2c83d7e3dd8c3a75132 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -623,7 +623,7 @@ MODULE_DEVICE_TABLE(of, arche_platform_of_match); static struct platform_driver arche_platform_device_driver = { .probe = arche_platform_probe, - .remove_new = arche_platform_remove, + .remove = arche_platform_remove, .shutdown = arche_platform_shutdown, .driver = { .name = "arche-platform-ctrl", diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index 9b26e148d40fba89398ef02a2517fdedd539130b..16bcf7fc8158659284dff900d33befa3b65fe7be 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -42,11 +42,6 @@ struct gb_gpio_controller { struct mutex irq_lock; }; -static inline struct gb_gpio_controller *gpio_chip_to_gb_gpio_controller(struct gpio_chip *chip) -{ - return container_of(chip, struct gb_gpio_controller, chip); -} - static struct gpio_chip *irq_data_to_gpio_chip(struct irq_data *d) { return d->domain->host_data; @@ -278,7 +273,7 @@ static void _gb_gpio_irq_set_type(struct gb_gpio_controller *ggc, static void gb_gpio_irq_mask(struct irq_data *d) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); struct gb_gpio_line *line = &ggc->lines[d->hwirq]; line->masked = true; @@ -288,7 +283,7 @@ static void gb_gpio_irq_mask(struct irq_data *d) static void gb_gpio_irq_unmask(struct irq_data *d) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); struct gb_gpio_line *line = &ggc->lines[d->hwirq]; line->masked = false; @@ -298,7 +293,7 @@ static void gb_gpio_irq_unmask(struct irq_data *d) static int gb_gpio_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); struct gb_gpio_line *line = &ggc->lines[d->hwirq]; struct device *dev = &ggc->gbphy_dev->dev; u8 irq_type; @@ -336,7 +331,7 @@ static int gb_gpio_irq_set_type(struct irq_data *d, unsigned int type) static void gb_gpio_irq_bus_lock(struct irq_data *d) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); mutex_lock(&ggc->irq_lock); } @@ -344,7 +339,7 @@ static void gb_gpio_irq_bus_lock(struct irq_data *d) static void gb_gpio_irq_bus_sync_unlock(struct irq_data *d) { struct gpio_chip *chip = irq_data_to_gpio_chip(d); - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); struct gb_gpio_line *line = &ggc->lines[d->hwirq]; if (line->irq_type_pending) { @@ -407,21 +402,21 @@ static int gb_gpio_request_handler(struct gb_operation *op) static int gb_gpio_request(struct gpio_chip *chip, unsigned int offset) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); return gb_gpio_activate_operation(ggc, (u8)offset); } static void gb_gpio_free(struct gpio_chip *chip, unsigned int offset) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); gb_gpio_deactivate_operation(ggc, (u8)offset); } static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); u8 which; int ret; @@ -435,7 +430,7 @@ static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); return gb_gpio_direction_in_operation(ggc, (u8)offset); } @@ -443,14 +438,14 @@ static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); return gb_gpio_direction_out_operation(ggc, (u8)offset, !!value); } static int gb_gpio_get(struct gpio_chip *chip, unsigned int offset) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); u8 which; int ret; @@ -464,7 +459,7 @@ static int gb_gpio_get(struct gpio_chip *chip, unsigned int offset) static void gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); gb_gpio_set_value_operation(ggc, (u8)offset, !!value); } @@ -472,7 +467,7 @@ static void gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) static int gb_gpio_set_config(struct gpio_chip *chip, unsigned int offset, unsigned long config) { - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); + struct gb_gpio_controller *ggc = gpiochip_get_data(chip); u32 debounce; if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) @@ -579,7 +574,7 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev, if (ret) goto exit_line_free; - ret = gpiochip_add_data(gpio, NULL); + ret = gpiochip_add_data(gpio, ggc); if (ret) { dev_err(&gbphy_dev->dev, "failed to add gpio chip: %d\n", ret); goto exit_line_free; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index cdf4ebb93b104e85296fa770a2d9692114b3d022..8eab94cb06faf64dbf171edb7c924cbc00fb3c02 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -596,11 +596,13 @@ static int get_serial_info(struct tty_struct *tty, struct gb_tty *gb_tty = tty->driver_data; ss->line = gb_tty->minor; + mutex_lock(&gb_tty->port.mutex); ss->close_delay = jiffies_to_msecs(gb_tty->port.close_delay) / 10; ss->closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : jiffies_to_msecs(gb_tty->port.closing_wait) / 10; + mutex_unlock(&gb_tty->port.mutex); return 0; } diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO deleted file mode 100644 index 0fa6a5500bdb10c59d4e09c0326be3e73d5e7b22..0000000000000000000000000000000000000000 --- a/drivers/staging/iio/TODO +++ /dev/null @@ -1,5 +0,0 @@ -2020-02-25 - - -Contact: Jonathan Cameron . -Mailing list: linux-iio@vger.kernel.org diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c index c0e4c9266b5f4aa987d5cde8eab20078fa85a385..c1c73308800c50dbb84574df9e645a167e08c6fd 100644 --- a/drivers/staging/iio/accel/adis16203.c +++ b/drivers/staging/iio/accel/adis16203.c @@ -312,4 +312,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:adis16203"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index 337492785f04c98df122b4f4844f739a7ed707ae..3be3eaf5d9d4d45a47950d8c045999c98983cd91 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c @@ -440,4 +440,4 @@ MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); MODULE_DESCRIPTION("Analog Devices Programmable Impact Sensor and Recorder"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:adis16240"); -MODULE_IMPORT_NS(IIO_ADISLIB); +MODULE_IMPORT_NS("IIO_ADISLIB"); diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 4ae1a7039418b13aba6b9b6c28cceb46e738306a..d5544fc2fe989b90bf7c1eb5fab60dd206754ae2 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -628,9 +628,9 @@ static void ad5933_work(struct work_struct *work) int scan_count = bitmap_weight(indio_dev->active_scan_mask, iio_get_masklength(indio_dev)); ret = ad5933_i2c_read(st->client, - test_bit(1, indio_dev->active_scan_mask) ? - AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, - scan_count * 2, (u8 *)buf); + test_bit(1, indio_dev->active_scan_mask) ? + AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, + scan_count * 2, (u8 *)buf); if (ret) return; diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index d92b5cce107aff277ce0f80de3b71c1c465da272..2841824cd0ca5c66b8c39d438d46c0118bbb5334 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1482,4 +1482,4 @@ MODULE_AUTHOR("Wen Wang "); MODULE_AUTHOR("Xiaolin Zhang "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Intel ATOM Platform ISP Driver"); -MODULE_IMPORT_NS(INTEL_IPU_BRIDGE); +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE"); diff --git a/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c b/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c index 712f916f0935f5be7d4284cf2698828ef89a7e64..71e6e278a4b3cc6c8118f884d556ac47e2f8c9dc 100644 --- a/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c +++ b/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c @@ -629,7 +629,7 @@ MODULE_DEVICE_TABLE(of, atmel_isc_of_match); static struct platform_driver atmel_isc_driver = { .probe = atmel_isc_probe, - .remove_new = atmel_isc_remove, + .remove = atmel_isc_remove, .driver = { .name = "atmel-sama5d2-isc", .pm = &atmel_isc_dev_pm_ops, diff --git a/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c b/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c index 9485167d5b7d7385431df579afaa879531680baa..1f74c2dd044cfb9e7df926524171ac758d9b53b2 100644 --- a/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c +++ b/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c @@ -592,7 +592,7 @@ MODULE_DEVICE_TABLE(of, microchip_xisc_of_match); static struct platform_driver microchip_xisc_driver = { .probe = microchip_xisc_probe, - .remove_new = microchip_xisc_remove, + .remove = microchip_xisc_remove, .driver = { .name = "microchip-sama7g5-xisc", .pm = µchip_xisc_dev_pm_ops, diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 785aac88192212bcb31d6145522f5ebb2b356feb..3edbc57be2caa76d0f1236fc4337992095962475 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -2076,7 +2076,7 @@ MODULE_DEVICE_TABLE(platform, imx_csi_ids); static struct platform_driver imx_csi_driver = { .probe = imx_csi_probe, - .remove_new = imx_csi_remove, + .remove = imx_csi_remove, .id_table = imx_csi_ids, .driver = { .name = "imx-ipuv3-csi", diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c index be54dca11465dc4eb0112fc44556596e05a17d83..a08389b99d14acceb50ba854f0c579fc646ac808 100644 --- a/drivers/staging/media/imx/imx-media-dev.c +++ b/drivers/staging/media/imx/imx-media-dev.c @@ -129,7 +129,7 @@ MODULE_DEVICE_TABLE(of, imx_media_dt_ids); static struct platform_driver imx_media_pdrv = { .probe = imx_media_probe, - .remove_new = imx_media_remove, + .remove = imx_media_remove, .driver = { .name = "imx-media", .of_match_table = imx_media_dt_ids, diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c index 0d8b420616235dd32d155de4ce489cd5acc63752..dd8c7b3233bccfc34b59e0f0ff813b36752e1526 100644 --- a/drivers/staging/media/imx/imx6-mipi-csi2.c +++ b/drivers/staging/media/imx/imx6-mipi-csi2.c @@ -836,7 +836,7 @@ static struct platform_driver csi2_driver = { .of_match_table = csi2_dt_ids, }, .probe = csi2_probe, - .remove_new = csi2_remove, + .remove = csi2_remove, }; module_platform_driver(csi2_driver); diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c index 52185090129ba5a5c5f3d7747f7d00268375aa33..6d34a482492e8838cf9dbb104315b87abf3f3e3b 100644 --- a/drivers/staging/media/meson/vdec/vdec.c +++ b/drivers/staging/media/meson/vdec/vdec.c @@ -1117,7 +1117,7 @@ static void vdec_remove(struct platform_device *pdev) static struct platform_driver meson_vdec_driver = { .probe = vdec_probe, - .remove_new = vdec_remove, + .remove = vdec_remove, .driver = { .name = "meson-vdec", .of_match_table = vdec_dt_match, diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index f468af64bbef1c7e9019352508f95f5e2d2a083a..f9bef5173bf25c0cd6b09d2b253d36aa78d7b0c4 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -1101,7 +1101,7 @@ static const struct dev_pm_ops rkvdec_pm_ops = { static struct platform_driver rkvdec_driver = { .probe = rkvdec_probe, - .remove_new = rkvdec_remove, + .remove = rkvdec_remove, .driver = { .name = "rkvdec", .of_match_table = of_rkvdec_match, diff --git a/drivers/staging/media/starfive/camss/stf-camss.c b/drivers/staging/media/starfive/camss/stf-camss.c index b6d34145bc191e8f2e39713553c28ce0c6ca2d9f..259aaad010d2f02b620ce7ac98517c75134566bb 100644 --- a/drivers/staging/media/starfive/camss/stf-camss.c +++ b/drivers/staging/media/starfive/camss/stf-camss.c @@ -422,7 +422,7 @@ static const struct dev_pm_ops stfcamss_pm_ops = { static struct platform_driver stfcamss_driver = { .probe = stfcamss_probe, - .remove_new = stfcamss_remove, + .remove = stfcamss_remove, .driver = { .name = "starfive-camss", .pm = &stfcamss_pm_ops, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index f52df683604525fd17b82087ef7f867f2d9155a2..52a9588462ce5898705cc351fa461f3c49600ad2 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -705,7 +705,7 @@ static const struct dev_pm_ops cedrus_dev_pm_ops = { static struct platform_driver cedrus_driver = { .probe = cedrus_probe, - .remove_new = cedrus_remove, + .remove = cedrus_remove, .driver = { .name = CEDRUS_NAME, .of_match_table = cedrus_dt_match, diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c index 58f8ae92320d676058d170cc0871df70b2571559..6877f2beee8c8c069a0aa1aeeafd052acc713164 100644 --- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c +++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c @@ -536,7 +536,7 @@ MODULE_DEVICE_TABLE(of, sun6i_isp_of_match); static struct platform_driver sun6i_isp_platform_driver = { .probe = sun6i_isp_probe, - .remove_new = sun6i_isp_remove, + .remove = sun6i_isp_remove, .driver = { .name = SUN6I_ISP_NAME, .of_match_table = sun6i_isp_of_match, diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c index 255cccd0c5fda8e47455142451f56d27bcd7a608..604185c00a1a39e34357e3beefa75aa87b0a1189 100644 --- a/drivers/staging/media/tegra-video/csi.c +++ b/drivers/staging/media/tegra-video/csi.c @@ -858,5 +858,5 @@ struct platform_driver tegra_csi_driver = { .pm = &tegra_csi_pm_ops, }, .probe = tegra_csi_probe, - .remove_new = tegra_csi_remove, + .remove = tegra_csi_remove, }; diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index ad481b35e618a0b0e85af7276d84342440b82e64..c9276ff76157fa2d17e05df271c6ebea4b4455ed 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -1977,5 +1977,5 @@ struct platform_driver tegra_vi_driver = { .pm = &tegra_vi_pm_ops, }, .probe = tegra_vi_probe, - .remove_new = tegra_vi_remove, + .remove = tegra_vi_remove, }; diff --git a/drivers/staging/media/tegra-video/vip.c b/drivers/staging/media/tegra-video/vip.c index 8504b9ea9cea2ce27164c689116663a820608706..5ec717f3afd503b1ef7e3690d3f028531c1afa9f 100644 --- a/drivers/staging/media/tegra-video/vip.c +++ b/drivers/staging/media/tegra-video/vip.c @@ -281,5 +281,5 @@ struct platform_driver tegra_vip_driver = { .of_match_table = tegra_vip_of_id_table, }, .probe = tegra_vip_probe, - .remove_new = tegra_vip_remove, + .remove = tegra_vip_remove, }; diff --git a/drivers/staging/most/TODO b/drivers/staging/most/TODO index 4fa11a9d2cf741fcf49ee9e74f8b635e9990549d..a6448a05ed4612082a2e391d5022d12bda0783cf 100644 --- a/drivers/staging/most/TODO +++ b/drivers/staging/most/TODO @@ -1,8 +1 @@ * Get through code review with Greg Kroah-Hartman - -Contact: -To: -Christian Gromm -Cc: -Michael Fabry -Christian Gromm diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index ed6a9cc8854129ea9526eb6f37f7cc6d8edce140..dad2abe6c0c90e0af0902d2022a8438370d4c5aa 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -1090,7 +1090,7 @@ MODULE_DEVICE_TABLE(of, dim2_of_match); static struct platform_driver dim2_driver = { .probe = dim2_probe, - .remove_new = dim2_remove, + .remove = dim2_remove, .driver = { .name = "hdm_dim2", .of_match_table = dim2_of_match, diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c index ce869280a056b6fb88d61880b2c34a7785ad2b86..184b2dd11fc34a23be1d31107e73ddde7f0d1201 100644 --- a/drivers/staging/most/i2c/i2c.c +++ b/drivers/staging/most/i2c/i2c.c @@ -352,8 +352,8 @@ static void i2c_remove(struct i2c_client *client) } static const struct i2c_device_id i2c_id[] = { - { "most_i2c", 0 }, - { }, /* Terminating entry */ + { "most_i2c" }, + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(i2c, i2c_id); diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 977f8fc29e631f1a391da08531a51a98c4a0e443..263774e6a78cae913ebd74af5d16ed0dc6ee86ad 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -952,7 +952,7 @@ MODULE_DEVICE_TABLE(of, nvidia_nvec_of_match); static struct platform_driver nvec_device_driver = { .probe = tegra_nvec_probe, - .remove_new = tegra_nvec_remove, + .remove = tegra_nvec_remove, .driver = { .name = "nvec", .pm = &nvec_pm_ops, diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index d0259c80f8105e6529262329e5ad0ce4405e512f..d2b91318f1516f2e9f8edbe4f68731595999f4c5 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -175,7 +175,7 @@ static void nvec_kbd_remove(struct platform_device *pdev) static struct platform_driver nvec_kbd_driver = { .probe = nvec_kbd_probe, - .remove_new = nvec_kbd_remove, + .remove = nvec_kbd_remove, .driver = { .name = "nvec-kbd", }, diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index 9943b1fff1905d4cfc5ebf6274ecd65598f7680a..e0e67a3eb7222b38a45aa61fd23db0336d5b21a0 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -433,7 +433,7 @@ static void nvec_power_remove(struct platform_device *pdev) static struct platform_driver nvec_power_driver = { .probe = nvec_power_probe, - .remove_new = nvec_power_remove, + .remove = nvec_power_remove, .driver = { .name = "nvec-power", } diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index f34016c4a26b6ecafdf68bb28989e8852d1bd925..575233fa1677eaab75b28448f3a15f9839527b12 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -175,7 +175,7 @@ static SIMPLE_DEV_PM_OPS(nvec_mouse_pm_ops, nvec_mouse_suspend, static struct platform_driver nvec_mouse_driver = { .probe = nvec_mouse_probe, - .remove_new = nvec_mouse_remove, + .remove = nvec_mouse_remove, .driver = { .name = "nvec-mouse", .pm = &nvec_mouse_pm_ops, diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index bbf33b88bb7c2afe59321c5862e42102ab15a52a..261f8dbdc3827360bdff4565d511b47883a6ef84 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -40,8 +40,8 @@ #define GET_SKBUFF_QOS(skb) 0 #endif -static void cvm_oct_tx_do_cleanup(unsigned long arg); -static DECLARE_TASKLET_OLD(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup); +static void cvm_oct_tx_do_cleanup(struct tasklet_struct *clean); +static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup); /* Maximum number of SKBs to try to free per xmit packet. */ #define MAX_SKB_TO_FREE (MAX_OUT_QUEUE_DEPTH * 2) @@ -670,7 +670,7 @@ void cvm_oct_tx_shutdown_dev(struct net_device *dev) } } -static void cvm_oct_tx_do_cleanup(unsigned long arg) +static void cvm_oct_tx_do_cleanup(struct tasklet_struct *clean) { int port; diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index a5e99cc78a454f5666b6bb3632e701e794db781e..eadb74fc14c8d9d88731c2b500ef38d27fa56cfb 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -977,7 +977,7 @@ MODULE_DEVICE_TABLE(of, cvm_oct_match); static struct platform_driver cvm_oct_driver = { .probe = cvm_oct_probe, - .remove_new = cvm_oct_remove, + .remove = cvm_oct_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = cvm_oct_match, diff --git a/drivers/staging/olpc_dcon/Kconfig b/drivers/staging/olpc_dcon/Kconfig deleted file mode 100644 index d0ba34cc32f7a8f9861cd97e2dbc27358a9767ec..0000000000000000000000000000000000000000 --- a/drivers/staging/olpc_dcon/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config FB_OLPC_DCON - tristate "One Laptop Per Child Display CONtroller support" - depends on OLPC && FB && BROKEN - depends on I2C - depends on GPIO_CS5535 && ACPI - select BACKLIGHT_CLASS_DEVICE - help - In order to support very low power operation, the XO laptop uses a - secondary Display CONtroller, or DCON. This secondary controller - is present in the video pipeline between the primary display - controller (integrate into the processor or chipset) and the LCD - panel. It allows the main processor/display controller to be - completely powered off while still retaining an image on the display. - This controller is only available on OLPC platforms. Unless you have - one of these platforms, you will want to say 'N'. - diff --git a/drivers/staging/olpc_dcon/Makefile b/drivers/staging/olpc_dcon/Makefile deleted file mode 100644 index 734b2ce26066f34fd005b053aac2513ef5bb1933..0000000000000000000000000000000000000000 --- a/drivers/staging/olpc_dcon/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -olpc-dcon-objs += olpc_dcon.o olpc_dcon_xo_1.o olpc_dcon_xo_1_5.o -obj-$(CONFIG_FB_OLPC_DCON) += olpc-dcon.o - - diff --git a/drivers/staging/olpc_dcon/TODO b/drivers/staging/olpc_dcon/TODO deleted file mode 100644 index 7c263358b44a96bd8160b65baf0186e3ad450dfa..0000000000000000000000000000000000000000 --- a/drivers/staging/olpc_dcon/TODO +++ /dev/null @@ -1,15 +0,0 @@ -TODO: - - complete rewrite: - 1. The underlying fbdev drivers need to be converted into drm kernel - modesetting drivers. - 2. The dcon low-power display mode can then be integrated using the - drm damage tracking and self-refresh helpers. - This bolted-on self-refresh support that digs around in fbdev - internals, but isn't properly integrated, is not the correct solution. - - see if vx855 gpio API can be made similar enough to cs5535 so we can - share more code - -Please send patches to Greg Kroah-Hartman and -copy: - Daniel Drake - Jens Frederich diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c deleted file mode 100644 index 4cb904a5f8f40258a2f03b39109366c5ebf50298..0000000000000000000000000000000000000000 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ /dev/null @@ -1,807 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Mainly by David Woodhouse, somewhat modified by Jordan Crouse - * - * Copyright © 2006-2007 Red Hat, Inc. - * Copyright © 2006-2007 Advanced Micro Devices, Inc. - * Copyright © 2009 VIA Technology, Inc. - * Copyright (c) 2010-2011 Andres Salomon - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "olpc_dcon.h" - -/* Module definitions */ - -static ushort resumeline = 898; -module_param(resumeline, ushort, 0444); - -static struct dcon_platform_data *pdata; - -/* I2C structures */ - -/* Platform devices */ -static struct platform_device *dcon_device; - -static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END }; - -static s32 dcon_write(struct dcon_priv *dcon, u8 reg, u16 val) -{ - return i2c_smbus_write_word_data(dcon->client, reg, val); -} - -static s32 dcon_read(struct dcon_priv *dcon, u8 reg) -{ - return i2c_smbus_read_word_data(dcon->client, reg); -} - -/* ===== API functions - these are called by a variety of users ==== */ - -static int dcon_hw_init(struct dcon_priv *dcon, int is_init) -{ - u16 ver; - int rc = 0; - - ver = dcon_read(dcon, DCON_REG_ID); - if ((ver >> 8) != 0xDC) { - pr_err("DCON ID not 0xDCxx: 0x%04x instead.\n", ver); - rc = -ENXIO; - goto err; - } - - if (is_init) { - pr_info("Discovered DCON version %x\n", ver & 0xFF); - rc = pdata->init(dcon); - if (rc != 0) { - pr_err("Unable to init.\n"); - goto err; - } - } - - if (ver < 0xdc02) { - dev_err(&dcon->client->dev, - "DCON v1 is unsupported, giving up..\n"); - rc = -ENODEV; - goto err; - } - - /* SDRAM setup/hold time */ - dcon_write(dcon, 0x3a, 0xc040); - dcon_write(dcon, DCON_REG_MEM_OPT_A, 0x0000); /* clear option bits */ - dcon_write(dcon, DCON_REG_MEM_OPT_A, - MEM_DLL_CLOCK_DELAY | MEM_POWER_DOWN); - dcon_write(dcon, DCON_REG_MEM_OPT_B, MEM_SOFT_RESET); - - /* Colour swizzle, AA, no passthrough, backlight */ - if (is_init) { - dcon->disp_mode = MODE_PASSTHRU | MODE_BL_ENABLE | - MODE_CSWIZZLE | MODE_COL_AA; - } - dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); - - /* Set the scanline to interrupt on during resume */ - dcon_write(dcon, DCON_REG_SCAN_INT, resumeline); - -err: - return rc; -} - -/* - * The smbus doesn't always come back due to what is believed to be - * hardware (power rail) bugs. For older models where this is known to - * occur, our solution is to attempt to wait for the bus to stabilize; - * if it doesn't happen, cut power to the dcon, repower it, and wait - * for the bus to stabilize. Rinse, repeat until we have a working - * smbus. For newer models, we simply BUG(); we want to know if this - * still happens despite the power fixes that have been made! - */ -static int dcon_bus_stabilize(struct dcon_priv *dcon, int is_powered_down) -{ - unsigned long timeout; - u8 pm; - int x; - -power_up: - if (is_powered_down) { - pm = 1; - x = olpc_ec_cmd(EC_DCON_POWER_MODE, &pm, 1, NULL, 0); - if (x) { - pr_warn("unable to force dcon to power up: %d!\n", x); - return x; - } - usleep_range(10000, 11000); /* we'll be conservative */ - } - - pdata->bus_stabilize_wiggle(); - - for (x = -1, timeout = 50; timeout && x < 0; timeout--) { - usleep_range(1000, 1100); - x = dcon_read(dcon, DCON_REG_ID); - } - if (x < 0) { - pr_err("unable to stabilize dcon's smbus, reasserting power and praying.\n"); - BUG_ON(olpc_board_at_least(olpc_board(0xc2))); - pm = 0; - olpc_ec_cmd(EC_DCON_POWER_MODE, &pm, 1, NULL, 0); - msleep(100); - is_powered_down = 1; - goto power_up; /* argh, stupid hardware.. */ - } - - if (is_powered_down) - return dcon_hw_init(dcon, 0); - return 0; -} - -static void dcon_set_backlight(struct dcon_priv *dcon, u8 level) -{ - dcon->bl_val = level; - dcon_write(dcon, DCON_REG_BRIGHT, dcon->bl_val); - - /* Purposely turn off the backlight when we go to level 0 */ - if (dcon->bl_val == 0) { - dcon->disp_mode &= ~MODE_BL_ENABLE; - dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); - } else if (!(dcon->disp_mode & MODE_BL_ENABLE)) { - dcon->disp_mode |= MODE_BL_ENABLE; - dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); - } -} - -/* Set the output type to either color or mono */ -static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono) -{ - if (dcon->mono == enable_mono) - return 0; - - dcon->mono = enable_mono; - - if (enable_mono) { - dcon->disp_mode &= ~(MODE_CSWIZZLE | MODE_COL_AA); - dcon->disp_mode |= MODE_MONO_LUMA; - } else { - dcon->disp_mode &= ~(MODE_MONO_LUMA); - dcon->disp_mode |= MODE_CSWIZZLE | MODE_COL_AA; - } - - dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); - return 0; -} - -/* For now, this will be really stupid - we need to address how - * DCONLOAD works in a sleep and account for it accordingly - */ - -static void dcon_sleep(struct dcon_priv *dcon, bool sleep) -{ - int x; - - /* Turn off the backlight and put the DCON to sleep */ - - if (dcon->asleep == sleep) - return; - - if (!olpc_board_at_least(olpc_board(0xc2))) - return; - - if (sleep) { - u8 pm = 0; - - x = olpc_ec_cmd(EC_DCON_POWER_MODE, &pm, 1, NULL, 0); - if (x) - pr_warn("unable to force dcon to power down: %d!\n", x); - else - dcon->asleep = sleep; - } else { - /* Only re-enable the backlight if the backlight value is set */ - if (dcon->bl_val != 0) - dcon->disp_mode |= MODE_BL_ENABLE; - x = dcon_bus_stabilize(dcon, 1); - if (x) - pr_warn("unable to reinit dcon hardware: %d!\n", x); - else - dcon->asleep = sleep; - - /* Restore backlight */ - dcon_set_backlight(dcon, dcon->bl_val); - } - - /* We should turn off some stuff in the framebuffer - but what? */ -} - -/* the DCON seems to get confused if we change DCONLOAD too - * frequently -- i.e., approximately faster than frame time. - * normally we don't change it this fast, so in general we won't - * delay here. - */ -static void dcon_load_holdoff(struct dcon_priv *dcon) -{ - ktime_t delta_t, now; - - while (1) { - now = ktime_get(); - delta_t = ktime_sub(now, dcon->load_time); - if (ktime_to_ns(delta_t) > NSEC_PER_MSEC * 20) - break; - mdelay(4); - } -} - -static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank) -{ - int err; - - console_lock(); - lock_fb_info(dcon->fbinfo); - - dcon->ignore_fb_events = true; - err = fb_blank(dcon->fbinfo, - blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); - dcon->ignore_fb_events = false; - unlock_fb_info(dcon->fbinfo); - console_unlock(); - - if (err) { - dev_err(&dcon->client->dev, "couldn't %sblank framebuffer\n", - blank ? "" : "un"); - return false; - } - return true; -} - -/* Set the source of the display (CPU or DCON) */ -static void dcon_source_switch(struct work_struct *work) -{ - struct dcon_priv *dcon = container_of(work, struct dcon_priv, - switch_source); - int source = dcon->pending_src; - - if (dcon->curr_src == source) - return; - - dcon_load_holdoff(dcon); - - dcon->switched = false; - - switch (source) { - case DCON_SOURCE_CPU: - pr_info("%s to CPU\n", __func__); - /* Enable the scanline interrupt bit */ - if (dcon_write(dcon, DCON_REG_MODE, - dcon->disp_mode | MODE_SCAN_INT)) - pr_err("couldn't enable scanline interrupt!\n"); - else - /* Wait up to one second for the scanline interrupt */ - wait_event_timeout(dcon->waitq, dcon->switched, HZ); - - if (!dcon->switched) - pr_err("Timeout entering CPU mode; expect a screen glitch.\n"); - - /* Turn off the scanline interrupt */ - if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode)) - pr_err("couldn't disable scanline interrupt!\n"); - - /* - * Ideally we'd like to disable interrupts here so that the - * fb unblanking and DCON turn on happen at a known time value; - * however, we can't do that right now with fb_blank - * messing with semaphores. - * - * For now, we just hope.. - */ - if (!dcon_blank_fb(dcon, false)) { - pr_err("Failed to enter CPU mode\n"); - dcon->pending_src = DCON_SOURCE_DCON; - return; - } - - /* And turn off the DCON */ - pdata->set_dconload(1); - dcon->load_time = ktime_get(); - - pr_info("The CPU has control\n"); - break; - case DCON_SOURCE_DCON: - { - ktime_t delta_t; - - pr_info("%s to DCON\n", __func__); - - /* Clear DCONLOAD - this implies that the DCON is in control */ - pdata->set_dconload(0); - dcon->load_time = ktime_get(); - - wait_event_timeout(dcon->waitq, dcon->switched, HZ / 2); - - if (!dcon->switched) { - pr_err("Timeout entering DCON mode; expect a screen glitch.\n"); - } else { - /* sometimes the DCON doesn't follow its own rules, - * and doesn't wait for two vsync pulses before - * ack'ing the frame load with an IRQ. the result - * is that the display shows the *previously* - * loaded frame. we can detect this by looking at - * the time between asserting DCONLOAD and the IRQ -- - * if it's less than 20msec, then the DCON couldn't - * have seen two VSYNC pulses. in that case we - * deassert and reassert, and hope for the best. - * see http://dev.laptop.org/ticket/9664 - */ - delta_t = ktime_sub(dcon->irq_time, dcon->load_time); - if (dcon->switched && ktime_to_ns(delta_t) - < NSEC_PER_MSEC * 20) { - pr_err("missed loading, retrying\n"); - pdata->set_dconload(1); - mdelay(41); - pdata->set_dconload(0); - dcon->load_time = ktime_get(); - mdelay(41); - } - } - - dcon_blank_fb(dcon, true); - pr_info("The DCON has control\n"); - break; - } - default: - BUG(); - } - - dcon->curr_src = source; -} - -static void dcon_set_source(struct dcon_priv *dcon, int arg) -{ - if (dcon->pending_src == arg) - return; - - dcon->pending_src = arg; - - if (dcon->curr_src != arg) - schedule_work(&dcon->switch_source); -} - -static void dcon_set_source_sync(struct dcon_priv *dcon, int arg) -{ - dcon_set_source(dcon, arg); - flush_work(&dcon->switch_source); -} - -static ssize_t dcon_mode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct dcon_priv *dcon = dev_get_drvdata(dev); - - return sprintf(buf, "%4.4X\n", dcon->disp_mode); -} - -static ssize_t dcon_sleep_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct dcon_priv *dcon = dev_get_drvdata(dev); - - return sprintf(buf, "%d\n", dcon->asleep); -} - -static ssize_t dcon_freeze_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct dcon_priv *dcon = dev_get_drvdata(dev); - - return sprintf(buf, "%d\n", dcon->curr_src == DCON_SOURCE_DCON ? 1 : 0); -} - -static ssize_t dcon_mono_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct dcon_priv *dcon = dev_get_drvdata(dev); - - return sprintf(buf, "%d\n", dcon->mono); -} - -static ssize_t dcon_resumeline_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%d\n", resumeline); -} - -static ssize_t dcon_mono_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long enable_mono; - int rc; - - rc = kstrtoul(buf, 10, &enable_mono); - if (rc) - return rc; - - dcon_set_mono_mode(dev_get_drvdata(dev), enable_mono ? true : false); - - return count; -} - -static ssize_t dcon_freeze_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct dcon_priv *dcon = dev_get_drvdata(dev); - unsigned long output; - int ret; - - ret = kstrtoul(buf, 10, &output); - if (ret) - return ret; - - switch (output) { - case 0: - dcon_set_source(dcon, DCON_SOURCE_CPU); - break; - case 1: - dcon_set_source_sync(dcon, DCON_SOURCE_DCON); - break; - case 2: /* normally unused */ - dcon_set_source(dcon, DCON_SOURCE_DCON); - break; - default: - return -EINVAL; - } - - return count; -} - -static ssize_t dcon_resumeline_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned short rl; - int rc; - - rc = kstrtou16(buf, 10, &rl); - if (rc) - return rc; - - resumeline = rl; - dcon_write(dev_get_drvdata(dev), DCON_REG_SCAN_INT, resumeline); - - return count; -} - -static ssize_t dcon_sleep_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long output; - int ret; - - ret = kstrtoul(buf, 10, &output); - if (ret) - return ret; - - dcon_sleep(dev_get_drvdata(dev), output ? true : false); - return count; -} - -static struct device_attribute dcon_device_files[] = { - __ATTR(mode, 0444, dcon_mode_show, NULL), - __ATTR(sleep, 0644, dcon_sleep_show, dcon_sleep_store), - __ATTR(freeze, 0644, dcon_freeze_show, dcon_freeze_store), - __ATTR(monochrome, 0644, dcon_mono_show, dcon_mono_store), - __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store), -}; - -static int dcon_bl_update(struct backlight_device *dev) -{ - struct dcon_priv *dcon = bl_get_data(dev); - u8 level = backlight_get_brightness(dev) & 0x0F; - - if (level != dcon->bl_val) - dcon_set_backlight(dcon, level); - - /* power down the DCON when the screen is blanked */ - if (!dcon->ignore_fb_events) - dcon_sleep(dcon, !!(dev->props.state & BL_CORE_FBBLANK)); - - return 0; -} - -static int dcon_bl_get(struct backlight_device *dev) -{ - struct dcon_priv *dcon = bl_get_data(dev); - - return dcon->bl_val; -} - -static const struct backlight_ops dcon_bl_ops = { - .update_status = dcon_bl_update, - .get_brightness = dcon_bl_get, -}; - -static struct backlight_properties dcon_bl_props = { - .max_brightness = 15, - .type = BACKLIGHT_RAW, - .power = BACKLIGHT_POWER_ON, -}; - -static int dcon_reboot_notify(struct notifier_block *nb, - unsigned long foo, void *bar) -{ - struct dcon_priv *dcon = container_of(nb, struct dcon_priv, reboot_nb); - - if (!dcon || !dcon->client) - return NOTIFY_DONE; - - /* Turn off the DCON. Entirely. */ - dcon_write(dcon, DCON_REG_MODE, 0x39); - dcon_write(dcon, DCON_REG_MODE, 0x32); - return NOTIFY_DONE; -} - -static int unfreeze_on_panic(struct notifier_block *nb, - unsigned long e, void *p) -{ - pdata->set_dconload(1); - return NOTIFY_DONE; -} - -static struct notifier_block dcon_panic_nb = { - .notifier_call = unfreeze_on_panic, -}; - -static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info) -{ - strscpy(info->type, "olpc_dcon", I2C_NAME_SIZE); - - return 0; -} - -static int dcon_probe(struct i2c_client *client) -{ - struct dcon_priv *dcon; - int rc, i, j; - - if (!pdata) - return -ENXIO; - - dcon = kzalloc(sizeof(*dcon), GFP_KERNEL); - if (!dcon) - return -ENOMEM; - - dcon->client = client; - init_waitqueue_head(&dcon->waitq); - INIT_WORK(&dcon->switch_source, dcon_source_switch); - dcon->reboot_nb.notifier_call = dcon_reboot_notify; - dcon->reboot_nb.priority = -1; - - i2c_set_clientdata(client, dcon); - - if (num_registered_fb < 1) { - dev_err(&client->dev, "DCON driver requires a registered fb\n"); - rc = -EIO; - goto einit; - } - dcon->fbinfo = registered_fb[0]; - - rc = dcon_hw_init(dcon, 1); - if (rc) - goto einit; - - /* Add the DCON device */ - - dcon_device = platform_device_alloc("dcon", -1); - - if (!dcon_device) { - pr_err("Unable to create the DCON device\n"); - rc = -ENOMEM; - goto eirq; - } - rc = platform_device_add(dcon_device); - platform_set_drvdata(dcon_device, dcon); - - if (rc) { - pr_err("Unable to add the DCON device\n"); - goto edev; - } - - for (i = 0; i < ARRAY_SIZE(dcon_device_files); i++) { - rc = device_create_file(&dcon_device->dev, - &dcon_device_files[i]); - if (rc) { - dev_err(&dcon_device->dev, "Cannot create sysfs file\n"); - goto ecreate; - } - } - - dcon->bl_val = dcon_read(dcon, DCON_REG_BRIGHT) & 0x0F; - - /* Add the backlight device for the DCON */ - dcon_bl_props.brightness = dcon->bl_val; - dcon->bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev, - dcon, &dcon_bl_ops, - &dcon_bl_props); - if (IS_ERR(dcon->bl_dev)) { - dev_err(&client->dev, "cannot register backlight dev (%ld)\n", - PTR_ERR(dcon->bl_dev)); - dcon->bl_dev = NULL; - } - - register_reboot_notifier(&dcon->reboot_nb); - atomic_notifier_chain_register(&panic_notifier_list, &dcon_panic_nb); - - return 0; - - ecreate: - for (j = 0; j < i; j++) - device_remove_file(&dcon_device->dev, &dcon_device_files[j]); - platform_device_del(dcon_device); - edev: - platform_device_put(dcon_device); - dcon_device = NULL; - eirq: - free_irq(DCON_IRQ, dcon); - einit: - kfree(dcon); - return rc; -} - -static void dcon_remove(struct i2c_client *client) -{ - struct dcon_priv *dcon = i2c_get_clientdata(client); - - unregister_reboot_notifier(&dcon->reboot_nb); - atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb); - - free_irq(DCON_IRQ, dcon); - - backlight_device_unregister(dcon->bl_dev); - - if (dcon_device) - platform_device_unregister(dcon_device); - cancel_work_sync(&dcon->switch_source); - - kfree(dcon); -} - -#ifdef CONFIG_PM -static int dcon_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct dcon_priv *dcon = i2c_get_clientdata(client); - - if (!dcon->asleep) { - /* Set up the DCON to have the source */ - dcon_set_source_sync(dcon, DCON_SOURCE_DCON); - } - - return 0; -} - -static int dcon_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct dcon_priv *dcon = i2c_get_clientdata(client); - - if (!dcon->asleep) { - dcon_bus_stabilize(dcon, 0); - dcon_set_source(dcon, DCON_SOURCE_CPU); - } - - return 0; -} - -#else - -#define dcon_suspend NULL -#define dcon_resume NULL - -#endif /* CONFIG_PM */ - -irqreturn_t dcon_interrupt(int irq, void *id) -{ - struct dcon_priv *dcon = id; - u8 status; - - if (pdata->read_status(&status)) - return IRQ_NONE; - - switch (status & 3) { - case 3: - pr_debug("DCONLOAD_MISSED interrupt\n"); - break; - - case 2: /* switch to DCON mode */ - case 1: /* switch to CPU mode */ - dcon->switched = true; - dcon->irq_time = ktime_get(); - wake_up(&dcon->waitq); - break; - - case 0: - /* workaround resume case: the DCON (on 1.5) doesn't - * ever assert status 0x01 when switching to CPU mode - * during resume. this is because DCONLOAD is de-asserted - * _immediately_ upon exiting S3, so the actual release - * of the DCON happened long before this point. - * see http://dev.laptop.org/ticket/9869 - */ - if (dcon->curr_src != dcon->pending_src && !dcon->switched) { - dcon->switched = true; - dcon->irq_time = ktime_get(); - wake_up(&dcon->waitq); - pr_debug("switching w/ status 0/0\n"); - } else { - pr_debug("scanline interrupt w/CPU\n"); - } - } - - return IRQ_HANDLED; -} - -static const struct dev_pm_ops dcon_pm_ops = { - .suspend = dcon_suspend, - .resume = dcon_resume, -}; - -static const struct i2c_device_id dcon_idtable[] = { - { "olpc_dcon", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, dcon_idtable); - -static struct i2c_driver dcon_driver = { - .driver = { - .name = "olpc_dcon", - .pm = &dcon_pm_ops, - }, - .class = I2C_CLASS_HWMON, - .id_table = dcon_idtable, - .probe = dcon_probe, - .remove = dcon_remove, - .detect = dcon_detect, - .address_list = normal_i2c, -}; - -static int __init olpc_dcon_init(void) -{ - /* XO-1.5 */ - if (olpc_board_at_least(olpc_board(0xd0))) - pdata = &dcon_pdata_xo_1_5; - else - pdata = &dcon_pdata_xo_1; - - return i2c_add_driver(&dcon_driver); -} - -static void __exit olpc_dcon_exit(void) -{ - i2c_del_driver(&dcon_driver); -} - -module_init(olpc_dcon_init); -module_exit(olpc_dcon_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h deleted file mode 100644 index 41bd1360b56e479837256851e976001c2ab7dc2a..0000000000000000000000000000000000000000 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ /dev/null @@ -1,112 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef OLPC_DCON_H_ -#define OLPC_DCON_H_ - -#include -#include - -/* DCON registers */ - -#define DCON_REG_ID 0 -#define DCON_REG_MODE 1 - -#define MODE_PASSTHRU BIT(0) -#define MODE_SLEEP BIT(1) -#define MODE_SLEEP_AUTO BIT(2) -#define MODE_BL_ENABLE BIT(3) -#define MODE_BLANK BIT(4) -#define MODE_CSWIZZLE BIT(5) -#define MODE_COL_AA BIT(6) -#define MODE_MONO_LUMA BIT(7) -#define MODE_SCAN_INT BIT(8) -#define MODE_CLOCKDIV BIT(9) -#define MODE_DEBUG BIT(14) -#define MODE_SELFTEST BIT(15) - -#define DCON_REG_HRES 0x2 -#define DCON_REG_HTOTAL 0x3 -#define DCON_REG_HSYNC_WIDTH 0x4 -#define DCON_REG_VRES 0x5 -#define DCON_REG_VTOTAL 0x6 -#define DCON_REG_VSYNC_WIDTH 0x7 -#define DCON_REG_TIMEOUT 0x8 -#define DCON_REG_SCAN_INT 0x9 -#define DCON_REG_BRIGHT 0xa -#define DCON_REG_MEM_OPT_A 0x41 -#define DCON_REG_MEM_OPT_B 0x42 - -/* Load Delay Locked Loop (DLL) settings for clock delay */ -#define MEM_DLL_CLOCK_DELAY BIT(0) -/* Memory controller power down function */ -#define MEM_POWER_DOWN BIT(8) -/* Memory controller software reset */ -#define MEM_SOFT_RESET BIT(0) - -/* Status values */ - -#define DCONSTAT_SCANINT 0 -#define DCONSTAT_SCANINT_DCON 1 -#define DCONSTAT_DISPLAYLOAD 2 -#define DCONSTAT_MISSED 3 - -/* Source values */ - -#define DCON_SOURCE_DCON 0 -#define DCON_SOURCE_CPU 1 - -/* Interrupt */ -#define DCON_IRQ 6 - -struct dcon_priv { - struct i2c_client *client; - struct fb_info *fbinfo; - struct backlight_device *bl_dev; - - wait_queue_head_t waitq; - struct work_struct switch_source; - struct notifier_block reboot_nb; - - /* Shadow register for the DCON_REG_MODE register */ - u8 disp_mode; - - /* The current backlight value - this saves us some smbus traffic */ - u8 bl_val; - - /* Current source, initialized at probe time */ - int curr_src; - - /* Desired source */ - int pending_src; - - /* Variables used during switches */ - bool switched; - ktime_t irq_time; - ktime_t load_time; - - /* Current output type; true == mono, false == color */ - bool mono; - bool asleep; - /* This get set while controlling fb blank state from the driver */ - bool ignore_fb_events; -}; - -struct dcon_platform_data { - int (*init)(struct dcon_priv *dcon); - void (*bus_stabilize_wiggle)(void); - void (*set_dconload)(int load); - int (*read_status)(u8 *status); -}; - -struct dcon_gpio { - const char *name; - unsigned long flags; -}; - -#include - -irqreturn_t dcon_interrupt(int irq, void *id); - -extern struct dcon_platform_data dcon_pdata_xo_1; -extern struct dcon_platform_data dcon_pdata_xo_1_5; - -#endif diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c deleted file mode 100644 index 02c059897784d18fba755a61ec8e79b2438e544b..0000000000000000000000000000000000000000 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Mainly by David Woodhouse, somewhat modified by Jordan Crouse - * - * Copyright © 2006-2007 Red Hat, Inc. - * Copyright © 2006-2007 Advanced Micro Devices, Inc. - * Copyright © 2009 VIA Technology, Inc. - * Copyright (c) 2010 Andres Salomon - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include - -#include "olpc_dcon.h" - -enum dcon_gpios { - OLPC_DCON_STAT0, - OLPC_DCON_STAT1, - OLPC_DCON_IRQ, - OLPC_DCON_LOAD, - OLPC_DCON_BLANK, -}; - -static const struct dcon_gpio gpios_asis[] = { - [OLPC_DCON_STAT0] = { .name = "dcon_stat0", .flags = GPIOD_ASIS }, - [OLPC_DCON_STAT1] = { .name = "dcon_stat1", .flags = GPIOD_ASIS }, - [OLPC_DCON_IRQ] = { .name = "dcon_irq", .flags = GPIOD_ASIS }, - [OLPC_DCON_LOAD] = { .name = "dcon_load", .flags = GPIOD_ASIS }, - [OLPC_DCON_BLANK] = { .name = "dcon_blank", .flags = GPIOD_ASIS }, -}; - -static struct gpio_desc *gpios[5]; - -static int dcon_init_xo_1(struct dcon_priv *dcon) -{ - unsigned char lob; - int ret, i; - const struct dcon_gpio *pin = &gpios_asis[0]; - - for (i = 0; i < ARRAY_SIZE(gpios_asis); i++) { - gpios[i] = devm_gpiod_get(&dcon->client->dev, pin[i].name, - pin[i].flags); - if (IS_ERR(gpios[i])) { - ret = PTR_ERR(gpios[i]); - pr_err("failed to request %s GPIO: %d\n", pin[i].name, - ret); - return ret; - } - } - - /* Turn off the event enable for GPIO7 just to be safe */ - cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE); - - /* - * Determine the current state by reading the GPIO bit; earlier - * stages of the boot process have established the state. - * - * Note that we read GPIO_OUTPUT_VAL rather than GPIO_READ_BACK here; - * this is because OFW will disable input for the pin and set a value.. - * READ_BACK will only contain a valid value if input is enabled and - * then a value is set. So, future readings of the pin can use - * READ_BACK, but the first one cannot. Awesome, huh? - */ - dcon->curr_src = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL) - ? DCON_SOURCE_CPU - : DCON_SOURCE_DCON; - dcon->pending_src = dcon->curr_src; - - /* Set the directions for the GPIO pins */ - gpiod_direction_input(gpios[OLPC_DCON_STAT0]); - gpiod_direction_input(gpios[OLPC_DCON_STAT1]); - gpiod_direction_input(gpios[OLPC_DCON_IRQ]); - gpiod_direction_input(gpios[OLPC_DCON_BLANK]); - gpiod_direction_output(gpios[OLPC_DCON_LOAD], - dcon->curr_src == DCON_SOURCE_CPU); - - /* Set up the interrupt mappings */ - - /* Set the IRQ to pair 2 */ - cs5535_gpio_setup_event(OLPC_GPIO_DCON_IRQ, 2, 0); - - /* Enable group 2 to trigger the DCON interrupt */ - cs5535_gpio_set_irq(2, DCON_IRQ); - - /* Select edge level for interrupt (in PIC) */ - lob = inb(0x4d0); - lob &= ~(1 << DCON_IRQ); - outb(lob, 0x4d0); - - /* Register the interrupt handler */ - if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) { - pr_err("failed to request DCON's irq\n"); - return -EIO; - } - - /* Clear INV_EN for GPIO7 (DCONIRQ) */ - cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_INVERT); - - /* Enable filter for GPIO12 (DCONBLANK) */ - cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_FILTER); - - /* Disable filter for GPIO7 */ - cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_FILTER); - - /* Disable event counter for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ - cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_EVENT_COUNT); - cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_EVENT_COUNT); - - /* Add GPIO12 to the Filter Event Pair #7 */ - cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_FE7_SEL); - - /* Turn off negative Edge Enable for GPIO12 */ - cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_EN); - - /* Enable negative Edge Enable for GPIO7 */ - cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_EN); - - /* Zero the filter amount for Filter Event Pair #7 */ - cs5535_gpio_set(0, GPIO_FLTR7_AMOUNT); - - /* Clear the negative edge status for GPIO7 and GPIO12 */ - cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS); - cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_STS); - - /* FIXME: Clear the positive status as well, just to be sure */ - cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_POSITIVE_EDGE_STS); - cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_POSITIVE_EDGE_STS); - - /* Enable events for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */ - cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE); - cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_EVENTS_ENABLE); - - return 0; -} - -static void dcon_wiggle_xo_1(void) -{ - int x; - - /* - * According to HiMax, when powering the DCON up we should hold - * SMB_DATA high for 8 SMB_CLK cycles. This will force the DCON - * state machine to reset to a (sane) initial state. Mitch Bradley - * did some testing and discovered that holding for 16 SMB_CLK cycles - * worked a lot more reliably, so that's what we do here. - * - * According to the cs5536 spec, to set GPIO14 to SMB_CLK we must - * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and - * GPIO15. - */ - cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); - cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_VAL); - cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_ENABLE); - cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_ENABLE); - cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1); - cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); - cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX2); - cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX2); - cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1); - cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); - - for (x = 0; x < 16; x++) { - udelay(5); - cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); - udelay(5); - cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL); - } - udelay(5); - cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1); - cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1); - cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1); - cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1); -} - -static void dcon_set_dconload_1(int val) -{ - gpiod_set_value(gpios[OLPC_DCON_LOAD], val); -} - -static int dcon_read_status_xo_1(u8 *status) -{ - *status = gpiod_get_value(gpios[OLPC_DCON_STAT0]); - *status |= gpiod_get_value(gpios[OLPC_DCON_STAT1]) << 1; - - /* Clear the negative edge status for GPIO7 */ - cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS); - - return 0; -} - -struct dcon_platform_data dcon_pdata_xo_1 = { - .init = dcon_init_xo_1, - .bus_stabilize_wiggle = dcon_wiggle_xo_1, - .set_dconload = dcon_set_dconload_1, - .read_status = dcon_read_status_xo_1, -}; diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c deleted file mode 100644 index 52cdcd2a89d6f39bbc344eda483c5ecb8316476d..0000000000000000000000000000000000000000 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ /dev/null @@ -1,204 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2009,2010 One Laptop per Child - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include - -/* TODO: this eventually belongs in linux/vx855.h */ -#define NR_VX855_GPI 14 -#define NR_VX855_GPO 13 -#define NR_VX855_GPIO 15 - -#define VX855_GPI(n) (n) -#define VX855_GPO(n) (NR_VX855_GPI + (n)) -#define VX855_GPIO(n) (NR_VX855_GPI + NR_VX855_GPO + (n)) - -#include "olpc_dcon.h" - -/* Hardware setup on the XO 1.5: - * DCONLOAD connects to VX855_GPIO1 (not SMBCK2) - * DCONBLANK connects to VX855_GPIO8 (not SSPICLK) unused in driver - * DCONSTAT0 connects to VX855_GPI10 (not SSPISDI) - * DCONSTAT1 connects to VX855_GPI11 (not nSSPISS) - * DCONIRQ connects to VX855_GPIO12 - * DCONSMBDATA connects to VX855 graphics CRTSPD - * DCONSMBCLK connects to VX855 graphics CRTSPCLK - */ - -#define VX855_GENL_PURPOSE_OUTPUT 0x44c /* PMIO_Rx4c-4f */ -#define VX855_GPI_STATUS_CHG 0x450 /* PMIO_Rx50 */ -#define VX855_GPI_SCI_SMI 0x452 /* PMIO_Rx52 */ -#define BIT_GPIO12 0x40 - -#define PREFIX "OLPC DCON:" - -enum dcon_gpios { - OLPC_DCON_STAT0, - OLPC_DCON_STAT1, - OLPC_DCON_LOAD, -}; - -struct gpiod_lookup_table gpios_table = { - .dev_id = NULL, - .table = { - GPIO_LOOKUP("VX855 South Bridge", VX855_GPIO(1), "dcon_load", - GPIO_ACTIVE_LOW), - GPIO_LOOKUP("VX855 South Bridge", VX855_GPI(10), "dcon_stat0", - GPIO_ACTIVE_LOW), - GPIO_LOOKUP("VX855 South Bridge", VX855_GPI(11), "dcon_stat1", - GPIO_ACTIVE_LOW), - { }, - }, -}; - -static const struct dcon_gpio gpios_asis[] = { - [OLPC_DCON_STAT0] = { .name = "dcon_stat0", .flags = GPIOD_ASIS }, - [OLPC_DCON_STAT1] = { .name = "dcon_stat1", .flags = GPIOD_ASIS }, - [OLPC_DCON_LOAD] = { .name = "dcon_load", .flags = GPIOD_ASIS }, -}; - -static struct gpio_desc *gpios[3]; - -static void dcon_clear_irq(void) -{ - /* irq status will appear in PMIO_Rx50[6] (RW1C) on gpio12 */ - outb(BIT_GPIO12, VX855_GPI_STATUS_CHG); -} - -static int dcon_was_irq(void) -{ - u8 tmp; - - /* irq status will appear in PMIO_Rx50[6] on gpio12 */ - tmp = inb(VX855_GPI_STATUS_CHG); - - return !!(tmp & BIT_GPIO12); -} - -static int dcon_init_xo_1_5(struct dcon_priv *dcon) -{ - unsigned int irq; - const struct dcon_gpio *pin = &gpios_asis[0]; - int i; - int ret; - - /* Add GPIO look up table */ - gpios_table.dev_id = dev_name(&dcon->client->dev); - gpiod_add_lookup_table(&gpios_table); - - /* Get GPIO descriptor */ - for (i = 0; i < ARRAY_SIZE(gpios_asis); i++) { - gpios[i] = devm_gpiod_get(&dcon->client->dev, pin[i].name, - pin[i].flags); - if (IS_ERR(gpios[i])) { - ret = PTR_ERR(gpios[i]); - pr_err("failed to request %s GPIO: %d\n", pin[i].name, - ret); - return ret; - } - } - - dcon_clear_irq(); - - /* set PMIO_Rx52[6] to enable SCI/SMI on gpio12 */ - outb(inb(VX855_GPI_SCI_SMI) | BIT_GPIO12, VX855_GPI_SCI_SMI); - - /* Determine the current state of DCONLOAD, likely set by firmware */ - /* GPIO1 */ - dcon->curr_src = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ? - DCON_SOURCE_CPU : DCON_SOURCE_DCON; - dcon->pending_src = dcon->curr_src; - - /* we're sharing the IRQ with ACPI */ - irq = acpi_gbl_FADT.sci_interrupt; - if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", dcon)) { - pr_err("DCON (IRQ%d) allocation failed\n", irq); - return 1; - } - - return 0; -} - -static void set_i2c_line(int sda, int scl) -{ - unsigned char tmp; - unsigned int port = 0x26; - - /* FIXME: This directly accesses the CRT GPIO controller !!! */ - outb(port, 0x3c4); - tmp = inb(0x3c5); - - if (scl) - tmp |= 0x20; - else - tmp &= ~0x20; - - if (sda) - tmp |= 0x10; - else - tmp &= ~0x10; - - tmp |= 0x01; - - outb(port, 0x3c4); - outb(tmp, 0x3c5); -} - -static void dcon_wiggle_xo_1_5(void) -{ - int x; - - /* - * According to HiMax, when powering the DCON up we should hold - * SMB_DATA high for 8 SMB_CLK cycles. This will force the DCON - * state machine to reset to a (sane) initial state. Mitch Bradley - * did some testing and discovered that holding for 16 SMB_CLK cycles - * worked a lot more reliably, so that's what we do here. - */ - set_i2c_line(1, 1); - - for (x = 0; x < 16; x++) { - udelay(5); - set_i2c_line(1, 0); - udelay(5); - set_i2c_line(1, 1); - } - udelay(5); - - /* set PMIO_Rx52[6] to enable SCI/SMI on gpio12 */ - outb(inb(VX855_GPI_SCI_SMI) | BIT_GPIO12, VX855_GPI_SCI_SMI); -} - -static void dcon_set_dconload_xo_1_5(int val) -{ - gpiod_set_value(gpios[OLPC_DCON_LOAD], val); -} - -static int dcon_read_status_xo_1_5(u8 *status) -{ - if (!dcon_was_irq()) - return -1; - - /* i believe this is the same as "inb(0x44b) & 3" */ - *status = gpiod_get_value(gpios[OLPC_DCON_STAT0]); - *status |= gpiod_get_value(gpios[OLPC_DCON_STAT1]) << 1; - - dcon_clear_irq(); - - return 0; -} - -struct dcon_platform_data dcon_pdata_xo_1_5 = { - .init = dcon_init_xo_1_5, - .bus_stabilize_wiggle = dcon_wiggle_xo_1_5, - .set_dconload = dcon_set_dconload_xo_1_5, - .read_status = dcon_read_status_xo_1_5, -}; diff --git a/drivers/staging/rtl8712/Kconfig b/drivers/staging/rtl8712/Kconfig deleted file mode 100644 index 8de26425225b380ed62cb224676a0b00445a8439..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config R8712U - tristate "RealTek RTL8712U (RTL8192SU) Wireless LAN NIC driver" - depends on WLAN && USB && CFG80211 - select WIRELESS_EXT - select WEXT_PRIV - select FW_LOADER - help - This option adds the Realtek RTL8712 USB device such as the - D-Link DWA-130. - - If built as a module, it will be called r8712u. - -config R8712_TX_AGGR - bool "Realtek RTL8712U Transmit Aggregation code" - depends on R8712U && BROKEN - help - This option provides transmit aggregation for the Realtek - RTL8712 USB device. - - diff --git a/drivers/staging/rtl8712/Makefile b/drivers/staging/rtl8712/Makefile deleted file mode 100644 index 3ae216b6621b1c95d8aed2e51ebda955fcbead7f..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -r8712u-y := \ - rtl871x_cmd.o \ - rtl8712_cmd.o \ - rtl871x_security.o \ - rtl871x_eeprom.o \ - rtl8712_efuse.o \ - hal_init.o \ - usb_halinit.o \ - usb_ops.o \ - usb_ops_linux.o \ - rtl871x_io.o \ - rtl8712_io.o \ - rtl871x_ioctl_linux.o \ - rtl871x_ioctl_rtl.o \ - rtl871x_ioctl_set.o \ - rtl8712_led.o \ - rtl871x_mlme.o \ - ieee80211.o \ - rtl871x_mp_ioctl.o \ - rtl871x_mp.o \ - mlme_linux.o \ - recv_linux.o \ - xmit_linux.o \ - usb_intf.o \ - os_intfs.o \ - rtl871x_pwrctrl.o \ - rtl8712_recv.o \ - rtl871x_recv.o \ - rtl871x_sta_mgt.o \ - rtl871x_xmit.o \ - rtl8712_xmit.o - -obj-$(CONFIG_R8712U) := r8712u.o - diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO deleted file mode 100644 index 5aed36efa7cbf4be1ce7c8ff592b6c0eca74c4ac..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/TODO +++ /dev/null @@ -1,12 +0,0 @@ -TODO: -- merge Realtek's bugfixes and new features into the driver -- switch to use MAC80211 -- checkpatch.pl fixes - only a few remain - -A replacement for this driver with MAC80211 support is available -at https://github.com/chunkeey/rtl8192su - -Please send any patches to Greg Kroah-Hartman , -Larry Finger , -Florian Schilhabel and -Linux Driver Project Developer List . diff --git a/drivers/staging/rtl8712/basic_types.h b/drivers/staging/rtl8712/basic_types.h deleted file mode 100644 index aecded87dd4c8733742c433f4111b009f9f82c27..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/basic_types.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __BASIC_TYPES_H__ -#define __BASIC_TYPES_H__ - -#include - -#define sint signed int - -/* Should we extend this to be host_addr_t and target_addr_t for case: - * host : x86_64 - * target : mips64 - */ -#define addr_t unsigned long - -#endif /*__BASIC_TYPES_H__*/ - diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h deleted file mode 100644 index 76ac798642bd2b01e36a170061d7f7a7914d6ddb..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/drv_types.h +++ /dev/null @@ -1,175 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -/* --------------------------------------------------------------------- - * - * For type defines and data structure defines - * - * --------------------------------------------------------------------- - */ -#ifndef __DRV_TYPES_H__ -#define __DRV_TYPES_H__ - -struct _adapter; - -#include "osdep_service.h" -#include "wlan_bssdef.h" -#include "rtl8712_spec.h" -#include "rtl8712_hal.h" -#include -#include - -enum _NIC_VERSION { - RTL8711_NIC, - RTL8712_NIC, - RTL8713_NIC, - RTL8716_NIC -}; - -struct qos_priv { - /* bit mask option: u-apsd, s-apsd, ts, block ack... */ - unsigned int qos_option; -}; - -#include "rtl871x_ht.h" -#include "rtl871x_cmd.h" -#include "rtl871x_xmit.h" -#include "rtl871x_recv.h" -#include "rtl871x_security.h" -#include "rtl871x_pwrctrl.h" -#include "rtl871x_io.h" -#include "rtl871x_eeprom.h" -#include "sta_info.h" -#include "rtl871x_mlme.h" -#include "rtl871x_mp.h" -#include "rtl871x_debug.h" -#include "rtl871x_rf.h" -#include "rtl871x_event.h" -#include "rtl871x_led.h" - -#define SPEC_DEV_ID_DISABLE_HT BIT(1) - -struct specific_device_id { - u32 flags; - u16 idVendor; - u16 idProduct; - -}; - -struct registry_priv { - u8 chip_version; - u8 rfintfs; - u8 lbkmode; - u8 hci; - u8 network_mode; /*infra, ad-hoc, auto*/ - struct ndis_802_11_ssid ssid; - u8 channel;/* ad-hoc support requirement */ - u8 wireless_mode;/* A, B, G, auto */ - u8 vrtl_carrier_sense; /*Enable, Disable, Auto*/ - u8 vcs_type;/*RTS/CTS, CTS-to-self*/ - u16 rts_thresh; - u16 frag_thresh; - u8 preamble;/*long, short, auto*/ - u8 scan_mode;/*active, passive*/ - u8 adhoc_tx_pwr; - u8 soft_ap; - u8 smart_ps; - u8 power_mgnt; - u8 radio_enable; - u8 long_retry_lmt; - u8 short_retry_lmt; - u16 busy_thresh; - u8 ack_policy; - u8 mp_mode; - u8 software_encrypt; - u8 software_decrypt; - /* UAPSD */ - u8 wmm_enable; - u8 uapsd_enable; - u8 uapsd_max_sp; - u8 uapsd_acbk_en; - u8 uapsd_acbe_en; - u8 uapsd_acvi_en; - u8 uapsd_acvo_en; - - struct wlan_bssid_ex dev_network; - - u8 ht_enable; - u8 cbw40_enable; - u8 ampdu_enable;/*for tx*/ - u8 rf_config; - u8 low_power; - u8 wifi_test; -}; - -struct dvobj_priv { - struct _adapter *padapter; - u32 nr_endpoint; - u8 ishighspeed; - uint (*inirp_init)(struct _adapter *adapter); - uint (*inirp_deinit)(struct _adapter *adapter); - struct usb_device *pusbdev; -}; - -/** - * struct _adapter - the main adapter structure for this device. - * - * bup: True indicates that the interface is up. - */ -struct _adapter { - struct dvobj_priv dvobjpriv; - struct mlme_priv mlmepriv; - struct cmd_priv cmdpriv; - struct evt_priv evtpriv; - struct io_queue *pio_queue; - struct xmit_priv xmitpriv; - struct recv_priv recvpriv; - struct sta_priv stapriv; - struct security_priv securitypriv; - struct registry_priv registrypriv; - struct wlan_acl_pool acl_list; - struct pwrctrl_priv pwrctrlpriv; - struct eeprom_priv eeprompriv; - struct hal_priv halpriv; - struct led_priv ledpriv; - struct mp_priv mppriv; - bool driver_stopped; - bool surprise_removed; - bool suspended; - u8 eeprom_address_size; - u8 hw_init_completed; - struct task_struct *cmd_thread; - uint (*dvobj_init)(struct _adapter *adapter); - void (*dvobj_deinit)(struct _adapter *adapter); - struct net_device *pnetdev; - int bup; - struct net_device_stats stats; - struct iw_statistics iwstats; - int pid; /*process id from UI*/ - struct work_struct wk_filter_rx_ff0; - const struct firmware *fw; - struct usb_interface *pusb_intf; - struct mutex mutex_start; - struct completion rtl8712_fw_ready; - struct completion rx_filter_ready; -}; - -static inline u8 *myid(struct eeprom_priv *peepriv) -{ - return peepriv->mac_addr; -} - -u8 r8712_usb_hal_bus_init(struct _adapter *adapter); - -#endif /*__DRV_TYPES_H__*/ - diff --git a/drivers/staging/rtl8712/ethernet.h b/drivers/staging/rtl8712/ethernet.h deleted file mode 100644 index 4b9b8a97a0bc6c950a465591caa4e00c68fe6069..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/ethernet.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __INC_ETHERNET_H -#define __INC_ETHERNET_H - -#define ETHERNET_HEADER_SIZE 14 /*!< Ethernet Header Length*/ -#define LLC_HEADER_SIZE 6 /*!< LLC Header Length*/ - -#endif /* #ifndef __INC_ETHERNET_H */ - diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c deleted file mode 100644 index 1148075f0cd64c5045c6df8bf5a228031f8bfe98..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/hal_init.c +++ /dev/null @@ -1,401 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _HAL_INIT_C_ - -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "usb_osintf.h" - -#define FWBUFF_ALIGN_SZ 512 -#define MAX_DUMP_FWSZ (48 * 1024) - -static void rtl871x_load_fw_fail(struct _adapter *adapter) -{ - struct usb_device *udev = adapter->dvobjpriv.pusbdev; - struct device *dev = &udev->dev; - struct device *parent = dev->parent; - - complete(&adapter->rtl8712_fw_ready); - - dev_err(&udev->dev, "r8712u: Firmware request failed\n"); - - if (parent) - device_lock(parent); - - device_release_driver(dev); - - if (parent) - device_unlock(parent); -} - -static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context) -{ - struct _adapter *adapter = context; - - if (!firmware) { - rtl871x_load_fw_fail(adapter); - return; - } - adapter->fw = firmware; - /* firmware available - start netdev */ - register_netdev(adapter->pnetdev); - complete(&adapter->rtl8712_fw_ready); -} - -static const char firmware_file[] = "rtlwifi/rtl8712u.bin"; - -int rtl871x_load_fw(struct _adapter *padapter) -{ - struct device *dev = &padapter->dvobjpriv.pusbdev->dev; - int rc; - - init_completion(&padapter->rtl8712_fw_ready); - dev_info(dev, "r8712u: Loading firmware from \"%s\"\n", firmware_file); - rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev, - GFP_KERNEL, padapter, rtl871x_load_fw_cb); - if (rc) - dev_err(dev, "r8712u: Firmware request error %d\n", rc); - return rc; -} -MODULE_FIRMWARE("rtlwifi/rtl8712u.bin"); - -static u32 rtl871x_open_fw(struct _adapter *adapter, const u8 **mappedfw) -{ - if (adapter->fw->size > 200000) { - dev_err(&adapter->pnetdev->dev, "r8712u: Bad fw->size of %zu\n", - adapter->fw->size); - return 0; - } - *mappedfw = adapter->fw->data; - return adapter->fw->size; -} - -static void fill_fwpriv(struct _adapter *adapter, struct fw_priv *fwpriv) -{ - struct dvobj_priv *dvobj = &adapter->dvobjpriv; - struct registry_priv *regpriv = &adapter->registrypriv; - - memset(fwpriv, 0, sizeof(struct fw_priv)); - /* todo: check if needs endian conversion */ - fwpriv->hci_sel = RTL8712_HCI_TYPE_72USB; - fwpriv->usb_ep_num = (u8)dvobj->nr_endpoint; - fwpriv->bw_40MHz_en = regpriv->cbw40_enable; - switch (regpriv->rf_config) { - case RTL8712_RF_1T1R: - fwpriv->rf_config = RTL8712_RFC_1T1R; - break; - case RTL8712_RF_2T2R: - fwpriv->rf_config = RTL8712_RFC_2T2R; - break; - case RTL8712_RF_1T2R: - default: - fwpriv->rf_config = RTL8712_RFC_1T2R; - } - fwpriv->mp_mode = (regpriv->mp_mode == 1); - /* 0:off 1:on 2:auto */ - fwpriv->vcs_type = regpriv->vrtl_carrier_sense; - fwpriv->vcs_mode = regpriv->vcs_type; /* 1:RTS/CTS 2:CTS to self */ - /* default enable turbo_mode */ - fwpriv->turbo_mode = (regpriv->wifi_test != 1); - fwpriv->low_power_mode = regpriv->low_power; -} - -static void update_fwhdr(struct fw_hdr *pfwhdr, const u8 *pmappedfw) -{ - pfwhdr->signature = le16_to_cpu(*(__le16 *)pmappedfw); - pfwhdr->version = le16_to_cpu(*(__le16 *)(pmappedfw + 2)); - /* define the size of boot loader */ - pfwhdr->dmem_size = le32_to_cpu(*(__le32 *)(pmappedfw + 4)); - /* define the size of FW in IMEM */ - pfwhdr->img_IMEM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 8)); - /* define the size of FW in SRAM */ - pfwhdr->img_SRAM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 12)); - /* define the size of DMEM variable */ - pfwhdr->fw_priv_sz = le32_to_cpu(*(__le32 *)(pmappedfw + 16)); -} - -static u8 chk_fwhdr(struct fw_hdr *pfwhdr, u32 ulfilelength) -{ - u32 fwhdrsz, fw_sz; - - /* check signature */ - if ((pfwhdr->signature != 0x8712) && (pfwhdr->signature != 0x8192)) - return _FAIL; - /* check fw_priv_sze & sizeof(struct fw_priv) */ - if (pfwhdr->fw_priv_sz != sizeof(struct fw_priv)) - return _FAIL; - /* check fw_sz & image_fw_sz */ - fwhdrsz = offsetof(struct fw_hdr, fwpriv) + pfwhdr->fw_priv_sz; - fw_sz = fwhdrsz + pfwhdr->img_IMEM_size + pfwhdr->img_SRAM_size + - pfwhdr->dmem_size; - if (fw_sz != ulfilelength) - return _FAIL; - return _SUCCESS; -} - -static u8 rtl8712_dl_fw(struct _adapter *adapter) -{ - sint i; - u8 tmp8, tmp8_a; - u16 tmp16; - u32 maxlen = 0; /* for compare usage */ - uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */ - struct fw_hdr fwhdr; - u32 ulfilelength; /* FW file size */ - const u8 *mappedfw = NULL; - u8 *tmpchar = NULL, *payload, *ptr; - struct tx_desc *txdesc; - u32 txdscp_sz = sizeof(struct tx_desc); - u8 ret = _FAIL; - - ulfilelength = rtl871x_open_fw(adapter, &mappedfw); - if (mappedfw && (ulfilelength > 0)) { - update_fwhdr(&fwhdr, mappedfw); - if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL) - return ret; - fill_fwpriv(adapter, &fwhdr.fwpriv); - /* firmware check ok */ - maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ? - fwhdr.img_IMEM_size : fwhdr.img_SRAM_size; - maxlen += txdscp_sz; - tmpchar = kmalloc(maxlen + FWBUFF_ALIGN_SZ, GFP_KERNEL); - if (!tmpchar) - return ret; - - txdesc = (struct tx_desc *)(tmpchar + FWBUFF_ALIGN_SZ - - ((addr_t)(tmpchar) & (FWBUFF_ALIGN_SZ - 1))); - payload = (u8 *)(txdesc) + txdscp_sz; - ptr = (u8 *)mappedfw + offsetof(struct fw_hdr, fwpriv) + - fwhdr.fw_priv_sz; - /* Download FirmWare */ - /* 1. determine IMEM code size and Load IMEM Code Section */ - imem_sz = fwhdr.img_IMEM_size; - do { - memset(txdesc, 0, TXDESC_SIZE); - if (imem_sz > MAX_DUMP_FWSZ/*49152*/) { - dump_imem_sz = MAX_DUMP_FWSZ; - } else { - dump_imem_sz = imem_sz; - txdesc->txdw0 |= cpu_to_le32(BIT(28)); - } - txdesc->txdw0 |= cpu_to_le32(dump_imem_sz & - 0x0000ffff); - memcpy(payload, ptr, dump_imem_sz); - r8712_write_mem(adapter, RTL8712_DMA_VOQ, - dump_imem_sz + TXDESC_SIZE, - (u8 *)txdesc); - ptr += dump_imem_sz; - imem_sz -= dump_imem_sz; - } while (imem_sz > 0); - i = 10; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _IMEM_CODE_DONE) == 0) && (i > 0)) { - usleep_range(10, 1000); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0 || (tmp16 & _IMEM_CHK_RPT) == 0) - goto exit_fail; - - /* 2.Download EMEM code size and Load EMEM Code Section */ - emem_sz = fwhdr.img_SRAM_size; - do { - memset(txdesc, 0, TXDESC_SIZE); - if (emem_sz > MAX_DUMP_FWSZ) { /* max=48k */ - dump_emem_sz = MAX_DUMP_FWSZ; - } else { - dump_emem_sz = emem_sz; - txdesc->txdw0 |= cpu_to_le32(BIT(28)); - } - txdesc->txdw0 |= cpu_to_le32(dump_emem_sz & - 0x0000ffff); - memcpy(payload, ptr, dump_emem_sz); - r8712_write_mem(adapter, RTL8712_DMA_VOQ, - dump_emem_sz + TXDESC_SIZE, - (u8 *)txdesc); - ptr += dump_emem_sz; - emem_sz -= dump_emem_sz; - } while (emem_sz > 0); - i = 5; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _EMEM_CODE_DONE) == 0) && (i > 0)) { - usleep_range(10, 1000); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0 || (tmp16 & _EMEM_CHK_RPT) == 0) - goto exit_fail; - - /* 3.Enable CPU */ - tmp8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, tmp8 | BIT(2)); - tmp8_a = r8712_read8(adapter, SYS_CLKR); - if (tmp8_a != (tmp8 | BIT(2))) - goto exit_fail; - - tmp8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, tmp8 | BIT(2)); - tmp8_a = r8712_read8(adapter, SYS_FUNC_EN + 1); - if (tmp8_a != (tmp8 | BIT(2))) - goto exit_fail; - - r8712_read32(adapter, TCR); - - /* 4.polling IMEM Ready */ - i = 100; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _IMEM_RDY) == 0) && (i > 0)) { - msleep(20); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0) { - r8712_write16(adapter, 0x10250348, 0xc000); - r8712_write16(adapter, 0x10250348, 0xc001); - r8712_write16(adapter, 0x10250348, 0x2000); - r8712_write16(adapter, 0x10250348, 0x2001); - r8712_write16(adapter, 0x10250348, 0x2002); - r8712_write16(adapter, 0x10250348, 0x2003); - goto exit_fail; - } - /* 5.Download DMEM code size and Load EMEM Code Section */ - memset(txdesc, 0, TXDESC_SIZE); - txdesc->txdw0 |= cpu_to_le32(fwhdr.fw_priv_sz & 0x0000ffff); - txdesc->txdw0 |= cpu_to_le32(BIT(28)); - memcpy(payload, &fwhdr.fwpriv, fwhdr.fw_priv_sz); - r8712_write_mem(adapter, RTL8712_DMA_VOQ, - fwhdr.fw_priv_sz + TXDESC_SIZE, (u8 *)txdesc); - - /* polling dmem code done */ - i = 100; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _DMEM_CODE_DONE) == 0) && (i > 0)) { - msleep(20); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0) - goto exit_fail; - - tmp8 = r8712_read8(adapter, 0x1025000A); - if (tmp8 & BIT(4)) /* When boot from EEPROM, - * & FW need more time to read EEPROM - */ - i = 60; - else /* boot from EFUSE */ - i = 30; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _FWRDY) == 0) && (i > 0)) { - msleep(100); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0) - goto exit_fail; - } else { - goto exit_fail; - } - ret = _SUCCESS; - -exit_fail: - kfree(tmpchar); - return ret; -} - -uint rtl8712_hal_init(struct _adapter *padapter) -{ - u32 val32; - int i; - - /* r8712 firmware download */ - if (rtl8712_dl_fw(padapter) != _SUCCESS) - return _FAIL; - - netdev_info(padapter->pnetdev, "1 RCR=0x%x\n", - r8712_read32(padapter, RCR)); - val32 = r8712_read32(padapter, RCR); - r8712_write32(padapter, RCR, (val32 | BIT(26))); /* Enable RX TCP - * Checksum offload - */ - netdev_info(padapter->pnetdev, "2 RCR=0x%x\n", - r8712_read32(padapter, RCR)); - val32 = r8712_read32(padapter, RCR); - r8712_write32(padapter, RCR, (val32 | BIT(25))); /* Append PHY status */ - val32 = r8712_read32(padapter, 0x10250040); - r8712_write32(padapter, 0x10250040, (val32 & 0x00FFFFFF)); - /* for usb rx aggregation */ - r8712_write8(padapter, 0x102500B5, r8712_read8(padapter, 0x102500B5) | - BIT(0)); /* page = 128bytes */ - r8712_write8(padapter, 0x102500BD, r8712_read8(padapter, 0x102500BD) | - BIT(7)); /* enable usb rx aggregation */ - r8712_write8(padapter, 0x102500D9, 1); /* TH=1 => means that invalidate - * usb rx aggregation - */ - r8712_write8(padapter, 0x1025FE5B, 0x04); /* 1.7ms/4 */ - /* Fix the RX FIFO issue(USB error) */ - r8712_write8(padapter, 0x1025fe5C, r8712_read8(padapter, 0x1025fe5C) - | BIT(7)); - for (i = 0; i < ETH_ALEN; i++) - padapter->eeprompriv.mac_addr[i] = r8712_read8(padapter, - MACID + i); - return _SUCCESS; -} - -uint rtl8712_hal_deinit(struct _adapter *padapter) -{ - r8712_write8(padapter, RF_CTRL, 0x00); - /* Turn off BB */ - msleep(20); - /* Turn off MAC */ - r8712_write8(padapter, SYS_CLKR + 1, 0x38); /* Switch Control Path */ - r8712_write8(padapter, SYS_FUNC_EN + 1, 0x70); - r8712_write8(padapter, PMC_FSM, 0x06); /* Enable Loader Data Keep */ - r8712_write8(padapter, SYS_ISO_CTRL, 0xF9); /* Isolation signals from - * CORE, PLL - */ - r8712_write8(padapter, SYS_ISO_CTRL + 1, 0xe8); /* Enable EFUSE 1.2V */ - r8712_write8(padapter, AFE_PLL_CTRL, 0x00); /* Disable AFE PLL. */ - r8712_write8(padapter, LDOA15_CTRL, 0x54); /* Disable A15V */ - r8712_write8(padapter, SYS_FUNC_EN + 1, 0x50); /* Disable E-Fuse 1.2V */ - r8712_write8(padapter, LDOV12D_CTRL, 0x24); /* Disable LDO12(for CE) */ - r8712_write8(padapter, AFE_MISC, 0x30); /* Disable AFE BG&MB */ - /* Option for Disable 1.6V LDO. */ - r8712_write8(padapter, SPS0_CTRL, 0x56); /* Disable 1.6V LDO */ - r8712_write8(padapter, SPS0_CTRL + 1, 0x43); /* Set SW PFM */ - return _SUCCESS; -} - -uint rtl871x_hal_init(struct _adapter *padapter) -{ - padapter->hw_init_completed = false; - if (!padapter->halpriv.hal_bus_init) - return _FAIL; - if (padapter->halpriv.hal_bus_init(padapter) != _SUCCESS) - return _FAIL; - if (rtl8712_hal_init(padapter) == _SUCCESS) { - padapter->hw_init_completed = true; - } else { - padapter->hw_init_completed = false; - return _FAIL; - } - return _SUCCESS; -} diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c deleted file mode 100644 index 7d8f1a29d18a909de4117f09cdbd0084f49dc997..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/ieee80211.c +++ /dev/null @@ -1,415 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * ieee80211.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _IEEE80211_C - -#include "drv_types.h" -#include "ieee80211.h" -#include "wifi.h" -#include "osdep_service.h" -#include "wlan_bssdef.h" - -static const u8 WPA_OUI_TYPE[] = {0x00, 0x50, 0xf2, 1}; -static const u8 WPA_CIPHER_SUITE_NONE[] = {0x00, 0x50, 0xf2, 0}; -static const u8 WPA_CIPHER_SUITE_WEP40[] = {0x00, 0x50, 0xf2, 1}; -static const u8 WPA_CIPHER_SUITE_TKIP[] = {0x00, 0x50, 0xf2, 2}; -static const u8 WPA_CIPHER_SUITE_CCMP[] = {0x00, 0x50, 0xf2, 4}; -static const u8 WPA_CIPHER_SUITE_WEP104[] = {0x00, 0x50, 0xf2, 5}; - -static const u8 RSN_CIPHER_SUITE_NONE[] = {0x00, 0x0f, 0xac, 0}; -static const u8 RSN_CIPHER_SUITE_WEP40[] = {0x00, 0x0f, 0xac, 1}; -static const u8 RSN_CIPHER_SUITE_TKIP[] = {0x00, 0x0f, 0xac, 2}; -static const u8 RSN_CIPHER_SUITE_CCMP[] = {0x00, 0x0f, 0xac, 4}; -static const u8 RSN_CIPHER_SUITE_WEP104[] = {0x00, 0x0f, 0xac, 5}; - -/*----------------------------------------------------------- - * for adhoc-master to generate ie and provide supported-rate to fw - *----------------------------------------------------------- - */ - -static u8 WIFI_CCKRATES[] = { - (IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK), - (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK), - (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK), - (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK) -}; - -static u8 WIFI_OFDMRATES[] = { - (IEEE80211_OFDM_RATE_6MB), - (IEEE80211_OFDM_RATE_9MB), - (IEEE80211_OFDM_RATE_12MB), - (IEEE80211_OFDM_RATE_18MB), - (IEEE80211_OFDM_RATE_24MB), - (IEEE80211_OFDM_RATE_36MB), - (IEEE80211_OFDM_RATE_48MB), - (IEEE80211_OFDM_RATE_54MB) -}; - -uint r8712_is_cckrates_included(u8 *rate) -{ - u32 i = 0; - - while (rate[i] != 0) { - if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || - (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) - return true; - i++; - } - return false; -} - -uint r8712_is_cckratesonly_included(u8 *rate) -{ - u32 i = 0; - - while (rate[i] != 0) { - if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && - (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) - return false; - i++; - } - return true; -} - -/* r8712_set_ie will update frame length */ -u8 *r8712_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen) -{ - *pbuf = (u8)index; - *(pbuf + 1) = (u8)len; - if (len > 0) - memcpy((void *)(pbuf + 2), (void *)source, len); - *frlen = *frlen + (len + 2); - return pbuf + len + 2; -} - -/* --------------------------------------------------------------------------- - * index: the information element id index, limit is the limit for search - * --------------------------------------------------------------------------- - */ -u8 *r8712_get_ie(u8 *pbuf, sint index, uint *len, sint limit) -{ - sint tmp, i; - u8 *p; - - if (limit < 1) - return NULL; - p = pbuf; - i = 0; - *len = 0; - while (1) { - if (*p == index) { - *len = *(p + 1); - return p; - } - tmp = *(p + 1); - p += (tmp + 2); - i += (tmp + 2); - if (i >= limit) - break; - } - return NULL; -} - -static void set_supported_rate(u8 *rates, uint mode) -{ - memset(rates, 0, NDIS_802_11_LENGTH_RATES_EX); - switch (mode) { - case WIRELESS_11B: - memcpy(rates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); - break; - case WIRELESS_11G: - case WIRELESS_11A: - memcpy(rates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); - break; - case WIRELESS_11BG: - memcpy(rates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); - memcpy(rates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, - IEEE80211_NUM_OFDM_RATESLEN); - break; - } -} - -static uint r8712_get_rateset_len(u8 *rateset) -{ - uint i = 0; - - while (1) { - if ((rateset[i]) == 0) - break; - if (i > 12) - break; - i++; - } - return i; -} - -int r8712_generate_ie(struct registry_priv *registrypriv) -{ - int rate_len; - uint sz = 0; - struct wlan_bssid_ex *dev_network = ®istrypriv->dev_network; - u8 *ie = dev_network->IEs; - u16 beacon_period = (u16)dev_network->Configuration.BeaconPeriod; - - /*timestamp will be inserted by hardware*/ - sz += 8; - ie += sz; - /*beacon interval : 2bytes*/ - *(__le16 *)ie = cpu_to_le16(beacon_period); - sz += 2; - ie += 2; - /*capability info*/ - *(u16 *)ie = 0; - *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_IBSS); - if (registrypriv->preamble == PREAMBLE_SHORT) - *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); - if (dev_network->Privacy) - *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - sz += 2; - ie += 2; - /*SSID*/ - ie = r8712_set_ie(ie, WLAN_EID_SSID, dev_network->Ssid.SsidLength, - dev_network->Ssid.Ssid, &sz); - /*supported rates*/ - set_supported_rate(dev_network->rates, registrypriv->wireless_mode); - rate_len = r8712_get_rateset_len(dev_network->rates); - if (rate_len > 8) { - ie = r8712_set_ie(ie, WLAN_EID_SUPP_RATES, 8, - dev_network->rates, &sz); - ie = r8712_set_ie(ie, WLAN_EID_EXT_SUPP_RATES, (rate_len - 8), - (dev_network->rates + 8), &sz); - } else { - ie = r8712_set_ie(ie, WLAN_EID_SUPP_RATES, - rate_len, dev_network->rates, &sz); - } - /*DS parameter set*/ - ie = r8712_set_ie(ie, WLAN_EID_DS_PARAMS, 1, - (u8 *)&dev_network->Configuration.DSConfig, &sz); - /*IBSS Parameter Set*/ - ie = r8712_set_ie(ie, WLAN_EID_IBSS_PARAMS, 2, - (u8 *)&dev_network->Configuration.ATIMWindow, &sz); - return sz; -} - -unsigned char *r8712_get_wpa_ie(unsigned char *ie, uint *wpa_ie_len, int limit) -{ - u32 len; - u16 val16; - unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; - u8 *buf = ie; - - while (1) { - buf = r8712_get_ie(buf, _WPA_IE_ID_, &len, limit); - if (buf) { - /*check if oui matches...*/ - if (memcmp((buf + 2), wpa_oui_type, - sizeof(wpa_oui_type))) - goto check_next_ie; - /*check version...*/ - memcpy((u8 *)&val16, (buf + 6), sizeof(val16)); - le16_to_cpus(&val16); - if (val16 != 0x0001) - goto check_next_ie; - *wpa_ie_len = *(buf + 1); - return buf; - } - *wpa_ie_len = 0; - return NULL; -check_next_ie: - limit = limit - (buf - ie) - 2 - len; - if (limit <= 0) - break; - buf += (2 + len); - } - *wpa_ie_len = 0; - return NULL; -} - -unsigned char *r8712_get_wpa2_ie(unsigned char *pie, uint *rsn_ie_len, - int limit) -{ - return r8712_get_ie(pie, _WPA2_IE_ID_, rsn_ie_len, limit); -} - -static int r8712_get_wpa_cipher_suite(u8 *s) -{ - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN)) - return WPA_CIPHER_NONE; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN)) - return WPA_CIPHER_WEP40; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN)) - return WPA_CIPHER_TKIP; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN)) - return WPA_CIPHER_CCMP; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN)) - return WPA_CIPHER_WEP104; - return 0; -} - -static int r8712_get_wpa2_cipher_suite(u8 *s) -{ - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN)) - return WPA_CIPHER_NONE; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN)) - return WPA_CIPHER_WEP40; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN)) - return WPA_CIPHER_TKIP; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN)) - return WPA_CIPHER_CCMP; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN)) - return WPA_CIPHER_WEP104; - return 0; -} - -int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, - int *pairwise_cipher) -{ - int i; - int left, count; - u8 *pos; - - if (wpa_ie_len <= 0) { - /* No WPA IE - fail silently */ - return -EINVAL; - } - if ((*wpa_ie != _WPA_IE_ID_) || - (*(wpa_ie + 1) != (u8)(wpa_ie_len - 2)) || - (memcmp(wpa_ie + 2, (void *)WPA_OUI_TYPE, WPA_SELECTOR_LEN))) - return -EINVAL; - pos = wpa_ie; - pos += 8; - left = wpa_ie_len - 8; - /*group_cipher*/ - if (left >= WPA_SELECTOR_LEN) { - *group_cipher = r8712_get_wpa_cipher_suite(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } else if (left > 0) { - return -EINVAL; - } - /*pairwise_cipher*/ - if (left >= 2) { - count = le16_to_cpu(*(__le16 *)pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) - return -EINVAL; - for (i = 0; i < count; i++) { - *pairwise_cipher |= r8712_get_wpa_cipher_suite(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) { - return -EINVAL; - } - return 0; -} - -int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, - int *pairwise_cipher) -{ - int i; - int left, count; - u8 *pos; - - if (rsn_ie_len <= 0) { - /* No RSN IE - fail silently */ - return -EINVAL; - } - if ((*rsn_ie != _WPA2_IE_ID_) || - (*(rsn_ie + 1) != (u8)(rsn_ie_len - 2))) - return -EINVAL; - pos = rsn_ie; - pos += 4; - left = rsn_ie_len - 4; - /*group_cipher*/ - if (left >= RSN_SELECTOR_LEN) { - *group_cipher = r8712_get_wpa2_cipher_suite(pos); - pos += RSN_SELECTOR_LEN; - left -= RSN_SELECTOR_LEN; - } else if (left > 0) { - return -EINVAL; - } - /*pairwise_cipher*/ - if (left >= 2) { - count = le16_to_cpu(*(__le16 *)pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * RSN_SELECTOR_LEN) - return -EINVAL; - for (i = 0; i < count; i++) { - *pairwise_cipher |= r8712_get_wpa2_cipher_suite(pos); - pos += RSN_SELECTOR_LEN; - left -= RSN_SELECTOR_LEN; - } - } else if (left == 1) { - return -EINVAL; - } - return 0; -} - -int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, - u8 *wpa_ie, u16 *wpa_len) -{ - u8 authmode; - u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; - uint cnt; - - /*Search required WPA or WPA2 IE and copy to sec_ie[ ]*/ - cnt = _TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_; - while (cnt < in_len) { - authmode = in_ie[cnt]; - if ((authmode == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { - memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); - *wpa_len = in_ie[cnt + 1] + 2; - cnt += in_ie[cnt + 1] + 2; /*get next */ - } else { - if (authmode == _WPA2_IE_ID_) { - memcpy(rsn_ie, &in_ie[cnt], - in_ie[cnt + 1] + 2); - *rsn_len = in_ie[cnt + 1] + 2; - cnt += in_ie[cnt + 1] + 2; /*get next*/ - } else { - cnt += in_ie[cnt + 1] + 2; /*get next*/ - } - } - } - return *rsn_len + *wpa_len; -} - -int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) -{ - int match; - uint cnt; - u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - - cnt = 12; - match = false; - while (cnt < in_len) { - eid = in_ie[cnt]; - if ((eid == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) { - memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); - *wps_ielen = in_ie[cnt + 1] + 2; - cnt += in_ie[cnt + 1] + 2; - match = true; - break; - } - cnt += in_ie[cnt + 1] + 2; /* goto next */ - } - return match; -} diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h deleted file mode 100644 index 65ceaca9b51ea725e1947f041179c53080d06460..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/ieee80211.h +++ /dev/null @@ -1,165 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __IEEE80211_H -#define __IEEE80211_H - -#include - -#define IEEE_CMD_SET_WPA_PARAM 1 -#define IEEE_CMD_SET_WPA_IE 2 -#define IEEE_CMD_SET_ENCRYPTION 3 -#define IEEE_CMD_MLME 4 - -#define IEEE_PARAM_WPA_ENABLED 1 -#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 -#define IEEE_PARAM_DROP_UNENCRYPTED 3 -#define IEEE_PARAM_PRIVACY_INVOKED 4 -#define IEEE_PARAM_AUTH_ALGS 5 -#define IEEE_PARAM_IEEE_802_1X 6 -#define IEEE_PARAM_WPAX_SELECT 7 - -#define AUTH_ALG_OPEN_SYSTEM 0x1 -#define AUTH_ALG_SHARED_KEY 0x2 -#define AUTH_ALG_LEAP 0x00000004 - -#define IEEE_MLME_STA_DEAUTH 1 -#define IEEE_MLME_STA_DISASSOC 2 - -#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 -#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 -#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 - -#define IEEE_CRYPT_ALG_NAME_LEN 16 - -#define WPA_CIPHER_NONE BIT(0) -#define WPA_CIPHER_WEP40 BIT(1) -#define WPA_CIPHER_WEP104 BIT(2) -#define WPA_CIPHER_TKIP BIT(3) -#define WPA_CIPHER_CCMP BIT(4) - -#define WPA_SELECTOR_LEN 4 -#define RSN_HEADER_LEN 4 - -#define RSN_SELECTOR_LEN 4 - -enum NETWORK_TYPE { - WIRELESS_INVALID = 0, - WIRELESS_11B = 1, - WIRELESS_11G = 2, - WIRELESS_11BG = (WIRELESS_11B | WIRELESS_11G), - WIRELESS_11A = 4, - WIRELESS_11N = 8, - WIRELESS_11GN = (WIRELESS_11G | WIRELESS_11N), - WIRELESS_11BGN = (WIRELESS_11B | WIRELESS_11G | WIRELESS_11N), -}; - -struct ieee_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[]; - } wpa_ie; - struct { - int command; - int reason_code; - } mlme; - struct { - u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[]; - } crypt; - } u; -}; - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - -/* QoS,QOS */ -#define NORMAL_ACK 0 - -/* IEEE 802.11 defines */ - -#define P80211_OUI_LEN 3 - -struct ieee80211_snap_hdr { - u8 dsap; /* always 0xAA */ - u8 ssap; /* always 0xAA */ - u8 ctrl; /* always 0x03 */ - u8 oui[P80211_OUI_LEN]; /* organizational universal id */ -} __packed; - -#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) - -#define IEEE80211_CCK_RATE_LEN 4 -#define IEEE80211_NUM_OFDM_RATESLEN 8 - -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C -#define IEEE80211_BASIC_RATE_MASK 0x80 - -#define WEP_KEYS 4 - -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... - */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_WPA_IE_LEN 128 - -struct registry_priv; - -u8 *r8712_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen); -u8 *r8712_get_ie(u8 *pbuf, sint index, uint *len, sint limit); -unsigned char *r8712_get_wpa_ie(unsigned char *pie, uint *rsn_ie_len, - int limit); -unsigned char *r8712_get_wpa2_ie(unsigned char *pie, uint *rsn_ie_len, - int limit); -int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, - int *pairwise_cipher); -int r8712_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, - int *pairwise_cipher); -int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, - u8 *wpa_ie, u16 *wpa_len); -int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); -int r8712_generate_ie(struct registry_priv *pregistrypriv); -uint r8712_is_cckrates_included(u8 *rate); -uint r8712_is_cckratesonly_included(u8 *rate); - -#endif /* IEEE80211_H */ - diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c deleted file mode 100644 index 436816d14cdf351c07b6fb8142f53ada95696d41..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/mlme_linux.c +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * mlme_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _MLME_OSDEP_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "mlme_osdep.h" - -static void sitesurvey_ctrl_handler(struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, - mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer); - - _r8712_sitesurvey_ctrl_handler(adapter); - mod_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, - jiffies + msecs_to_jiffies(3000)); -} - -static void join_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.assoc_timer); - - _r8712_join_timeout_handler(adapter); -} - -static void _scan_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.scan_to_timer); - - r8712_scan_timeout_handler(adapter); -} - -static void dhcp_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.dhcp_timer); - - _r8712_dhcp_timeout_handler(adapter); -} - -static void wdg_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.wdg_timer); - - r8712_wdg_wk_cmd(adapter); - - mod_timer(&adapter->mlmepriv.wdg_timer, - jiffies + msecs_to_jiffies(2000)); -} - -void r8712_init_mlme_timer(struct _adapter *adapter) -{ - struct mlme_priv *mlmepriv = &adapter->mlmepriv; - - timer_setup(&mlmepriv->assoc_timer, join_timeout_handler, 0); - timer_setup(&mlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer, - sitesurvey_ctrl_handler, 0); - timer_setup(&mlmepriv->scan_to_timer, _scan_timeout_handler, 0); - timer_setup(&mlmepriv->dhcp_timer, dhcp_timeout_handler, 0); - timer_setup(&mlmepriv->wdg_timer, wdg_timeout_handler, 0); -} - -void r8712_os_indicate_connect(struct _adapter *adapter) -{ - r8712_indicate_wx_assoc_event(adapter); - netif_carrier_on(adapter->pnetdev); -} - -static struct RT_PMKID_LIST backup_PMKID_list[NUM_PMKID_CACHE]; -void r8712_os_indicate_disconnect(struct _adapter *adapter) -{ - u8 backup_PMKID_index = 0; - u8 backup_TKIP_countermeasure = 0x00; - - r8712_indicate_wx_disassoc_event(adapter); - netif_carrier_off(adapter->pnetdev); - if (adapter->securitypriv.AuthAlgrthm == 2) { /*/802.1x*/ - /* We have to backup the PMK information for WiFi PMK Caching - * test item. Backup the btkip_countermeasure information. - * When the countermeasure is trigger, the driver have to - * disconnect with AP for 60 seconds. - */ - - memcpy(&backup_PMKID_list[0], - &adapter->securitypriv.PMKIDList[0], - sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - backup_PMKID_index = adapter->securitypriv.PMKIDIndex; - backup_TKIP_countermeasure = - adapter->securitypriv.btkip_countermeasure; - memset((unsigned char *)&adapter->securitypriv, 0, - sizeof(struct security_priv)); - timer_setup(&adapter->securitypriv.tkip_timer, - r8712_use_tkipkey_handler, 0); - /* Restore the PMK information to securitypriv structure - * for the following connection. - */ - memcpy(&adapter->securitypriv.PMKIDList[0], - &backup_PMKID_list[0], - sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - adapter->securitypriv.PMKIDIndex = backup_PMKID_index; - adapter->securitypriv.btkip_countermeasure = - backup_TKIP_countermeasure; - } else { /*reset values in securitypriv*/ - struct security_priv *sec_priv = &adapter->securitypriv; - - sec_priv->AuthAlgrthm = 0; /*open system*/ - sec_priv->PrivacyAlgrthm = _NO_PRIVACY_; - sec_priv->PrivacyKeyIndex = 0; - sec_priv->XGrpPrivacy = _NO_PRIVACY_; - sec_priv->XGrpKeyid = 1; - sec_priv->ndisauthtype = Ndis802_11AuthModeOpen; - sec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; - sec_priv->wps_phase = false; - } -} - -void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie) -{ - uint len; - u8 *buff, *p, i; - union iwreq_data wrqu; - - buff = NULL; - if (authmode == _WPA_IE_ID_) { - buff = kzalloc(IW_CUSTOM_MAX, GFP_ATOMIC); - if (!buff) - return; - p = buff; - p += sprintf(p, "ASSOCINFO(ReqIEs="); - len = sec_ie[1] + 2; - len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX; - for (i = 0; i < len; i++) - p += sprintf(p, "%02x", sec_ie[i]); - p += sprintf(p, ")"); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = p - buff; - wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? - wrqu.data.length : IW_CUSTOM_MAX; - wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff); - kfree(buff); - } -} diff --git a/drivers/staging/rtl8712/mlme_osdep.h b/drivers/staging/rtl8712/mlme_osdep.h deleted file mode 100644 index a02c782588ddbfd0bfcd233948b5a2ccf6f84bcf..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/mlme_osdep.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __MLME_OSDEP_H_ -#define __MLME_OSDEP_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -void r8712_init_mlme_timer(struct _adapter *padapter); -void r8712_os_indicate_disconnect(struct _adapter *adapter); -void r8712_os_indicate_connect(struct _adapter *adapter); -void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie); -int r8712_recv_indicatepkts_in_order(struct _adapter *adapter, - struct recv_reorder_ctrl *precvreorder_ctrl, - int bforced); -void r8712_indicate_wx_assoc_event(struct _adapter *padapter); -void r8712_indicate_wx_disassoc_event(struct _adapter *padapter); - -#endif /*_MLME_OSDEP_H_*/ - diff --git a/drivers/staging/rtl8712/mp_custom_oid.h b/drivers/staging/rtl8712/mp_custom_oid.h deleted file mode 100644 index a9fac87fcabc59b9d02ebbb68903e62055d0ad1e..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/mp_custom_oid.h +++ /dev/null @@ -1,287 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __CUSTOM_OID_H -#define __CUSTOM_OID_H - -/* 0xFF818000 - 0xFF81802F RTL8180 Mass Production Kit - * 0xFF818500 - 0xFF81850F RTL8185 Setup Utility - * 0xFF818580 - 0xFF81858F RTL8185 Phy Status Utility - * - * by Owen for Production Kit - * For Production Kit with Agilent Equipments - * in order to make our custom oids hopefully somewhat unique - * we will use 0xFF (indicating implementation specific OID) - * 81(first byte of non zero Realtek unique identifier) - * 80 (second byte of non zero Realtek unique identifier) - * XX (the custom OID number - providing 255 possible custom oids) - */ -#define OID_RT_PRO_RESET_DUT 0xFF818000 -#define OID_RT_PRO_SET_DATA_RATE 0xFF818001 -#define OID_RT_PRO_START_TEST 0xFF818002 -#define OID_RT_PRO_STOP_TEST 0xFF818003 -#define OID_RT_PRO_SET_PREAMBLE 0xFF818004 -#define OID_RT_PRO_SET_SCRAMBLER 0xFF818005 -#define OID_RT_PRO_SET_FILTER_BB 0xFF818006 -#define OID_RT_PRO_SET_MANUAL_DIVERSITY_BB 0xFF818007 -#define OID_RT_PRO_SET_CHANNEL_DIRECT_CALL 0xFF818008 -#define OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL 0xFF818009 -#define OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL 0xFF81800A - -#define OID_RT_PRO_SET_TX_ANTENNA_BB 0xFF81800D -#define OID_RT_PRO_SET_ANTENNA_BB 0xFF81800E -#define OID_RT_PRO_SET_CR_SCRAMBLER 0xFF81800F -#define OID_RT_PRO_SET_CR_NEW_FILTER 0xFF818010 -#define OID_RT_PRO_SET_TX_POWER_CONTROL 0xFF818011 -#define OID_RT_PRO_SET_CR_TX_CONFIG 0xFF818012 -#define OID_RT_PRO_GET_TX_POWER_CONTROL 0xFF818013 -#define OID_RT_PRO_GET_CR_SIGNAL_QUALITY 0xFF818014 -#define OID_RT_PRO_SET_CR_SETPOINT 0xFF818015 -#define OID_RT_PRO_SET_INTEGRATOR 0xFF818016 -#define OID_RT_PRO_SET_SIGNAL_QUALITY 0xFF818017 -#define OID_RT_PRO_GET_INTEGRATOR 0xFF818018 -#define OID_RT_PRO_GET_SIGNAL_QUALITY 0xFF818019 -#define OID_RT_PRO_QUERY_EEPROM_TYPE 0xFF81801A -#define OID_RT_PRO_WRITE_MAC_ADDRESS 0xFF81801B -#define OID_RT_PRO_READ_MAC_ADDRESS 0xFF81801C -#define OID_RT_PRO_WRITE_CIS_DATA 0xFF81801D -#define OID_RT_PRO_READ_CIS_DATA 0xFF81801E -#define OID_RT_PRO_WRITE_POWER_CONTROL 0xFF81801F -#define OID_RT_PRO_READ_POWER_CONTROL 0xFF818020 -#define OID_RT_PRO_WRITE_EEPROM 0xFF818021 -#define OID_RT_PRO_READ_EEPROM 0xFF818022 -#define OID_RT_PRO_RESET_TX_PACKET_SENT 0xFF818023 -#define OID_RT_PRO_QUERY_TX_PACKET_SENT 0xFF818024 -#define OID_RT_PRO_RESET_RX_PACKET_RECEIVED 0xFF818025 -#define OID_RT_PRO_QUERY_RX_PACKET_RECEIVED 0xFF818026 -#define OID_RT_PRO_QUERY_RX_PACKET_CRC32_ERROR 0xFF818027 -#define OID_RT_PRO_QUERY_CURRENT_ADDRESS 0xFF818028 -#define OID_RT_PRO_QUERY_PERMANENT_ADDRESS 0xFF818029 -#define OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS 0xFF81802A -#define OID_RT_PRO_RECEIVE_PACKET 0xFF81802C -#define OID_RT_PRO_WRITE_EEPROM_BYTE 0xFF81802D -#define OID_RT_PRO_READ_EEPROM_BYTE 0xFF81802E -#define OID_RT_PRO_SET_MODULATION 0xFF81802F -#define OID_RT_DRIVER_OPTION 0xFF818080 -#define OID_RT_RF_OFF 0xFF818081 -#define OID_RT_AUTH_STATUS 0xFF818082 -#define OID_RT_PRO_SET_CONTINUOUS_TX 0xFF81800B -#define OID_RT_PRO_SET_SINGLE_CARRIER_TX 0xFF81800C -#define OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX 0xFF81802B -#define OID_RT_PRO_SET_SINGLE_TONE_TX 0xFF818043 -#define OID_RT_UTILITY_FALSE_ALARM_COUNTERS 0xFF818580 -#define OID_RT_UTILITY_SELECT_DEBUG_MODE 0xFF818581 -#define OID_RT_UTILITY_SELECT_SUBCARRIER_NUMBER 0xFF818582 -#define OID_RT_UTILITY_GET_RSSI_STATUS 0xFF818583 -#define OID_RT_UTILITY_GET_FRAME_DETECTION_STATUS 0xFF818584 -#define OID_RT_UTILITY_GET_AGC_AND_FREQUENCY_OFFSET_ESTIMATION_STATUS \ - 0xFF818585 -#define OID_RT_UTILITY_GET_CHANNEL_ESTIMATION_STATUS 0xFF818586 -#define OID_RT_WIRELESS_MODE 0xFF818500 -#define OID_RT_SUPPORTED_RATES 0xFF818501 -#define OID_RT_DESIRED_RATES 0xFF818502 -#define OID_RT_WIRELESS_MODE_STARTING_ADHOC 0xFF818503 -#define OID_RT_GET_CONNECT_STATE 0xFF030001 -#define OID_RT_RESCAN 0xFF030002 -#define OID_RT_SET_KEY_LENGTH 0xFF030003 -#define OID_RT_SET_DEFAULT_KEY_ID 0xFF030004 -#define OID_RT_SET_CHANNEL 0xFF010182 -#define OID_RT_SET_SNIFFER_MODE 0xFF010183 -#define OID_RT_GET_SIGNAL_QUALITY 0xFF010184 -#define OID_RT_GET_SMALL_PACKET_CRC 0xFF010185 -#define OID_RT_GET_MIDDLE_PACKET_CRC 0xFF010186 -#define OID_RT_GET_LARGE_PACKET_CRC 0xFF010187 -#define OID_RT_GET_TX_RETRY 0xFF010188 -#define OID_RT_GET_RX_RETRY 0xFF010189 -#define OID_RT_PRO_SET_FW_DIG_STATE 0xFF01018A -#define OID_RT_PRO_SET_FW_RA_STATE 0xFF01018B -#define OID_RT_GET_RX_TOTAL_PACKET 0xFF010190 -#define OID_RT_GET_TX_BEACON_OK 0xFF010191 -#define OID_RT_GET_TX_BEACON_ERR 0xFF010192 -#define OID_RT_GET_RX_ICV_ERR 0xFF010193 -#define OID_RT_SET_ENCRYPTION_ALGORITHM 0xFF010194 -#define OID_RT_SET_NO_AUTO_RESCAN 0xFF010195 -#define OID_RT_GET_PREAMBLE_MODE 0xFF010196 -#define OID_RT_GET_DRIVER_UP_DELTA_TIME 0xFF010197 -#define OID_RT_GET_AP_IP 0xFF010198 -#define OID_RT_GET_CHANNELPLAN 0xFF010199 -#define OID_RT_SET_PREAMBLE_MODE 0xFF01019A -#define OID_RT_SET_BCN_INTVL 0xFF01019B -#define OID_RT_GET_RF_VENDER 0xFF01019C -#define OID_RT_DEDICATE_PROBE 0xFF01019D -#define OID_RT_PRO_RX_FILTER_PATTERN 0xFF01019E -#define OID_RT_GET_DCST_CURRENT_THRESHOLD 0xFF01019F -#define OID_RT_GET_CCA_ERR 0xFF0101A0 -#define OID_RT_GET_CCA_UPGRADE_THRESHOLD 0xFF0101A1 -#define OID_RT_GET_CCA_FALLBACK_THRESHOLD 0xFF0101A2 -#define OID_RT_GET_CCA_UPGRADE_EVALUATE_TIMES 0xFF0101A3 -#define OID_RT_GET_CCA_FALLBACK_EVALUATE_TIMES 0xFF0101A4 -#define OID_RT_SET_RATE_ADAPTIVE 0xFF0101A5 -#define OID_RT_GET_DCST_EVALUATE_PERIOD 0xFF0101A5 -#define OID_RT_GET_DCST_TIME_UNIT_INDEX 0xFF0101A6 -#define OID_RT_GET_TOTAL_TX_BYTES 0xFF0101A7 -#define OID_RT_GET_TOTAL_RX_BYTES 0xFF0101A8 -#define OID_RT_CURRENT_TX_POWER_LEVEL 0xFF0101A9 -#define OID_RT_GET_ENC_KEY_MISMATCH_COUNT 0xFF0101AA -#define OID_RT_GET_ENC_KEY_MATCH_COUNT 0xFF0101AB -#define OID_RT_GET_CHANNEL 0xFF0101AC -#define OID_RT_SET_CHANNELPLAN 0xFF0101AD -#define OID_RT_GET_HARDWARE_RADIO_OFF 0xFF0101AE -#define OID_RT_CHANNELPLAN_BY_COUNTRY 0xFF0101AF -#define OID_RT_SCAN_AVAILABLE_BSSID 0xFF0101B0 -#define OID_RT_GET_HARDWARE_VERSION 0xFF0101B1 -#define OID_RT_GET_IS_ROAMING 0xFF0101B2 -#define OID_RT_GET_IS_PRIVACY 0xFF0101B3 -#define OID_RT_GET_KEY_MISMATCH 0xFF0101B4 -#define OID_RT_SET_RSSI_ROAM_TRAFFIC_TH 0xFF0101B5 -#define OID_RT_SET_RSSI_ROAM_SIGNAL_TH 0xFF0101B6 -#define OID_RT_RESET_LOG 0xFF0101B7 -#define OID_RT_GET_LOG 0xFF0101B8 -#define OID_RT_SET_INDICATE_HIDDEN_AP 0xFF0101B9 -#define OID_RT_GET_HEADER_FAIL 0xFF0101BA -#define OID_RT_SUPPORTED_WIRELESS_MODE 0xFF0101BB -#define OID_RT_GET_CHANNEL_LIST 0xFF0101BC -#define OID_RT_GET_SCAN_IN_PROGRESS 0xFF0101BD -#define OID_RT_GET_TX_INFO 0xFF0101BE -#define OID_RT_RF_READ_WRITE_OFFSET 0xFF0101BF -#define OID_RT_RF_READ_WRITE 0xFF0101C0 -#define OID_RT_FORCED_DATA_RATE 0xFF0101C1 -#define OID_RT_WIRELESS_MODE_FOR_SCAN_LIST 0xFF0101C2 -#define OID_RT_GET_BSS_WIRELESS_MODE 0xFF0101C3 -#define OID_RT_SCAN_WITH_MAGIC_PACKET 0xFF0101C4 -#define OID_RT_PRO_RX_FILTER 0xFF0111C0 -#define OID_CE_USB_WRITE_REGISTRY 0xFF0111C1 -#define OID_CE_USB_READ_REGISTRY 0xFF0111C2 -#define OID_RT_PRO_SET_INITIAL_GAIN 0xFF0111C3 -#define OID_RT_PRO_SET_BB_RF_STANDBY_MODE 0xFF0111C4 -#define OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE 0xFF0111C5 -#define OID_RT_PRO_SET_TX_CHARGE_PUMP 0xFF0111C6 -#define OID_RT_PRO_SET_RX_CHARGE_PUMP 0xFF0111C7 -#define OID_RT_PRO_RF_WRITE_REGISTRY 0xFF0111C8 -#define OID_RT_PRO_RF_READ_REGISTRY 0xFF0111C9 -#define OID_RT_PRO_QUERY_RF_TYPE 0xFF0111CA -#define OID_RT_AP_GET_ASSOCIATED_STATION_LIST 0xFF010300 -#define OID_RT_AP_GET_CURRENT_TIME_STAMP 0xFF010301 -#define OID_RT_AP_SWITCH_INTO_AP_MODE 0xFF010302 -#define OID_RT_AP_SET_DTIM_PERIOD 0xFF010303 -#define OID_RT_AP_SUPPORTED 0xFF010304 -#define OID_RT_AP_SET_PASSPHRASE 0xFF010305 -#define OID_RT_PRO8187_WI_POLL 0xFF818780 -#define OID_RT_PRO_WRITE_BB_REG 0xFF818781 -#define OID_RT_PRO_READ_BB_REG 0xFF818782 -#define OID_RT_PRO_WRITE_RF_REG 0xFF818783 -#define OID_RT_PRO_READ_RF_REG 0xFF818784 -#define OID_RT_MH_VENDER_ID 0xFFEDC100 -#define OID_RT_PRO8711_JOIN_BSS 0xFF871100 -#define OID_RT_PRO_READ_REGISTER 0xFF871101 -#define OID_RT_PRO_WRITE_REGISTER 0xFF871102 -#define OID_RT_PRO_BURST_READ_REGISTER 0xFF871103 -#define OID_RT_PRO_BURST_WRITE_REGISTER 0xFF871104 -#define OID_RT_PRO_WRITE_TXCMD 0xFF871105 -#define OID_RT_PRO_READ16_EEPROM 0xFF871106 -#define OID_RT_PRO_WRITE16_EEPROM 0xFF871107 -#define OID_RT_PRO_H2C_SET_COMMAND 0xFF871108 -#define OID_RT_PRO_H2C_QUERY_RESULT 0xFF871109 -#define OID_RT_PRO8711_WI_POLL 0xFF87110A -#define OID_RT_PRO8711_PKT_LOSS 0xFF87110B -#define OID_RT_RD_ATTRIB_MEM 0xFF87110C -#define OID_RT_WR_ATTRIB_MEM 0xFF87110D -/*Method 2 for H2C/C2H*/ -#define OID_RT_PRO_H2C_CMD_MODE 0xFF871110 -#define OID_RT_PRO_H2C_CMD_RSP_MODE 0xFF871111 -#define OID_RT_PRO_H2C_CMD_EVENT_MODE 0xFF871112 -#define OID_RT_PRO_WAIT_C2H_EVENT 0xFF871113 -#define OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST 0xFF871114 -#define OID_RT_PRO_SCSI_ACCESS_TEST 0xFF871115 -#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT 0xFF871116 -#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN 0xFF871117 -#define OID_RT_RRO_RX_PKT_VIA_IOCTRL 0xFF871118 -#define OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL 0xFF871119 -#define OID_RT_RPO_SET_PWRMGT_TEST 0xFF87111A -#define OID_RT_PRO_QRY_PWRMGT_TEST 0XFF87111B -#define OID_RT_RPO_ASYNC_RWIO_TEST 0xFF87111C -#define OID_RT_RPO_ASYNC_RWIO_POLL 0xFF87111D -#define OID_RT_PRO_SET_RF_INTFS 0xFF87111E -#define OID_RT_POLL_RX_STATUS 0xFF87111F -#define OID_RT_PRO_CFG_DEBUG_MESSAGE 0xFF871120 -#define OID_RT_PRO_SET_DATA_RATE_EX 0xFF871121 -#define OID_RT_PRO_SET_BASIC_RATE 0xFF871122 -#define OID_RT_PRO_READ_TSSI 0xFF871123 -#define OID_RT_PRO_SET_POWER_TRACKING 0xFF871124 -#define OID_RT_PRO_QRY_PWRSTATE 0xFF871150 -#define OID_RT_PRO_SET_PWRSTATE 0xFF871151 -/*Method 2 , using workitem */ -#define OID_RT_SET_READ_REG 0xFF871181 -#define OID_RT_SET_WRITE_REG 0xFF871182 -#define OID_RT_SET_BURST_READ_REG 0xFF871183 -#define OID_RT_SET_BURST_WRITE_REG 0xFF871184 -#define OID_RT_SET_WRITE_TXCMD 0xFF871185 -#define OID_RT_SET_READ16_EEPROM 0xFF871186 -#define OID_RT_SET_WRITE16_EEPROM 0xFF871187 -#define OID_RT_QRY_POLL_WKITEM 0xFF871188 - -/*For SDIO INTERFACE only*/ -#define OID_RT_PRO_SYNCPAGERW_SRAM 0xFF8711A0 -#define OID_RT_PRO_871X_DRV_EXT 0xFF8711A1 - -/*For USB INTERFACE only*/ -#define OID_RT_PRO_USB_VENDOR_REQ 0xFF8711B0 -#define OID_RT_PRO_SCSI_AUTO_TEST 0xFF8711B1 -#define OID_RT_PRO_USB_MAC_AC_FIFO_WRITE 0xFF8711B2 -#define OID_RT_PRO_USB_MAC_RX_FIFO_READ 0xFF8711B3 -#define OID_RT_PRO_USB_MAC_RX_FIFO_POLLING 0xFF8711B4 - -#define OID_RT_PRO_H2C_SET_RATE_TABLE 0xFF8711FB -#define OID_RT_PRO_H2C_GET_RATE_TABLE 0xFF8711FC -#define OID_RT_PRO_H2C_C2H_LBK_TEST 0xFF8711FE - -#define OID_RT_PRO_ENCRYPTION_CTRL 0xFF871200 -#define OID_RT_PRO_ADD_STA_INFO 0xFF871201 -#define OID_RT_PRO_DELE_STA_INFO 0xFF871202 -#define OID_RT_PRO_QUERY_DR_VARIABLE 0xFF871203 - -#define OID_RT_PRO_RX_PACKET_TYPE 0xFF871204 - -#define OID_RT_PRO_READ_EFUSE 0xFF871205 -#define OID_RT_PRO_WRITE_EFUSE 0xFF871206 -#define OID_RT_PRO_RW_EFUSE_PGPKT 0xFF871207 -#define OID_RT_GET_EFUSE_CURRENT_SIZE 0xFF871208 - -#define OID_RT_SET_BANDWIDTH 0xFF871209 -#define OID_RT_SET_CRYSTAL_CAP 0xFF87120A - -#define OID_RT_SET_RX_PACKET_TYPE 0xFF87120B - -#define OID_RT_GET_EFUSE_MAX_SIZE 0xFF87120C - -#define OID_RT_PRO_SET_TX_AGC_OFFSET 0xFF87120D - -#define OID_RT_PRO_SET_PKT_TEST_MODE 0xFF87120E - -#define OID_RT_PRO_FOR_EVM_TEST_SETTING 0xFF87120F - -#define OID_RT_PRO_GET_THERMAL_METER 0xFF871210 - -#define OID_RT_RESET_PHY_RX_PACKET_COUNT 0xFF871211 -#define OID_RT_GET_PHY_RX_PACKET_RECEIVED 0xFF871212 -#define OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR 0xFF871213 - -#define OID_RT_SET_POWER_DOWN 0xFF871214 - -#define OID_RT_GET_POWER_MODE 0xFF871215 - -#define OID_RT_PRO_EFUSE 0xFF871216 -#define OID_RT_PRO_EFUSE_MAP 0xFF871217 - -#endif /*#ifndef __CUSTOM_OID_H */ - diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c deleted file mode 100644 index 1b11f8b04e13f28fa12564bdff5b3b1cbbcc6cd4..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/os_intfs.c +++ /dev/null @@ -1,482 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * os_intfs.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _OS_INTFS_C_ - -#include -#include -#include -#include "osdep_service.h" -#include "drv_types.h" -#include "xmit_osdep.h" -#include "recv_osdep.h" -#include "rtl871x_ioctl.h" -#include "usb_osintf.h" - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("rtl871x wireless lan driver"); -MODULE_AUTHOR("Larry Finger"); - -static char ifname[IFNAMSIZ] = "wlan%d"; - -/* module param defaults */ -static int chip_version = RTL8712_2ndCUT; -static int rfintfs = HWPI; -static int lbkmode = RTL8712_AIR_TRX; -static int hci = RTL8712_USB; -static int ampdu_enable = 1;/*for enable tx_ampdu*/ - -/* The video_mode variable is for video mode.*/ -/* It may be specify when inserting module with video_mode=1 parameter.*/ -static int video_mode = 1; /* enable video mode*/ - -/*Ndis802_11Infrastructure; infra, ad-hoc, auto*/ -static int network_mode = Ndis802_11IBSS; -static int channel = 1;/*ad-hoc support requirement*/ -static int wireless_mode = WIRELESS_11BG; -static int vrtl_carrier_sense = AUTO_VCS; -static int vcs_type = RTS_CTS; -static int frag_thresh = 2346; -static int preamble = PREAMBLE_LONG;/*long, short, auto*/ -static int scan_mode = 1;/*active, passive*/ -static int adhoc_tx_pwr = 1; -static int soft_ap; -static int smart_ps = 1; -static int power_mgnt = PS_MODE_ACTIVE; -static int radio_enable = 1; -static int long_retry_lmt = 7; -static int short_retry_lmt = 7; -static int busy_thresh = 40; -static int ack_policy = NORMAL_ACK; -static int mp_mode; -static int software_encrypt; -static int software_decrypt; - -static int wmm_enable;/* default is set to disable the wmm.*/ -static int uapsd_enable; -static int uapsd_max_sp = NO_LIMIT; -static int uapsd_acbk_en; -static int uapsd_acbe_en; -static int uapsd_acvi_en; -static int uapsd_acvo_en; - -static int ht_enable = 1; -static int cbw40_enable = 1; -static int rf_config = RTL8712_RF_1T2R; /* 1T2R*/ -static int low_power; -/* mac address to use instead of the one stored in Efuse */ -char *r8712_initmac; -static char *initmac; -/* if wifi_test = 1, driver will disable the turbo mode and pass it to - * firmware private. - */ -static int wifi_test; - -module_param_string(ifname, ifname, sizeof(ifname), 0644); -module_param(wifi_test, int, 0644); -module_param(initmac, charp, 0644); -module_param(video_mode, int, 0644); -module_param(chip_version, int, 0644); -module_param(rfintfs, int, 0644); -module_param(lbkmode, int, 0644); -module_param(hci, int, 0644); -module_param(network_mode, int, 0644); -module_param(channel, int, 0644); -module_param(mp_mode, int, 0644); -module_param(wmm_enable, int, 0644); -module_param(vrtl_carrier_sense, int, 0644); -module_param(vcs_type, int, 0644); -module_param(busy_thresh, int, 0644); -module_param(ht_enable, int, 0644); -module_param(cbw40_enable, int, 0644); -module_param(ampdu_enable, int, 0644); -module_param(rf_config, int, 0644); -module_param(power_mgnt, int, 0644); -module_param(low_power, int, 0644); - -MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); -MODULE_PARM_DESC(initmac, "MAC-Address, default: use FUSE"); - -static int netdev_open(struct net_device *pnetdev); -static int netdev_close(struct net_device *pnetdev); - -static void loadparam(struct _adapter *padapter, struct net_device *pnetdev) -{ - struct registry_priv *registry_par = &padapter->registrypriv; - - registry_par->chip_version = (u8)chip_version; - registry_par->rfintfs = (u8)rfintfs; - registry_par->lbkmode = (u8)lbkmode; - registry_par->hci = (u8)hci; - registry_par->network_mode = (u8)network_mode; - memcpy(registry_par->ssid.Ssid, "ANY", 3); - registry_par->ssid.SsidLength = 3; - registry_par->channel = (u8)channel; - registry_par->wireless_mode = (u8)wireless_mode; - registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense; - registry_par->vcs_type = (u8)vcs_type; - registry_par->frag_thresh = (u16)frag_thresh; - registry_par->preamble = (u8)preamble; - registry_par->scan_mode = (u8)scan_mode; - registry_par->adhoc_tx_pwr = (u8)adhoc_tx_pwr; - registry_par->soft_ap = (u8)soft_ap; - registry_par->smart_ps = (u8)smart_ps; - registry_par->power_mgnt = (u8)power_mgnt; - registry_par->radio_enable = (u8)radio_enable; - registry_par->long_retry_lmt = (u8)long_retry_lmt; - registry_par->short_retry_lmt = (u8)short_retry_lmt; - registry_par->busy_thresh = (u16)busy_thresh; - registry_par->ack_policy = (u8)ack_policy; - registry_par->mp_mode = (u8)mp_mode; - registry_par->software_encrypt = (u8)software_encrypt; - registry_par->software_decrypt = (u8)software_decrypt; - /*UAPSD*/ - registry_par->wmm_enable = (u8)wmm_enable; - registry_par->uapsd_enable = (u8)uapsd_enable; - registry_par->uapsd_max_sp = (u8)uapsd_max_sp; - registry_par->uapsd_acbk_en = (u8)uapsd_acbk_en; - registry_par->uapsd_acbe_en = (u8)uapsd_acbe_en; - registry_par->uapsd_acvi_en = (u8)uapsd_acvi_en; - registry_par->uapsd_acvo_en = (u8)uapsd_acvo_en; - registry_par->ht_enable = (u8)ht_enable; - registry_par->cbw40_enable = (u8)cbw40_enable; - registry_par->ampdu_enable = (u8)ampdu_enable; - registry_par->rf_config = (u8)rf_config; - registry_par->low_power = (u8)low_power; - registry_par->wifi_test = (u8)wifi_test; - r8712_initmac = initmac; -} - -static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - struct sockaddr *addr = p; - - if (!padapter->bup) - eth_hw_addr_set(pnetdev, addr->sa_data); - return 0; -} - -static struct net_device_stats *r871x_net_get_stats(struct net_device *pnetdev) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct recv_priv *precvpriv = &padapter->recvpriv; - - padapter->stats.tx_packets = pxmitpriv->tx_pkts; - padapter->stats.rx_packets = precvpriv->rx_pkts; - padapter->stats.tx_dropped = pxmitpriv->tx_drop; - padapter->stats.rx_dropped = precvpriv->rx_drop; - padapter->stats.tx_bytes = pxmitpriv->tx_bytes; - padapter->stats.rx_bytes = precvpriv->rx_bytes; - return &padapter->stats; -} - -static const struct net_device_ops rtl8712_netdev_ops = { - .ndo_open = netdev_open, - .ndo_stop = netdev_close, - .ndo_start_xmit = r8712_xmit_entry, - .ndo_set_mac_address = r871x_net_set_mac_address, - .ndo_get_stats = r871x_net_get_stats, - .ndo_do_ioctl = r871x_ioctl, -}; - -struct net_device *r8712_init_netdev(void) -{ - struct _adapter *padapter; - struct net_device *pnetdev; - - pnetdev = alloc_etherdev(sizeof(struct _adapter)); - if (!pnetdev) - return NULL; - if (dev_alloc_name(pnetdev, ifname) < 0) { - strscpy(ifname, "wlan%d", sizeof(ifname)); - dev_alloc_name(pnetdev, ifname); - } - padapter = netdev_priv(pnetdev); - padapter->pnetdev = pnetdev; - pr_info("r8712u: register rtl8712_netdev_ops to netdev_ops\n"); - pnetdev->netdev_ops = &rtl8712_netdev_ops; - pnetdev->watchdog_timeo = HZ; /* 1 second timeout */ - pnetdev->wireless_handlers = (struct iw_handler_def *) - &r871x_handlers_def; - loadparam(padapter, pnetdev); - netif_carrier_off(pnetdev); - padapter->pid = 0; /* Initial the PID value used for HW PBC.*/ - return pnetdev; -} - -static u32 start_drv_threads(struct _adapter *padapter) -{ - padapter->cmd_thread = kthread_run(r8712_cmd_thread, padapter, "%s", - padapter->pnetdev->name); - if (IS_ERR(padapter->cmd_thread)) - return _FAIL; - return _SUCCESS; -} - -void r8712_stop_drv_threads(struct _adapter *padapter) -{ - struct completion *completion = - &padapter->cmdpriv.terminate_cmdthread_comp; - - /*Below is to terminate r8712_cmd_thread & event_thread...*/ - complete(&padapter->cmdpriv.cmd_queue_comp); - if (padapter->cmd_thread) - wait_for_completion_interruptible(completion); - padapter->cmdpriv.cmd_seq = 1; -} - -static void start_drv_timers(struct _adapter *padapter) -{ - mod_timer(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, - jiffies + msecs_to_jiffies(5000)); - mod_timer(&padapter->mlmepriv.wdg_timer, - jiffies + msecs_to_jiffies(2000)); -} - -void r8712_stop_drv_timers(struct _adapter *padapter) -{ - del_timer_sync(&padapter->mlmepriv.assoc_timer); - del_timer_sync(&padapter->securitypriv.tkip_timer); - del_timer_sync(&padapter->mlmepriv.scan_to_timer); - del_timer_sync(&padapter->mlmepriv.dhcp_timer); - del_timer_sync(&padapter->mlmepriv.wdg_timer); - del_timer_sync(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer); -} - -static void init_default_value(struct _adapter *padapter) -{ - struct registry_priv *pregistrypriv = &padapter->registrypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - /*xmit_priv*/ - pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; - pxmitpriv->vcs = pregistrypriv->vcs_type; - pxmitpriv->vcs_type = pregistrypriv->vcs_type; - pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; - pxmitpriv->frag_len = pregistrypriv->frag_thresh; - /* mlme_priv */ - /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/ - pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */ - /*ht_priv*/ - { - int i; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - phtpriv->ampdu_enable = false;/*set to disabled*/ - for (i = 0; i < 16; i++) - phtpriv->baddbareq_issued[i] = false; - } - /*security_priv*/ - psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; - psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; - psecuritypriv->binstallGrpkey = _FAIL; - /*pwrctrl_priv*/ - /*registry_priv*/ - r8712_init_registrypriv_dev_network(padapter); - r8712_update_registrypriv_dev_network(padapter); - /*misc.*/ -} - -int r8712_init_drv_sw(struct _adapter *padapter) -{ - int ret; - - ret = r8712_init_cmd_priv(&padapter->cmdpriv); - if (ret) - return ret; - padapter->cmdpriv.padapter = padapter; - ret = r8712_init_evt_priv(&padapter->evtpriv); - if (ret) - goto free_cmd; - ret = r8712_init_mlme_priv(padapter); - if (ret) - goto free_evt; - ret = _r8712_init_xmit_priv(&padapter->xmitpriv, padapter); - if (ret) - goto free_mlme; - ret = _r8712_init_recv_priv(&padapter->recvpriv, padapter); - if (ret) - goto free_xmit; - memset((unsigned char *)&padapter->securitypriv, 0, - sizeof(struct security_priv)); - timer_setup(&padapter->securitypriv.tkip_timer, - r8712_use_tkipkey_handler, 0); - ret = _r8712_init_sta_priv(&padapter->stapriv); - if (ret) - goto free_recv; - padapter->stapriv.padapter = padapter; - r8712_init_bcmc_stainfo(padapter); - r8712_init_pwrctrl_priv(padapter); - mp871xinit(padapter); - init_default_value(padapter); - r8712_InitSwLeds(padapter); - mutex_init(&padapter->mutex_start); - - return 0; - -free_recv: - _r8712_free_recv_priv(&padapter->recvpriv); -free_xmit: - _free_xmit_priv(&padapter->xmitpriv); -free_mlme: - r8712_free_mlme_priv(&padapter->mlmepriv); -free_evt: - r8712_free_evt_priv(&padapter->evtpriv); -free_cmd: - r8712_free_cmd_priv(&padapter->cmdpriv); - return ret; -} - -void r8712_free_drv_sw(struct _adapter *padapter) -{ - r8712_free_cmd_priv(&padapter->cmdpriv); - r8712_free_evt_priv(&padapter->evtpriv); - r8712_DeInitSwLeds(padapter); - r8712_free_mlme_priv(&padapter->mlmepriv); - _free_xmit_priv(&padapter->xmitpriv); - _r8712_free_sta_priv(&padapter->stapriv); - _r8712_free_recv_priv(&padapter->recvpriv); - mp871xdeinit(padapter); -} - -static void enable_video_mode(struct _adapter *padapter, int cbw40_value) -{ - /* bit 8: - * 1 -> enable video mode to 96B AP - * 0 -> disable video mode to 96B AP - * bit 9: - * 1 -> enable 40MHz mode - * 0 -> disable 40MHz mode - * bit 10: - * 1 -> enable STBC - * 0 -> disable STBC - */ - u32 intcmd = 0xf4000500; /* enable bit8, bit10*/ - - if (cbw40_value) { - /* if the driver supports the 40M bandwidth, - * we can enable the bit 9. - */ - intcmd |= 0x200; - } - r8712_fw_cmd(padapter, intcmd); -} - -/* - * - * This function intends to handle the activation of an interface - * i.e. when it is brought Up/Active from a Down state. - * - */ -static int netdev_open(struct net_device *pnetdev) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - - mutex_lock(&padapter->mutex_start); - if (!padapter->bup) { - padapter->driver_stopped = false; - padapter->surprise_removed = false; - padapter->bup = true; - if (rtl871x_hal_init(padapter) != _SUCCESS) - goto netdev_open_error; - if (!r8712_initmac) { - /* Use the mac address stored in the Efuse */ - eth_hw_addr_set(pnetdev, - padapter->eeprompriv.mac_addr); - } else { - /* We have to inform f/w to use user-supplied MAC - * address. - */ - msleep(200); - r8712_setMacAddr_cmd(padapter, - (const u8 *)pnetdev->dev_addr); - /* - * The "myid" function will get the wifi mac address - * from eeprompriv structure instead of netdev - * structure. So, we have to overwrite the mac_addr - * stored in the eeprompriv structure. In this case, - * the real mac address won't be used anymore. So that, - * the eeprompriv.mac_addr should store the mac which - * users specify. - */ - memcpy(padapter->eeprompriv.mac_addr, - pnetdev->dev_addr, ETH_ALEN); - } - if (start_drv_threads(padapter) != _SUCCESS) - goto netdev_open_error; - if (!padapter->dvobjpriv.inirp_init) - goto netdev_open_error; - else - padapter->dvobjpriv.inirp_init(padapter); - r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, - padapter->registrypriv.smart_ps); - } - if (!netif_queue_stopped(pnetdev)) - netif_start_queue(pnetdev); - else - netif_wake_queue(pnetdev); - - if (video_mode) - enable_video_mode(padapter, cbw40_enable); - /* start driver mlme relation timer */ - start_drv_timers(padapter); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); - mutex_unlock(&padapter->mutex_start); - return 0; -netdev_open_error: - padapter->bup = false; - netif_carrier_off(pnetdev); - netif_stop_queue(pnetdev); - mutex_unlock(&padapter->mutex_start); - return -1; -} - -/* - * - * This function intends to handle the shutdown of an interface - * i.e. when it is brought Down from an Up/Active state. - * - */ -static int netdev_close(struct net_device *pnetdev) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - - /* Close LED*/ - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF); - msleep(200); - - /*s1.*/ - if (pnetdev) { - if (!netif_queue_stopped(pnetdev)) - netif_stop_queue(pnetdev); - } - /*s2.*/ - /*s2-1. issue disassoc_cmd to fw*/ - r8712_disassoc_cmd(padapter); - /*s2-2. indicate disconnect to os*/ - r8712_ind_disconnect(padapter); - /*s2-3.*/ - r8712_free_assoc_resources(padapter); - /*s2-4.*/ - r8712_free_network_queue(padapter); - return 0; -} - -#include "mlme_osdep.h" diff --git a/drivers/staging/rtl8712/osdep_intf.h b/drivers/staging/rtl8712/osdep_intf.h deleted file mode 100644 index 9e75116c987ec32a518a8ece1829457180aee6a0..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/osdep_intf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __OSDEP_INTF_H_ -#define __OSDEP_INTF_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define RND4(x) (((x >> 2) + ((x & 3) != 0)) << 2) - -struct intf_priv { - u8 *intf_dev; - /* when in USB, IO is through interrupt in/out endpoints */ - struct usb_device *udev; - struct urb *piorw_urb; - struct completion io_retevt_comp; -}; - -int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); - -#endif /*_OSDEP_INTF_H_*/ diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h deleted file mode 100644 index 0d9bb42cbc589eb8e5350d70e7ce98039fbf01d2..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/osdep_service.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __OSDEP_SERVICE_H_ -#define __OSDEP_SERVICE_H_ - -#define _SUCCESS 1 -#define _FAIL 0 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include /* Necessary because we use the proc fs */ - -#include "basic_types.h" - -struct __queue { - struct list_head queue; - spinlock_t lock; -}; - -#define _pkt struct sk_buff -#define _buffer unsigned char - -#define _init_queue(pqueue) \ - do { \ - INIT_LIST_HEAD(&((pqueue)->queue)); \ - spin_lock_init(&((pqueue)->lock)); \ - } while (0) - -static inline u32 end_of_queue_search(struct list_head *head, - struct list_head *plist) -{ - return (head == plist); -} - -static inline void flush_signals_thread(void) -{ - if (signal_pending(current)) - flush_signals(current); -} - -#endif - diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c deleted file mode 100644 index 215fca4abb3a0669b2646edf4e060651a45aea67..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/recv_linux.c +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * recv_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RECV_OSDEP_C_ - -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "wifi.h" -#include "recv_osdep.h" -#include "osdep_intf.h" -#include "ethernet.h" -#include -#include "usb_ops.h" - -/*init os related resource in struct recv_priv*/ -/*alloc os related resource in union recv_frame*/ -void r8712_os_recv_resource_alloc(struct _adapter *padapter, - union recv_frame *precvframe) -{ - precvframe->u.hdr.pkt_newalloc = NULL; - precvframe->u.hdr.pkt = NULL; -} - -/*alloc os related resource in struct recv_buf*/ -int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter, - struct recv_buf *precvbuf) -{ - int res = 0; - - precvbuf->irp_pending = false; - precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); - if (!precvbuf->purb) - res = -ENOMEM; - precvbuf->pskb = NULL; - precvbuf->pallocated_buf = NULL; - precvbuf->pbuf = NULL; - precvbuf->pdata = NULL; - precvbuf->phead = NULL; - precvbuf->ptail = NULL; - precvbuf->pend = NULL; - precvbuf->transfer_len = 0; - precvbuf->len = 0; - return res; -} - -/*free os related resource in struct recv_buf*/ -void r8712_os_recvbuf_resource_free(struct _adapter *padapter, - struct recv_buf *precvbuf) -{ - if (precvbuf->pskb) - dev_kfree_skb_any(precvbuf->pskb); - if (precvbuf->purb) { - usb_kill_urb(precvbuf->purb); - usb_free_urb(precvbuf->purb); - } -} - -void r8712_handle_tkip_mic_err(struct _adapter *adapter, u8 bgroup) -{ - union iwreq_data wrqu; - struct iw_michaelmicfailure ev; - struct mlme_priv *mlmepriv = &adapter->mlmepriv; - - memset(&ev, 0x00, sizeof(ev)); - if (bgroup) - ev.flags |= IW_MICFAILURE_GROUP; - else - ev.flags |= IW_MICFAILURE_PAIRWISE; - ev.src_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(ev.src_addr.sa_data, &mlmepriv->assoc_bssid[0]); - memset(&wrqu, 0x00, sizeof(wrqu)); - wrqu.data.length = sizeof(ev); - wireless_send_event(adapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu, - (char *)&ev); -} - -void r8712_recv_indicatepkt(struct _adapter *adapter, - union recv_frame *recvframe) -{ - struct recv_priv *recvpriv; - struct __queue *free_recv_queue; - _pkt *skb; - struct rx_pkt_attrib *attrib = &recvframe->u.hdr.attrib; - - recvpriv = &adapter->recvpriv; - free_recv_queue = &recvpriv->free_recv_queue; - skb = recvframe->u.hdr.pkt; - if (!skb) - goto _recv_indicatepkt_drop; - skb->data = recvframe->u.hdr.rx_data; - skb->len = recvframe->u.hdr.len; - skb_set_tail_pointer(skb, skb->len); - if ((attrib->tcpchk_valid == 1) && (attrib->tcp_chkrpt == 1)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb->ip_summed = CHECKSUM_NONE; - skb->dev = adapter->pnetdev; - skb->protocol = eth_type_trans(skb, adapter->pnetdev); - netif_rx(skb); - recvframe->u.hdr.pkt = NULL; /* pointers to NULL before - * r8712_free_recvframe() - */ - r8712_free_recvframe(recvframe, free_recv_queue); - return; -_recv_indicatepkt_drop: - /*enqueue back to free_recv_queue*/ - if (recvframe) - r8712_free_recvframe(recvframe, free_recv_queue); - recvpriv->rx_drop++; -} - -static void _r8712_reordering_ctrl_timeout_handler (struct timer_list *t) -{ - struct recv_reorder_ctrl *reorder_ctrl = - from_timer(reorder_ctrl, t, reordering_ctrl_timer); - - r8712_reordering_ctrl_timeout_handler(reorder_ctrl); -} - -void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) -{ - timer_setup(&preorder_ctrl->reordering_ctrl_timer, - _r8712_reordering_ctrl_timeout_handler, 0); -} diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h deleted file mode 100644 index fbe3f28685064785dc1ecd9539b28d40737be22e..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/recv_osdep.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RECV_OSDEP_H_ -#define __RECV_OSDEP_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include - -int _r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter); -void _r8712_free_recv_priv(struct recv_priv *precvpriv); -void r8712_recv_entry(union recv_frame *precv_frame); -void r8712_recv_indicatepkt(struct _adapter *adapter, - union recv_frame *precv_frame); -void r8712_handle_tkip_mic_err(struct _adapter *padapter, u8 bgroup); -int r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter); -void r8712_free_recv_priv(struct recv_priv *precvpriv); -void r8712_os_recv_resource_alloc(struct _adapter *padapter, - union recv_frame *precvframe); -int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter, - struct recv_buf *precvbuf); -void r8712_os_recvbuf_resource_free(struct _adapter *padapter, - struct recv_buf *precvbuf); -void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_bitdef.h b/drivers/staging/rtl8712/rtl8712_bitdef.h deleted file mode 100644 index a4a687dcc2e7bb41e68012ece28952d4b587bc34..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_bitdef.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ - -#ifndef __RTL8712_BITDEF_H__ -#define __RTL8712_BITDEF_H__ - -#include "rtl8712_cmdctrl_bitdef.h" -#include "rtl8712_syscfg_bitdef.h" -#include "rtl8712_macsetting_bitdef.h" -#include "rtl8712_timectrl_bitdef.h" -#include "rtl8712_fifoctrl_bitdef.h" -#include "rtl8712_ratectrl_bitdef.h" -#include "rtl8712_edcasetting_bitdef.h" -#include "rtl8712_wmac_bitdef.h" -#include "rtl8712_security_bitdef.h" -#include "rtl8712_powersave_bitdef.h" -#include "rtl8712_gp_bitdef.h" -#include "rtl8712_interrupt_bitdef.h" -#include "rtl8712_debugctrl_bitdef.h" - -#endif /* __RTL8712_BITDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c deleted file mode 100644 index bb7db96ed8219f250cbc039ba374637de5026796..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ /dev/null @@ -1,409 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_cmd.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_CMD_C_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" -#include "rtl871x_ioctl_set.h" - -static void check_hw_pbc(struct _adapter *padapter) -{ - u8 tmp1byte; - - r8712_write8(padapter, MAC_PINMUX_CTRL, (GPIOMUX_EN | GPIOSEL_GPIO)); - tmp1byte = r8712_read8(padapter, GPIO_IO_SEL); - tmp1byte &= ~(HAL_8192S_HW_GPIO_WPS_BIT); - r8712_write8(padapter, GPIO_IO_SEL, tmp1byte); - tmp1byte = r8712_read8(padapter, GPIO_CTRL); - if (tmp1byte == 0xff) - return; - if (tmp1byte & HAL_8192S_HW_GPIO_WPS_BIT) { - /* Here we only set bPbcPressed to true - * After trigger PBC, the variable will be set to false - */ - netdev_dbg(padapter->pnetdev, "CheckPbcGPIO - PBC is pressed !!!!\n"); - /* 0 is the default value and it means the application monitors - * the HW PBC doesn't provide its pid to driver. - */ - if (padapter->pid == 0) - return; - kill_pid(find_vpid(padapter->pid), SIGUSR1, 1); - } -} - -/* query rx phy status from fw. - * Adhoc mode: beacon. - * Infrastructure mode: beacon , data. - */ -static void query_fw_rx_phy_status(struct _adapter *padapter) -{ - u32 val32 = 0; - int pollingcnts = 50; - - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { - r8712_write32(padapter, IOCMD_CTRL_REG, 0xf4000001); - msleep(100); - /* Wait FW complete IO Cmd */ - while ((r8712_read32(padapter, IOCMD_CTRL_REG)) && - (pollingcnts > 0)) { - pollingcnts--; - msleep(20); - } - if (pollingcnts != 0) - val32 = r8712_read32(padapter, IOCMD_DATA_REG); - else /* time out */ - val32 = 0; - val32 >>= 4; - padapter->recvpriv.fw_rssi = - (u8)r8712_signal_scale_mapping(val32); - } -} - -/* check mlme, hw, phy, or dynamic algorithm status. */ -static void StatusWatchdogCallback(struct _adapter *padapter) -{ - check_hw_pbc(padapter); - query_fw_rx_phy_status(padapter); -} - -static void r871x_internal_cmd_hdl(struct _adapter *padapter, u8 *pbuf) -{ - struct drvint_cmd_parm *pdrvcmd; - - if (!pbuf) - return; - pdrvcmd = (struct drvint_cmd_parm *)pbuf; - switch (pdrvcmd->i_cid) { - case WDG_WK_CID: - StatusWatchdogCallback(padapter); - break; - default: - break; - } - kfree(pdrvcmd->pbuf); -} - -static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - r8712_free_cmd_obj(pcmd); - return H2C_SUCCESS; -} - -static u8 write_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (!pcmd_callback) - r8712_free_cmd_obj(pcmd); - else - pcmd_callback(padapter, pcmd); - return H2C_SUCCESS; -} - -static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - u32 val; - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - if (pcmd->rsp && pcmd->rspsz > 0) - memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); - pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (!pcmd_callback) - r8712_free_cmd_obj(pcmd); - else - pcmd_callback(padapter, pcmd); - return H2C_SUCCESS; -} - -static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (!pcmd_callback) - r8712_free_cmd_obj(pcmd); - else - pcmd_callback(padapter, pcmd); - return H2C_SUCCESS; -} - -static u8 sys_suspend_hdl(struct _adapter *padapter, u8 *pbuf) -{ - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - r8712_free_cmd_obj(pcmd); - return H2C_SUCCESS; -} - -static struct cmd_obj *cmd_hdl_filter(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - struct cmd_obj *pcmd_r; - - if (!pcmd) - return pcmd; - pcmd_r = NULL; - - switch (pcmd->cmdcode) { - case GEN_CMD_CODE(_Read_BBREG): - read_bbreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_Write_BBREG): - write_bbreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_Read_RFREG): - read_rfreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_Write_RFREG): - write_rfreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_SetUsbSuspend): - sys_suspend_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_JoinBss): - r8712_joinbss_reset(padapter); - /* Before set JoinBss_CMD to FW, driver must ensure FW is in - * PS_MODE_ACTIVE. Directly write rpwm to radio on and assign - * new pwr_mode to Driver, instead of use workitem to change - * state. - */ - if (padapter->pwrctrlpriv.pwr_mode > PS_MODE_ACTIVE) { - padapter->pwrctrlpriv.pwr_mode = PS_MODE_ACTIVE; - mutex_lock(&padapter->pwrctrlpriv.mutex_lock); - r8712_set_rpwm(padapter, PS_STATE_S4); - mutex_unlock(&padapter->pwrctrlpriv.mutex_lock); - } - pcmd_r = pcmd; - break; - case _DRV_INT_CMD_: - r871x_internal_cmd_hdl(padapter, pcmd->parmbuf); - r8712_free_cmd_obj(pcmd); - pcmd_r = NULL; - break; - default: - pcmd_r = pcmd; - break; - } - return pcmd_r; /* if returning pcmd_r == NULL, pcmd must be free. */ -} - -u8 r8712_fw_cmd(struct _adapter *pAdapter, u32 cmd) -{ - int pollingcnts = 50; - - r8712_write32(pAdapter, IOCMD_CTRL_REG, cmd); - msleep(100); - while ((r8712_read32(pAdapter, IOCMD_CTRL_REG != 0)) && - (pollingcnts > 0)) { - pollingcnts--; - msleep(20); - } - if (pollingcnts == 0) - return false; - return true; -} - -void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag) -{ - if (flag == 0) /* set */ - r8712_write32(pAdapter, IOCMD_DATA_REG, *value); - else /* query */ - *value = r8712_read32(pAdapter, IOCMD_DATA_REG); -} - -int r8712_cmd_thread(void *context) -{ - struct cmd_obj *pcmd; - unsigned int cmdsz, wr_sz; - __le32 *pcmdbuf; - struct tx_desc *pdesc; - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct _adapter *padapter = context; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct completion *cmd_queue_comp = - &pcmdpriv->cmd_queue_comp; - struct mutex *pwctrl_lock = &padapter->pwrctrlpriv.mutex_lock; - - allow_signal(SIGTERM); - while (1) { - if (wait_for_completion_interruptible(cmd_queue_comp)) - break; - if (padapter->driver_stopped || padapter->surprise_removed) - break; - if (r8712_register_cmd_alive(padapter)) - continue; -_next: - pcmd = r8712_dequeue_cmd(&pcmdpriv->cmd_queue); - if (!(pcmd)) { - r8712_unregister_cmd_alive(padapter); - continue; - } - pcmdbuf = (__le32 *)pcmdpriv->cmd_buf; - pdesc = (struct tx_desc *)pcmdbuf; - memset(pdesc, 0, TXDESC_SIZE); - pcmd = cmd_hdl_filter(padapter, pcmd); - if (pcmd) { /* if pcmd != NULL, cmd will be handled by f/w */ - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - u8 blnPending = 0; - u16 cmdcode = pcmd->cmdcode; - - pcmdpriv->cmd_issued_cnt++; - cmdsz = round_up(pcmd->cmdsz, 8); - wr_sz = TXDESC_SIZE + 8 + cmdsz; - pdesc->txdw0 |= cpu_to_le32((wr_sz - TXDESC_SIZE) & - 0x0000ffff); - if (pdvobj->ishighspeed) { - if ((wr_sz % 512) == 0) - blnPending = 1; - } else { - if ((wr_sz % 64) == 0) - blnPending = 1; - } - if (blnPending) { /* 32 bytes for TX Desc - 8 offset */ - pdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + - OFFSET_SZ + 8) << OFFSET_SHT) & - 0x00ff0000); - } else { - pdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + - OFFSET_SZ) << - OFFSET_SHT) & - 0x00ff0000); - } - pdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); - pdesc->txdw1 |= cpu_to_le32((0x13 << QSEL_SHT) & - 0x00001f00); - pcmdbuf += (TXDESC_SIZE >> 2); - *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) | - (pcmd->cmdcode << 16) | - (pcmdpriv->cmd_seq << 24)); - pcmdbuf += 2; /* 8 bytes alignment */ - memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); - if (blnPending) - wr_sz += 8; /* Append 8 bytes */ - r8712_write_mem(padapter, RTL8712_DMA_H2CCMD, wr_sz, - (u8 *)pdesc); - pcmdpriv->cmd_seq++; - if (cmdcode == GEN_CMD_CODE(_CreateBss)) { - pcmd->res = H2C_SUCCESS; - pcmd_callback = cmd_callback[cmdcode].callback; - if (pcmd_callback) - pcmd_callback(padapter, pcmd); - continue; - } - if (cmdcode == GEN_CMD_CODE(_SetPwrMode)) { - if (padapter->pwrctrlpriv.bSleep) { - mutex_lock(pwctrl_lock); - r8712_set_rpwm(padapter, PS_STATE_S2); - mutex_unlock(pwctrl_lock); - } - } - r8712_free_cmd_obj(pcmd); - if (list_empty(&pcmdpriv->cmd_queue.queue)) { - r8712_unregister_cmd_alive(padapter); - continue; - } else { - goto _next; - } - } else { - goto _next; - } - flush_signals_thread(); - } - /* free all cmd_obj resources */ - do { - pcmd = r8712_dequeue_cmd(&pcmdpriv->cmd_queue); - if (!pcmd) - break; - r8712_free_cmd_obj(pcmd); - } while (1); - complete(&pcmdpriv->terminate_cmdthread_comp); - return 0; -} - -void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf) -{ - u8 evt_code, evt_seq; - u16 evt_sz; - void (*event_callback)(struct _adapter *dev, u8 *pbuf); - struct evt_priv *pevt_priv = &padapter->evtpriv; - - if (!peventbuf) - goto _abort_event_; - evt_sz = (u16)(le32_to_cpu(*peventbuf) & 0xffff); - evt_seq = (u8)((le32_to_cpu(*peventbuf) >> 24) & 0x7f); - evt_code = (u8)((le32_to_cpu(*peventbuf) >> 16) & 0xff); - /* checking event sequence... */ - if ((evt_seq & 0x7f) != pevt_priv->event_seq) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } - /* checking if event code is valid */ - if (evt_code >= MAX_C2HEVT) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } else if ((evt_code == GEN_EVT_CODE(_Survey)) && - (evt_sz > sizeof(struct wlan_bssid_ex))) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } - /* checking if event size match the event parm size */ - if ((wlanevents[evt_code].parmsize) && - (wlanevents[evt_code].parmsize != evt_sz)) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } else if ((evt_sz == 0) && (evt_code != GEN_EVT_CODE(_WPS_PBC))) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } - pevt_priv->event_seq++; /* update evt_seq */ - if (pevt_priv->event_seq > 127) - pevt_priv->event_seq = 0; - /* move to event content, 8 bytes alignment */ - peventbuf = peventbuf + 2; - event_callback = wlanevents[evt_code].event_callback; - if (event_callback) - event_callback(padapter, (u8 *)peventbuf); - pevt_priv->evt_done_cnt++; -_abort_event_: - return; -} diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h deleted file mode 100644 index a34d0dd023f33bbc4960bc6e720f2d3c31c71706..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmd.h +++ /dev/null @@ -1,231 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_CMD_H_ -#define __RTL8712_CMD_H_ - -#define CMD_HDR_SZ 8 - -u8 r8712_fw_cmd(struct _adapter *pAdapter, u32 cmd); -void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag); - -struct cmd_hdr { - u32 cmd_dw0; - u32 cmd_dw1; -}; - -enum rtl8712_h2c_cmd { - GEN_CMD_CODE(_Read_MACREG), /*0*/ - GEN_CMD_CODE(_Write_MACREG), - GEN_CMD_CODE(_Read_BBREG), - GEN_CMD_CODE(_Write_BBREG), - GEN_CMD_CODE(_Read_RFREG), - GEN_CMD_CODE(_Write_RFREG), /*5*/ - GEN_CMD_CODE(_Read_EEPROM), - GEN_CMD_CODE(_Write_EEPROM), - GEN_CMD_CODE(_Read_EFUSE), - GEN_CMD_CODE(_Write_EFUSE), - - GEN_CMD_CODE(_Read_CAM), /*10*/ - GEN_CMD_CODE(_Write_CAM), - GEN_CMD_CODE(_setBCNITV), - GEN_CMD_CODE(_setMBIDCFG), - GEN_CMD_CODE(_JoinBss), /*14*/ - GEN_CMD_CODE(_DisConnect), /*15*/ - GEN_CMD_CODE(_CreateBss), - GEN_CMD_CODE(_SetOpMode), - GEN_CMD_CODE(_SiteSurvey), /*18*/ - GEN_CMD_CODE(_SetAuth), - - GEN_CMD_CODE(_SetKey), /*20*/ - GEN_CMD_CODE(_SetStaKey), - GEN_CMD_CODE(_SetAssocSta), - GEN_CMD_CODE(_DelAssocSta), - GEN_CMD_CODE(_SetStaPwrState), - GEN_CMD_CODE(_SetBasicRate), /*25*/ - GEN_CMD_CODE(_GetBasicRate), - GEN_CMD_CODE(_SetDataRate), - GEN_CMD_CODE(_GetDataRate), - GEN_CMD_CODE(_SetPhyInfo), - - GEN_CMD_CODE(_GetPhyInfo), /*30*/ - GEN_CMD_CODE(_SetPhy), - GEN_CMD_CODE(_GetPhy), - GEN_CMD_CODE(_readRssi), - GEN_CMD_CODE(_readGain), - GEN_CMD_CODE(_SetAtim), /*35*/ - GEN_CMD_CODE(_SetPwrMode), - GEN_CMD_CODE(_JoinbssRpt), - GEN_CMD_CODE(_SetRaTable), - GEN_CMD_CODE(_GetRaTable), - - GEN_CMD_CODE(_GetCCXReport), /*40*/ - GEN_CMD_CODE(_GetDTMReport), - GEN_CMD_CODE(_GetTXRateStatistics), - GEN_CMD_CODE(_SetUsbSuspend), - GEN_CMD_CODE(_SetH2cLbk), - GEN_CMD_CODE(_AddBAReq), /*45*/ - - GEN_CMD_CODE(_SetChannel), /*46*/ -/* MP_OFFLOAD Start (47~54)*/ - GEN_CMD_CODE(_SetTxPower), - GEN_CMD_CODE(_SwitchAntenna), - GEN_CMD_CODE(_SetCrystalCap), - GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ - GEN_CMD_CODE(_SetSingleToneTx), - GEN_CMD_CODE(_SetCarrierSuppressionTx), - GEN_CMD_CODE(_SetContinuousTx), - GEN_CMD_CODE(_SwitchBandwidth), /*54*/ -/* MP_OFFLOAD End*/ - GEN_CMD_CODE(_TX_Beacon), /*55*/ - GEN_CMD_CODE(_SetPowerTracking), - GEN_CMD_CODE(_AMSDU_TO_AMPDU), /*57*/ - GEN_CMD_CODE(_SetMacAddress), /*58*/ - - GEN_CMD_CODE(_DisconnectCtrl), /*59*/ - GEN_CMD_CODE(_SetChannelPlan), /*60*/ - GEN_CMD_CODE(_DisconnectCtrlEx), /*61*/ - - /* To do, modify these h2c cmd, add or delete */ - GEN_CMD_CODE(_GetH2cLbk), - - /* WPS extra IE */ - GEN_CMD_CODE(_SetProbeReqExtraIE), - GEN_CMD_CODE(_SetAssocReqExtraIE), - GEN_CMD_CODE(_SetProbeRspExtraIE), - GEN_CMD_CODE(_SetAssocRspExtraIE), - - /* the following is driver will do */ - GEN_CMD_CODE(_GetCurDataRate), - - GEN_CMD_CODE(_GetTxRetrycnt), /* to record times that Tx retry to - * transmit packet after association - */ - GEN_CMD_CODE(_GetRxRetrycnt), /* to record total number of the - * received frame with ReTry bit set in - * the WLAN header - */ - - GEN_CMD_CODE(_GetBCNOKcnt), - GEN_CMD_CODE(_GetBCNERRcnt), - GEN_CMD_CODE(_GetCurTxPwrLevel), - - GEN_CMD_CODE(_SetDIG), - GEN_CMD_CODE(_SetRA), - GEN_CMD_CODE(_SetPT), - GEN_CMD_CODE(_ReadTSSI), - - MAX_H2CCMD -}; - -#define _GetBBReg_CMD_ _Read_BBREG_CMD_ -#define _SetBBReg_CMD_ _Write_BBREG_CMD_ -#define _GetRFReg_CMD_ _Read_RFREG_CMD_ -#define _SetRFReg_CMD_ _Write_RFREG_CMD_ -#define _DRV_INT_CMD_ (MAX_H2CCMD + 1) -#define _SetRFIntFs_CMD_ (MAX_H2CCMD + 2) - -#ifdef _RTL8712_CMD_C_ -static struct _cmd_callback cmd_callback[] = { - {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ - {GEN_CMD_CODE(_Write_MACREG), NULL}, - {GEN_CMD_CODE(_Read_BBREG), NULL}, - {GEN_CMD_CODE(_Write_BBREG), NULL}, - {GEN_CMD_CODE(_Read_RFREG), &r8712_getbbrfreg_cmdrsp_callback}, - {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ - {GEN_CMD_CODE(_Read_EEPROM), NULL}, - {GEN_CMD_CODE(_Write_EEPROM), NULL}, - {GEN_CMD_CODE(_Read_EFUSE), NULL}, - {GEN_CMD_CODE(_Write_EFUSE), NULL}, - - {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ - {GEN_CMD_CODE(_Write_CAM), NULL}, - {GEN_CMD_CODE(_setBCNITV), NULL}, - {GEN_CMD_CODE(_setMBIDCFG), NULL}, - {GEN_CMD_CODE(_JoinBss), &r8712_joinbss_cmd_callback}, /*14*/ - {GEN_CMD_CODE(_DisConnect), &r8712_disassoc_cmd_callback}, /*15*/ - {GEN_CMD_CODE(_CreateBss), &r8712_createbss_cmd_callback}, - {GEN_CMD_CODE(_SetOpMode), NULL}, - {GEN_CMD_CODE(_SiteSurvey), &r8712_survey_cmd_callback}, /*18*/ - {GEN_CMD_CODE(_SetAuth), NULL}, - - {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ - {GEN_CMD_CODE(_SetStaKey), &r8712_setstaKey_cmdrsp_callback}, - {GEN_CMD_CODE(_SetAssocSta), &r8712_setassocsta_cmdrsp_callback}, - {GEN_CMD_CODE(_DelAssocSta), NULL}, - {GEN_CMD_CODE(_SetStaPwrState), NULL}, - {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ - {GEN_CMD_CODE(_GetBasicRate), NULL}, - {GEN_CMD_CODE(_SetDataRate), NULL}, - {GEN_CMD_CODE(_GetDataRate), NULL}, - {GEN_CMD_CODE(_SetPhyInfo), NULL}, - - {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ - {GEN_CMD_CODE(_SetPhy), NULL}, - {GEN_CMD_CODE(_GetPhy), NULL}, - {GEN_CMD_CODE(_readRssi), NULL}, - {GEN_CMD_CODE(_readGain), NULL}, - {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ - {GEN_CMD_CODE(_SetPwrMode), NULL}, - {GEN_CMD_CODE(_JoinbssRpt), NULL}, - {GEN_CMD_CODE(_SetRaTable), NULL}, - {GEN_CMD_CODE(_GetRaTable), NULL}, - - {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ - {GEN_CMD_CODE(_GetDTMReport), NULL}, - {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, - {GEN_CMD_CODE(_SetUsbSuspend), NULL}, - {GEN_CMD_CODE(_SetH2cLbk), NULL}, - {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ - - {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ -/* MP_OFFLOAD Start (47~54)*/ - {GEN_CMD_CODE(_SetTxPower), NULL}, - {GEN_CMD_CODE(_SwitchAntenna), NULL}, - {GEN_CMD_CODE(_SetCrystalCap), NULL}, - {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ - {GEN_CMD_CODE(_SetSingleToneTx), NULL}, - {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, - {GEN_CMD_CODE(_SetContinuousTx), NULL}, - {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ -/* MP_OFFLOAD End*/ - {GEN_CMD_CODE(_TX_Beacon), NULL}, /*55*/ - {GEN_CMD_CODE(_SetPowerTracking), NULL}, - {GEN_CMD_CODE(_AMSDU_TO_AMPDU), NULL}, /*57*/ - {GEN_CMD_CODE(_SetMacAddress), NULL}, /*58*/ - - {GEN_CMD_CODE(_DisconnectCtrl), NULL}, /*59*/ - {GEN_CMD_CODE(_SetChannelPlan), NULL}, /*60*/ - {GEN_CMD_CODE(_DisconnectCtrlEx), NULL}, /*61*/ - - /* To do, modify these h2c cmd, add or delete */ - {GEN_CMD_CODE(_GetH2cLbk), NULL}, - - {_SetProbeReqExtraIE_CMD_, NULL}, - {_SetAssocReqExtraIE_CMD_, NULL}, - {_SetProbeRspExtraIE_CMD_, NULL}, - {_SetAssocRspExtraIE_CMD_, NULL}, - {_GetCurDataRate_CMD_, NULL}, - {_GetTxRetrycnt_CMD_, NULL}, - {_GetRxRetrycnt_CMD_, NULL}, - {_GetBCNOKcnt_CMD_, NULL}, - {_GetBCNERRcnt_CMD_, NULL}, - {_GetCurTxPwrLevel_CMD_, NULL}, - {_SetDIG_CMD_, NULL}, - {_SetRA_CMD_, NULL}, - {_SetPT_CMD_, NULL}, - {GEN_CMD_CODE(_ReadTSSI), &r8712_readtssi_cmdrsp_callback} -}; -#endif - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h deleted file mode 100644 index 68bdec07f51e855846845674dc1bb9b814a6127c..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_CMDCTRL_BITDEF_H__ -#define __RTL8712_CMDCTRL_BITDEF_H__ - -/* - * 2. Command Control Registers (Offset: 0x0040 - 0x004F) - */ -/*--------------------------------------------------------------------------*/ -/* 8192S (CMD) command register bits (Offset 0x40, 16 bits)*/ -/*--------------------------------------------------------------------------*/ -#define _APSDOFF_STATUS BIT(15) -#define _APSDOFF BIT(14) -#define _BBRSTn BIT(13) /*Enable OFDM/CCK*/ -#define _BB_GLB_RSTn BIT(12) /*Enable BB*/ -#define _SCHEDULE_EN BIT(10) /*Enable MAC scheduler*/ -#define _MACRXEN BIT(9) -#define _MACTXEN BIT(8) -#define _DDMA_EN BIT(7) /*FW off load function enable*/ -#define _FW2HW_EN BIT(6) /*MAC every module reset */ -#define _RXDMA_EN BIT(5) -#define _TXDMA_EN BIT(4) -#define _HCI_RXDMA_EN BIT(3) -#define _HCI_TXDMA_EN BIT(2) - -/*TXPAUSE*/ -#define _STOPHCCA BIT(6) -#define _STOPHIGH BIT(5) -#define _STOPMGT BIT(4) -#define _STOPVO BIT(3) -#define _STOPVI BIT(2) -#define _STOPBE BIT(1) -#define _STOPBK BIT(0) - -/*TCR*/ -#define _DISCW BIT(20) -#define _ICV BIT(19) -#define _CFEND_FMT BIT(17) -#define _CRC BIT(16) -#define _FWRDY BIT(7) -#define _BASECHG BIT(6) -#define _IMEM_RDY BIT(5) -#define _DMEM_CODE_DONE BIT(4) -#define _EMEM_CHK_RPT BIT(3) -#define _EMEM_CODE_DONE BIT(2) -#define _IMEM_CHK_RPT BIT(1) -#define _IMEM_CODE_DONE BIT(0) - -#define _TXDMA_INIT_VALUE (_IMEM_CHK_RPT | _EMEM_CHK_RPT) - -/*RCR*/ -#define _ENMBID BIT(27) -#define _APP_PHYST_RXFF BIT(25) -#define _APP_PHYST_STAFF BIT(24) -#define _CBSSID BIT(23) -#define _APWRMGT BIT(22) -#define _ADD3 BIT(21) -#define _AMF BIT(20) -#define _ACF BIT(19) -#define _ADF BIT(18) -#define _APP_MIC BIT(17) -#define _APP_ICV BIT(16) -#define _RXFTH_MSK 0x0000E000 -#define _RXFTH_SHT 13 -#define _AICV BIT(12) -#define _RXPKTLMT_MSK 0x00000FC0 -#define _RXPKTLMT_SHT 6 -#define _ACRC32 BIT(5) -#define _AB BIT(3) -#define _AM BIT(2) -#define _APM BIT(1) -#define _AAP BIT(0) - -/*MSR*/ -#define _NETTYPE_MSK 0x03 -#define _NETTYPE_SHT 0 - -/*BT*/ -#define _BTMODE_MSK 0x06 -#define _BTMODE_SHT 1 -#define _ENBT BIT(0) - -/*MBIDCTRL*/ -#define _ENMBID_MODE BIT(15) -#define _BCNNO_MSK 0x7000 -#define _BCNNO_SHT 12 -#define _BCNSPACE_MSK 0x0FFF -#define _BCNSPACE_SHT 0 - -#endif /* __RTL8712_CMDCTRL_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h deleted file mode 100644 index fc67771c89b7851e01769eda3bb1f7ce200be9c5..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_CMDCTRL_REGDEF_H__ -#define __RTL8712_CMDCTRL_REGDEF_H__ - -#define CR (RTL8712_CMDCTRL_ + 0x0000) -#define TXPAUSE (RTL8712_CMDCTRL_ + 0x0002) -#define TCR (RTL8712_CMDCTRL_ + 0x0004) -#define RCR (RTL8712_CMDCTRL_ + 0x0008) -#define MSR (RTL8712_CMDCTRL_ + 0x000C) -#define SYSF_CFG (RTL8712_CMDCTRL_ + 0x000D) -#define MBIDCTRL (RTL8712_CMDCTRL_ + 0x000E) - -#endif /* __RTL8712_CMDCTRL_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h deleted file mode 100644 index bb3863467f0d67951b03b1edc47135179805eae8..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_DEBUGCTRL_BITDEF_H__ -#define __RTL8712_DEBUGCTRL_BITDEF_H__ - -/*BIST*/ -#define _BIST_RST BIT(0) - -/*LMS*/ -#define _LMS_MSK 0x03 - -/*WDG_CTRL*/ -#define _OVSEL_MSK 0x0600 -#define _OVSEL_SHT 9 -#define _WDGCLR BIT(8) -#define _WDGEN_MSK 0x00FF -#define _WDGEN_SHT 0 - -/*INTM*/ -#define _TXTIMER_MSK 0xF000 -#define _TXTIMER_SHT 12 -#define _TXNUM_MSK 0x0F00 -#define _TXNUM_SHT 8 -#define _RXTIMER_MSK 0x00F0 -#define _RXTIMER_SHT 4 -#define _RXNUM_MSK 0x000F -#define _RXNUM_SHT 0 - -/*FDLOCKTURN0*/ -/*FDLOCKTURN1*/ -#define _TURN1 BIT(0) - -/*FDLOCKFLAG0*/ -/*FDLOCKFLAG1*/ -#define _LOCKFLAG1_MSK 0x03 - -#endif /* __RTL8712_DEBUGCTRL_BITDEF_H__ */ diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h deleted file mode 100644 index 319220e9d53de3f0111893b396c66ea80988b19e..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_DEBUGCTRL_REGDEF_H__ -#define __RTL8712_DEBUGCTRL_REGDEF_H__ - -#define BIST (RTL8712_DEBUGCTRL_ + 0x00) -#define DBS (RTL8712_DEBUGCTRL_ + 0x04) -#define LMS (RTL8712_DEBUGCTRL_ + 0x05) -#define CPUINST (RTL8712_DEBUGCTRL_ + 0x08) -#define CPUCAUSE (RTL8712_DEBUGCTRL_ + 0x0C) -#define LBUS_ERR_ADDR (RTL8712_DEBUGCTRL_ + 0x10) -#define LBUS_ERR_CMD (RTL8712_DEBUGCTRL_ + 0x14) -#define LBUS_ERR_DATA_L (RTL8712_DEBUGCTRL_ + 0x18) -#define LBUS_ERR_DATA_H (RTL8712_DEBUGCTRL_ + 0x1C) -#define LBUS_EXCEPTION_ADDR (RTL8712_DEBUGCTRL_ + 0x20) -#define WDG_CTRL (RTL8712_DEBUGCTRL_ + 0x24) -#define INTMTU (RTL8712_DEBUGCTRL_ + 0x28) -#define INTM (RTL8712_DEBUGCTRL_ + 0x2A) -#define FDLOCKTURN0 (RTL8712_DEBUGCTRL_ + 0x2C) -#define FDLOCKTURN1 (RTL8712_DEBUGCTRL_ + 0x2D) -#define FDLOCKFLAG0 (RTL8712_DEBUGCTRL_ + 0x2E) -#define FDLOCKFLAG1 (RTL8712_DEBUGCTRL_ + 0x2F) -#define TRXPKTBUF_DBG_DATA (RTL8712_DEBUGCTRL_ + 0x30) -#define TRXPKTBUF_DBG_CTRL (RTL8712_DEBUGCTRL_ + 0x38) -#define DPLL_MON (RTL8712_DEBUGCTRL_ + 0x3A) - -#endif /* __RTL8712_DEBUGCTRL_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h deleted file mode 100644 index 9048d6a6529697ddd9b71f1ac811497afd550402..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_EDCASETTING_BITDEF_H__ -#define __RTL8712_EDCASETTING_BITDEF_H__ - -/*EDCAPARAM*/ -#define _TXOPLIMIT_MSK 0xFFFF0000 -#define _TXOPLIMIT_SHT 16 -#define _ECWIN_MSK 0x0000FF00 -#define _ECWIN_SHT 8 -#define _AIFS_MSK 0x000000FF -#define _AIFS_SHT 0 - -/*BCNTCFG*/ -#define _BCNECW_MSK 0xFF00 -#define _BCNECW_SHT 8 -#define _BCNIFS_MSK 0x00FF -#define _BCNIFS_SHT 0 - -/*CWRR*/ -#define _CWRR_MSK 0x03FF - -/*ACMAVG*/ -#define _AVG_TIME_UP BIT(3) -#define _AVGPERIOD_MSK 0x03 - -/*ACMHWCTRL*/ -#define _VOQ_ACM_STATUS BIT(6) -#define _VIQ_ACM_STATUS BIT(5) -#define _BEQ_ACM_STATUS BIT(4) -#define _VOQ_ACM_EN BIT(3) -#define _VIQ_ACM_EN BIT(2) -#define _BEQ_ACM_EN BIT(1) -#define _ACMHWEN BIT(0) - -/*VO_ADMTIME*/ -#define _VO_ACM_RUT BIT(18) -#define _VO_ADMTIME_MSK 0x0003FFF - -/*VI_ADMTIME*/ -#define _VI_ACM_RUT BIT(18) -#define _VI_ADMTIME_MSK 0x0003FFF - -/*BE_ADMTIME*/ -#define _BE_ACM_RUT BIT(18) -#define _BE_ADMTIME_MSK 0x0003FFF - -/*Retry limit reg*/ -#define _SRL_MSK 0xFF00 -#define _SRL_SHT 8 -#define _LRL_MSK 0x00FF -#define _LRL_SHT 0 - -#endif /* __RTL8712_EDCASETTING_BITDEF_H__*/ diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h deleted file mode 100644 index 02ec9f3bba6659774eaa6eacbab93ad852ae4d5a..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_EDCASETTING_REGDEF_H__ -#define __RTL8712_EDCASETTING_REGDEF_H__ - -#define EDCA_VO_PARAM (RTL8712_EDCASETTING_ + 0x00) -#define EDCA_VI_PARAM (RTL8712_EDCASETTING_ + 0x04) -#define EDCA_BE_PARAM (RTL8712_EDCASETTING_ + 0x08) -#define EDCA_BK_PARAM (RTL8712_EDCASETTING_ + 0x0C) -#define BCNTCFG (RTL8712_EDCASETTING_ + 0x10) -#define CWRR (RTL8712_EDCASETTING_ + 0x12) -#define ACMAVG (RTL8712_EDCASETTING_ + 0x16) -#define ACMHWCTRL (RTL8712_EDCASETTING_ + 0x17) -#define VO_ADMTIME (RTL8712_EDCASETTING_ + 0x18) -#define VI_ADMTIME (RTL8712_EDCASETTING_ + 0x1C) -#define BE_ADMTIME (RTL8712_EDCASETTING_ + 0x20) -#define RL (RTL8712_EDCASETTING_ + 0x24) - -#endif /* __RTL8712_EDCASETTING_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c deleted file mode 100644 index a39d6c06648f5d7dc4a286ce71cf120c4b649baf..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ /dev/null @@ -1,563 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rtl8712_efuse.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_EFUSE_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl8712_efuse.h" - -/* reserve 3 bytes for HW stop read */ -static int efuse_available_max_size = EFUSE_MAX_SIZE - 3 /*0x1FD*/; - -static void efuse_reg_ctrl(struct _adapter *adapter, u8 bPowerOn) -{ - u8 tmpu8 = 0; - - if (bPowerOn) { - /* -----------------e-fuse pwr & clk reg ctrl --------------- - * Enable LDOE25 Macro Block - */ - tmpu8 = r8712_read8(adapter, EFUSE_TEST + 3); - tmpu8 |= 0x80; - r8712_write8(adapter, EFUSE_TEST + 3, tmpu8); - msleep(20); /* for some platform , need some delay time */ - /* Change Efuse Clock for write action to 40MHZ */ - r8712_write8(adapter, EFUSE_CLK_CTRL, 0x03); - msleep(20); /* for some platform , need some delay time */ - } else { - /* -----------------e-fuse pwr & clk reg ctrl ----------------- - * Disable LDOE25 Macro Block - */ - tmpu8 = r8712_read8(adapter, EFUSE_TEST + 3); - tmpu8 &= 0x7F; - r8712_write8(adapter, EFUSE_TEST + 3, tmpu8); - /* Change Efuse Clock for write action to 500K */ - r8712_write8(adapter, EFUSE_CLK_CTRL, 0x02); - } -} - -/* - * Before write E-Fuse, this function must be called. - */ -u8 r8712_efuse_reg_init(struct _adapter *adapter) -{ - return true; -} - -void r8712_efuse_reg_uninit(struct _adapter *adapter) -{ - efuse_reg_ctrl(adapter, false); -} - -static u8 efuse_one_byte_read(struct _adapter *adapter, u16 addr, u8 *data) -{ - u8 tmpidx = 0, bResult; - - /* -----------------e-fuse reg ctrl --------------------------------- */ - r8712_write8(adapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */ - r8712_write8(adapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | - (r8712_read8(adapter, EFUSE_CTRL + 2) & 0xFC)); - r8712_write8(adapter, EFUSE_CTRL + 3, 0x72); /* read cmd */ - /* wait for complete */ - while (!(0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) { - *data = r8712_read8(adapter, EFUSE_CTRL); - bResult = true; - } else { - *data = 0xff; - bResult = false; - } - return bResult; -} - -static u8 efuse_one_byte_write(struct _adapter *adapter, u16 addr, u8 data) -{ - u8 tmpidx = 0, bResult; - - /* -----------------e-fuse reg ctrl -------------------------------- */ - r8712_write8(adapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */ - r8712_write8(adapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | - (r8712_read8(adapter, EFUSE_CTRL + 2) & 0xFC)); - r8712_write8(adapter, EFUSE_CTRL, data); /* data */ - r8712_write8(adapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */ - /* wait for complete */ - while ((0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) - bResult = true; - else - bResult = false; - return bResult; -} - -static u8 efuse_one_byte_rw(struct _adapter *adapter, u8 bRead, u16 addr, - u8 *data) -{ - u8 tmpidx = 0, tmpv8 = 0, bResult; - - /* -----------------e-fuse reg ctrl --------------------------------- */ - r8712_write8(adapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */ - tmpv8 = ((u8)((addr >> 8) & 0x03)) | - (r8712_read8(adapter, EFUSE_CTRL + 2) & 0xFC); - r8712_write8(adapter, EFUSE_CTRL + 2, tmpv8); - if (bRead) { - r8712_write8(adapter, EFUSE_CTRL + 3, 0x72); /* read cmd */ - while (!(0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) { - *data = r8712_read8(adapter, EFUSE_CTRL); - bResult = true; - } else { - *data = 0; - bResult = false; - } - } else { - r8712_write8(adapter, EFUSE_CTRL, *data); /* data */ - r8712_write8(adapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */ - while ((0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) - bResult = true; - else - bResult = false; - } - return bResult; -} - -static u8 efuse_is_empty(struct _adapter *adapter, u8 *empty) -{ - u8 value, ret = true; - - /* read one byte to check if E-Fuse is empty */ - if (efuse_one_byte_rw(adapter, true, 0, &value)) { - if (value == 0xFF) - *empty = true; - else - *empty = false; - } else { - ret = false; - } - return ret; -} - -void r8712_efuse_change_max_size(struct _adapter *adapter) -{ - u16 pre_pg_data_saddr = 0x1FB; - u16 i; - u16 pre_pg_data_size = 5; - u8 pre_pg_data[5]; - - for (i = 0; i < pre_pg_data_size; i++) - efuse_one_byte_read(adapter, pre_pg_data_saddr + i, - &pre_pg_data[i]); - if ((pre_pg_data[0] == 0x03) && (pre_pg_data[1] == 0x00) && - (pre_pg_data[2] == 0x00) && (pre_pg_data[3] == 0x00) && - (pre_pg_data[4] == 0x0C)) - efuse_available_max_size -= pre_pg_data_size; -} - -int r8712_efuse_get_max_size(struct _adapter *adapter) -{ - return efuse_available_max_size; -} - -static u8 calculate_word_cnts(const u8 word_en) -{ - u8 word_cnts = 0; - u8 word_idx; - - for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++) - if (!(word_en & BIT(word_idx))) - word_cnts++; /* 0 : write enable */ - return word_cnts; -} - -static void pgpacket_copy_data(const u8 word_en, const u8 *sourdata, - u8 *targetdata) -{ - u8 tmpindex = 0; - u8 word_idx, byte_idx; - - for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++) { - if (!(word_en & BIT(word_idx))) { - byte_idx = word_idx * 2; - targetdata[byte_idx] = sourdata[tmpindex++]; - targetdata[byte_idx + 1] = sourdata[tmpindex++]; - } - } -} - -u16 r8712_efuse_get_current_size(struct _adapter *adapter) -{ - int bContinual = true; - u16 efuse_addr = 0; - u8 hworden = 0; - u8 efuse_data, word_cnts = 0; - - while (bContinual && efuse_one_byte_read(adapter, efuse_addr, &efuse_data) && - (efuse_addr < efuse_available_max_size)) { - if (efuse_data != 0xFF) { - hworden = efuse_data & 0x0F; - word_cnts = calculate_word_cnts(hworden); - /* read next header */ - efuse_addr = efuse_addr + (word_cnts * 2) + 1; - } else { - bContinual = false; - } - } - return efuse_addr; -} - -u8 r8712_efuse_pg_packet_read(struct _adapter *adapter, u8 offset, u8 *data) -{ - u8 hoffset = 0, hworden = 0, word_cnts = 0; - u16 efuse_addr = 0; - u8 efuse_data; - u8 tmpidx = 0; - u8 tmpdata[PGPKT_DATA_SIZE]; - u8 ret = true; - - if (!data) - return false; - if (offset > 0x0f) - return false; - memset(data, 0xFF, sizeof(u8) * PGPKT_DATA_SIZE); - while (efuse_addr < efuse_available_max_size) { - if (efuse_one_byte_read(adapter, efuse_addr, &efuse_data)) { - if (efuse_data == 0xFF) - break; - hoffset = (efuse_data >> 4) & 0x0F; - hworden = efuse_data & 0x0F; - word_cnts = calculate_word_cnts(hworden); - if (hoffset == offset) { - memset(tmpdata, 0xFF, PGPKT_DATA_SIZE); - for (tmpidx = 0; tmpidx < word_cnts * 2; - tmpidx++) { - if (efuse_one_byte_read(adapter, efuse_addr + 1 + tmpidx, - &efuse_data)) { - tmpdata[tmpidx] = efuse_data; - } else { - ret = false; - } - } - pgpacket_copy_data(hworden, tmpdata, data); - } - efuse_addr += 1 + (word_cnts * 2); - } else { - ret = false; - break; - } - } - return ret; -} - -static u8 fix_header(struct _adapter *adapter, u8 header, u16 header_addr) -{ - struct PGPKT_STRUCT pkt; - u8 offset, word_en, value; - u16 addr; - int i; - u8 ret = true; - - pkt.offset = GET_EFUSE_OFFSET(header); - pkt.word_en = GET_EFUSE_WORD_EN(header); - addr = header_addr + 1 + calculate_word_cnts(pkt.word_en) * 2; - if (addr > efuse_available_max_size) - return false; - /* retrieve original data */ - addr = 0; - while (addr < header_addr) { - if (!efuse_one_byte_read(adapter, addr++, &value)) { - ret = false; - break; - } - offset = GET_EFUSE_OFFSET(value); - word_en = GET_EFUSE_WORD_EN(value); - if (pkt.offset != offset) { - addr += calculate_word_cnts(word_en) * 2; - continue; - } - for (i = 0; i < PGPKG_MAX_WORDS; i++) { - if (!(BIT(i) & word_en)) - continue; - if (BIT(i) & pkt.word_en) { - if (efuse_one_byte_read(adapter, - addr, - &value)) - pkt.data[i * 2] = value; - else - return false; - if (efuse_one_byte_read(adapter, - addr + 1, - &value)) - pkt.data[i * 2 + 1] = value; - else - return false; - } - addr += 2; - } - } - if (addr != header_addr) - return false; - addr++; - /* fill original data */ - for (i = 0; i < PGPKG_MAX_WORDS; i++) { - if (BIT(i) & pkt.word_en) { - efuse_one_byte_write(adapter, addr, pkt.data[i * 2]); - efuse_one_byte_write(adapter, addr + 1, - pkt.data[i * 2 + 1]); - /* additional check */ - if (!efuse_one_byte_read(adapter, addr, &value)) { - ret = false; - } else if (pkt.data[i * 2] != value) { - ret = false; - if (value == 0xFF) /* write again */ - efuse_one_byte_write(adapter, addr, - pkt.data[i * 2]); - } - if (!efuse_one_byte_read(adapter, addr + 1, &value)) { - ret = false; - } else if (pkt.data[i * 2 + 1] != value) { - ret = false; - if (value == 0xFF) /* write again */ - efuse_one_byte_write(adapter, addr + 1, - pkt.data[i * 2 + - 1]); - } - } - addr += 2; - } - return ret; -} - -u8 r8712_efuse_pg_packet_write(struct _adapter *adapter, const u8 offset, - const u8 word_en, const u8 *data) -{ - u8 pg_header = 0; - u16 efuse_addr = 0, curr_size = 0; - u8 efuse_data, target_word_cnts = 0; - int repeat_times; - int sub_repeat; - u8 bResult = true; - - /* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */ - efuse_data = r8712_read8(adapter, EFUSE_CLK_CTRL); - if (efuse_data != 0x03) - return false; - pg_header = MAKE_EFUSE_HEADER(offset, word_en); - target_word_cnts = calculate_word_cnts(word_en); - repeat_times = 0; - efuse_addr = 0; - while (efuse_addr < efuse_available_max_size) { - curr_size = r8712_efuse_get_current_size(adapter); - if ((curr_size + 1 + target_word_cnts * 2) > - efuse_available_max_size) - return false; /*target_word_cnts + pg header(1 byte)*/ - efuse_addr = curr_size; /* current size is also the last addr*/ - efuse_one_byte_write(adapter, efuse_addr, pg_header); /*hdr*/ - sub_repeat = 0; - /* check if what we read is what we write */ - while (!efuse_one_byte_read(adapter, efuse_addr, - &efuse_data)) { - if (++sub_repeat > _REPEAT_THRESHOLD_) { - bResult = false; /* continue to blind write */ - break; /* continue to blind write */ - } - } - if ((sub_repeat > _REPEAT_THRESHOLD_) || - (pg_header == efuse_data)) { - /* write header ok OR can't check header(creep) */ - u8 i; - - /* go to next address */ - efuse_addr++; - for (i = 0; i < target_word_cnts * 2; i++) { - efuse_one_byte_write(adapter, - efuse_addr + i, - *(data + i)); - if (!efuse_one_byte_read(adapter, - efuse_addr + i, - &efuse_data)) - bResult = false; - else if (*(data + i) != efuse_data) /* fail */ - bResult = false; - } - break; - } - /* write header fail */ - bResult = false; - if (efuse_data == 0xFF) - return bResult; /* nothing damaged. */ - /* call rescue procedure */ - if (!fix_header(adapter, efuse_data, efuse_addr)) - return false; /* rescue fail */ - - if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */ - break; - /* otherwise, take another risk... */ - } - return bResult; -} - -u8 r8712_efuse_access(struct _adapter *adapter, u8 bRead, u16 start_addr, - u16 cnts, u8 *data) -{ - int i; - u8 res = true; - - if (start_addr > EFUSE_MAX_SIZE) - return false; - if (!bRead && ((start_addr + cnts) > - efuse_available_max_size)) - return false; - if (!bRead && !r8712_efuse_reg_init(adapter)) - return false; - /* -----------------e-fuse one byte read / write ---------------------*/ - for (i = 0; i < cnts; i++) { - if ((start_addr + i) > EFUSE_MAX_SIZE) { - res = false; - break; - } - res = efuse_one_byte_rw(adapter, bRead, start_addr + i, - data + i); - if (!bRead && !res) - break; - } - if (!bRead) - r8712_efuse_reg_uninit(adapter); - return res; -} - -u8 r8712_efuse_map_read(struct _adapter *adapter, u16 addr, u16 cnts, u8 *data) -{ - u8 offset, ret = true; - u8 pktdata[PGPKT_DATA_SIZE]; - int i, idx; - - if ((addr + cnts) > EFUSE_MAP_MAX_SIZE) - return false; - if (efuse_is_empty(adapter, &offset) && offset) { - for (i = 0; i < cnts; i++) - data[i] = 0xFF; - return ret; - } - offset = (addr >> 3) & 0xF; - ret = r8712_efuse_pg_packet_read(adapter, offset, pktdata); - i = addr & 0x7; /* pktdata index */ - idx = 0; /* data index */ - - do { - for (; i < PGPKT_DATA_SIZE; i++) { - data[idx++] = pktdata[i]; - if (idx == cnts) - return ret; - } - offset++; - if (!r8712_efuse_pg_packet_read(adapter, offset, pktdata)) - ret = false; - i = 0; - } while (1); - return ret; -} - -u8 r8712_efuse_map_write(struct _adapter *adapter, u16 addr, u16 cnts, - u8 *data) -{ - u8 offset, word_en, empty; - u8 pktdata[PGPKT_DATA_SIZE], newdata[PGPKT_DATA_SIZE]; - int i, j, idx; - - if ((addr + cnts) > EFUSE_MAP_MAX_SIZE) - return false; - /* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */ - empty = r8712_read8(adapter, EFUSE_CLK_CTRL); - if (empty != 0x03) - return false; - if (efuse_is_empty(adapter, &empty)) { - if (empty) - memset(pktdata, 0xFF, PGPKT_DATA_SIZE); - } else { - return false; - } - offset = (addr >> 3) & 0xF; - if (!empty) - if (!r8712_efuse_pg_packet_read(adapter, offset, pktdata)) - return false; - word_en = 0xF; - memset(newdata, 0xFF, PGPKT_DATA_SIZE); - i = addr & 0x7; /* pktdata index */ - j = 0; /* newdata index */ - idx = 0; /* data index */ - - if (i & 0x1) { - /* odd start */ - if (data[idx] != pktdata[i]) { - word_en &= ~BIT(i >> 1); - newdata[j++] = pktdata[i - 1]; - newdata[j++] = data[idx]; - } - i++; - idx++; - } - do { - for (; i < PGPKT_DATA_SIZE; i += 2) { - if ((cnts - idx) == 1) { - if (data[idx] != pktdata[i]) { - word_en &= ~BIT(i >> 1); - newdata[j++] = data[idx]; - newdata[j++] = pktdata[1 + 1]; - } - idx++; - break; - } - - if ((data[idx] != pktdata[i]) || (data[idx + 1] != - pktdata[i + 1])) { - word_en &= ~BIT(i >> 1); - newdata[j++] = data[idx]; - newdata[j++] = data[idx + 1]; - } - idx += 2; - - if (idx == cnts) - break; - } - - if (word_en != 0xF) - if (!r8712_efuse_pg_packet_write(adapter, offset, - word_en, newdata)) - return false; - if (idx == cnts) - break; - offset++; - if (!empty) - if (!r8712_efuse_pg_packet_read(adapter, offset, - pktdata)) - return false; - i = 0; - j = 0; - word_en = 0xF; - memset(newdata, 0xFF, PGPKT_DATA_SIZE); - } while (1); - - return true; -} diff --git a/drivers/staging/rtl8712/rtl8712_efuse.h b/drivers/staging/rtl8712/rtl8712_efuse.h deleted file mode 100644 index 7a49740212eb5c1f78d1faa1ad78f7b407a0b4ed..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_efuse.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __RTL8712_EFUSE_H__ -#define __RTL8712_EFUSE_H__ - -#include "osdep_service.h" - -#define _REPEAT_THRESHOLD_ 3 - -#define EFUSE_MAX_SIZE 512 -#define EFUSE_MAP_MAX_SIZE 128 - -#define PGPKG_MAX_WORDS 4 -#define PGPKT_DATA_SIZE 8 /* PGPKG_MAX_WORDS*2; BYTES sizeof(u8)*8*/ -#define MAX_PGPKT_SIZE 9 /* 1 + PGPKT_DATA_SIZE; header + 2 * 4 words (BYTES)*/ - -#define GET_EFUSE_OFFSET(header) ((header & 0xF0) >> 4) -#define GET_EFUSE_WORD_EN(header) (header & 0x0F) -#define MAKE_EFUSE_HEADER(offset, word_en) ((((offset) & 0x0F) << 4) | \ - ((word_en) & 0x0F)) -/*--------------------------------------------------------------------------*/ -struct PGPKT_STRUCT { - u8 offset; - u8 word_en; - u8 data[PGPKT_DATA_SIZE]; -}; - -/*--------------------------------------------------------------------------*/ -u8 r8712_efuse_reg_init(struct _adapter *padapter); -void r8712_efuse_reg_uninit(struct _adapter *padapter); -u16 r8712_efuse_get_current_size(struct _adapter *padapter); -int r8712_efuse_get_max_size(struct _adapter *padapter); -void r8712_efuse_change_max_size(struct _adapter *padapter); -u8 r8712_efuse_pg_packet_read(struct _adapter *padapter, - u8 offset, u8 *data); -u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, - const u8 offset, const u8 word_en, - const u8 *data); -u8 r8712_efuse_access(struct _adapter *padapter, u8 bRead, - u16 start_addr, u16 cnts, u8 *data); -u8 r8712_efuse_map_read(struct _adapter *padapter, u16 addr, - u16 cnts, u8 *data); -u8 r8712_efuse_map_write(struct _adapter *padapter, u16 addr, - u16 cnts, u8 *data); -#endif diff --git a/drivers/staging/rtl8712/rtl8712_event.h b/drivers/staging/rtl8712/rtl8712_event.h deleted file mode 100644 index 0d3e5feadcc01027d5b8106b200a4b976c5e49d5..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_event.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL8712_EVENT_H_ -#define _RTL8712_EVENT_H_ - -void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf); -void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf); - -enum rtl8712_c2h_event { - GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/ - GEN_EVT_CODE(_Read_BBREG), - GEN_EVT_CODE(_Read_RFREG), - GEN_EVT_CODE(_Read_EEPROM), - GEN_EVT_CODE(_Read_EFUSE), - GEN_EVT_CODE(_Read_CAM), /*5*/ - GEN_EVT_CODE(_Get_BasicRate), - GEN_EVT_CODE(_Get_DataRate), - GEN_EVT_CODE(_Survey), /*8*/ - GEN_EVT_CODE(_SurveyDone), /*9*/ - - GEN_EVT_CODE(_JoinBss), /*10*/ - GEN_EVT_CODE(_AddSTA), - GEN_EVT_CODE(_DelSTA), - GEN_EVT_CODE(_AtimDone), - GEN_EVT_CODE(_TX_Report), - GEN_EVT_CODE(_CCX_Report), /*15*/ - GEN_EVT_CODE(_DTM_Report), - GEN_EVT_CODE(_TX_Rate_Statistics), - GEN_EVT_CODE(_C2HLBK), - GEN_EVT_CODE(_FWDBG), - GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ - GEN_EVT_CODE(_ADDBA), - GEN_EVT_CODE(_C2HBCN), - GEN_EVT_CODE(_ReportPwrState), /*filen: only for PCIE, USB*/ - GEN_EVT_CODE(_WPS_PBC), /*24*/ - GEN_EVT_CODE(_ADDBAReq_Report), /*25*/ - MAX_C2HEVT -}; - -#ifdef _RTL8712_CMD_C_ - -static struct fwevent wlanevents[] = { - {0, NULL}, /*0*/ - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, &r8712_survey_event_callback}, /*8*/ - {sizeof(struct surveydone_event), - &r8712_surveydone_event_callback}, /*9*/ - - {0, &r8712_joinbss_event_callback}, /*10*/ - {sizeof(struct stassoc_event), &r8712_stassoc_event_callback}, - {sizeof(struct stadel_event), &r8712_stadel_event_callback}, - {0, &r8712_atimdone_event_callback}, - {0, NULL}, - {0, NULL}, /*15*/ - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, /*fwdbg_event_callback},*/ - {0, NULL}, /*20*/ - {0, NULL}, - {0, NULL}, - {0, &r8712_cpwm_event_callback}, - {0, &r8712_wpspbc_event_callback}, - {0, &r8712_got_addbareq_event_callback}, -}; - -#endif/*_RTL8712_CMD_C_*/ - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h deleted file mode 100644 index f09645fa1886e44de061ab6b752bceb2ca38bc51..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_FIFOCTRL_BITDEF_H__ -#define __RTL8712_FIFOCTRL_BITDEF_H__ - -/*PBP*/ -#define _PSTX_MSK 0xF0 -#define _PSTX_SHT 4 -#define _PSRX_MSK 0x0F -#define _PSRX_SHT 0 - -/*TXFF_STATUS*/ -#define _TXSTATUS_OVF BIT(15) - -/*RXFF_STATUS*/ -#define _STATUSFF1_OVF BIT(7) -#define _STATUSFF1_EMPTY BIT(6) -#define _STATUSFF0_OVF BIT(5) -#define _STATUSFF0_EMPTY BIT(4) -#define _RXFF1_OVF BIT(3) -#define _RXFF1_EMPTY BIT(2) -#define _RXFF0_OVF BIT(1) -#define _RXFF0_EMPTY BIT(0) - -/*TXFF_EMPTY_TH*/ -#define _BKQ_EMPTY_TH_MSK 0x0F0000 -#define _BKQ_EMPTY_TH_SHT 16 -#define _BEQ_EMPTY_TH_MSK 0x00F000 -#define _BEQ_EMPTY_TH_SHT 12 -#define _VIQ_EMPTY_TH_MSK 0x000F00 -#define _VIQ_EMPTY_TH_SHT 8 -#define _VOQ_EMPTY_TH_MSK 0x0000F0 -#define _VOQ_EMPTY_TH_SHT 4 -#define _BMCQ_EMPTY_TH_MSK 0x00000F -#define _BMCQ_EMPTY_TH_SHT 0 - -/*SDIO_RX_BLKSZ*/ -#define _SDIO_RX_BLKSZ_MSK 0x07 - -/*RXDMA_CTRL*/ -#define _C2HFF_POLL BIT(4) -#define _RXPKT_POLL BIT(0) - -/*RXPKT_NUM*/ -#define _RXCMD_NUM_MSK 0xFF00 -#define _RXCMD_NUM_SHT 8 -#define _RXFF0_NUM_MSK 0x00FF -#define _RXFF0_NUM_SHT 0 - -/*FIFOPAGE2*/ -#define _PUB_AVAL_PG_MSK 0xFFFF0000 -#define _PUB_AVAL_PG_SHT 16 -#define _BCN_AVAL_PG_MSK 0x0000FFFF -#define _BCN_AVAL_PG_SHT 0 - -/*RX0PKTNUM*/ -#define _RXFF0_DEC_POLL BIT(15) -#define _RXFF0_PKT_DEC_NUM_MSK 0x3F00 -#define _RXFF0_PKT_DEC_NUM_SHT 8 -#define _RXFF0_PKTNUM_RPT_MSK 0x00FF -#define _RXFF0_PKTNUM_RPT_SHT 0 - -/*RX1PKTNUM*/ -#define _RXFF1_DEC_POLL BIT(15) -#define _RXFF1_PKT_DEC_NUM_MSK 0x3F00 -#define _RXFF1_PKT_DEC_NUM_SHT 8 -#define _RXFF1_PKTNUM_RPT_MSK 0x00FF -#define _RXFF1_PKTNUM_RPT_SHT 0 - -/*RXFLTMAP0*/ -#define _MGTFLT13EN BIT(13) -#define _MGTFLT12EN BIT(12) -#define _MGTFLT11EN BIT(11) -#define _MGTFLT10EN BIT(10) -#define _MGTFLT9EN BIT(9) -#define _MGTFLT8EN BIT(8) -#define _MGTFLT5EN BIT(5) -#define _MGTFLT4EN BIT(4) -#define _MGTFLT3EN BIT(3) -#define _MGTFLT2EN BIT(2) -#define _MGTFLT1EN BIT(1) -#define _MGTFLT0EN BIT(0) - -/*RXFLTMAP1*/ -#define _CTRLFLT15EN BIT(15) -#define _CTRLFLT14EN BIT(14) -#define _CTRLFLT13EN BIT(13) -#define _CTRLFLT12EN BIT(12) -#define _CTRLFLT11EN BIT(11) -#define _CTRLFLT10EN BIT(10) -#define _CTRLFLT9EN BIT(9) -#define _CTRLFLT8EN BIT(8) -#define _CTRLFLT7EN BIT(7) -#define _CTRLFLT6EN BIT(6) - -/*RXFLTMAP2*/ -#define _DATAFLT15EN BIT(15) -#define _DATAFLT14EN BIT(14) -#define _DATAFLT13EN BIT(13) -#define _DATAFLT12EN BIT(12) -#define _DATAFLT11EN BIT(11) -#define _DATAFLT10EN BIT(10) -#define _DATAFLT9EN BIT(9) -#define _DATAFLT8EN BIT(8) -#define _DATAFLT7EN BIT(7) -#define _DATAFLT6EN BIT(6) -#define _DATAFLT5EN BIT(5) -#define _DATAFLT4EN BIT(4) -#define _DATAFLT3EN BIT(3) -#define _DATAFLT2EN BIT(2) -#define _DATAFLT1EN BIT(1) -#define _DATAFLT0EN BIT(0) - -/*RXFLTMAP3*/ -#define _MESHAFLT1EN BIT(1) -#define _MESHAFLT0EN BIT(0) - -/*TXPKT_NUM_CTRL*/ -#define _TXPKTNUM_DEC BIT(8) -#define _TXPKTNUM_MSK 0x00FF -#define _TXPKTNUM_SHT 0 - -/*TXFF_PG_NUM*/ -#define _TXFF_PG_NUM_MSK 0x0FFF - -#endif /* __RTL8712_FIFOCTRL_BITDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h deleted file mode 100644 index 189fdeb16d7d31fb779f3ad4fd6499033b411b6f..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_FIFOCTRL_REGDEF_H__ -#define __RTL8712_FIFOCTRL_REGDEF_H__ - -#define RQPN (RTL8712_FIFOCTRL_ + 0x00) -#define RXFF_BNDY (RTL8712_FIFOCTRL_ + 0x0C) -#define RXRPT_BNDY (RTL8712_FIFOCTRL_ + 0x10) -#define TXPKTBUF_PGBNDY (RTL8712_FIFOCTRL_ + 0x14) -#define PBP (RTL8712_FIFOCTRL_ + 0x15) -#define RX_DRVINFO_SZ (RTL8712_FIFOCTRL_ + 0x16) -#define TXFF_STATUS (RTL8712_FIFOCTRL_ + 0x17) -#define RXFF_STATUS (RTL8712_FIFOCTRL_ + 0x18) -#define TXFF_EMPTY_TH (RTL8712_FIFOCTRL_ + 0x19) -#define SDIO_RX_BLKSZ (RTL8712_FIFOCTRL_ + 0x1C) -#define RXDMA_RXCTRL (RTL8712_FIFOCTRL_ + 0x1D) -#define RXPKT_NUM (RTL8712_FIFOCTRL_ + 0x1E) -#define RXPKT_NUM_C2H (RTL8712_FIFOCTRL_ + 0x1F) -#define C2HCMD_UDT_SIZE (RTL8712_FIFOCTRL_ + 0x20) -#define C2HCMD_UDT_ADDR (RTL8712_FIFOCTRL_ + 0x22) -#define FIFOPAGE2 (RTL8712_FIFOCTRL_ + 0x24) -#define FIFOPAGE1 (RTL8712_FIFOCTRL_ + 0x28) -#define FW_RSVD_PG_CTRL (RTL8712_FIFOCTRL_ + 0x30) -#define TXRPTFF_RDPTR (RTL8712_FIFOCTRL_ + 0x40) -#define TXRPTFF_WTPTR (RTL8712_FIFOCTRL_ + 0x44) -#define C2HFF_RDPTR (RTL8712_FIFOCTRL_ + 0x48) -#define C2HFF_WTPTR (RTL8712_FIFOCTRL_ + 0x4C) -#define RXFF0_RDPTR (RTL8712_FIFOCTRL_ + 0x50) -#define RXFF0_WTPTR (RTL8712_FIFOCTRL_ + 0x54) -#define RXFF1_RDPTR (RTL8712_FIFOCTRL_ + 0x58) -#define RXFF1_WTPTR (RTL8712_FIFOCTRL_ + 0x5C) -#define RXRPT0FF_RDPTR (RTL8712_FIFOCTRL_ + 0x60) -#define RXRPT0FF_WTPTR (RTL8712_FIFOCTRL_ + 0x64) -#define RXRPT1FF_RDPTR (RTL8712_FIFOCTRL_ + 0x68) -#define RXRPT1FF_WTPTR (RTL8712_FIFOCTRL_ + 0x6C) -#define RX0PKTNUM (RTL8712_FIFOCTRL_ + 0x72) -#define RX1PKTNUM (RTL8712_FIFOCTRL_ + 0x74) -#define RXFLTMAP0 (RTL8712_FIFOCTRL_ + 0x76) -#define RXFLTMAP1 (RTL8712_FIFOCTRL_ + 0x78) -#define RXFLTMAP2 (RTL8712_FIFOCTRL_ + 0x7A) -#define RXFLTMAP3 (RTL8712_FIFOCTRL_ + 0x7c) -#define TBDA (RTL8712_FIFOCTRL_ + 0x84) -#define THPDA (RTL8712_FIFOCTRL_ + 0x88) -#define TCDA (RTL8712_FIFOCTRL_ + 0x8C) -#define TMDA (RTL8712_FIFOCTRL_ + 0x90) -#define HDA (RTL8712_FIFOCTRL_ + 0x94) -#define TVODA (RTL8712_FIFOCTRL_ + 0x98) -#define TVIDA (RTL8712_FIFOCTRL_ + 0x9C) -#define TBEDA (RTL8712_FIFOCTRL_ + 0xA0) -#define TBKDA (RTL8712_FIFOCTRL_ + 0xA4) -#define RCDA (RTL8712_FIFOCTRL_ + 0xA8) -#define RDSA (RTL8712_FIFOCTRL_ + 0xAC) -#define TXPKT_NUM_CTRL (RTL8712_FIFOCTRL_ + 0xB0) -#define TXQ_PGADD (RTL8712_FIFOCTRL_ + 0xB3) -#define TXFF_PG_NUM (RTL8712_FIFOCTRL_ + 0xB4) - -#endif /* __RTL8712_FIFOCTRL_REGDEF_H__ */ diff --git a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h deleted file mode 100644 index ee651fb3fde3fce6114201fe024a68f75b981451..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_GP_BITDEF_H__ -#define __RTL8712_GP_BITDEF_H__ - -/*GPIO_CTRL*/ -#define _GPIO_MOD_MSK 0xFF000000 -#define _GPIO_MOD_SHT 24 -#define _GPIO_IO_SEL_MSK 0x00FF0000 -#define _GPIO_IO_SEL_SHT 16 -#define _GPIO_OUT_MSK 0x0000FF00 -#define _GPIO_OUT_SHT 8 -#define _GPIO_IN_MSK 0x000000FF -#define _GPIO_IN_SHT 0 - -/*SYS_PINMUX_CFG*/ -#define _GPIOSEL_MSK 0x0003 -#define _GPIOSEL_SHT 0 - -/*LED_CFG*/ -#define _LED1SV BIT(7) -#define _LED1CM_MSK 0x0070 -#define _LED1CM_SHT 4 -#define _LED0SV BIT(3) -#define _LED0CM_MSK 0x0007 -#define _LED0CM_SHT 0 - -/*PHY_REG*/ -#define _HST_RDRDY_SHT 0 -#define _HST_RDRDY_MSK 0xFF -#define _HST_RDRDY BIT(_HST_RDRDY_SHT) -#define _CPU_WTBUSY_SHT 1 -#define _CPU_WTBUSY_MSK 0xFF -#define _CPU_WTBUSY BIT(_CPU_WTBUSY_SHT) - -/* 11. General Purpose Registers (Offset: 0x02E0 - 0x02FF)*/ - -/* 8192S GPIO Config Setting (offset 0x2F1, 1 byte)*/ - -/*----------------------------------------------------------------------------*/ - -#define GPIOMUX_EN BIT(3) /* When this bit is set to "1", - * GPIO PINs will switch to MAC - * GPIO Function - */ -#define GPIOSEL_GPIO 0 /* UART or JTAG or pure GPIO*/ -#define GPIOSEL_PHYDBG 1 /* PHYDBG*/ -#define GPIOSEL_BT 2 /* BT_coex*/ -#define GPIOSEL_WLANDBG 3 /* WLANDBG*/ -#define GPIOSEL_GPIO_MASK (~(BIT(0) | BIT(1))) -/* HW Radio OFF switch (GPIO BIT) */ -#define HAL_8192S_HW_GPIO_OFF_BIT BIT(3) -#define HAL_8192S_HW_GPIO_OFF_MASK 0xF7 -#define HAL_8192S_HW_GPIO_WPS_BIT BIT(4) - -#endif /*__RTL8712_GP_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_gp_regdef.h b/drivers/staging/rtl8712/rtl8712_gp_regdef.h deleted file mode 100644 index 892a7fb1392355c9dd757011c05f708cfddb83ab..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_gp_regdef.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_GP_REGDEF_H__ -#define __RTL8712_GP_REGDEF_H__ - -#define PSTIMER (RTL8712_GP_ + 0x00) -#define TIMER1 (RTL8712_GP_ + 0x04) -#define TIMER2 (RTL8712_GP_ + 0x08) -#define GPIO_CTRL (RTL8712_GP_ + 0x0C) -#define GPIO_IO_SEL (RTL8712_GP_ + 0x0E) -#define GPIO_INTCTRL (RTL8712_GP_ + 0x10) -#define MAC_PINMUX_CTRL (RTL8712_GP_ + 0x11) -#define LEDCFG (RTL8712_GP_ + 0x12) -#define PHY_REG_RPT (RTL8712_GP_ + 0x13) -#define PHY_REG_DATA (RTL8712_GP_ + 0x14) - -#endif /*__RTL8712_GP_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h deleted file mode 100644 index 66cc4645e2d1c9692477c5e0b46d063c2344363d..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_hal.h +++ /dev/null @@ -1,142 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_HAL_H__ -#define __RTL8712_HAL_H__ - -enum _HW_VERSION { - RTL8712_FPGA, - RTL8712_1stCUT, /*A Cut (RTL8712_ASIC)*/ - RTL8712_2ndCUT, /*B Cut*/ - RTL8712_3rdCUT, /*C Cut*/ -}; - -enum _LOOPBACK_TYPE { - RTL8712_AIR_TRX = 0, - RTL8712_MAC_LBK, - RTL8712_BB_LBK, - RTL8712_MAC_FW_LBK = 4, - RTL8712_BB_FW_LBK = 8, -}; - -enum RTL871X_HCI_TYPE { - RTL8712_SDIO, - RTL8712_USB, -}; - -enum RTL8712_RF_CONFIG { - RTL8712_RF_1T1R, - RTL8712_RF_1T2R, - RTL8712_RF_2T2R -}; - -enum _RTL8712_HCI_TYPE_ { - RTL8712_HCI_TYPE_PCIE = 0x01, - RTL8712_HCI_TYPE_AP_PCIE = 0x81, - RTL8712_HCI_TYPE_USB = 0x02, - RTL8712_HCI_TYPE_92USB = 0x02, - RTL8712_HCI_TYPE_AP_USB = 0x82, - RTL8712_HCI_TYPE_72USB = 0x12, - RTL8712_HCI_TYPE_SDIO = 0x04, - RTL8712_HCI_TYPE_72SDIO = 0x14 -}; - -struct fw_priv { /*8-bytes alignment required*/ - /*--- long word 0 ----*/ - unsigned char signature_0; /*0x12: CE product, 0x92: IT product*/ - unsigned char signature_1; /*0x87: CE product, 0x81: IT product*/ - unsigned char hci_sel; /*0x81: PCI-AP, 01:PCIe, 02: 92S-U, 0x82: USB-AP, - * 0x12: 72S-U, 03:SDIO - */ - unsigned char chip_version; /*the same value as register value*/ - unsigned char customer_ID_0; /*customer ID low byte*/ - unsigned char customer_ID_1; /*customer ID high byte*/ - unsigned char rf_config; /*0x11: 1T1R, 0x12: 1T2R, 0x92: 1T2R turbo, - * 0x22: 2T2R - */ - unsigned char usb_ep_num; /* 4: 4EP, 6: 6EP, 11: 11EP*/ - /*--- long word 1 ----*/ - unsigned char regulatory_class_0; /*regulatory class bit map 0*/ - unsigned char regulatory_class_1; /*regulatory class bit map 1*/ - unsigned char regulatory_class_2; /*regulatory class bit map 2*/ - unsigned char regulatory_class_3; /*regulatory class bit map 3*/ - unsigned char rfintfs; /* 0:SWSI, 1:HWSI, 2:HWPI*/ - unsigned char def_nettype; - unsigned char turbo_mode; - unsigned char low_power_mode;/* 0: normal mode, 1: low power mode*/ - /*--- long word 2 ----*/ - unsigned char lbk_mode; /*0x00: normal, 0x03: MACLBK, 0x01: PHYLBK*/ - unsigned char mp_mode; /* 1: for MP use, 0: for normal driver */ - unsigned char vcs_type; /* 0:off 1:on 2:auto */ - unsigned char vcs_mode; /* 1:RTS/CTS 2:CTS to self */ - unsigned char rsvd022; - unsigned char rsvd023; - unsigned char rsvd024; - unsigned char rsvd025; - /*--- long word 3 ----*/ - unsigned char qos_en; /*1: QoS enable*/ - unsigned char bw_40MHz_en; /*1: 40MHz BW enable*/ - unsigned char AMSDU2AMPDU_en; /*1: 4181 convert AMSDU to AMPDU, - * 0: disable - */ - unsigned char AMPDU_en; /*1: 11n AMPDU enable*/ - unsigned char rate_control_offload; /*1: FW offloads,0: driver handles*/ - unsigned char aggregation_offload; /*1: FW offloads,0: driver handles*/ - unsigned char rsvd030; - unsigned char rsvd031; - /*--- long word 4 ----*/ - unsigned char beacon_offload; /* 1. FW offloads, 0: driver handles*/ - unsigned char MLME_offload; /* 2. FW offloads, 0: driver handles*/ - unsigned char hwpc_offload; /* 3. FW offloads, 0: driver handles*/ - unsigned char tcp_checksum_offload; /*4. FW offloads,0: driver handles*/ - unsigned char tcp_offload; /* 5. FW offloads, 0: driver handles*/ - unsigned char ps_control_offload; /* 6. FW offloads, 0: driver handles*/ - unsigned char WWLAN_offload; /* 7. FW offloads, 0: driver handles*/ - unsigned char rsvd040; - /*--- long word 5 ----*/ - unsigned char tcp_tx_frame_len_L; /*tcp tx packet length low byte*/ - unsigned char tcp_tx_frame_len_H; /*tcp tx packet length high byte*/ - unsigned char tcp_rx_frame_len_L; /*tcp rx packet length low byte*/ - unsigned char tcp_rx_frame_len_H; /*tcp rx packet length high byte*/ - unsigned char rsvd050; - unsigned char rsvd051; - unsigned char rsvd052; - unsigned char rsvd053; -}; - -struct fw_hdr {/*8-byte alignment required*/ - unsigned short signature; - unsigned short version; /* 0x8000 ~ 0x8FFF for FPGA version, - * 0x0000 ~ 0x7FFF for ASIC version, - */ - unsigned int dmem_size; /*define the size of boot loader*/ - unsigned int img_IMEM_size; /*define the size of FW in IMEM*/ - unsigned int img_SRAM_size; /*define the size of FW in SRAM*/ - unsigned int fw_priv_sz; /*define the size of DMEM variable*/ - unsigned short efuse_addr; - unsigned short h2ccnd_resp_addr; - unsigned int SVNRevision; - unsigned int release_time; /*Mon:Day:Hr:Min*/ - struct fw_priv fwpriv; -}; - -struct hal_priv { - /*Endpoint handles*/ - struct net_device *pipehdls_r8712[10]; - u8 (*hal_bus_init)(struct _adapter *adapter); -}; - -uint rtl8712_hal_init(struct _adapter *padapter); -int rtl871x_load_fw(struct _adapter *padapter); - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h b/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h deleted file mode 100644 index e9732a1bcd7ef8f058bf7dcd0424304abcfe3ead..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_INTERRUPT_BITDEF_H__ -#define __RTL8712_INTERRUPT_BITDEF_H__ - -/*HIMR*/ -/*HISR*/ -#define _CPUERR BIT(29) -#define _ATIMEND BIT(28) -#define _TXBCNOK BIT(27) -#define _TXBCNERR BIT(26) -#define _BCNDMAINT4 BIT(25) -#define _BCNDMAINT3 BIT(24) -#define _BCNDMAINT2 BIT(23) -#define _BCNDMAINT1 BIT(22) -#define _BCNDOK4 BIT(21) -#define _BCNDOK3 BIT(20) -#define _BCNDOK2 BIT(19) -#define _BCNDOK1 BIT(18) -#define _TIMEOUT2 BIT(17) -#define _TIMEOUT1 BIT(16) -#define _TXFOVW BIT(15) -#define _PSTIMEOUT BIT(14) -#define _BCNDMAINT0 BIT(13) -#define _FOVW BIT(12) -#define _RDU BIT(11) -#define _RXCMDOK BIT(10) -#define _BCNDOK0 BIT(9) -#define _HIGHDOK BIT(8) -#define _COMDOK BIT(7) -#define _MGTDOK BIT(6) -#define _HCCADOK BIT(5) -#define _BKDOK BIT(4) -#define _BEDOK BIT(3) -#define _VIDOK BIT(2) -#define _VODOK BIT(1) -#define _RXOK BIT(0) - -#endif /*__RTL8712_INTERRUPT_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_io.c b/drivers/staging/rtl8712/rtl8712_io.c deleted file mode 100644 index 384cbdb05e1963015656cc83a1ffb6a1ae3927a7..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_io.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_io.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_IO_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_io.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -u8 r8712_read8(struct _adapter *adapter, u32 addr) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - return hdl->io_ops._read8(hdl, addr); -} - -u16 r8712_read16(struct _adapter *adapter, u32 addr) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - return hdl->io_ops._read16(hdl, addr); -} - -u32 r8712_read32(struct _adapter *adapter, u32 addr) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - return hdl->io_ops._read32(hdl, addr); -} - -void r8712_write8(struct _adapter *adapter, u32 addr, u8 val) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write8(hdl, addr, val); -} - -void r8712_write16(struct _adapter *adapter, u32 addr, u16 val) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write16(hdl, addr, val); -} - -void r8712_write32(struct _adapter *adapter, u32 addr, u32 val) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write32(hdl, addr, val); -} - -void r8712_read_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - if (adapter->driver_stopped || adapter->surprise_removed) - return; - - hdl->io_ops._read_mem(hdl, addr, cnt, pmem); -} - -void r8712_write_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write_mem(hdl, addr, cnt, pmem); -} - -void r8712_read_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - if (adapter->driver_stopped || adapter->surprise_removed) - return; - - hdl->io_ops._read_port(hdl, addr, cnt, pmem); -} - -void r8712_write_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write_port(hdl, addr, cnt, pmem); -} diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c deleted file mode 100644 index 6d9be5dec4e72898aaa2e6ebfbfd68dd9135ae22..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ /dev/null @@ -1,1830 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_led.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#include "drv_types.h" - -/*=========================================================================== - * Constant. - *=========================================================================== - - * - * Default LED behavior. - */ -#define LED_BLINK_NORMAL_INTERVAL 100 -#define LED_BLINK_SLOWLY_INTERVAL 200 -#define LED_BLINK_LONG_INTERVAL 400 - -#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 -#define LED_BLINK_LINK_INTERVAL_ALPHA 500 -#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 -#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 -#define LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA 5000 - -/*=========================================================================== - * LED object. - *=========================================================================== - */ -enum _LED_STATE_871x { - LED_UNKNOWN = 0, - LED_STATE_ON = 1, - LED_STATE_OFF = 2, - LED_BLINK_NORMAL = 3, - LED_BLINK_SLOWLY = 4, - LED_POWER_ON_BLINK = 5, - LED_SCAN_BLINK = 6, /* LED is blinking during scanning period, - * the # of times to blink is depend on time - * for scanning. - */ - LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */ - LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer - * Server case - */ - LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */ - LED_TXRX_BLINK = 10, - LED_BLINK_WPS_STOP = 11, /*for ALPHA */ - LED_BLINK_WPS_STOP_OVERLAP = 12, /*for BELKIN */ -}; - -/*=========================================================================== - * Prototype of protected function. - *=========================================================================== - */ -static void BlinkTimerCallback(struct timer_list *t); - -static void BlinkWorkItemCallback(struct work_struct *work); -/*=========================================================================== - * LED_819xUsb routines. - *=========================================================================== - * - * - * - * Description: - * Initialize an LED_871x object. - */ -static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed, - enum LED_PIN_871x LedPin) -{ - pLed->padapter = padapter; - pLed->LedPin = LedPin; - pLed->CurrLedState = LED_STATE_OFF; - pLed->bLedOn = false; - pLed->bLedBlinkInProgress = false; - pLed->BlinkTimes = 0; - pLed->BlinkingLedState = LED_UNKNOWN; - timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0); - INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback); -} - -/* - * Description: - * DeInitialize an LED_871x object. - */ -static void DeInitLed871x(struct LED_871x *pLed) -{ - del_timer_sync(&pLed->BlinkTimer); - /* We should reset bLedBlinkInProgress if we cancel - * the LedControlTimer, - */ - pLed->bLedBlinkInProgress = false; -} - -/* - * Description: - * Turn on LED according to LedPin specified. - */ -static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed) -{ - u8 LedCfg; - - if (padapter->surprise_removed || padapter->driver_stopped) - return; - LedCfg = r8712_read8(padapter, LEDCFG); - switch (pLed->LedPin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - /* SW control led0 on.*/ - r8712_write8(padapter, LEDCFG, LedCfg & 0xf0); - break; - case LED_PIN_LED1: - /* SW control led1 on.*/ - r8712_write8(padapter, LEDCFG, LedCfg & 0x0f); - break; - default: - break; - } - pLed->bLedOn = true; -} - -/* - * Description: - * Turn off LED according to LedPin specified. - */ -static void SwLedOff(struct _adapter *padapter, struct LED_871x *pLed) -{ - u8 LedCfg; - - if (padapter->surprise_removed || padapter->driver_stopped) - return; - LedCfg = r8712_read8(padapter, LEDCFG); - switch (pLed->LedPin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - LedCfg &= 0xf0; /* Set to software control.*/ - r8712_write8(padapter, LEDCFG, (LedCfg | BIT(3))); - break; - case LED_PIN_LED1: - LedCfg &= 0x0f; /* Set to software control.*/ - r8712_write8(padapter, LEDCFG, (LedCfg | BIT(7))); - break; - default: - break; - } - pLed->bLedOn = false; -} - -/*=========================================================================== - * Interface to manipulate LED objects. - *=========================================================================== - * - * Description: - * Initialize all LED_871x objects. - */ -void r8712_InitSwLeds(struct _adapter *padapter) -{ - struct led_priv *pledpriv = &padapter->ledpriv; - - pledpriv->LedControlHandler = LedControl871x; - InitLed871x(padapter, &pledpriv->SwLed0, LED_PIN_LED0); - InitLed871x(padapter, &pledpriv->SwLed1, LED_PIN_LED1); -} - -/* Description: - * DeInitialize all LED_819xUsb objects. - */ -void r8712_DeInitSwLeds(struct _adapter *padapter) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - - DeInitLed871x(&ledpriv->SwLed0); - DeInitLed871x(&ledpriv->SwLed1); -} - -/* Description: - * Implementation of LED blinking behavior. - * It toggle off LED and schedule corresponding timer if necessary. - */ -static void SwLedBlink(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - /* Determine if we shall change LED state again. */ - pLed->BlinkTimes--; - switch (pLed->CurrLedState) { - case LED_BLINK_NORMAL: - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - case LED_BLINK_StartToBlink: - if (check_fwstate(pmlmepriv, _FW_LINKED) && - (pmlmepriv->fw_state & WIFI_STATION_STATE)) - bStopBlinking = true; - if (check_fwstate(pmlmepriv, _FW_LINKED) && - ((pmlmepriv->fw_state & WIFI_ADHOC_STATE) || - (pmlmepriv->fw_state & WIFI_ADHOC_MASTER_STATE))) - bStopBlinking = true; - else if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - case LED_BLINK_WPS: - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - default: - bStopBlinking = true; - break; - } - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED) && - !pLed->bLedOn) - SwLedOn(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) && pLed->bLedOn) - SwLedOff(padapter, pLed); - pLed->BlinkTimes = 0; - pLed->bLedBlinkInProgress = false; - } else { - /* Assign LED state to toggle. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - - /* Schedule a timer to toggle LED state. */ - switch (pLed->CurrLedState) { - case LED_BLINK_NORMAL: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_BLINK_SLOWLY: - case LED_BLINK_StartToBlink: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - break; - case LED_BLINK_WPS: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LONG_INTERVAL)); - break; - default: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - break; - } - } -} - -static void SwLedBlink1(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct eeprom_priv *peeprompriv = &padapter->eeprompriv; - struct LED_871x *pLed1 = &ledpriv->SwLed1; - u8 bStopBlinking = false; - - if (peeprompriv->CustomerID == RT_CID_819x_CAMEO) - pLed = &ledpriv->SwLed1; - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - if (peeprompriv->CustomerID == RT_CID_DEFAULT) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (!pLed1->bSWLedCtrl) { - SwLedOn(padapter, pLed1); - pLed1->bSWLedCtrl = true; - } else if (!pLed1->bLedOn) { - SwLedOn(padapter, pLed1); - } - } else { - if (!pLed1->bSWLedCtrl) { - SwLedOff(padapter, pLed1); - pLed1->bSWLedCtrl = true; - } else if (pLed1->bLedOn) { - SwLedOff(padapter, pLed1); - } - } - } - switch (pLed->CurrLedState) { - case LED_BLINK_SLOWLY: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_BLINK_NORMAL: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - break; - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - pLed->BlinkTimes = 0; - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - break; - case LED_BLINK_WPS_STOP: /* WPS success */ - if (pLed->BlinkingLedState == LED_STATE_ON) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - bStopBlinking = false; - } else { - bStopBlinking = true; - } - if (bStopBlinking) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } - pLed->bLedWPSBlinkInProgress = false; - break; - default: - break; - } -} - -static void SwLedBlink2(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - SwLedOff(padapter, pLed); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - SwLedOff(padapter, pLed); - } - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - default: - break; - } -} - -static void SwLedBlink3(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - if (pLed->CurrLedState != LED_BLINK_WPS_STOP) - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedOn) - SwLedOff(padapter, pLed); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedOn) - SwLedOff(padapter, pLed); - } - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - break; - case LED_BLINK_WPS_STOP: /*WPS success*/ - if (pLed->BlinkingLedState == LED_STATE_ON) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - bStopBlinking = false; - } else { - bStopBlinking = true; - } - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - SwLedOn(padapter, pLed); - pLed->bLedWPSBlinkInProgress = false; - } - break; - default: - break; - } -} - -static void SwLedBlink4(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct led_priv *ledpriv = &padapter->ledpriv; - struct LED_871x *pLed1 = &ledpriv->SwLed1; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - if (!pLed1->bLedWPSBlinkInProgress && - pLed1->BlinkingLedState == LED_UNKNOWN) { - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - SwLedOff(padapter, pLed1); - } - switch (pLed->CurrLedState) { - case LED_BLINK_SLOWLY: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_BLINK_StartToBlink: - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - break; - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - break; - case LED_BLINK_WPS_STOP: /*WPS authentication fail*/ - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_BLINK_WPS_STOP_OVERLAP: /*WPS session overlap */ - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - if (pLed->bLedOn) - pLed->BlinkTimes = 1; - else - bStopBlinking = true; - } - if (bStopBlinking) { - pLed->BlinkTimes = 10; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - break; - default: - break; - } -} - -static void SwLedBlink5(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - default: - break; - } -} - -static void SwLedBlink6(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - SwLedOn(padapter, pLed); - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - break; - - default: - break; - } -} - -/* Description: - * Callback function of LED BlinkTimer, - * it just schedules to corresponding BlinkWorkItem. - */ -static void BlinkTimerCallback(struct timer_list *t) -{ - struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer); - - /* This fixed the crash problem on Fedora 12 when trying to do the - * insmod;ifconfig up;rmmod commands. - */ - if (pLed->padapter->surprise_removed || pLed->padapter->driver_stopped) - return; - schedule_work(&pLed->BlinkWorkItem); -} - -/* Description: - * Callback function of LED BlinkWorkItem. - * We dispatch actual LED blink action according to LedStrategy. - */ -static void BlinkWorkItemCallback(struct work_struct *work) -{ - struct LED_871x *pLed = container_of(work, struct LED_871x, - BlinkWorkItem); - struct led_priv *ledpriv = &pLed->padapter->ledpriv; - - switch (ledpriv->LedStrategy) { - case SW_LED_MODE0: - SwLedBlink(pLed); - break; - case SW_LED_MODE1: - SwLedBlink1(pLed); - break; - case SW_LED_MODE2: - SwLedBlink2(pLed); - break; - case SW_LED_MODE3: - SwLedBlink3(pLed); - break; - case SW_LED_MODE4: - SwLedBlink4(pLed); - break; - case SW_LED_MODE5: - SwLedBlink5(pLed); - break; - case SW_LED_MODE6: - SwLedBlink6(pLed); - break; - default: - SwLedBlink(pLed); - break; - } -} - -/*============================================================================ - * Default LED behavior. - *============================================================================ - * - * Description: - * Implement each led action for SW_LED_MODE0. - * This is default strategy. - */ - -static void SwLedControlMode1(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl; - - if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO) - pLed = &ledpriv->SwLed1; - switch (LedAction) { - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!pLed->bLedNoLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - break; - case LED_CTL_LINK: - if (!pLed->bLedLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } - break; - case LED_CTL_SITE_SURVEY: - if (psitesurveyctrl->traffic_busy && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_START_WPS: /*wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_STOP_WPS: - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) - del_timer(&pLed->BlinkTimer); - else - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_STOP_WPS_FAIL: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - default: - break; - } -} - -static void SwLedControlMode2(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - switch (LedAction) { - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_LINK: - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - - case LED_CTL_START_WPS: /*wait until xinpin finish*/ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - - case LED_CTL_STOP_WPS: - pLed->bLedWPSBlinkInProgress = false; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - - case LED_CTL_STOP_WPS_FAIL: - pLed->bLedWPSBlinkInProgress = false; - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - default: - break; - } -} - -static void SwLedControlMode3(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - switch (LedAction) { - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_LINK: - if (IS_LED_WPS_BLINKING(pLed)) - return; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_START_WPS: /* wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_STOP_WPS: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } else { - pLed->bLedWPSBlinkInProgress = true; - } - pLed->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_STOP_WPS_FAIL: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - default: - break; - } -} - -static void SwLedControlMode4(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - struct LED_871x *pLed1 = &ledpriv->SwLed1; - - switch (LedAction) { - case LED_CTL_START_TO_LINK: - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer(&pLed1->BlinkTimer); - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - if (!pLed->bLedStartToLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - pLed->bLedStartToLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_StartToBlink; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - } - break; - case LED_CTL_LINK: - case LED_CTL_NO_LINK: - /*LED1 settings*/ - if (LedAction == LED_CTL_LINK) { - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer(&pLed1->BlinkTimer); - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - } - if (!pLed->bLedNoLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - break; - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_START_WPS: /*wait until xinpin finish*/ - case LED_CTL_START_WPS_BOTTON: - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer(&pLed1->BlinkTimer); - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - } - break; - case LED_CTL_STOP_WPS: /*WPS connect success*/ - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/ - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - /*LED1 settings*/ - if (pLed1->bLedWPSBlinkInProgress) - del_timer(&pLed1->BlinkTimer); - else - pLed1->bLedWPSBlinkInProgress = true; - pLed1->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed1->bLedOn) - pLed1->BlinkingLedState = LED_STATE_OFF; - else - pLed1->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/ - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - /*LED1 settings*/ - if (pLed1->bLedWPSBlinkInProgress) - del_timer(&pLed1->BlinkTimer); - else - pLed1->bLedWPSBlinkInProgress = true; - pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; - pLed1->BlinkTimes = 10; - if (pLed1->bLedOn) - pLed1->BlinkingLedState = LED_STATE_OFF; - else - pLed1->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedStartToLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedStartToLinkBlinkInProgress = false; - } - if (pLed1->bLedWPSBlinkInProgress) { - del_timer(&pLed1->BlinkTimer); - pLed1->bLedWPSBlinkInProgress = false; - } - pLed1->BlinkingLedState = LED_UNKNOWN; - SwLedOff(padapter, pLed); - SwLedOff(padapter, pLed1); - break; - default: - break; - } -} - -static void SwLedControlMode5(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO) - pLed = &ledpriv->SwLed1; - - switch (LedAction) { - case LED_CTL_POWER_ON: - case LED_CTL_NO_LINK: - case LED_CTL_LINK: /* solid blue */ - if (pLed->CurrLedState == LED_SCAN_BLINK) - return; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - pLed->bLedBlinkInProgress = false; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - SwLedOff(padapter, pLed); - break; - default: - break; - } -} - -static void SwLedControlMode6(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - switch (LedAction) { - case LED_CTL_POWER_ON: - case LED_CTL_NO_LINK: - case LED_CTL_LINK: /*solid blue*/ - case LED_CTL_SITE_SURVEY: - if (IS_LED_WPS_BLINKING(pLed)) - return; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - pLed->bLedBlinkInProgress = false; - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_START_WPS: /*wait until xinpin finish*/ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_STOP_WPS_FAIL: - case LED_CTL_STOP_WPS: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - SwLedOff(padapter, pLed); - break; - default: - break; - } -} - -/* Description: - * Dispatch LED action according to pHalData->LedStrategy. - */ -void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - - if (!ledpriv->bRegUseLed) - return; - switch (ledpriv->LedStrategy) { - case SW_LED_MODE0: - break; - case SW_LED_MODE1: - SwLedControlMode1(padapter, LedAction); - break; - case SW_LED_MODE2: - SwLedControlMode2(padapter, LedAction); - break; - case SW_LED_MODE3: - SwLedControlMode3(padapter, LedAction); - break; - case SW_LED_MODE4: - SwLedControlMode4(padapter, LedAction); - break; - case SW_LED_MODE5: - SwLedControlMode5(padapter, LedAction); - break; - case SW_LED_MODE6: - SwLedControlMode6(padapter, LedAction); - break; - default: - break; - } -} - -void r8712_flush_led_works(struct _adapter *padapter) -{ - struct led_priv *pledpriv = &padapter->ledpriv; - - flush_work(&pledpriv->SwLed0.BlinkWorkItem); - flush_work(&pledpriv->SwLed1.BlinkWorkItem); -} diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h deleted file mode 100644 index 46d758d3f3a4dd286501eabee589154144cf7727..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_MACSETTING_BITDEF_H__ -#define __RTL8712_MACSETTING_BITDEF_H__ - -/*MACID*/ -/*BSSID*/ - -/*HWVID*/ -#define _HWVID_MSK 0x0F - -/*MAR*/ -/*MBIDCANCONTENT*/ - -/*MBIDCANCFG*/ -#define _POOLING BIT(31) -#define _WRITE_EN BIT(16) -#define _CAM_ADDR_MSK 0x001F -#define _CAM_ADDR_SHT 0 - -/*BUILDTIME*/ -#define _BUILDTIME_MSK 0x3FFFFFFF - -/*BUILDUSER*/ - -#endif /* __RTL8712_MACSETTING_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h deleted file mode 100644 index 64740d99c252334d42d6e53a4d38b206471defb2..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_MACSETTING_REGDEF_H__ -#define __RTL8712_MACSETTING_REGDEF_H__ - -#define MACID (RTL8712_MACIDSETTING_ + 0x0000) -#define BSSIDR (RTL8712_MACIDSETTING_ + 0x0008) -#define HWVID (RTL8712_MACIDSETTING_ + 0x000E) -#define MAR (RTL8712_MACIDSETTING_ + 0x0010) -#define MBIDCANCONTENT (RTL8712_MACIDSETTING_ + 0x0018) -#define MBIDCANCFG (RTL8712_MACIDSETTING_ + 0x0020) -#define BUILDTIME (RTL8712_MACIDSETTING_ + 0x0024) -#define BUILDUSER (RTL8712_MACIDSETTING_ + 0x0028) - -#endif /*__RTL8712_MACSETTING_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h b/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h deleted file mode 100644 index 53e0d6b440f34ee5bc3a4893e4df9d70a2f2f967..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_POWERSAVE_BITDEF_H__ -#define __RTL8712_POWERSAVE_BITDEF_H__ - -/*WOWCTRL*/ -#define _UWF BIT(3) -#define _MAGIC BIT(2) -#define _WOW_EN BIT(1) -#define _PMEN BIT(0) - -/*PSSTATUS*/ -#define _PSSTATUS_SEL_MSK 0x0F - -/*PSSWITCH*/ -#define _PSSWITCH_ACT BIT(7) -#define _PSSWITCH_SEL_MSK 0x0F -#define _PSSWITCH_SEL_SHT 0 - -/*LPNAV_CTRL*/ -#define _LPNAV_EN BIT(31) -#define _LPNAV_EARLY_MSK 0x7FFF0000 -#define _LPNAV_EARLY_SHT 16 -#define _LPNAV_TH_MSK 0x0000FFFF -#define _LPNAV_TH_SHT 0 - -/*RPWM*/ -/*CPWM*/ -#define _TOGGLING BIT(7) -#define _WWLAN BIT(3) -#define _RPS_ST BIT(2) -#define _WLAN_TRX BIT(1) -#define _SYS_CLK BIT(0) - -#endif /* __RTL8712_POWERSAVE_BITDEF_H__*/ diff --git a/drivers/staging/rtl8712/rtl8712_powersave_regdef.h b/drivers/staging/rtl8712/rtl8712_powersave_regdef.h deleted file mode 100644 index 1bcfde4b1c11f1647d9c0208cbb8a192ca8fd105..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_powersave_regdef.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_POWERSAVE_REGDEF_H__ -#define __RTL8712_POWERSAVE_REGDEF_H__ - -#define WOWCTRL (RTL8712_POWERSAVE_ + 0x00) -#define PSSTATUS (RTL8712_POWERSAVE_ + 0x01) -#define PSSWITCH (RTL8712_POWERSAVE_ + 0x02) -#define MIMOPS_WAITPERIOD (RTL8712_POWERSAVE_ + 0x03) -#define LPNAV_CTRL (RTL8712_POWERSAVE_ + 0x04) -#define WFM0 (RTL8712_POWERSAVE_ + 0x10) -#define WFM1 (RTL8712_POWERSAVE_ + 0x20) -#define WFM2 (RTL8712_POWERSAVE_ + 0x30) -#define WFM3 (RTL8712_POWERSAVE_ + 0x40) -#define WFM4 (RTL8712_POWERSAVE_ + 0x50) -#define WFM5 (RTL8712_POWERSAVE_ + 0x60) -#define WFCRC (RTL8712_POWERSAVE_ + 0x70) -#define RPWM (RTL8712_POWERSAVE_ + 0x7C) -#define CPWM (RTL8712_POWERSAVE_ + 0x7D) - -#endif /* __RTL8712_POWERSAVE_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h deleted file mode 100644 index 1de51c48f9c1b2d01866a3a6ec9dbc03ac9d35c2..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_RATECTRL_BITDEF_H__ -#define __RTL8712_RATECTRL_BITDEF_H__ - -/*INIRTSMCS_SEL*/ -#define _INIRTSMCS_SEL_MSK 0x3F - -/* RRSR*/ -#define _RRSR_SHORT BIT(23) -#define _RRSR_RSC_MSK 0x600000 -#define _RRSR_RSC_SHT 21 -#define _RRSR_BITMAP_MSK 0x0FFFFF -#define _RRSR_BITMAP_SHT 0 - -/* AGGLEN_LMT_H*/ -#define _AGGLMT_MCS32_MSK 0xF0 -#define _AGGLMT_MCS32_SHT 4 -#define _AGGLMT_MCS15_SGI_MSK 0x0F -#define _AGGLMT_MCS15_SGI_SHT 0 - -/* DARFRC*/ -/* RARFRC*/ -/* MCS_TXAGC*/ -/* CCK_TXAGC*/ -#define _CCK_MSK 0xFF00 -#define _CCK_SHT 8 -#define _BARKER_MSK 0x00FF -#define _BARKER_SHT 0 - -#endif /* __RTL8712_RATECTRL_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h deleted file mode 100644 index 9ed5653f3f7f117716d7772883a195f1c5907b4e..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_RATECTRL_REGDEF_H__ -#define __RTL8712_RATECTRL_REGDEF_H__ - -#define INIMCS_SEL (RTL8712_RATECTRL_ + 0x00) -#define INIRTSMCS_SEL (RTL8712_RATECTRL_ + 0x20) -#define RRSR (RTL8712_RATECTRL_ + 0x21) -#define ARFR0 (RTL8712_RATECTRL_ + 0x24) -#define ARFR1 (RTL8712_RATECTRL_ + 0x28) -#define ARFR2 (RTL8712_RATECTRL_ + 0x2C) -#define ARFR3 (RTL8712_RATECTRL_ + 0x30) -#define ARFR4 (RTL8712_RATECTRL_ + 0x34) -#define ARFR5 (RTL8712_RATECTRL_ + 0x38) -#define ARFR6 (RTL8712_RATECTRL_ + 0x3C) -#define ARFR7 (RTL8712_RATECTRL_ + 0x40) -#define AGGLEN_LMT_H (RTL8712_RATECTRL_ + 0x47) -#define AGGLEN_LMT_L (RTL8712_RATECTRL_ + 0x48) -#define DARFRC (RTL8712_RATECTRL_ + 0x50) -#define RARFRC (RTL8712_RATECTRL_ + 0x58) -#define MCS_TXAGC0 (RTL8712_RATECTRL_ + 0x60) -#define MCS_TXAGC1 (RTL8712_RATECTRL_ + 0x61) -#define MCS_TXAGC2 (RTL8712_RATECTRL_ + 0x62) -#define MCS_TXAGC3 (RTL8712_RATECTRL_ + 0x63) -#define MCS_TXAGC4 (RTL8712_RATECTRL_ + 0x64) -#define MCS_TXAGC5 (RTL8712_RATECTRL_ + 0x65) -#define MCS_TXAGC6 (RTL8712_RATECTRL_ + 0x66) -#define MCS_TXAGC7 (RTL8712_RATECTRL_ + 0x67) -#define CCK_TXAGC (RTL8712_RATECTRL_ + 0x68) - -#endif /*__RTL8712_RATECTRL_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c deleted file mode 100644 index ab344d676bb94665ac57e8d74a27f7283b8a781a..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ /dev/null @@ -1,1075 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_recv.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_RECV_C_ - -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" -#include "ethernet.h" -#include "usb_ops.h" -#include "wifi.h" - -static void recv_tasklet(struct tasklet_struct *t); - -int r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter) -{ - int i; - struct recv_buf *precvbuf; - addr_t tmpaddr = 0; - int alignment = 0; - struct sk_buff *pskb = NULL; - - /*init recv_buf*/ - _init_queue(&precvpriv->free_recv_buf_queue); - precvpriv->pallocated_recv_buf = - kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_ATOMIC); - if (!precvpriv->pallocated_recv_buf) - return -ENOMEM; - precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 - - ((addr_t)(precvpriv->pallocated_recv_buf) & 3); - precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - INIT_LIST_HEAD(&precvbuf->list); - spin_lock_init(&precvbuf->recvbuf_lock); - if (r8712_os_recvbuf_resource_alloc(padapter, precvbuf)) - break; - precvbuf->ref_cnt = 0; - precvbuf->adapter = padapter; - list_add_tail(&precvbuf->list, - &precvpriv->free_recv_buf_queue.queue); - precvbuf++; - } - precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; - tasklet_setup(&precvpriv->recv_tasklet, recv_tasklet); - skb_queue_head_init(&precvpriv->rx_skb_queue); - - skb_queue_head_init(&precvpriv->free_recv_skb_queue); - for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) { - pskb = netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + - RECVBUFF_ALIGN_SZ); - if (pskb) { - tmpaddr = (addr_t)pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); - skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); - skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); - } - pskb = NULL; - } - return 0; -} - -void r8712_free_recv_priv(struct recv_priv *precvpriv) -{ - int i; - struct recv_buf *precvbuf; - struct _adapter *padapter = precvpriv->adapter; - - precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - r8712_os_recvbuf_resource_free(padapter, precvbuf); - precvbuf++; - } - kfree(precvpriv->pallocated_recv_buf); - skb_queue_purge(&precvpriv->rx_skb_queue); - if (skb_queue_len(&precvpriv->rx_skb_queue)) - netdev_warn(padapter->pnetdev, "r8712u: rx_skb_queue not empty\n"); - skb_queue_purge(&precvpriv->free_recv_skb_queue); - if (skb_queue_len(&precvpriv->free_recv_skb_queue)) - netdev_warn(padapter->pnetdev, "r8712u: free_recv_skb_queue not empty %d\n", - skb_queue_len(&precvpriv->free_recv_skb_queue)); -} - -void r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf) -{ - precvbuf->transfer_len = 0; - precvbuf->len = 0; - precvbuf->ref_cnt = 0; - if (precvbuf->pbuf) { - precvbuf->pdata = precvbuf->pbuf; - precvbuf->phead = precvbuf->pbuf; - precvbuf->ptail = precvbuf->pbuf; - precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ; - } -} - -void r8712_free_recvframe(union recv_frame *precvframe, - struct __queue *pfree_recv_queue) -{ - unsigned long irqL; - struct _adapter *padapter = precvframe->u.hdr.adapter; - struct recv_priv *precvpriv = &padapter->recvpriv; - - if (precvframe->u.hdr.pkt) { - dev_kfree_skb_any(precvframe->u.hdr.pkt);/*free skb by driver*/ - precvframe->u.hdr.pkt = NULL; - } - spin_lock_irqsave(&pfree_recv_queue->lock, irqL); - list_del_init(&precvframe->u.hdr.list); - list_add_tail(&precvframe->u.hdr.list, &pfree_recv_queue->queue); - if (padapter) { - if (pfree_recv_queue == &precvpriv->free_recv_queue) - precvpriv->free_recvframe_cnt++; - } - spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL); -} - -static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, - struct recv_stat *prxstat) -{ - /*TODO: - * Offset 0 - */ - pattrib->bdecrypted = (le32_to_cpu(prxstat->rxdw0) & BIT(27)) == 0; - pattrib->crc_err = (le32_to_cpu(prxstat->rxdw0) & BIT(14)) != 0; - /*Offset 4*/ - /*Offset 8*/ - /*Offset 12*/ - if (le32_to_cpu(prxstat->rxdw3) & BIT(13)) { - pattrib->tcpchk_valid = 1; /* valid */ - if (le32_to_cpu(prxstat->rxdw3) & BIT(11)) - pattrib->tcp_chkrpt = 1; /* correct */ - else - pattrib->tcp_chkrpt = 0; /* incorrect */ - if (le32_to_cpu(prxstat->rxdw3) & BIT(12)) - pattrib->ip_chkrpt = 1; /* correct */ - else - pattrib->ip_chkrpt = 0; /* incorrect */ - } else { - pattrib->tcpchk_valid = 0; /* invalid */ - } - pattrib->mcs_rate = (u8)((le32_to_cpu(prxstat->rxdw3)) & 0x3f); - pattrib->htc = (u8)((le32_to_cpu(prxstat->rxdw3) >> 14) & 0x1); - /*Offset 16*/ - /*Offset 20*/ - /*phy_info*/ -} - -/*perform defrag*/ -static union recv_frame *recvframe_defrag(struct _adapter *adapter, - struct __queue *defrag_q) -{ - struct list_head *plist, *phead; - u8 wlanhdr_offset; - u8 curfragnum; - struct recv_frame_hdr *pfhdr, *pnfhdr; - union recv_frame *prframe, *pnextrframe; - struct __queue *pfree_recv_queue; - - pfree_recv_queue = &adapter->recvpriv.free_recv_queue; - phead = &defrag_q->queue; - plist = phead->next; - prframe = container_of(plist, union recv_frame, u.list); - list_del_init(&prframe->u.list); - pfhdr = &prframe->u.hdr; - curfragnum = 0; - if (curfragnum != pfhdr->attrib.frag_num) { - /*the first fragment number must be 0 - *free the whole queue - */ - r8712_free_recvframe(prframe, pfree_recv_queue); - r8712_free_recvframe_queue(defrag_q, pfree_recv_queue); - return NULL; - } - curfragnum++; - plist = &defrag_q->queue; - plist = plist->next; - while (!end_of_queue_search(phead, plist)) { - pnextrframe = container_of(plist, union recv_frame, u.list); - pnfhdr = &pnextrframe->u.hdr; - /*check the fragment sequence (2nd ~n fragment frame) */ - if (curfragnum != pnfhdr->attrib.frag_num) { - /* the fragment number must increase (after decache) - * release the defrag_q & prframe - */ - r8712_free_recvframe(prframe, pfree_recv_queue); - r8712_free_recvframe_queue(defrag_q, pfree_recv_queue); - return NULL; - } - curfragnum++; - /* copy the 2nd~n fragment frame's payload to the first fragment - * get the 2nd~last fragment frame's payload - */ - wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; - recvframe_pull(pnextrframe, wlanhdr_offset); - /* append to first fragment frame's tail (if privacy frame, - * pull the ICV) - */ - recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); - memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); - recvframe_put(prframe, pnfhdr->len); - pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len; - plist = plist->next; - } - /* free the defrag_q queue and return the prframe */ - r8712_free_recvframe_queue(defrag_q, pfree_recv_queue); - return prframe; -} - -/* check if need to defrag, if needed queue the frame to defrag_q */ -union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter, - union recv_frame *precv_frame) -{ - u8 ismfrag; - u8 fragnum; - u8 *psta_addr; - struct recv_frame_hdr *pfhdr; - struct sta_info *psta; - struct sta_priv *pstapriv; - struct list_head *phead; - union recv_frame *prtnframe = NULL; - struct __queue *pfree_recv_queue, *pdefrag_q; - - pstapriv = &padapter->stapriv; - pfhdr = &precv_frame->u.hdr; - pfree_recv_queue = &padapter->recvpriv.free_recv_queue; - /* need to define struct of wlan header frame ctrl */ - ismfrag = pfhdr->attrib.mfrag; - fragnum = pfhdr->attrib.frag_num; - psta_addr = pfhdr->attrib.ta; - psta = r8712_get_stainfo(pstapriv, psta_addr); - if (!psta) - pdefrag_q = NULL; - else - pdefrag_q = &psta->sta_recvpriv.defrag_q; - - if ((ismfrag == 0) && (fragnum == 0)) - prtnframe = precv_frame;/*isn't a fragment frame*/ - if (ismfrag == 1) { - /* 0~(n-1) fragment frame - * enqueue to defraf_g - */ - if (pdefrag_q) { - if (fragnum == 0) { - /*the first fragment*/ - if (!list_empty(&pdefrag_q->queue)) { - /*free current defrag_q */ - r8712_free_recvframe_queue(pdefrag_q, pfree_recv_queue); - } - } - /* Then enqueue the 0~(n-1) fragment to the defrag_q */ - phead = &pdefrag_q->queue; - list_add_tail(&pfhdr->list, phead); - prtnframe = NULL; - } else { - /* can't find this ta's defrag_queue, so free this - * recv_frame - */ - r8712_free_recvframe(precv_frame, pfree_recv_queue); - prtnframe = NULL; - } - } - if ((ismfrag == 0) && (fragnum != 0)) { - /* the last fragment frame - * enqueue the last fragment - */ - if (pdefrag_q) { - phead = &pdefrag_q->queue; - list_add_tail(&pfhdr->list, phead); - /*call recvframe_defrag to defrag*/ - precv_frame = recvframe_defrag(padapter, pdefrag_q); - prtnframe = precv_frame; - } else { - /* can't find this ta's defrag_queue, so free this - * recv_frame - */ - r8712_free_recvframe(precv_frame, pfree_recv_queue); - prtnframe = NULL; - } - } - if (prtnframe && (prtnframe->u.hdr.attrib.privacy)) { - /* after defrag we must check tkip mic code */ - if (r8712_recvframe_chkmic(padapter, prtnframe) == _FAIL) { - r8712_free_recvframe(prtnframe, pfree_recv_queue); - prtnframe = NULL; - } - } - return prtnframe; -} - -static void amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe) -{ - int a_len, padding_len; - u16 eth_type, nSubframe_Length; - u8 nr_subframes, i; - unsigned char *pdata; - struct rx_pkt_attrib *pattrib; - _pkt *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; - struct recv_priv *precvpriv = &padapter->recvpriv; - struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; - - nr_subframes = 0; - pattrib = &prframe->u.hdr.attrib; - recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen); - if (prframe->u.hdr.attrib.iv_len > 0) - recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len); - a_len = prframe->u.hdr.len; - pdata = prframe->u.hdr.rx_data; - while (a_len > ETH_HLEN) { - /* Offset 12 denote 2 mac address */ - nSubframe_Length = *((u16 *)(pdata + 12)); - /*==m==>change the length order*/ - nSubframe_Length = (nSubframe_Length >> 8) + - (nSubframe_Length << 8); - if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { - netdev_warn(padapter->pnetdev, "r8712u: nRemain_Length is %d and nSubframe_Length is: %d\n", - a_len, nSubframe_Length); - goto exit; - } - /* move the data point to data content */ - pdata += ETH_HLEN; - a_len -= ETH_HLEN; - /* Allocate new skb for releasing to upper layer */ - sub_skb = dev_alloc_skb(nSubframe_Length + 12); - if (!sub_skb) - break; - skb_reserve(sub_skb, 12); - skb_put_data(sub_skb, pdata, nSubframe_Length); - subframes[nr_subframes++] = sub_skb; - if (nr_subframes >= MAX_SUBFRAME_COUNT) { - netdev_warn(padapter->pnetdev, "r8712u: ParseSubframe(): Too many Subframes! Packets dropped!\n"); - break; - } - pdata += nSubframe_Length; - a_len -= nSubframe_Length; - if (a_len != 0) { - padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & 3); - if (padding_len == 4) - padding_len = 0; - if (a_len < padding_len) - goto exit; - pdata += padding_len; - a_len -= padding_len; - } - } - for (i = 0; i < nr_subframes; i++) { - sub_skb = subframes[i]; - /* convert hdr + possible LLC headers into Ethernet header */ - eth_type = (sub_skb->data[6] << 8) | sub_skb->data[7]; - if (sub_skb->len >= 8 && - ((!memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) && - eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || - !memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE))) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType - */ - skb_pull(sub_skb, SNAP_SIZE); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, - ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, - ETH_ALEN); - } else { - __be16 len; - /* Leave Ethernet header part of hdr and full payload */ - len = htons(sub_skb->len); - memcpy(skb_push(sub_skb, 2), &len, 2); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, - ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, - ETH_ALEN); - } - /* Indicate the packets to upper layer */ - if (sub_skb) { - sub_skb->protocol = - eth_type_trans(sub_skb, padapter->pnetdev); - sub_skb->dev = padapter->pnetdev; - if ((pattrib->tcpchk_valid == 1) && - (pattrib->tcp_chkrpt == 1)) { - sub_skb->ip_summed = CHECKSUM_UNNECESSARY; - } else { - sub_skb->ip_summed = CHECKSUM_NONE; - } - netif_rx(sub_skb); - } - } -exit: - prframe->u.hdr.len = 0; - r8712_free_recvframe(prframe, pfree_recv_queue); -} - -void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) -{ - __le32 voffset; - u8 *poffset; - u16 cmd_len, drvinfo_sz; - struct recv_stat *prxstat; - - poffset = prxcmdbuf; - voffset = *(__le32 *)poffset; - prxstat = prxcmdbuf; - drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; - drvinfo_sz <<= 3; - poffset += RXDESC_SIZE + drvinfo_sz; - do { - voffset = *(__le32 *)poffset; - cmd_len = (u16)(le32_to_cpu(voffset) & 0xffff); - r8712_event_handle(padapter, (__le32 *)poffset); - poffset += (cmd_len + 8);/*8 bytes alignment*/ - } while (le32_to_cpu(voffset) & BIT(31)); -} - -static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, - u16 seq_num) -{ - u8 wsize = preorder_ctrl->wsize_b; - u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) % 4096; - - /* Rx Reorder initialize condition.*/ - if (preorder_ctrl->indicate_seq == 0xffff) - preorder_ctrl->indicate_seq = seq_num; - /* Drop out the packet which SeqNum is smaller than WinStart */ - if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) - return false; - /* - * Sliding window manipulation. Conditions includes: - * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 - * 2. Incoming SeqNum is larger than the WinEnd => Window shift N - */ - if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) - preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + - 1) % 4096; - else if (SN_LESS(wend, seq_num)) { - if (seq_num >= (wsize - 1)) - preorder_ctrl->indicate_seq = seq_num + 1 - wsize; - else - preorder_ctrl->indicate_seq = 4095 - (wsize - - (seq_num + 1)) + 1; - } - return true; -} - -static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, - union recv_frame *prframe) -{ - struct list_head *phead, *plist; - union recv_frame *pnextrframe; - struct rx_pkt_attrib *pnextattrib; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; - - phead = &ppending_recvframe_queue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - pnextrframe = container_of(plist, union recv_frame, u.list); - pnextattrib = &pnextrframe->u.hdr.attrib; - - if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) - return false; - - if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) - plist = plist->next; - else - break; - } - list_del_init(&prframe->u.hdr.list); - list_add_tail(&prframe->u.hdr.list, plist); - return true; -} - -int r8712_recv_indicatepkts_in_order(struct _adapter *padapter, - struct recv_reorder_ctrl *preorder_ctrl, - int bforced) -{ - struct list_head *phead, *plist; - union recv_frame *prframe; - struct rx_pkt_attrib *pattrib; - int bPktInBuf = false; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - - phead = &ppending_recvframe_queue->queue; - plist = phead->next; - /* Handling some condition for forced indicate case.*/ - if (bforced) { - if (list_empty(phead)) - return true; - - prframe = container_of(plist, union recv_frame, u.list); - pattrib = &prframe->u.hdr.attrib; - preorder_ctrl->indicate_seq = pattrib->seq_num; - } - /* Prepare indication list and indication. - * Check if there is any packet need indicate. - */ - while (!list_empty(phead)) { - prframe = container_of(plist, union recv_frame, u.list); - pattrib = &prframe->u.hdr.attrib; - if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) { - plist = plist->next; - list_del_init(&prframe->u.hdr.list); - if (SN_EQUAL(preorder_ctrl->indicate_seq, - pattrib->seq_num)) - preorder_ctrl->indicate_seq = - (preorder_ctrl->indicate_seq + 1) % 4096; - /*indicate this recv_frame*/ - if (!pattrib->amsdu) { - if (!padapter->driver_stopped && - !padapter->surprise_removed) { - /* indicate this recv_frame */ - r8712_recv_indicatepkt(padapter, - prframe); - } - } else if (pattrib->amsdu == 1) { - amsdu_to_msdu(padapter, prframe); - } - /* Update local variables. */ - bPktInBuf = false; - } else { - bPktInBuf = true; - break; - } - } - return bPktInBuf; -} - -static int recv_indicatepkt_reorder(struct _adapter *padapter, - union recv_frame *prframe) -{ - unsigned long irql; - struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; - struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - - if (!pattrib->amsdu) { - /* s1. */ - r8712_wlanhdr_to_ethhdr(prframe); - if (pattrib->qos != 1) { - if (!padapter->driver_stopped && - !padapter->surprise_removed) { - r8712_recv_indicatepkt(padapter, prframe); - return 0; - } else { - return -EINVAL; - } - } - } - spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); - /*s2. check if winstart_b(indicate_seq) needs to be updated*/ - if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) - goto _err_exit; - /*s3. Insert all packet into Reorder Queue to maintain its ordering.*/ - if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) - goto _err_exit; - /*s4. - * Indication process. - * After Packet dropping and Sliding Window shifting as above, we can - * now just indicate the packets with the SeqNum smaller than latest - * WinStart and buffer other packets. - * - * For Rx Reorder condition: - * 1. All packets with SeqNum smaller than WinStart => Indicate - * 2. All packets with SeqNum larger than or equal to - * WinStart => Buffer it. - */ - if (r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, false)) { - mod_timer(&preorder_ctrl->reordering_ctrl_timer, - jiffies + msecs_to_jiffies(REORDER_WAIT_TIME)); - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); - } else { - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); - del_timer(&preorder_ctrl->reordering_ctrl_timer); - } - return 0; -_err_exit: - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); - return -ENOMEM; -} - -void r8712_reordering_ctrl_timeout_handler(void *pcontext) -{ - unsigned long irql; - struct recv_reorder_ctrl *preorder_ctrl = pcontext; - struct _adapter *padapter = preorder_ctrl->padapter; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - - if (padapter->driver_stopped || padapter->surprise_removed) - return; - spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); - r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, true); - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); -} - -static int r8712_process_recv_indicatepkts(struct _adapter *padapter, - union recv_frame *prframe) -{ - int retval = _SUCCESS; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - if (phtpriv->ht_option == 1) { /*B/G/N Mode*/ - if (recv_indicatepkt_reorder(padapter, prframe)) { - /* including perform A-MPDU Rx Ordering Buffer Control*/ - if (!padapter->driver_stopped && - !padapter->surprise_removed) - return _FAIL; - } - } else { /*B/G mode*/ - retval = r8712_wlanhdr_to_ethhdr(prframe); - if (retval) - return _FAIL; - if (!padapter->driver_stopped && !padapter->surprise_removed) { - /* indicate this recv_frame */ - r8712_recv_indicatepkt(padapter, prframe); - } else { - return _FAIL; - } - } - return retval; -} - -static u8 query_rx_pwr_percentage(s8 antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; -} - -static u8 evm_db2percentage(s8 value) -{ - /* - * -33dB~0dB to 0%~99% - */ - s8 ret_val = clamp(-value, 0, 33) * 3; - - if (ret_val == 99) - ret_val = 100; - - return ret_val; -} - -s32 r8712_signal_scale_mapping(s32 cur_sig) -{ - s32 ret_sig; - - if (cur_sig >= 51 && cur_sig <= 100) - ret_sig = 100; - else if (cur_sig >= 41 && cur_sig <= 50) - ret_sig = 80 + ((cur_sig - 40) * 2); - else if (cur_sig >= 31 && cur_sig <= 40) - ret_sig = 66 + (cur_sig - 30); - else if (cur_sig >= 21 && cur_sig <= 30) - ret_sig = 54 + (cur_sig - 20); - else if (cur_sig >= 10 && cur_sig <= 20) - ret_sig = 42 + (((cur_sig - 10) * 2) / 3); - else if (cur_sig >= 5 && cur_sig <= 9) - ret_sig = 22 + (((cur_sig - 5) * 3) / 2); - else if (cur_sig >= 1 && cur_sig <= 4) - ret_sig = 6 + (((cur_sig - 1) * 3) / 2); - else - ret_sig = cur_sig; - return ret_sig; -} - -static s32 translate2dbm(struct _adapter *padapter, u8 signal_strength_idx) -{ - s32 signal_power; /* in dBm.*/ - /* Translate to dBm (x=0.5y-95).*/ - signal_power = (s32)((signal_strength_idx + 1) >> 1); - signal_power -= 95; - return signal_power; -} - -static void query_rx_phy_status(struct _adapter *padapter, - union recv_frame *prframe) -{ - u8 i, max_spatial_stream, evm; - struct recv_stat *prxstat = (struct recv_stat *)prframe->u.hdr.rx_head; - struct phy_stat *pphy_stat = (struct phy_stat *)(prxstat + 1); - u8 *pphy_head = (u8 *)(prxstat + 1); - s8 rx_pwr[4], rx_pwr_all; - u8 pwdb_all; - u32 rssi, total_rssi = 0; - u8 bcck_rate = 0, rf_rx_num = 0, cck_highpwr = 0; - struct phy_cck_rx_status *pcck_buf; - u8 sq; - - /* Record it for next packet processing*/ - bcck_rate = (prframe->u.hdr.attrib.mcs_rate <= 3 ? 1 : 0); - if (bcck_rate) { - u8 report; - - /* CCK Driver info Structure is not the same as OFDM packet.*/ - pcck_buf = (struct phy_cck_rx_status *)pphy_stat; - /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB calculated by hardware - * (for rate adaptive) - */ - if (!cck_highpwr) { - report = pcck_buf->cck_agc_rpt & 0xc0; - report >>= 6; - switch (report) { - /* Modify the RF RNA gain value to -40, -20, - * -2, 14 by Jenyu's suggestion - * Note: different RF with the different - * RNA gain. - */ - case 0x3: - rx_pwr_all = -40 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x2: - rx_pwr_all = -20 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x1: - rx_pwr_all = -2 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x0: - rx_pwr_all = 14 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - } - } else { - report = ((u8)(le32_to_cpu(pphy_stat->phydw1) >> 8)) & - 0x60; - report >>= 5; - switch (report) { - case 0x3: - rx_pwr_all = -40 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x2: - rx_pwr_all = -20 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x1: - rx_pwr_all = -2 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x0: - rx_pwr_all = 14 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - } - } - pwdb_all = query_rx_pwr_percentage(rx_pwr_all); - /* CCK gain is smaller than OFDM/MCS gain,*/ - /* so we add gain diff by experiences, the val is 6 */ - pwdb_all += 6; - if (pwdb_all > 100) - pwdb_all = 100; - /* modify the offset to make the same gain index with OFDM.*/ - if (pwdb_all > 34 && pwdb_all <= 42) - pwdb_all -= 2; - else if (pwdb_all > 26 && pwdb_all <= 34) - pwdb_all -= 6; - else if (pwdb_all > 14 && pwdb_all <= 26) - pwdb_all -= 8; - else if (pwdb_all > 4 && pwdb_all <= 14) - pwdb_all -= 4; - /* - * (3) Get Signal Quality (EVM) - */ - if (pwdb_all > 40) { - sq = 100; - } else { - sq = pcck_buf->sq_rpt; - if (pcck_buf->sq_rpt > 64) - sq = 0; - else if (pcck_buf->sq_rpt < 20) - sq = 100; - else - sq = ((64 - sq) * 100) / 44; - } - prframe->u.hdr.attrib.signal_qual = sq; - prframe->u.hdr.attrib.rx_mimo_signal_qual[0] = sq; - prframe->u.hdr.attrib.rx_mimo_signal_qual[1] = -1; - } else { - /* (1)Get RSSI for HT rate */ - for (i = 0; i < ((padapter->registrypriv.rf_config) & - 0x0f); i++) { - rf_rx_num++; - rx_pwr[i] = ((pphy_head[PHY_STAT_GAIN_TRSW_SHT + i] - & 0x3F) * 2) - 110; - /* Translate DBM to percentage. */ - rssi = query_rx_pwr_percentage(rx_pwr[i]); - total_rssi += rssi; - } - /* (2)PWDB, Average PWDB calculated by hardware (for - * rate adaptive) - */ - rx_pwr_all = (((pphy_head[PHY_STAT_PWDB_ALL_SHT]) >> 1) & 0x7f) - - 106; - pwdb_all = query_rx_pwr_percentage(rx_pwr_all); - - { - /* (3)EVM of HT rate */ - if (prframe->u.hdr.attrib.htc && - prframe->u.hdr.attrib.mcs_rate >= 20 && - prframe->u.hdr.attrib.mcs_rate <= 27) { - /* both spatial stream make sense */ - max_spatial_stream = 2; - } else { - /* only spatial stream 1 makes sense */ - max_spatial_stream = 1; - } - for (i = 0; i < max_spatial_stream; i++) { - evm = evm_db2percentage((pphy_head - [PHY_STAT_RXEVM_SHT + i]));/*dbm*/ - prframe->u.hdr.attrib.signal_qual = - (u8)(evm & 0xff); - prframe->u.hdr.attrib.rx_mimo_signal_qual[i] = - (u8)(evm & 0xff); - } - } - } - /* UI BSS List signal strength(in percentage), make it good looking, - * from 0~100. It is assigned to the BSS List in - * GetValueFromBeaconOrProbeRsp(). - */ - if (bcck_rate) { - prframe->u.hdr.attrib.signal_strength = - (u8)r8712_signal_scale_mapping(pwdb_all); - } else { - if (rf_rx_num != 0) - prframe->u.hdr.attrib.signal_strength = - (u8)(r8712_signal_scale_mapping(total_rssi /= - rf_rx_num)); - } -} - -static void process_link_qual(struct _adapter *padapter, - union recv_frame *prframe) -{ - u32 last_evm = 0, avg_val; - struct rx_pkt_attrib *pattrib; - struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; - - if (!prframe || !padapter) - return; - pattrib = &prframe->u.hdr.attrib; - if (pattrib->signal_qual != 0) { - /* - * 1. Record the general EVM to the sliding window. - */ - if (sqd->total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) { - sqd->total_num = PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = sqd->elements[sqd->index]; - sqd->total_val -= last_evm; - } - sqd->total_val += pattrib->signal_qual; - sqd->elements[sqd->index++] = pattrib->signal_qual; - if (sqd->index >= PHY_LINKQUALITY_SLID_WIN_MAX) - sqd->index = 0; - - /* <1> Showed on UI for user, in percentage. */ - avg_val = sqd->total_val / sqd->total_num; - padapter->recvpriv.signal = (u8)avg_val; - } -} - -static void process_rssi(struct _adapter *padapter, union recv_frame *prframe) -{ - u32 last_rssi, tmp_val; - struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; - struct smooth_rssi_data *ssd = &padapter->recvpriv.signal_strength_data; - - if (ssd->total_num++ >= PHY_RSSI_SLID_WIN_MAX) { - ssd->total_num = PHY_RSSI_SLID_WIN_MAX; - last_rssi = ssd->elements[ssd->index]; - ssd->total_val -= last_rssi; - } - ssd->total_val += pattrib->signal_strength; - ssd->elements[ssd->index++] = pattrib->signal_strength; - if (ssd->index >= PHY_RSSI_SLID_WIN_MAX) - ssd->index = 0; - tmp_val = ssd->total_val / ssd->total_num; - padapter->recvpriv.rssi = (s8)translate2dbm(padapter, (u8)tmp_val); -} - -static void process_phy_info(struct _adapter *padapter, - union recv_frame *prframe) -{ - query_rx_phy_status(padapter, prframe); - process_rssi(padapter, prframe); - process_link_qual(padapter, prframe); -} - -int recv_func(struct _adapter *padapter, void *pcontext) -{ - struct rx_pkt_attrib *pattrib; - union recv_frame *prframe, *orig_prframe; - int retval = _SUCCESS; - struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - prframe = pcontext; - orig_prframe = prframe; - pattrib = &prframe->u.hdr.attrib; - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - if (pattrib->crc_err == 1) - padapter->mppriv.rx_crcerrpktcount++; - else - padapter->mppriv.rx_pktcount++; - if (!check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE)) { - /* free this recv_frame */ - r8712_free_recvframe(orig_prframe, pfree_recv_queue); - goto _exit_recv_func; - } - } - /* check the frame crtl field and decache */ - retval = r8712_validate_recv_frame(padapter, prframe); - if (retval != _SUCCESS) { - /* free this recv_frame */ - r8712_free_recvframe(orig_prframe, pfree_recv_queue); - goto _exit_recv_func; - } - process_phy_info(padapter, prframe); - prframe = r8712_decryptor(padapter, prframe); - if (!prframe) { - retval = _FAIL; - goto _exit_recv_func; - } - prframe = r8712_recvframe_chk_defrag(padapter, prframe); - if (!prframe) - goto _exit_recv_func; - prframe = r8712_portctrl(padapter, prframe); - if (!prframe) { - retval = _FAIL; - goto _exit_recv_func; - } - retval = r8712_process_recv_indicatepkts(padapter, prframe); - if (retval != _SUCCESS) { - r8712_free_recvframe(orig_prframe, pfree_recv_queue); - goto _exit_recv_func; - } -_exit_recv_func: - return retval; -} - -static void recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) -{ - u8 *pbuf, shift_sz = 0; - u8 frag, mf; - uint pkt_len; - u32 transfer_len; - struct recv_stat *prxstat; - u16 pkt_cnt, drvinfo_sz, pkt_offset, tmp_len, alloc_sz; - struct __queue *pfree_recv_queue; - _pkt *pkt_copy = NULL; - union recv_frame *precvframe = NULL; - struct recv_priv *precvpriv = &padapter->recvpriv; - - pfree_recv_queue = &precvpriv->free_recv_queue; - pbuf = pskb->data; - prxstat = (struct recv_stat *)pbuf; - pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff; - pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x00003fff; - transfer_len = pskb->len; - /* Test throughput with Netgear 3700 (No security) with Chariot 3T3R - * pairs. The packet count will be a big number so that the containing - * packet will effect the Rx reordering. - */ - if (transfer_len < pkt_len) { - /* In this case, it means the MAX_RECVBUF_SZ is too small to - * get the data from 8712u. - */ - return; - } - do { - prxstat = (struct recv_stat *)pbuf; - pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x00003fff; - /* more fragment bit */ - mf = (le32_to_cpu(prxstat->rxdw1) >> 27) & 0x1; - /* ragmentation number */ - frag = (le32_to_cpu(prxstat->rxdw2) >> 12) & 0xf; - /* uint 2^3 = 8 bytes */ - drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; - drvinfo_sz <<= 3; - if (pkt_len <= 0) - return; - /* Qos data, wireless lan header length is 26 */ - if ((le32_to_cpu(prxstat->rxdw0) >> 23) & 0x01) - shift_sz = 2; - precvframe = r8712_alloc_recvframe(pfree_recv_queue); - if (!precvframe) - return; - INIT_LIST_HEAD(&precvframe->u.hdr.list); - precvframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf*/ - precvframe->u.hdr.len = 0; - tmp_len = pkt_len + drvinfo_sz + RXDESC_SIZE; - pkt_offset = (u16)round_up(tmp_len, 128); - /* for first fragment packet, driver need allocate 1536 + - * drvinfo_sz + RXDESC_SIZE to defrag packet. - */ - if ((mf == 1) && (frag == 0)) - /*1658+6=1664, 1664 is 128 alignment.*/ - alloc_sz = max_t(u16, tmp_len, 1658); - else - alloc_sz = tmp_len; - /* 2 is for IP header 4 bytes alignment in QoS packet case. - * 4 is for skb->data 4 bytes alignment. - */ - alloc_sz += 6; - pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz); - if (!pkt_copy) - return; - - precvframe->u.hdr.pkt = pkt_copy; - skb_reserve(pkt_copy, 4 - ((addr_t)(pkt_copy->data) % 4)); - skb_reserve(pkt_copy, shift_sz); - memcpy(pkt_copy->data, pbuf, tmp_len); - precvframe->u.hdr.rx_head = pkt_copy->data; - precvframe->u.hdr.rx_data = pkt_copy->data; - precvframe->u.hdr.rx_tail = pkt_copy->data; - precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz; - - recvframe_put(precvframe, tmp_len); - recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); - /* because the endian issue, driver avoid reference to the - * rxstat after calling update_recvframe_attrib_from_recvstat(); - */ - update_recvframe_attrib_from_recvstat(&precvframe->u.hdr.attrib, - prxstat); - r8712_recv_entry(precvframe); - transfer_len -= pkt_offset; - pbuf += pkt_offset; - pkt_cnt--; - precvframe = NULL; - pkt_copy = NULL; - } while ((transfer_len > 0) && pkt_cnt > 0); -} - -static void recv_tasklet(struct tasklet_struct *t) -{ - struct sk_buff *pskb; - struct _adapter *padapter = from_tasklet(padapter, t, - recvpriv.recv_tasklet); - struct recv_priv *precvpriv = &padapter->recvpriv; - - while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { - recvbuf2recvframe(padapter, pskb); - skb_reset_tail_pointer(pskb); - pskb->len = 0; - if (!skb_cloned(pskb)) - skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); - else - consume_skb(pskb); - } -} diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h deleted file mode 100644 index a1360dcf91cec4e64ec3bfba79fba1b43f716e6d..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_recv.h +++ /dev/null @@ -1,145 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL8712_RECV_H_ -#define _RTL8712_RECV_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -/* Realtek's v2.6.6 reduced this to 4. However, under heavy network and CPU - * loads, even 8 receive buffers might not be enough; cutting it to 4 seemed - * unwise. - */ -#define NR_RECVBUFF (8) - -#define NR_PREALLOC_RECV_SKB (8) -#define RXDESC_SIZE 24 -#define RXDESC_OFFSET RXDESC_SIZE -#define RECV_BLK_SZ 512 -#define RECV_BLK_CNT 16 -#define RECV_BLK_TH RECV_BLK_CNT -#define MAX_RECVBUF_SZ 9100 -#define RECVBUFF_ALIGN_SZ 512 -#define RSVD_ROOM_SZ (0) -/*These definition is used for Rx packet reordering.*/ -#define SN_LESS(a, b) (((a-b) & 0x800) != 0) -#define SN_EQUAL(a, b) (a == b) -#define REORDER_WAIT_TIME 30 /* (ms)*/ - -struct recv_stat { - __le32 rxdw0; - __le32 rxdw1; - __le32 rxdw2; - __le32 rxdw3; - __le32 rxdw4; - __le32 rxdw5; -}; - -struct phy_cck_rx_status { - /* For CCK rate descriptor. This is a unsigned 8:1 variable. - * LSB bit present 0.5. And MSB 7 bts present a signed value. - * Range from -64~+63.5. - */ - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -}; - -struct phy_stat { - __le32 phydw0; - __le32 phydw1; - __le32 phydw2; - __le32 phydw3; - __le32 phydw4; - __le32 phydw5; - __le32 phydw6; - __le32 phydw7; -}; - -#define PHY_STAT_GAIN_TRSW_SHT 0 -#define PHY_STAT_PWDB_ALL_SHT 4 -#define PHY_STAT_CFOSHO_SHT 5 -#define PHY_STAT_CCK_AGC_RPT_SHT 5 -#define PHY_STAT_CFOTAIL_SHT 9 -#define PHY_STAT_RXEVM_SHT 13 -#define PHY_STAT_RXSNR_SHT 15 -#define PHY_STAT_PDSNR_SHT 19 -#define PHY_STAT_CSI_CURRENT_SHT 21 -#define PHY_STAT_CSI_TARGET_SHT 23 -#define PHY_STAT_SIGEVM_SHT 25 -#define PHY_STAT_MAX_EX_PWR_SHT 26 - -union recvstat { - struct recv_stat recv_stat; - unsigned int value[RXDESC_SIZE >> 2]; -}; - -struct recv_buf { - struct list_head list; - spinlock_t recvbuf_lock; - u32 ref_cnt; - struct _adapter *adapter; - struct urb *purb; - _pkt *pskb; - u8 irp_pending; - u32 transfer_len; - uint len; - u8 *phead; - u8 *pdata; - u8 *ptail; - u8 *pend; - u8 *pbuf; - u8 *pallocated_buf; -}; - -/* - * head -----> - * data -----> - * payload - * tail -----> - * end -----> - * len = (unsigned int )(tail - data); - */ -struct recv_frame_hdr { - struct list_head list; - _pkt *pkt; - _pkt *pkt_newalloc; - struct _adapter *adapter; - u8 fragcnt; - struct rx_pkt_attrib attrib; - uint len; - u8 *rx_head; - u8 *rx_data; - u8 *rx_tail; - u8 *rx_end; - void *precvbuf; - struct sta_info *psta; - /*for A-MPDU Rx reordering buffer control*/ - struct recv_reorder_ctrl *preorder_ctrl; -}; - -union recv_frame { - union { - struct list_head list; - struct recv_frame_hdr hdr; - } u; -}; - -void r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf); -void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf); -s32 r8712_signal_scale_mapping(s32 cur_sig); -void r8712_reordering_ctrl_timeout_handler(void *pcontext); - -#endif - diff --git a/drivers/staging/rtl8712/rtl8712_regdef.h b/drivers/staging/rtl8712/rtl8712_regdef.h deleted file mode 100644 index 28aec9aa539fd315367c1bab84088c0e703d389c..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_regdef.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_REGDEF_H__ -#define __RTL8712_REGDEF_H__ - -#include "rtl8712_syscfg_regdef.h" -#include "rtl8712_cmdctrl_regdef.h" -#include "rtl8712_macsetting_regdef.h" -#include "rtl8712_timectrl_regdef.h" -#include "rtl8712_fifoctrl_regdef.h" -#include "rtl8712_ratectrl_regdef.h" -#include "rtl8712_edcasetting_regdef.h" -#include "rtl8712_wmac_regdef.h" -#include "rtl8712_powersave_regdef.h" -#include "rtl8712_gp_regdef.h" -#include "rtl8712_debugctrl_regdef.h" - -#define HIMR (RTL8712_INTERRUPT_ + 0x08) - -#endif /* __RTL8712_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_security_bitdef.h b/drivers/staging/rtl8712/rtl8712_security_bitdef.h deleted file mode 100644 index 44275ef455a0ae1a022e6ec7aa65b80f56b740ab..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_security_bitdef.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_SECURITY_BITDEF_H__ -#define __RTL8712_SECURITY_BITDEF_H__ - -/*CAMCMD*/ -#define _SECCAM_POLLING BIT(31) -#define _SECCAM_CLR BIT(30) -#define _SECCAM_WE BIT(16) -#define _SECCAM_ADR_MSK 0x000000FF -#define _SECCAM_ADR_SHT 0 - -/*CAMDBG*/ -#define _SECCAM_INFO BIT(31) -#define _SEC_KEYFOUND BIT(30) -#define _SEC_CONFIG_MSK 0x3F000000 -#define _SEC_CONFIG_SHT 24 -#define _SEC_KEYCONTENT_MSK 0x00FFFFFF -#define _SEC_KEYCONTENT_SHT 0 - -/*SECCFG*/ -#define _NOSKMC BIT(5) -#define _SKBYA2 BIT(4) -#define _RXDEC BIT(3) -#define _TXENC BIT(2) -#define _RXUSEDK BIT(1) -#define _TXUSEDK BIT(0) - -#endif /*__RTL8712_SECURITY_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_spec.h b/drivers/staging/rtl8712/rtl8712_spec.h deleted file mode 100644 index 613a410e5714bcb4725be55a3f38d5f18646c665..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_spec.h +++ /dev/null @@ -1,121 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_SPEC_H__ -#define __RTL8712_SPEC_H__ - -#define RTL8712_IOBASE_TXPKT 0x10200000 /*IOBASE_TXPKT*/ -#define RTL8712_IOBASE_RXPKT 0x10210000 /*IOBASE_RXPKT*/ -#define RTL8712_IOBASE_RXCMD 0x10220000 /*IOBASE_RXCMD*/ -#define RTL8712_IOBASE_TXSTATUS 0x10230000 /*IOBASE_TXSTATUS*/ -#define RTL8712_IOBASE_RXSTATUS 0x10240000 /*IOBASE_RXSTATUS*/ -#define RTL8712_IOBASE_IOREG 0x10250000 /*IOBASE_IOREG ADDR*/ -#define RTL8712_IOBASE_SCHEDULER 0x10260000 /*IOBASE_SCHEDULE*/ - -#define RTL8712_IOBASE_TRXDMA 0x10270000 /*IOBASE_TRXDMA*/ -#define RTL8712_IOBASE_TXLLT 0x10280000 /*IOBASE_TXLLT*/ -#define RTL8712_IOBASE_WMAC 0x10290000 /*IOBASE_WMAC*/ -#define RTL8712_IOBASE_FW2HW 0x102A0000 /*IOBASE_FW2HW*/ -#define RTL8712_IOBASE_ACCESS_PHYREG 0x102B0000 /*IOBASE_ACCESS_PHYREG*/ - -#define RTL8712_IOBASE_FF 0x10300000 /*IOBASE_FIFO 0x1031000~0x103AFFFF*/ - -/*IOREG Offset for 8712*/ -#define RTL8712_SYSCFG_ RTL8712_IOBASE_IOREG -#define RTL8712_CMDCTRL_ (RTL8712_IOBASE_IOREG + 0x40) -#define RTL8712_MACIDSETTING_ (RTL8712_IOBASE_IOREG + 0x50) -#define RTL8712_TIMECTRL_ (RTL8712_IOBASE_IOREG + 0x80) -#define RTL8712_FIFOCTRL_ (RTL8712_IOBASE_IOREG + 0xA0) -#define RTL8712_RATECTRL_ (RTL8712_IOBASE_IOREG + 0x160) -#define RTL8712_EDCASETTING_ (RTL8712_IOBASE_IOREG + 0x1D0) -#define RTL8712_WMAC_ (RTL8712_IOBASE_IOREG + 0x200) -#define RTL8712_SECURITY_ (RTL8712_IOBASE_IOREG + 0x240) -#define RTL8712_POWERSAVE_ (RTL8712_IOBASE_IOREG + 0x260) -#define RTL8712_GP_ (RTL8712_IOBASE_IOREG + 0x2E0) -#define RTL8712_INTERRUPT_ (RTL8712_IOBASE_IOREG + 0x300) -#define RTL8712_DEBUGCTRL_ (RTL8712_IOBASE_IOREG + 0x310) -#define RTL8712_OFFLOAD_ (RTL8712_IOBASE_IOREG + 0x2D0) - -/*FIFO for 8712*/ -#define RTL8712_DMA_BCNQ (RTL8712_IOBASE_FF + 0x10000) -#define RTL8712_DMA_MGTQ (RTL8712_IOBASE_FF + 0x20000) -#define RTL8712_DMA_BMCQ (RTL8712_IOBASE_FF + 0x30000) -#define RTL8712_DMA_VOQ (RTL8712_IOBASE_FF + 0x40000) -#define RTL8712_DMA_VIQ (RTL8712_IOBASE_FF + 0x50000) -#define RTL8712_DMA_BEQ (RTL8712_IOBASE_FF + 0x60000) -#define RTL8712_DMA_BKQ (RTL8712_IOBASE_FF + 0x70000) -#define RTL8712_DMA_RX0FF (RTL8712_IOBASE_FF + 0x80000) -#define RTL8712_DMA_H2CCMD (RTL8712_IOBASE_FF + 0x90000) -#define RTL8712_DMA_C2HCMD (RTL8712_IOBASE_FF + 0xA0000) - -/*------------------------------*/ - -/*BIT 16 15*/ -#define DID_SDIO_LOCAL 0 /* 0 0*/ -#define DID_WLAN_IOREG 1 /* 0 1*/ -#define DID_WLAN_FIFO 3 /* 1 1*/ -#define DID_UNDEFINE (-1) - -#define CMD_ADDR_MAPPING_SHIFT 2 /*SDIO CMD ADDR MAPPING, - *shift 2 bit for match - * offset[14:2] - */ - -/*Offset for SDIO LOCAL*/ -#define OFFSET_SDIO_LOCAL 0x0FFF - -/*Offset for WLAN IOREG*/ -#define OFFSET_WLAN_IOREG 0x0FFF - -/*Offset for WLAN FIFO*/ -#define OFFSET_TX_BCNQ 0x0300 -#define OFFSET_TX_HIQ 0x0310 -#define OFFSET_TX_CMDQ 0x0320 -#define OFFSET_TX_MGTQ 0x0330 -#define OFFSET_TX_HCCAQ 0x0340 -#define OFFSET_TX_VOQ 0x0350 -#define OFFSET_TX_VIQ 0x0360 -#define OFFSET_TX_BEQ 0x0370 -#define OFFSET_TX_BKQ 0x0380 -#define OFFSET_RX_RX0FFQ 0x0390 -#define OFFSET_RX_C2HFFQ 0x03A0 - -#define BK_QID_01 1 -#define BK_QID_02 2 -#define BE_QID_01 0 -#define BE_QID_02 3 -#define VI_QID_01 4 -#define VI_QID_02 5 -#define VO_QID_01 6 -#define VO_QID_02 7 -#define HCCA_QID_01 8 -#define HCCA_QID_02 9 -#define HCCA_QID_03 10 -#define HCCA_QID_04 11 -#define HCCA_QID_05 12 -#define HCCA_QID_06 13 -#define HCCA_QID_07 14 -#define HCCA_QID_08 15 -#define HI_QID 17 -#define CMD_QID 19 -#define MGT_QID 18 -#define BCN_QID 16 - -#include "rtl8712_regdef.h" - -#include "rtl8712_bitdef.h" - -#include "basic_types.h" - -#endif /* __RTL8712_SPEC_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h deleted file mode 100644 index d92df3fbd2b193c89d6b51e0311792d5523f8e42..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h +++ /dev/null @@ -1,163 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_SYSCFG_BITDEF_H__ -#define __RTL8712_SYSCFG_BITDEF_H__ - -/*SYS_PWR_CTRL*/ -/*SRCTRL0*/ -/*SRCTRL1*/ -/*SYS_CLKR*/ - -/*SYS_IOS_CTRL*/ -#define iso_LDR2RP_SHT 8 /* EE Loader to Retention Path*/ -#define iso_LDR2RP BIT(iso_LDR2RP_SHT) /* 1:isolation, 0:attach*/ - -/*SYS_CTRL*/ -#define FEN_DIO_SDIO_SHT 0 -#define FEN_DIO_SDIO BIT(FEN_DIO_SDIO_SHT) -#define FEN_SDIO_SHT 1 -#define FEN_SDIO BIT(FEN_SDIO_SHT) -#define FEN_USBA_SHT 2 -#define FEN_USBA BIT(FEN_USBA_SHT) -#define FEN_UPLL_SHT 3 -#define FEN_UPLL BIT(FEN_UPLL_SHT) -#define FEN_USBD_SHT 4 -#define FEN_USBD BIT(FEN_USBD_SHT) -#define FEN_DIO_PCIE_SHT 5 -#define FEN_DIO_PCIE BIT(FEN_DIO_PCIE_SHT) -#define FEN_PCIEA_SHT 6 -#define FEN_PCIEA BIT(FEN_PCIEA_SHT) -#define FEN_PPLL_SHT 7 -#define FEN_PPLL BIT(FEN_PPLL_SHT) -#define FEN_PCIED_SHT 8 -#define FEN_PCIED BIT(FEN_PCIED_SHT) -#define FEN_CPUEN_SHT 10 -#define FEN_CPUEN BIT(FEN_CPUEN_SHT) -#define FEN_DCORE_SHT 11 -#define FEN_DCORE BIT(FEN_DCORE_SHT) -#define FEN_ELDR_SHT 12 -#define FEN_ELDR BIT(FEN_ELDR_SHT) -#define PWC_DV2LDR_SHT 13 -#define PWC_DV2LDR BIT(PWC_DV2LDR_SHT) /* Loader Power Enable*/ - -/*=== SYS_CLKR ===*/ -#define SYS_CLKSEL_SHT 0 -#define SYS_CLKSEL BIT(SYS_CLKSEL_SHT) /* System Clock 80MHz*/ -#define PS_CLKSEL_SHT 1 -#define PS_CLKSEL BIT(PS_CLKSEL_SHT) /*System power save - * clock select. - */ -#define CPU_CLKSEL_SHT 2 -#define CPU_CLKSEL BIT(CPU_CLKSEL_SHT) /* System Clock select, - * 1: AFE source, - * 0: System clock(L-Bus) - */ -#define INT32K_EN_SHT 3 -#define INT32K_EN BIT(INT32K_EN_SHT) -#define MACSLP_SHT 4 -#define MACSLP BIT(MACSLP_SHT) -#define MAC_CLK_EN_SHT 11 -#define MAC_CLK_EN BIT(MAC_CLK_EN_SHT) /* MAC Clock Enable.*/ -#define SYS_CLK_EN_SHT 12 -#define SYS_CLK_EN BIT(SYS_CLK_EN_SHT) -#define RING_CLK_EN_SHT 13 -#define RING_CLK_EN BIT(RING_CLK_EN_SHT) -#define SWHW_SEL_SHT 14 -#define SWHW_SEL BIT(SWHW_SEL_SHT) /* Load done, - * control path switch. - */ -#define FWHW_SEL_SHT 15 -#define FWHW_SEL BIT(FWHW_SEL_SHT) /* Sleep exit, - * control path switch. - */ - -/*9346CR*/ -#define _VPDIDX_MSK 0xFF00 -#define _VPDIDX_SHT 8 -#define _EEM_MSK 0x00C0 -#define _EEM_SHT 6 -#define _EEM0 BIT(6) -#define _EEM1 BIT(7) -#define _EEPROM_EN BIT(5) -#define _9356SEL BIT(4) -#define _EECS BIT(3) -#define _EESK BIT(2) -#define _EEDI BIT(1) -#define _EEDO BIT(0) - -/*AFE_MISC*/ -#define AFE_MISC_USB_MBEN_SHT 7 -#define AFE_MISC_USB_MBEN BIT(AFE_MISC_USB_MBEN_SHT) -#define AFE_MISC_USB_BGEN_SHT 6 -#define AFE_MISC_USB_BGEN BIT(AFE_MISC_USB_BGEN_SHT) -#define AFE_MISC_LD12_VDAJ_SHT 4 -#define AFE_MISC_LD12_VDAJ_MSK 0X0030 -#define AFE_MISC_LD12_VDAJ BIT(AFE_MISC_LD12_VDAJ_SHT) -#define AFE_MISC_I32_EN_SHT 3 -#define AFE_MISC_I32_EN BIT(AFE_MISC_I32_EN_SHT) -#define AFE_MISC_E32_EN_SHT 2 -#define AFE_MISC_E32_EN BIT(AFE_MISC_E32_EN_SHT) -#define AFE_MISC_MBEN_SHT 1 -#define AFE_MISC_MBEN BIT(AFE_MISC_MBEN_SHT)/* Enable AFE Macro - * Block's Mbias. - */ -#define AFE_MISC_BGEN_SHT 0 -#define AFE_MISC_BGEN BIT(AFE_MISC_BGEN_SHT)/* Enable AFE Macro - * Block's Bandgap. - */ - -/*--------------------------------------------------------------------------*/ -/* SPS1_CTRL bits (Offset 0x18-1E, 56bits)*/ -/*--------------------------------------------------------------------------*/ -#define SPS1_SWEN BIT(1) /* Enable vsps18 SW Macro Block.*/ -#define SPS1_LDEN BIT(0) /* Enable VSPS12 LDO Macro block.*/ - -/*----------------------------------------------------------------------------*/ -/* LDOA15_CTRL bits (Offset 0x20, 8bits)*/ -/*----------------------------------------------------------------------------*/ -#define LDA15_EN BIT(0) /* Enable LDOA15 Macro Block*/ - -/*----------------------------------------------------------------------------*/ -/* 8192S LDOV12D_CTRL bit (Offset 0x21, 8bits)*/ -/*----------------------------------------------------------------------------*/ -#define LDV12_EN BIT(0) /* Enable LDOVD12 Macro Block*/ -#define LDV12_SDBY BIT(1) /* LDOVD12 standby mode*/ - -/*CLK_PS_CTRL*/ -#define _CLK_GATE_EN BIT(0) - -/* EFUSE_CTRL*/ -#define EF_FLAG BIT(31) /* Access Flag, Write:1; - * Read:0 - */ -#define EF_PGPD 0x70000000 /* E-fuse Program time*/ -#define EF_RDT 0x0F000000 /* E-fuse read time: in the - * unit of cycle time - */ -#define EF_PDN_EN BIT(19) /* EFuse Power down enable*/ -#define ALD_EN BIT(18) /* Autoload Enable*/ -#define EF_ADDR 0x0003FF00 /* Access Address*/ -#define EF_DATA 0x000000FF /* Access Data*/ - -/* EFUSE_TEST*/ -#define LDOE25_EN BIT(31) /* Enable LDOE25 Macro Block*/ - -/* EFUSE_CLK_CTRL*/ -#define EFUSE_CLK_EN BIT(1) /* E-Fuse Clock Enable*/ -#define EFUSE_CLK_SEL BIT(0) /* E-Fuse Clock Select, - * 0:500K, 1:40M - */ - -#endif /*__RTL8712_SYSCFG_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h deleted file mode 100644 index da5efcdedabe2f091fee39cb104b086539264185..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_SYSCFG_REGDEF_H__ -#define __RTL8712_SYSCFG_REGDEF_H__ - -#define SYS_ISO_CTRL (RTL8712_SYSCFG_ + 0x0000) -#define SYS_FUNC_EN (RTL8712_SYSCFG_ + 0x0002) -#define PMC_FSM (RTL8712_SYSCFG_ + 0x0004) -#define SYS_CLKR (RTL8712_SYSCFG_ + 0x0008) -#define EE_9346CR (RTL8712_SYSCFG_ + 0x000A) -#define EE_VPD (RTL8712_SYSCFG_ + 0x000C) -#define AFE_MISC (RTL8712_SYSCFG_ + 0x0010) -#define SPS0_CTRL (RTL8712_SYSCFG_ + 0x0011) -#define SPS1_CTRL (RTL8712_SYSCFG_ + 0x0018) -#define RF_CTRL (RTL8712_SYSCFG_ + 0x001F) -#define LDOA15_CTRL (RTL8712_SYSCFG_ + 0x0020) -#define LDOV12D_CTRL (RTL8712_SYSCFG_ + 0x0021) -#define LDOHCI12_CTRL (RTL8712_SYSCFG_ + 0x0022) -#define LDO_USB_CTRL (RTL8712_SYSCFG_ + 0x0023) -#define LPLDO_CTRL (RTL8712_SYSCFG_ + 0x0024) -#define AFE_XTAL_CTRL (RTL8712_SYSCFG_ + 0x0026) -#define AFE_PLL_CTRL (RTL8712_SYSCFG_ + 0x0028) -#define EFUSE_CTRL (RTL8712_SYSCFG_ + 0x0030) -#define EFUSE_TEST (RTL8712_SYSCFG_ + 0x0034) -#define PWR_DATA (RTL8712_SYSCFG_ + 0x0038) -#define DPS_TIMER (RTL8712_SYSCFG_ + 0x003C) -#define RCLK_MON (RTL8712_SYSCFG_ + 0x003E) -#define EFUSE_CLK_CTRL (RTL8712_SYSCFG_ + 0x02F8) - -#endif /*__RTL8712_SYSCFG_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h deleted file mode 100644 index d7bc9dd5cecd21d7d6c53b398ecb38b979edc77d..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_TIMECTRL_BITDEF_H__ -#define __RTL8712_TIMECTRL_BITDEF_H__ - -/*TSFTR*/ -/*SLOT*/ -/*USTIME*/ - -/*TUBASE*/ -#define _TUBASE_MSK 0x07FF - -/*SIFS_CCK*/ -#define _SIFS_CCK_TRX_MSK 0xFF00 -#define _SIFS_CCK_TRX_SHT 0x8 -#define _SIFS_CCK_CTX_MSK 0x00FF -#define _SIFS_CCK_CTX_SHT 0 - -/*SIFS_OFDM*/ -#define _SIFS_OFDM_TRX_MSK 0xFF00 -#define _SIFS_OFDM_TRX_SHT 0x8 -#define _SIFS_OFDM_CTX_MSK 0x00FF -#define _SIFS_OFDM_CTX_SHT 0 - -/*PIFS*/ -/*ACKTO*/ -/*EIFS*/ -/*BCNITV*/ -/*ATIMWND*/ - -/*DRVERLYINT*/ -#define _ENSWBCN BIT(15) -#define _DRVERLY_TU_MSK 0x0FF0 -#define _DRVERLY_TU_SHT 4 -#define _DRVERLY_US_MSK 0x000F -#define _DRVERLY_US_SHT 0 - -/*BCNDMATIM*/ -#define _BCNDMATIM_MSK 0x03FF - -/*BCNERRTH*/ -/*MLT*/ - -#endif /* __RTL8712_TIMECTRL_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h deleted file mode 100644 index b51603f1b880044a3ba7b6423b8877030d185374..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_TIMECTRL_REGDEF_H__ -#define __RTL8712_TIMECTRL_REGDEF_H__ - -#define TSFTR (RTL8712_TIMECTRL_ + 0x00) -#define USTIME (RTL8712_TIMECTRL_ + 0x08) -#define SLOT (RTL8712_TIMECTRL_ + 0x09) -#define TUBASE (RTL8712_TIMECTRL_ + 0x0A) -#define SIFS_CCK (RTL8712_TIMECTRL_ + 0x0C) -#define SIFS_OFDM (RTL8712_TIMECTRL_ + 0x0E) -#define PIFS (RTL8712_TIMECTRL_ + 0x10) -#define ACKTO (RTL8712_TIMECTRL_ + 0x11) -#define EIFS (RTL8712_TIMECTRL_ + 0x12) -#define BCNITV (RTL8712_TIMECTRL_ + 0x14) -#define ATIMWND (RTL8712_TIMECTRL_ + 0x16) -#define DRVERLYINT (RTL8712_TIMECTRL_ + 0x18) -#define BCNDMATIM (RTL8712_TIMECTRL_ + 0x1A) -#define BCNERRTH (RTL8712_TIMECTRL_ + 0x1C) -#define MLT (RTL8712_TIMECTRL_ + 0x1D) - -#endif /* __RTL8712_TIMECTRL_REGDEF_H__ */ diff --git a/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h b/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h deleted file mode 100644 index ea164e48234766798d11c1bf2d0e89397d4c286c..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_WMAC_BITDEF_H__ -#define __RTL8712_WMAC_BITDEF_H__ - -/*NAVCTRL*/ -#define _NAV_UPPER_EN BIT(18) -#define _NAV_MTO_EN BIT(17) -#define _NAV_UPPER BIT(16) -#define _NAV_MTO_MSK 0xFF00 -#define _NAV_MTO_SHT 8 -#define _RTSRST_MSK 0x00FF -#define _RTSRST_SHT 0 - -/*BWOPMODE*/ -#define _20MHZBW BIT(2) - -/*BACAMCMD*/ -#define _BACAM_POLL BIT(31) -#define _BACAM_RST BIT(17) -#define _BACAM_RW BIT(16) -#define _BACAM_ADDR_MSK 0x0000007F -#define _BACAM_ADDR_SHT 0 - -/*LBDLY*/ -#define _LBDLY_MSK 0x1F - -/*FWDLY*/ -#define _FWDLY_MSK 0x0F - -/*RXERR_RPT*/ -#define _RXERR_RPT_SEL_MSK 0xF0000000 -#define _RXERR_RPT_SEL_SHT 28 -#define _RPT_CNT_MSK 0x000FFFFF -#define _RPT_CNT_SHT 0 - -#endif /*__RTL8712_WMAC_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_wmac_regdef.h b/drivers/staging/rtl8712/rtl8712_wmac_regdef.h deleted file mode 100644 index dfe3e9fbed4313ff370c4c924c9742533ef91ab6..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_wmac_regdef.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_WMAC_REGDEF_H__ -#define __RTL8712_WMAC_REGDEF_H__ - -#define NAVCTRL (RTL8712_WMAC_ + 0x00) -#define BWOPMODE (RTL8712_WMAC_ + 0x03) -#define BACAMCMD (RTL8712_WMAC_ + 0x04) -#define BACAMCONTENT (RTL8712_WMAC_ + 0x08) -#define LBDLY (RTL8712_WMAC_ + 0x10) -#define FWDLY (RTL8712_WMAC_ + 0x11) -#define HWPC_RX_CTRL (RTL8712_WMAC_ + 0x18) -#define MQ (RTL8712_WMAC_ + 0x20) -#define MA (RTL8712_WMAC_ + 0x22) -#define MS (RTL8712_WMAC_ + 0x24) -#define CLM_RESULT (RTL8712_WMAC_ + 0x27) -#define NHM_RPI_CNT (RTL8712_WMAC_ + 0x28) -#define RXERR_RPT (RTL8712_WMAC_ + 0x30) -#define NAV_PROT_LEN (RTL8712_WMAC_ + 0x34) -#define CFEND_TH (RTL8712_WMAC_ + 0x36) -#define AMPDU_MIN_SPACE (RTL8712_WMAC_ + 0x37) -#define TXOP_STALL_CTRL (RTL8712_WMAC_ + 0x38) - -#endif /*__RTL8712_WMAC_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c deleted file mode 100644 index 12f2fdb1b3cbcc7c984e9eb2643e0972eed79184..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ /dev/null @@ -1,732 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_xmit.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_XMIT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wifi.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -static void dump_xframe(struct _adapter *padapter, - struct xmit_frame *pxmitframe); -static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz); - -sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag) -{ - phw_txqueue->ac_tag = ac_tag; - switch (ac_tag) { - case BE_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ; - break; - case BK_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_BKQ; - break; - case VI_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_VIQ; - break; - case VO_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_VOQ; - break; - case BMC_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ; - break; - } - return _SUCCESS; -} - -int r8712_txframes_sta_ac_pending(struct _adapter *padapter, - struct pkt_attrib *pattrib) -{ - struct sta_info *psta; - struct tx_servq *ptxservq; - int priority = pattrib->priority; - - psta = pattrib->psta; - switch (priority) { - case 1: - case 2: - ptxservq = &psta->sta_xmitpriv.bk_q; - break; - case 4: - case 5: - ptxservq = &psta->sta_xmitpriv.vi_q; - break; - case 6: - case 7: - ptxservq = &psta->sta_xmitpriv.vo_q; - break; - case 0: - case 3: - default: - ptxservq = &psta->sta_xmitpriv.be_q; - break; - } - return ptxservq->qcnt; -} - -static u32 get_ff_hwaddr(struct xmit_frame *pxmitframe) -{ - u32 addr = 0; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct _adapter *padapter = pxmitframe->padapter; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - - if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { - addr = RTL8712_DMA_H2CCMD; - } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { - addr = RTL8712_DMA_MGTQ; - } else if (pdvobj->nr_endpoint == 6) { - switch (pattrib->priority) { - case 0: - case 3: - addr = RTL8712_DMA_BEQ; - break; - case 1: - case 2: - addr = RTL8712_DMA_BKQ; - break; - case 4: - case 5: - addr = RTL8712_DMA_VIQ; - break; - case 6: - case 7: - addr = RTL8712_DMA_VOQ; - break; - case 0x10: - case 0x11: - case 0x12: - case 0x13: - addr = RTL8712_DMA_H2CCMD; - break; - default: - addr = RTL8712_DMA_BEQ; - break; - } - } else if (pdvobj->nr_endpoint == 4) { - switch (pattrib->qsel) { - case 0: - case 3: - case 1: - case 2: - addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/ - break; - case 4: - case 5: - case 6: - case 7: - addr = RTL8712_DMA_VOQ;/*RTL8712_EP_HI;*/ - break; - case 0x10: - case 0x11: - case 0x12: - case 0x13: - addr = RTL8712_DMA_H2CCMD; - break; - default: - addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/ - break; - } - } - return addr; -} - -static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, - struct hw_xmit *phwxmit, struct tx_servq *ptxservq, - struct __queue *pframe_queue) -{ - struct list_head *xmitframe_plist, *xmitframe_phead; - struct xmit_frame *pxmitframe = NULL; - - xmitframe_phead = &pframe_queue->queue; - xmitframe_plist = xmitframe_phead->next; - if (!end_of_queue_search(xmitframe_phead, xmitframe_plist)) { - pxmitframe = container_of(xmitframe_plist, - struct xmit_frame, list); - list_del_init(&pxmitframe->list); - ptxservq->qcnt--; - phwxmit->txcmdcnt++; - } - return pxmitframe; -} - -static struct xmit_frame *dequeue_xframe_ex(struct xmit_priv *pxmitpriv, - struct hw_xmit *phwxmit_i, sint entry) -{ - unsigned long irqL0; - struct list_head *sta_plist, *sta_phead; - struct hw_xmit *phwxmit; - struct tx_servq *ptxservq = NULL; - struct __queue *pframe_queue = NULL; - struct xmit_frame *pxmitframe = NULL; - int i, inx[4]; - int j, acirp_cnt[4]; - - /*entry indx: 0->vo, 1->vi, 2->be, 3->bk.*/ - inx[0] = 0; acirp_cnt[0] = pxmitpriv->voq_cnt; - inx[1] = 1; acirp_cnt[1] = pxmitpriv->viq_cnt; - inx[2] = 2; acirp_cnt[2] = pxmitpriv->beq_cnt; - inx[3] = 3; acirp_cnt[3] = pxmitpriv->bkq_cnt; - for (i = 0; i < 4; i++) { - for (j = i + 1; j < 4; j++) { - if (acirp_cnt[j] < acirp_cnt[i]) { - swap(acirp_cnt[i], acirp_cnt[j]); - swap(inx[i], inx[j]); - } - } - } - spin_lock_irqsave(&pxmitpriv->lock, irqL0); - for (i = 0; i < entry; i++) { - phwxmit = phwxmit_i + inx[i]; - sta_phead = &phwxmit->sta_queue->queue; - sta_plist = sta_phead->next; - while (!end_of_queue_search(sta_phead, sta_plist)) { - ptxservq = container_of(sta_plist, struct tx_servq, tx_pending); - pframe_queue = &ptxservq->sta_pending; - pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, - pframe_queue); - if (pxmitframe) { - phwxmit->accnt--; - goto exit_dequeue_xframe_ex; - } - sta_plist = sta_plist->next; - /*Remove sta node when there are no pending packets.*/ - if (list_empty(&pframe_queue->queue)) { - /* must be done after sta_plist->next - * and before break - */ - list_del_init(&ptxservq->tx_pending); - } - } - } -exit_dequeue_xframe_ex: - spin_unlock_irqrestore(&pxmitpriv->lock, irqL0); - return pxmitframe; -} - -void r8712_do_queue_select(struct _adapter *padapter, struct pkt_attrib *pattrib) -{ - unsigned int qsel = 0; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - - if (pdvobj->nr_endpoint == 6) { - qsel = (unsigned int)pattrib->priority; - } else if (pdvobj->nr_endpoint == 4) { - qsel = (unsigned int)pattrib->priority; - if (qsel == 0 || qsel == 3) - qsel = 3; - else if (qsel == 1 || qsel == 2) - qsel = 1; - else if (qsel == 4 || qsel == 5) - qsel = 5; - else if (qsel == 6 || qsel == 7) - qsel = 7; - else - qsel = 3; - } - pattrib->qsel = qsel; -} - -#ifdef CONFIG_R8712_TX_AGGR -void r8712_construct_txaggr_cmd_desc(struct xmit_buf *pxmitbuf) -{ - struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf; - - /* Fill up TxCmd Descriptor according as USB FW Tx Aggregation info.*/ - /* dw0 */ - ptx_desc->txdw0 = cpu_to_le32(CMD_HDR_SZ & 0xffff); - ptx_desc->txdw0 |= - cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & - 0x00ff0000); - ptx_desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); - - /* dw1 */ - ptx_desc->txdw1 |= cpu_to_le32((0x13 << QSEL_SHT) & 0x00001f00); -} - -void r8712_construct_txaggr_cmd_hdr(struct xmit_buf *pxmitbuf) -{ - struct xmit_frame *pxmitframe = (struct xmit_frame *) - pxmitbuf->priv_data; - struct _adapter *padapter = pxmitframe->padapter; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct cmd_hdr *pcmd_hdr = (struct cmd_hdr *) - (pxmitbuf->pbuf + TXDESC_SIZE); - - /* Fill up Cmd Header for USB FW Tx Aggregation.*/ - /* dw0 */ - pcmd_hdr->cmd_dw0 = cpu_to_le32((GEN_CMD_CODE(_AMSDU_TO_AMPDU) << 16) | - (pcmdpriv->cmd_seq << 24)); - pcmdpriv->cmd_seq++; -} - -void r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) -{ - struct _adapter *padapter = pxmitframe->padapter; - struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf; - int last_txcmdsz = 0; - int padding_sz = 0; - - /* 802.3->802.11 converter */ - r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); - /* free skb struct */ - r8712_xmit_complete(padapter, pxmitframe); - if (pxmitframe->attrib.ether_type != 0x0806) { - if ((pxmitframe->attrib.ether_type != 0x888e) && - (pxmitframe->attrib.dhcp_pkt != 1)) { - r8712_issue_addbareq_cmd(padapter, pxmitframe->attrib.priority); - } - } - pxmitframe->last[0] = 1; - update_txdesc(pxmitframe, (uint *)(pxmitframe->buf_addr), pxmitframe->attrib.last_txcmdsz); - /*padding zero */ - last_txcmdsz = pxmitframe->attrib.last_txcmdsz; - padding_sz = (8 - (last_txcmdsz % 8)); - if ((last_txcmdsz % 8) != 0) { - int i; - - for (i = 0; i < padding_sz; i++) - *(pxmitframe->buf_addr + TXDESC_SIZE + last_txcmdsz + - i) = 0; - } - /* Add the new mpdu's length */ - ptx_desc->txdw0 = cpu_to_le32((ptx_desc->txdw0 & 0xffff0000) | - ((ptx_desc->txdw0 & 0x0000ffff) + - ((TXDESC_SIZE + last_txcmdsz + padding_sz) & - 0x0000ffff))); -} - -void r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) -{ - /* linux complete context doesn't need to protect */ - pxmitframe->pxmitbuf = pxmitbuf; - pxmitbuf->priv_data = pxmitframe; - pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0]; - /* buffer addr assoc */ - pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE + CMD_HDR_SZ; - /*RTL8712_DMA_H2CCMD */ - r8712_construct_txaggr_cmd_desc(pxmitbuf); - r8712_construct_txaggr_cmd_hdr(pxmitbuf); - r8712_append_mpdu_unit(pxmitbuf, pxmitframe); - pxmitbuf->aggr_nr = 1; -} - -u16 r8712_xmitframe_aggr_next(struct xmit_buf *pxmitbuf, struct xmit_frame *pxmitframe) -{ - pxmitframe->pxmitbuf = pxmitbuf; - pxmitbuf->priv_data = pxmitframe; - pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0]; - /* buffer addr assoc */ - pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE + - (((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff); - r8712_append_mpdu_unit(pxmitbuf, pxmitframe); - r8712_free_xmitframe_ex(&pxmitframe->padapter->xmitpriv, - pxmitframe); - pxmitbuf->aggr_nr++; - - return TXDESC_SIZE + - (((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff); -} - -void r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) -{ - struct _adapter *padapter = pxmitframe->padapter; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - struct tx_desc *ptxdesc = pxmitbuf->pbuf; - struct cmd_hdr *pcmd_hdr = (struct cmd_hdr *) - (pxmitbuf->pbuf + TXDESC_SIZE); - u16 total_length = (u16)(ptxdesc->txdw0 & 0xffff); - - /* use 1st xmitframe as media */ - xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf); - pcmd_hdr->cmd_dw0 = cpu_to_le32(((total_length - CMD_HDR_SZ) & - 0x0000ffff) | (pcmd_hdr->cmd_dw0 & - 0xffff0000)); - - /* urb length in cmd_dw1 */ - pcmd_hdr->cmd_dw1 = cpu_to_le32((pxmitbuf->aggr_nr & 0xff) | - ((total_length + TXDESC_SIZE) << 16)); - pxmitframe->last[0] = 1; - pxmitframe->bpending[0] = false; - pxmitframe->mem_addr = pxmitbuf->pbuf; - - if ((pdvobj->ishighspeed && ((total_length + TXDESC_SIZE) % 0x200) == 0) || - ((!pdvobj->ishighspeed && ((total_length + TXDESC_SIZE) % - 0x40) == 0))) { - ptxdesc->txdw0 |= cpu_to_le32 - (((TXDESC_SIZE + OFFSET_SZ + 8) << OFFSET_SHT) & - 0x00ff0000); - /*32 bytes for TX Desc + 8 bytes pending*/ - } else { - ptxdesc->txdw0 |= cpu_to_le32 - (((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & - 0x00ff0000); - /*default = 32 bytes for TX Desc*/ - } - r8712_write_port(pxmitframe->padapter, RTL8712_DMA_H2CCMD, total_length + TXDESC_SIZE, - (u8 *)pxmitframe); -} - -#endif - -static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz) -{ - uint qsel; - struct _adapter *padapter = pxmitframe->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct tx_desc *ptxdesc = (struct tx_desc *)pmem; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; -#ifdef CONFIG_R8712_TX_AGGR - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; -#endif - u8 blnSetTxDescOffset; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - struct tx_desc txdesc_mp; - - memcpy(&txdesc_mp, ptxdesc, sizeof(struct tx_desc)); - memset(ptxdesc, 0, sizeof(struct tx_desc)); - /* offset 0 */ - ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff); - if (pdvobj->ishighspeed) { - if (((sz + TXDESC_SIZE) % 512) == 0) - blnSetTxDescOffset = 1; - else - blnSetTxDescOffset = 0; - } else { - if (((sz + TXDESC_SIZE) % 64) == 0) - blnSetTxDescOffset = 1; - else - blnSetTxDescOffset = 0; - } - if (blnSetTxDescOffset) { - /* 32 bytes for TX Desc + 8 bytes pending */ - ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ + 8) << - OFFSET_SHT) & 0x00ff0000); - } else { - /* default = 32 bytes for TX Desc */ - ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << - OFFSET_SHT) & 0x00ff0000); - } - ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); - if (pxmitframe->frame_tag == DATA_FRAMETAG) { - /* offset 4 */ - ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x1f); - -#ifdef CONFIG_R8712_TX_AGGR - /* dirty workaround, need to check if it is aggr cmd. */ - if ((u8 *)pmem != (u8 *)pxmitframe->pxmitbuf->pbuf) { - ptxdesc->txdw0 |= cpu_to_le32 - ((0x3 << TYPE_SHT) & TYPE_MSK); - qsel = (uint)(pattrib->qsel & 0x0000001f); - if (qsel == 2) - qsel = 0; - ptxdesc->txdw1 |= cpu_to_le32 - ((qsel << QSEL_SHT) & 0x00001f00); - ptxdesc->txdw2 = cpu_to_le32 - ((qsel << RTS_RC_SHT) & 0x001f0000); - ptxdesc->txdw6 |= cpu_to_le32 - ((0x5 << RSVD6_SHT) & RSVD6_MSK); - } else { - ptxdesc->txdw0 |= cpu_to_le32 - ((0x3 << TYPE_SHT) & TYPE_MSK); - ptxdesc->txdw1 |= cpu_to_le32 - ((0x13 << QSEL_SHT) & 0x00001f00); - qsel = (uint)(pattrib->qsel & 0x0000001f); - if (qsel == 2) - qsel = 0; - ptxdesc->txdw2 = cpu_to_le32 - ((qsel << RTS_RC_SHT) & 0x0001f000); - ptxdesc->txdw7 |= cpu_to_le32 - (pcmdpriv->cmd_seq << 24); - pcmdpriv->cmd_seq++; - } - pattrib->qsel = 0x13; -#else - qsel = (uint)(pattrib->qsel & 0x0000001f); - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); -#endif - if (!pqospriv->qos_option) - ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/*Non-QoS*/ - if ((pattrib->encrypt > 0) && !pattrib->bswenc) { - switch (pattrib->encrypt) { /*SEC_TYPE*/ - case _WEP40_: - case _WEP104_: - ptxdesc->txdw1 |= cpu_to_le32((0x01 << 22) & - 0x00c00000); - /*KEY_ID when WEP is used;*/ - ptxdesc->txdw1 |= - cpu_to_le32((psecuritypriv->PrivacyKeyIndex << 17) & - 0x00060000); - break; - case _TKIP_: - case _TKIP_WTMIC_: - ptxdesc->txdw1 |= cpu_to_le32((0x02 << 22) & - 0x00c00000); - break; - case _AES_: - ptxdesc->txdw1 |= cpu_to_le32((0x03 << 22) & - 0x00c00000); - break; - case _NO_PRIVACY_: - default: - break; - } - } - /*offset 8*/ - if (bmcst) - ptxdesc->txdw2 |= cpu_to_le32(BMC); - - /*offset 12*/ - /* f/w will increase the seqnum by itself, driver pass the - * correct priority to fw. - * fw will check the correct priority for increasing the - * seqnum per tid. about usb using 4-endpoint, qsel points out - * the correct mapping between AC&Endpoint, - * the purpose is that correct mapping lets the MAC release - * the AC Queue list correctly. - */ - ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) & - 0x0fff0000); - if ((pattrib->ether_type != 0x888e) && - (pattrib->ether_type != 0x0806) && - (pattrib->dhcp_pkt != 1)) { - /*Not EAP & ARP type data packet*/ - if (phtpriv->ht_option == 1) { /*B/G/N Mode*/ - if (!phtpriv->ampdu_enable) - ptxdesc->txdw2 |= cpu_to_le32(BK); - } - } else { - /* EAP data packet and ARP packet. - * Use the 1M data rate to send the EAP/ARP packet. - * This will maybe make the handshake smooth. - */ - /*driver uses data rate*/ - ptxdesc->txdw4 = cpu_to_le32(0x80000000); - ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/*1M*/ - } - if (pattrib->pctrl == 1) { /* mp tx packets */ - struct tx_desc *ptxdesc_mp; - - ptxdesc_mp = &txdesc_mp; - /* offset 8 */ - ptxdesc->txdw2 = ptxdesc_mp->txdw2; - if (bmcst) - ptxdesc->txdw2 |= cpu_to_le32(BMC); - ptxdesc->txdw2 |= cpu_to_le32(BK); - /* offset 16 */ - ptxdesc->txdw4 = ptxdesc_mp->txdw4; - /* offset 20 */ - ptxdesc->txdw5 = ptxdesc_mp->txdw5; - pattrib->pctrl = 0;/* reset to zero; */ - } - } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { - /* offset 4 */ - /* CAM_ID(MAC_ID), default=5; */ - ptxdesc->txdw1 |= cpu_to_le32((0x05) & 0x1f); - qsel = (uint)(pattrib->qsel & 0x0000001f); - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); - ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/* Non-QoS */ - /* offset 8 */ - if (bmcst) - ptxdesc->txdw2 |= cpu_to_le32(BMC); - /* offset 12 */ - /* f/w will increase the seqnum by itself, driver pass the - * correct priority to fw. - * fw will check the correct priority for increasing the seqnum - * per tid. about usb using 4-endpoint, qsel points out the - * correct mapping between AC&Endpoint, - * the purpose is that correct mapping let the MAC releases - * the AC Queue list correctly. - */ - ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) & - 0x0fff0000); - /* offset 16 */ - ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/ - /* offset 20 */ - ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/* gtest 1M */ - } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { - /* offset 4 */ - qsel = 0x13; - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); - } else { - /* offset 4 */ - qsel = (uint)(pattrib->priority & 0x0000001f); - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); - /*offset 8*/ - /*offset 12*/ - ptxdesc->txdw3 = cpu_to_le32((pattrib->seqnum << SEQ_SHT) & - 0x0fff0000); - /*offset 16*/ - ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/ - /*offset 20*/ - ptxdesc->txdw5 = cpu_to_le32(0x001f9600);/*gtest*/ - } -} - -int r8712_xmitframe_complete(struct _adapter *padapter, - struct xmit_priv *pxmitpriv, - struct xmit_buf *pxmitbuf) -{ - struct hw_xmit *phwxmits; - sint hwentry; - struct xmit_frame *pxmitframe = NULL; -#ifdef CONFIG_R8712_TX_AGGR - struct xmit_frame *p2ndxmitframe = NULL; -#else - int res = _SUCCESS; -#endif - - phwxmits = pxmitpriv->hwxmits; - hwentry = pxmitpriv->hwxmit_entry; - if (!pxmitbuf) { - pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv); - if (!pxmitbuf) - return false; -#ifdef CONFIG_R8712_TX_AGGR - pxmitbuf->aggr_nr = 0; -#endif - } - /* 1st frame dequeued */ - pxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, hwentry); - /* need to remember the 1st frame */ - if (pxmitframe) { -#ifdef CONFIG_R8712_TX_AGGR - /* 1. dequeue 2nd frame - * 2. aggr if 2nd xframe is dequeued, else dump directly - */ - if (AGGR_NR_HIGH_BOUND > 1) - p2ndxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, hwentry); - if (pxmitframe->frame_tag != DATA_FRAMETAG) { - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - return false; - } - if (p2ndxmitframe) - if (p2ndxmitframe->frame_tag != DATA_FRAMETAG) { - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - return false; - } - r8712_xmitframe_aggr_1st(pxmitbuf, pxmitframe); - if (p2ndxmitframe) { - u16 total_length; - - total_length = r8712_xmitframe_aggr_next(pxmitbuf, p2ndxmitframe); - do { - p2ndxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, hwentry); - if (p2ndxmitframe) - total_length = - r8712_xmitframe_aggr_next(pxmitbuf, p2ndxmitframe); - else - break; - } while (total_length <= 0x1800 && - pxmitbuf->aggr_nr <= AGGR_NR_HIGH_BOUND); - } - if (pxmitbuf->aggr_nr > 0) - r8712_dump_aggr_xframe(pxmitbuf, pxmitframe); - -#else - - xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf); - if (pxmitframe->frame_tag == DATA_FRAMETAG) { - if (pxmitframe->attrib.priority <= 15) - res = r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, - pxmitframe); - /* always return ndis_packet after - * r8712_xmitframe_coalesce - */ - r8712_xmit_complete(padapter, pxmitframe); - } - if (res == _SUCCESS) - dump_xframe(padapter, pxmitframe); - else - r8712_free_xmitframe_ex(pxmitpriv, pxmitframe); -#endif - - } else { /* pxmitframe == NULL && p2ndxmitframe == NULL */ - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - return false; - } - return true; -} - -static void dump_xframe(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - int t, sz, w_sz; - u8 *mem_addr; - u32 ff_hwaddr; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - if (pxmitframe->attrib.ether_type != 0x0806) { - if (pxmitframe->attrib.ether_type != 0x888e) - r8712_issue_addbareq_cmd(padapter, pattrib->priority); - } - mem_addr = pxmitframe->buf_addr; - for (t = 0; t < pattrib->nr_frags; t++) { - if (t != (pattrib->nr_frags - 1)) { - sz = pxmitpriv->frag_len; - sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : - pattrib->icv_len); - pxmitframe->last[t] = 0; - } else { - sz = pattrib->last_txcmdsz; - pxmitframe->last[t] = 1; - } - update_txdesc(pxmitframe, (uint *)mem_addr, sz); - w_sz = sz + TXDESC_SIZE; - pxmitframe->mem_addr = mem_addr; - pxmitframe->bpending[t] = false; - ff_hwaddr = get_ff_hwaddr(pxmitframe); -#ifdef CONFIG_R8712_TX_AGGR - r8712_write_port(padapter, RTL8712_DMA_H2CCMD, w_sz, - (unsigned char *)pxmitframe); -#else - r8712_write_port(padapter, ff_hwaddr, w_sz, - (unsigned char *)pxmitframe); -#endif - mem_addr += w_sz; - mem_addr = (u8 *)RND4(((addr_t)(mem_addr))); - } -} - -void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe) -{ - int res; - - res = r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); - pxmitframe->pkt = NULL; - if (res == _SUCCESS) - dump_xframe(padapter, pxmitframe); -} - -int r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe) -{ - if (r8712_xmit_classifier(padapter, pxmitframe)) { - pxmitframe->pkt = NULL; - return _FAIL; - } - return _SUCCESS; -} diff --git a/drivers/staging/rtl8712/rtl8712_xmit.h b/drivers/staging/rtl8712/rtl8712_xmit.h deleted file mode 100644 index 5cd651a0de75a900d1abadb9b1b987afd70e9d11..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl8712_xmit.h +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL8712_XMIT_H_ -#define _RTL8712_XMIT_H_ - -#define HWXMIT_ENTRY 4 - -#define VO_QUEUE_INX 0 -#define VI_QUEUE_INX 1 -#define BE_QUEUE_INX 2 -#define BK_QUEUE_INX 3 -#define TS_QUEUE_INX 4 -#define MGT_QUEUE_INX 5 -#define BMC_QUEUE_INX 6 -#define BCN_QUEUE_INX 7 - -#define HW_QUEUE_ENTRY 8 - -#define TXDESC_SIZE 32 -#define TXDESC_OFFSET TXDESC_SIZE - -#define NR_AMSDU_XMITFRAME 8 -#define NR_TXAGG_XMITFRAME 8 - -#define MAX_AMSDU_XMITBUF_SZ 8704 -#define MAX_TXAGG_XMITBUF_SZ 16384 /*16k*/ - -#define tx_cmd tx_desc - -/* - *defined for TX DESC Operation - */ - -#define MAX_TID (15) - -/*OFFSET 0*/ -#define OFFSET_SZ (0) -#define OFFSET_SHT (16) -#define OWN BIT(31) -#define FSG BIT(27) -#define LSG BIT(26) -#define TYPE_SHT (24) -#define TYPE_MSK (0x03000000) - -/*OFFSET 4*/ -#define PKT_OFFSET_SZ (0) -#define QSEL_SHT (8) -#define HWPC BIT(31) - -/*OFFSET 8*/ -#define BMC BIT(7) -#define BK BIT(30) -#define AGG_EN BIT(29) -#define RTS_RC_SHT (16) - -/*OFFSET 12*/ -#define SEQ_SHT (16) - -/*OFFSET 16*/ -#define TXBW BIT(18) - -/*OFFSET 20*/ -#define DISFB BIT(15) -#define RSVD6_MSK (0x00E00000) -#define RSVD6_SHT (21) - -struct tx_desc { - /*DWORD 0*/ - __le32 txdw0; - __le32 txdw1; - __le32 txdw2; - __le32 txdw3; - __le32 txdw4; - __le32 txdw5; - __le32 txdw6; - __le32 txdw7; -}; - -union txdesc { - struct tx_desc txdesc; - unsigned int value[TXDESC_SIZE >> 2]; -}; - -int r8712_xmitframe_complete(struct _adapter *padapter, - struct xmit_priv *pxmitpriv, - struct xmit_buf *pxmitbuf); -void r8712_do_queue_select(struct _adapter *padapter, - struct pkt_attrib *pattrib); - -#ifdef CONFIG_R8712_TX_AGGR -void r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe); -void r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe); -#endif - -#endif diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c deleted file mode 100644 index ffeb91dd28c4385733fefa097b4ab91d096483d9..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ /dev/null @@ -1,750 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_cmd.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_CMD_C_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" - -/* - * Caller and the r8712_cmd_thread can protect cmd_q by spin_lock. - * No irqsave is necessary. - */ - -int r8712_init_cmd_priv(struct cmd_priv *pcmdpriv) -{ - init_completion(&pcmdpriv->cmd_queue_comp); - init_completion(&pcmdpriv->terminate_cmdthread_comp); - - _init_queue(&(pcmdpriv->cmd_queue)); - - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - pcmdpriv->cmd_seq = 1; - pcmdpriv->cmd_allocated_buf = kmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, - GFP_ATOMIC); - if (!pcmdpriv->cmd_allocated_buf) - return -ENOMEM; - pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - - ((addr_t)(pcmdpriv->cmd_allocated_buf) & - (CMDBUFF_ALIGN_SZ - 1)); - pcmdpriv->rsp_allocated_buf = kmalloc(MAX_RSPSZ + 4, GFP_ATOMIC); - if (!pcmdpriv->rsp_allocated_buf) { - kfree(pcmdpriv->cmd_allocated_buf); - pcmdpriv->cmd_allocated_buf = NULL; - return -ENOMEM; - } - pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - - ((addr_t)(pcmdpriv->rsp_allocated_buf) & 3); - pcmdpriv->cmd_issued_cnt = 0; - pcmdpriv->cmd_done_cnt = 0; - pcmdpriv->rsp_cnt = 0; - return 0; -} - -int r8712_init_evt_priv(struct evt_priv *pevtpriv) -{ - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - pevtpriv->event_seq = 0; - pevtpriv->evt_allocated_buf = kmalloc(MAX_EVTSZ + 4, GFP_ATOMIC); - - if (!pevtpriv->evt_allocated_buf) - return -ENOMEM; - pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 - - ((addr_t)(pevtpriv->evt_allocated_buf) & 3); - pevtpriv->evt_done_cnt = 0; - return 0; -} - -void r8712_free_evt_priv(struct evt_priv *pevtpriv) -{ - kfree(pevtpriv->evt_allocated_buf); -} - -void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv) -{ - if (pcmdpriv) { - kfree(pcmdpriv->cmd_allocated_buf); - kfree(pcmdpriv->rsp_allocated_buf); - } -} - -/* - * Calling Context: - * - * r8712_enqueue_cmd can only be called between kernel thread, - * since only spin_lock is used. - * - * ISR/Call-Back functions can't call this sub-function. - * - */ - -void r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj) -{ - struct __queue *queue; - unsigned long irqL; - - if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag) - return; - if (!obj) - return; - queue = &pcmdpriv->cmd_queue; - spin_lock_irqsave(&queue->lock, irqL); - list_add_tail(&obj->list, &queue->queue); - spin_unlock_irqrestore(&queue->lock, irqL); - complete(&pcmdpriv->cmd_queue_comp); -} - -struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue) -{ - unsigned long irqL; - struct cmd_obj *obj; - - spin_lock_irqsave(&queue->lock, irqL); - obj = list_first_entry_or_null(&queue->queue, - struct cmd_obj, list); - if (obj) - list_del_init(&obj->list); - spin_unlock_irqrestore(&queue->lock, irqL); - return obj; -} - -void r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj) -{ - unsigned long irqL; - struct __queue *queue; - - if (!obj) - return; - if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag) - return; - queue = &pcmdpriv->cmd_queue; - spin_lock_irqsave(&queue->lock, irqL); - list_add_tail(&obj->list, &queue->queue); - spin_unlock_irqrestore(&queue->lock, irqL); - complete(&pcmdpriv->cmd_queue_comp); -} - -void r8712_free_cmd_obj(struct cmd_obj *pcmd) -{ - if ((pcmd->cmdcode != _JoinBss_CMD_) && - (pcmd->cmdcode != _CreateBss_CMD_)) - kfree(pcmd->parmbuf); - if (pcmd->rsp) { - if (pcmd->rspsz != 0) - kfree(pcmd->rsp); - } - kfree(pcmd); -} - -u8 r8712_sitesurvey_cmd(struct _adapter *padapter, - struct ndis_802_11_ssid *pssid) - __must_hold(&padapter->mlmepriv.lock) -{ - struct cmd_obj *ph2c; - struct sitesurvey_parm *psurveyPara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return _FAIL; - psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC); - if (!psurveyPara) { - kfree(ph2c); - return _FAIL; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, - GEN_CMD_CODE(_SiteSurvey)); - psurveyPara->bsslimit = cpu_to_le32(48); - psurveyPara->passive_mode = cpu_to_le32(pmlmepriv->passive_mode); - psurveyPara->ss_ssidlen = 0; - memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1); - if (pssid && pssid->SsidLength) { - int len = min_t(int, pssid->SsidLength, IW_ESSID_MAX_SIZE); - - memcpy(psurveyPara->ss_ssid, pssid->Ssid, len); - psurveyPara->ss_ssidlen = cpu_to_le32(len); - } - set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); - r8712_enqueue_cmd(pcmdpriv, ph2c); - mod_timer(&pmlmepriv->scan_to_timer, - jiffies + msecs_to_jiffies(SCANNING_TIMEOUT)); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_SITE_SURVEY); - complete(&padapter->rx_filter_ready); - return _SUCCESS; -} - -int r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset) -{ - struct cmd_obj *ph2c; - struct setdatarate_parm *pbsetdataratepara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return -ENOMEM; - pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC); - if (!pbsetdataratepara) { - kfree(ph2c); - return -ENOMEM; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, - GEN_CMD_CODE(_SetDataRate)); - pbsetdataratepara->mac_id = 5; - memcpy(pbsetdataratepara->datarates, rateset, NumRates); - r8712_enqueue_cmd(pcmdpriv, ph2c); - return 0; -} - -void r8712_set_chplan_cmd(struct _adapter *padapter, int chplan) -{ - struct cmd_obj *ph2c; - struct SetChannelPlan_param *psetchplanpara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC); - if (!psetchplanpara) { - kfree(ph2c); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetchplanpara, GEN_CMD_CODE(_SetChannelPlan)); - psetchplanpara->ChannelPlan = chplan; - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -int r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val) -{ - struct cmd_obj *ph2c; - struct writeRF_parm *pwriterfparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return -ENOMEM; - pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC); - if (!pwriterfparm) { - kfree(ph2c); - return -ENOMEM; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); - pwriterfparm->offset = offset; - pwriterfparm->value = val; - r8712_enqueue_cmd(pcmdpriv, ph2c); - return 0; -} - -int r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval) -{ - struct cmd_obj *ph2c; - struct readRF_parm *prdrfparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return -ENOMEM; - prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC); - if (!prdrfparm) { - kfree(ph2c); - return -ENOMEM; - } - INIT_LIST_HEAD(&ph2c->list); - ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg); - ph2c->parmbuf = (unsigned char *)prdrfparm; - ph2c->cmdsz = sizeof(struct readRF_parm); - ph2c->rsp = pval; - ph2c->rspsz = sizeof(struct readRF_rsp); - prdrfparm->offset = offset; - r8712_enqueue_cmd(pcmdpriv, ph2c); - return 0; -} - -void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - kfree(pcmd->parmbuf); - kfree(pcmd); - padapter->mppriv.workparam.bcompleted = true; -} - -void r8712_readtssi_cmdrsp_callback(struct _adapter *padapter, struct cmd_obj *pcmd) -{ - kfree(pcmd->parmbuf); - kfree(pcmd); - - padapter->mppriv.workparam.bcompleted = true; -} - -int r8712_createbss_cmd(struct _adapter *padapter) -{ - struct cmd_obj *pcmd; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct wlan_bssid_ex *pdev_network = - &padapter->registrypriv.dev_network; - - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK); - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - INIT_LIST_HEAD(&pcmd->list); - pcmd->cmdcode = _CreateBss_CMD_; - pcmd->parmbuf = (unsigned char *)pdev_network; - pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(pdev_network); - pcmd->rsp = NULL; - pcmd->rspsz = 0; - /* notes: translate IELength & Length after assign to cmdsz; */ - pdev_network->Length = pcmd->cmdsz; - pdev_network->IELength = pdev_network->IELength; - pdev_network->Ssid.SsidLength = pdev_network->Ssid.SsidLength; - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; -} - -int r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) -{ - struct wlan_bssid_ex *psecnetwork; - struct cmd_obj *pcmd; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct registry_priv *pregistrypriv = &padapter->registrypriv; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = - pnetwork->network.InfrastructureMode; - - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK); - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - - /* for hidden ap to set fw_state here */ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) != - true) { - switch (ndis_network_mode) { - case Ndis802_11IBSS: - pmlmepriv->fw_state |= WIFI_ADHOC_STATE; - break; - case Ndis802_11Infrastructure: - pmlmepriv->fw_state |= WIFI_STATION_STATE; - break; - case Ndis802_11APMode: - case Ndis802_11AutoUnknown: - case Ndis802_11InfrastructureMax: - break; - } - } - psecnetwork = &psecuritypriv->sec_bss; - memcpy(psecnetwork, &pnetwork->network, sizeof(*psecnetwork)); - psecuritypriv->authenticator_ie[0] = (unsigned char) - psecnetwork->IELength; - if ((psecnetwork->IELength - 12) < (256 - 1)) - memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], - psecnetwork->IELength - 12); - else - memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256 - 1)); - psecnetwork->IELength = 0; - /* - * If the driver wants to use the bssid to create the connection. - * If not, we copy the connecting AP's MAC address to it so that - * the driver just has the bssid information for PMKIDList searching. - */ - if (!pmlmepriv->assoc_by_bssid) - ether_addr_copy(&pmlmepriv->assoc_bssid[0], - &pnetwork->network.MacAddress[0]); - psecnetwork->IELength = r8712_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], - &psecnetwork->IEs[0], pnetwork->network.IELength); - pqospriv->qos_option = 0; - if (pregistrypriv->wmm_enable) { - u32 tmp_len; - - tmp_len = r8712_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], - &psecnetwork->IEs[0], pnetwork->network.IELength, - psecnetwork->IELength); - if (psecnetwork->IELength != tmp_len) { - psecnetwork->IELength = tmp_len; - pqospriv->qos_option = 1; /* WMM IE in beacon */ - } else { - pqospriv->qos_option = 0; /* no WMM IE in beacon */ - } - } - if (pregistrypriv->ht_enable) { - /* - * For WEP mode, we will use the bg mode to do the connection - * to avoid some IOT issues, especially for Realtek 8192u - * SoftAP. - */ - if ((padapter->securitypriv.PrivacyAlgrthm != _WEP40_) && - (padapter->securitypriv.PrivacyAlgrthm != _WEP104_)) { - /* restructure_ht_ie */ - r8712_restructure_ht_ie(padapter, - &pnetwork->network.IEs[0], - &psecnetwork->IEs[0], - pnetwork->network.IELength, - &psecnetwork->IELength); - } - } - psecuritypriv->supplicant_ie[0] = (u8)psecnetwork->IELength; - if (psecnetwork->IELength < 255) - memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], - psecnetwork->IELength); - else - memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], - 255); - /* get cmdsz before endian conversion */ - pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(psecnetwork); -#ifdef __BIG_ENDIAN - /* wlan_network endian conversion */ - psecnetwork->Length = cpu_to_le32(psecnetwork->Length); - psecnetwork->Ssid.SsidLength = cpu_to_le32(psecnetwork->Ssid.SsidLength); - psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy); - psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi); - psecnetwork->NetworkTypeInUse = cpu_to_le32(psecnetwork->NetworkTypeInUse); - psecnetwork->Configuration.ATIMWindow = cpu_to_le32(psecnetwork->Configuration.ATIMWindow); - psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(psecnetwork->Configuration.BeaconPeriod); - psecnetwork->Configuration.DSConfig = cpu_to_le32(psecnetwork->Configuration.DSConfig); - psecnetwork->Configuration.FHConfig.DwellTime = cpu_to_le32(psecnetwork->Configuration.FHConfig.DwellTime); - psecnetwork->Configuration.FHConfig.HopPattern = cpu_to_le32(psecnetwork->Configuration.FHConfig.HopPattern); - psecnetwork->Configuration.FHConfig.HopSet = cpu_to_le32(psecnetwork->Configuration.FHConfig.HopSet); - psecnetwork->Configuration.FHConfig.Length = cpu_to_le32(psecnetwork->Configuration.FHConfig.Length); - psecnetwork->Configuration.Length = cpu_to_le32(psecnetwork->Configuration.Length); - psecnetwork->InfrastructureMode = cpu_to_le32(psecnetwork->InfrastructureMode); - psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength); -#endif - INIT_LIST_HEAD(&pcmd->list); - pcmd->cmdcode = _JoinBss_CMD_; - pcmd->parmbuf = (unsigned char *)psecnetwork; - pcmd->rsp = NULL; - pcmd->rspsz = 0; - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; -} - -void r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */ -{ - struct cmd_obj *pdisconnect_cmd; - struct disconnect_parm *pdisconnect; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - pdisconnect_cmd = kmalloc(sizeof(*pdisconnect_cmd), GFP_ATOMIC); - if (!pdisconnect_cmd) - return; - pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC); - if (!pdisconnect) { - kfree(pdisconnect_cmd); - return; - } - init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd, pdisconnect, _DisConnect_CMD_); - r8712_enqueue_cmd(pcmdpriv, pdisconnect_cmd); -} - -void r8712_setopmode_cmd(struct _adapter *padapter, - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) -{ - struct cmd_obj *ph2c; - struct setopmode_parm *psetop; - - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC); - if (!psetop) { - kfree(ph2c); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); - psetop->mode = (u8)networktype; - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -void r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key) -{ - struct cmd_obj *ph2c; - struct set_stakey_parm *psetstakey_para; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct set_stakey_rsp *psetstakey_rsp = NULL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct sta_info *sta = (struct sta_info *)psta; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC); - if (!psetstakey_para) { - kfree(ph2c); - return; - } - psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC); - if (!psetstakey_rsp) { - kfree(ph2c); - kfree(psetstakey_para); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); - ph2c->rsp = (u8 *)psetstakey_rsp; - ph2c->rspsz = sizeof(struct set_stakey_rsp); - ether_addr_copy(psetstakey_para->addr, sta->hwaddr); - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - psetstakey_para->algorithm = (unsigned char) - psecuritypriv->PrivacyAlgrthm; - else - GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); - if (unicast_key) - memcpy(&psetstakey_para->key, &sta->x_UncstKey, 16); - else - memcpy(&psetstakey_para->key, - &psecuritypriv->XGrpKey[psecuritypriv->XGrpKeyid - 1].skey, - 16); - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -void r8712_setMacAddr_cmd(struct _adapter *padapter, const u8 *mac_addr) -{ - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct cmd_obj *ph2c; - struct SetMacAddr_param *psetMacAddr_para; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC); - if (!psetMacAddr_para) { - kfree(ph2c); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetMacAddr_para, _SetMacAddress_CMD_); - ether_addr_copy(psetMacAddr_para->MacAddr, mac_addr); - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -void r8712_addbareq_cmd(struct _adapter *padapter, u8 tid) -{ - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct cmd_obj *ph2c; - struct addBaReq_parm *paddbareq_parm; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC); - if (!paddbareq_parm) { - kfree(ph2c); - return; - } - paddbareq_parm->tid = tid; - init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); - r8712_enqueue_cmd_ex(pcmdpriv, ph2c); -} - -void r8712_wdg_wk_cmd(struct _adapter *padapter) -{ - struct cmd_obj *ph2c; - struct drvint_cmd_parm *pdrvintcmd_param; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC); - if (!pdrvintcmd_param) { - kfree(ph2c); - return; - } - pdrvintcmd_param->i_cid = WDG_WK_CID; - pdrvintcmd_param->sz = 0; - pdrvintcmd_param->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvintcmd_param, _DRV_INT_CMD_); - r8712_enqueue_cmd_ex(pcmdpriv, ph2c); -} - -void r8712_survey_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (pcmd->res != H2C_SUCCESS) - clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY); - r8712_free_cmd_obj(pcmd); -} - -void r8712_disassoc_cmd_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (pcmd->res != H2C_SUCCESS) { - spin_lock_irqsave(&pmlmepriv->lock, irqL); - set_fwstate(pmlmepriv, _FW_LINKED); - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return; - } - r8712_free_cmd_obj(pcmd); -} - -void r8712_joinbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (pcmd->res != H2C_SUCCESS) - mod_timer(&pmlmepriv->assoc_timer, jiffies + msecs_to_jiffies(1)); - r8712_free_cmd_obj(pcmd); -} - -void r8712_createbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd) -{ - unsigned long irqL; - struct sta_info *psta = NULL; - struct wlan_network *pwlan = NULL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf; - struct wlan_network *tgt_network = &(pmlmepriv->cur_network); - - if (pcmd->res != H2C_SUCCESS) - mod_timer(&pmlmepriv->assoc_timer, jiffies + msecs_to_jiffies(1)); - del_timer(&pmlmepriv->assoc_timer); -#ifdef __BIG_ENDIAN - /* endian_convert */ - pnetwork->Length = le32_to_cpu(pnetwork->Length); - pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); - pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy); - pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); - pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse); - pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow); - pnetwork->Configuration.DSConfig = le32_to_cpu(pnetwork->Configuration.DSConfig); - pnetwork->Configuration.FHConfig.DwellTime = le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); - pnetwork->Configuration.FHConfig.HopPattern = le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); - pnetwork->Configuration.FHConfig.HopSet = le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); - pnetwork->Configuration.FHConfig.Length = le32_to_cpu(pnetwork->Configuration.FHConfig.Length); - pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length); - pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode); - pnetwork->IELength = le32_to_cpu(pnetwork->IELength); -#endif - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if ((pmlmepriv->fw_state) & WIFI_AP_STATE) { - psta = r8712_get_stainfo(&padapter->stapriv, pnetwork->MacAddress); - if (!psta) { - psta = r8712_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); - if (!psta) - goto createbss_cmd_fail; - } - r8712_indicate_connect(padapter); - } else { - pwlan = _r8712_alloc_network(pmlmepriv); - if (!pwlan) { - pwlan = r8712_get_oldest_wlan_network(&pmlmepriv->scanned_queue); - if (!pwlan) - goto createbss_cmd_fail; - pwlan->last_scanned = jiffies; - } else { - list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); - } - pnetwork->Length = r8712_get_wlan_bssid_ex_sz(pnetwork); - memcpy(&(pwlan->network), pnetwork, pnetwork->Length); - pwlan->fixed = true; - memcpy(&tgt_network->network, pnetwork, (r8712_get_wlan_bssid_ex_sz(pnetwork))); - if (pmlmepriv->fw_state & _FW_UNDER_LINKING) - pmlmepriv->fw_state ^= _FW_UNDER_LINKING; - /* - * we will set _FW_LINKED when there is one more sat to - * join us (stassoc_event_callback) - */ - } -createbss_cmd_fail: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - r8712_free_cmd_obj(pcmd); -} - -void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter, struct cmd_obj *pcmd) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *) (pcmd->rsp); - struct sta_info *psta = r8712_get_stainfo(pstapriv, psetstakey_rsp->addr); - - if (!psta) - goto exit; - psta->aid = psta->mac_id = psetstakey_rsp->keyid; /*CAM_ID(CAM_ENTRY)*/ -exit: - r8712_free_cmd_obj(pcmd); -} - -void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - unsigned long irqL; - struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf); - struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *) (pcmd->rsp); - struct sta_info *psta = r8712_get_stainfo(pstapriv, passocsta_parm->addr); - - if (!psta) - return; - psta->aid = psta->mac_id = passocsta_rsp->cam_id; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE)) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) - pmlmepriv->fw_state ^= _FW_UNDER_LINKING; - set_fwstate(pmlmepriv, _FW_LINKED); - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - r8712_free_cmd_obj(pcmd); -} - -void r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl, u32 tryPktCnt, - u32 tryPktInterval, u32 firstStageTO) -{ - struct cmd_obj *ph2c; - struct DisconnectCtrlEx_param *param; - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - param = kzalloc(sizeof(*param), GFP_ATOMIC); - if (!param) { - kfree(ph2c); - return; - } - - param->EnableDrvCtrl = (unsigned char)enableDrvCtrl; - param->TryPktCnt = (unsigned char)tryPktCnt; - param->TryPktInterval = (unsigned char)tryPktInterval; - param->FirstStageTO = (unsigned int)firstStageTO; - - init_h2fwcmd_w_parm_no_rsp(ph2c, param, GEN_CMD_CODE(_DisconnectCtrlEx)); - r8712_enqueue_cmd(pcmdpriv, ph2c); -} diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h deleted file mode 100644 index 268844af57f006e9a21156cf1b3f50ebcec93b05..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_cmd.h +++ /dev/null @@ -1,750 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_CMD_H_ -#define __RTL871X_CMD_H_ - -#include "wlan_bssdef.h" -#include "rtl871x_rf.h" -#define C2H_MEM_SZ (16*1024) - -#include "osdep_service.h" -#include "ieee80211.h" - -#define FREE_CMDOBJ_SZ 128 -#define MAX_CMDSZ 512 -#define MAX_RSPSZ 512 -#define MAX_EVTSZ 1024 -#define CMDBUFF_ALIGN_SZ 512 - -struct cmd_obj { - u16 cmdcode; - u8 res; - u8 *parmbuf; - u32 cmdsz; - u8 *rsp; - u32 rspsz; - struct list_head list; -}; - -struct cmd_priv { - struct completion cmd_queue_comp; - struct completion terminate_cmdthread_comp; - struct __queue cmd_queue; - u8 cmd_seq; - u8 *cmd_buf; /*shall be non-paged, and 4 bytes aligned*/ - u8 *cmd_allocated_buf; - u8 *rsp_buf; /*shall be non-paged, and 4 bytes aligned*/ - u8 *rsp_allocated_buf; - u32 cmd_issued_cnt; - u32 cmd_done_cnt; - u32 rsp_cnt; - struct _adapter *padapter; -}; - -struct evt_obj { - u16 evtcode; - u8 res; - u8 *parmbuf; - u32 evtsz; - struct list_head list; -}; - -struct evt_priv { - struct __queue evt_queue; - u8 event_seq; - u8 *evt_buf; /*shall be non-paged, and 4 bytes aligned*/ - u8 *evt_allocated_buf; - u32 evt_done_cnt; -}; - -#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \ -do {\ - INIT_LIST_HEAD(&pcmd->list);\ - pcmd->cmdcode = code;\ - pcmd->parmbuf = (u8 *)(pparm);\ - pcmd->cmdsz = sizeof(*pparm);\ - pcmd->rsp = NULL;\ - pcmd->rspsz = 0;\ -} while (0) - -void r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); -void r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); -struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue); -void r8712_free_cmd_obj(struct cmd_obj *pcmd); -int r8712_cmd_thread(void *context); -int r8712_init_cmd_priv(struct cmd_priv *pcmdpriv); -void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv); -int r8712_init_evt_priv(struct evt_priv *pevtpriv); -void r8712_free_evt_priv(struct evt_priv *pevtpriv); - -enum rtl871x_drvint_cid { - NONE_WK_CID, - WDG_WK_CID, - MAX_WK_CID -}; - -enum RFINTFS { - SWSI, - HWSI, - HWPI, -}; - -/* - * Caller Mode: Infra, Ad-HoC(C) - * Notes: To enter USB suspend mode - * Command Mode - */ -struct usb_suspend_parm { - u32 action; /* 1: sleep, 0:resume */ -}; - -/* - * Caller Mode: Infra, Ad-HoC(C) - * Notes: To disconnect the current associated BSS - * Command Mode - */ -struct disconnect_parm { - u32 rsvd; -}; - -/* - * Caller Mode: AP, Ad-HoC, Infra - * Notes: To set the NIC mode of RTL8711 - * Command Mode - * The definition of mode: - * - * #define IW_MODE_AUTO 0 // Let the driver decides which AP to join - * #define IW_MODE_ADHOC 1 // Single cell network (Ad-Hoc Clients) - * #define IW_MODE_INFRA 2 // Multi cell network, roaming, .. - * #define IW_MODE_MASTER 3 // Synchronisation master or AP - * #define IW_MODE_REPEAT 4 // Wireless Repeater (forwarder) - * #define IW_MODE_SECOND 5 // Secondary master/repeater (backup) - * #define IW_MODE_MONITOR 6 // Passive monitor (listen only) - */ -struct setopmode_parm { - u8 mode; - u8 rsvd[3]; -}; - -/* - * Caller Mode: AP, Ad-HoC, Infra - * Notes: To ask RTL8711 performing site-survey - * Command-Event Mode - */ -struct sitesurvey_parm { - __le32 passive_mode; /*active: 1, passive: 0 */ - __le32 bsslimit; /* 1 ~ 48 */ - __le32 ss_ssidlen; - u8 ss_ssid[IW_ESSID_MAX_SIZE + 1]; -}; - -/* - * Caller Mode: Any - * Notes: To set the auth type of RTL8711. open/shared/802.1x - * Command Mode - */ -struct setauth_parm { - u8 mode; /*0: legacy open, 1: legacy shared 2: 802.1x*/ - u8 _1x; /*0: PSK, 1: TLS*/ - u8 rsvd[2]; -}; - -/* - * Caller Mode: Infra - * a. algorithm: wep40, wep104, tkip & aes - * b. keytype: grp key/unicast key - * c. key contents - * - * when shared key ==> keyid is the camid - * when 802.1x ==> keyid [0:1] ==> grp key - * when 802.1x ==> keyid > 2 ==> unicast key - */ -struct setkey_parm { - u8 algorithm; /* encryption algorithm, could be none, wep40, - * TKIP, CCMP, wep104 - */ - u8 keyid; - u8 grpkey; /* 1: this is the grpkey for 802.1x. - * 0: this is the unicast key for 802.1x - */ - u8 key[16]; /* this could be 40 or 104 */ -}; - -/* - * When in AP or Ad-Hoc mode, this is used to - * allocate an sw/hw entry for a newly associated sta. - * Command - * when shared key ==> algorithm/keyid - */ -struct set_stakey_parm { - u8 addr[ETH_ALEN]; - u8 algorithm; - u8 key[16]; -}; - -struct set_stakey_rsp { - u8 addr[ETH_ALEN]; - u8 keyid; - u8 rsvd; -}; - -struct SetMacAddr_param { - u8 MacAddr[ETH_ALEN]; -}; - -/* - * Caller Ad-Hoc/AP - * - * Command -Rsp(AID == CAMID) mode - * - * This is to force fw to add an sta_data entry per driver's request. - * - * FW will write an cam entry associated with it. - * - */ -struct set_assocsta_parm { - u8 addr[ETH_ALEN]; -}; - -struct set_assocsta_rsp { - u8 cam_id; - u8 rsvd[3]; -}; - -/* - * Caller Ad-Hoc/AP - * - * Command mode - * - * This is to force fw to del an sta_data entry per driver's request - * - * FW will invalidate the cam entry associated with it. - * - */ -struct del_assocsta_parm { - u8 addr[ETH_ALEN]; -}; - -/* - * Caller Mode: AP/Ad-HoC(M) - * - * Notes: To notify fw that given staid has changed its power state - * - * Command Mode - * - */ -struct setstapwrstate_parm { - u8 staid; - u8 status; - u8 hwaddr[6]; -}; - -/* - * Caller Mode: Any - * - * Notes: To setup the basic rate of RTL8711 - * - * Command Mode - * - */ -struct setbasicrate_parm { - u8 basicrates[NumRates]; -}; - -/* - * Caller Mode: Any - * - * Notes: To read the current basic rate - * - * Command-Rsp Mode - * - */ -struct getbasicrate_parm { - u32 rsvd; -}; - -struct getbasicrate_rsp { - u8 basicrates[NumRates]; -}; - -/* - * Caller Mode: Any - * - * Notes: To setup the data rate of RTL8711 - * - * Command Mode - * - */ -struct setdatarate_parm { - u8 mac_id; - u8 datarates[NumRates]; -}; - -enum _RT_CHANNEL_DOMAIN { - RT_CHANNEL_DOMAIN_FCC = 0, - RT_CHANNEL_DOMAIN_IC = 1, - RT_CHANNEL_DOMAIN_ETSI = 2, - RT_CHANNEL_DOMAIN_SPAIN = 3, - RT_CHANNEL_DOMAIN_FRANCE = 4, - RT_CHANNEL_DOMAIN_MKK = 5, - RT_CHANNEL_DOMAIN_MKK1 = 6, - RT_CHANNEL_DOMAIN_ISRAEL = 7, - RT_CHANNEL_DOMAIN_TELEC = 8, - - /* Be compatible with old channel plan. No good! */ - RT_CHANNEL_DOMAIN_MIC = 9, - RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 10, - RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 11, - RT_CHANNEL_DOMAIN_TELEC_NETGEAR = 12, - - RT_CHANNEL_DOMAIN_NCC = 13, - RT_CHANNEL_DOMAIN_5G = 14, - RT_CHANNEL_DOMAIN_5G_40M = 15, - /*===== Add new channel plan above this line===============*/ - RT_CHANNEL_DOMAIN_MAX, -}; - -struct SetChannelPlan_param { - enum _RT_CHANNEL_DOMAIN ChannelPlan; -}; - -/* - * Caller Mode: Any - * - * Notes: To read the current data rate - * - * Command-Rsp Mode - * - */ -struct getdatarate_parm { - u32 rsvd; - -}; - -struct getdatarate_rsp { - u8 datarates[NumRates]; -}; - -/* - * Caller Mode: Any - * AP: AP can use the info for the contents of beacon frame - * Infra: STA can use the info when sitesurveying - * Ad-HoC(M): Like AP - * Ad-HoC(C): Like STA - * - * - * Notes: To set the phy capability of the NIC - * - * Command Mode - * - */ - -/* - * Caller Mode: Any - * - * Notes: To set the channel/modem/band - * This command will be used when channel/modem/band is changed. - * - * Command Mode - * - */ -/* - * Caller Mode: Any - * - * Notes: To get the current setting of channel/modem/band - * - * Command-Rsp Mode - * - */ -struct getphy_rsp { - u8 rfchannel; - u8 modem; -}; - -struct readBB_parm { - u8 offset; -}; - -struct readBB_rsp { - u8 value; -}; - -struct readTSSI_parm { - u8 offset; -}; - -struct readTSSI_rsp { - u8 value; -}; - -struct writeBB_parm { - u8 offset; - u8 value; -}; - -struct writePTM_parm { - u8 type; -}; - -struct readRF_parm { - u8 offset; -}; - -struct readRF_rsp { - u32 value; -}; - -struct writeRF_parm { - u32 offset; - u32 value; -}; - -struct setrfintfs_parm { - u8 rfintfs; -}; - -struct getrfintfs_parm { - u8 rfintfs; -}; - -/* - * Notes: This command is used for H2C/C2H loopback testing - * - * mac[0] == 0 - * ==> CMD mode, return H2C_SUCCESS. - * The following condition must be true under CMD mode - * mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; - * s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; - * s2 == (b1 << 8 | b0); - * - * mac[0] == 1 - * ==> CMD_RSP mode, return H2C_SUCCESS_RSP - * - * The rsp layout shall be: - * rsp: parm: - * mac[0] = mac[5]; - * mac[1] = mac[4]; - * mac[2] = mac[3]; - * mac[3] = mac[2]; - * mac[4] = mac[1]; - * mac[5] = mac[0]; - * s0 = s1; - * s1 = swap16(s0); - * w0 = swap32(w1); - * b0 = b1 - * s2 = s0 + s1 - * b1 = b0 - * w1 = w0 - * - * mac[0] == 2 - * ==> CMD_EVENT mode, return H2C_SUCCESS - * The event layout shall be: - * event: parm: - * mac[0] = mac[5]; - * mac[1] = mac[4]; - * mac[2] = event's sequence number, starting from 1 to parm's marc[3] - * mac[3] = mac[2]; - * mac[4] = mac[1]; - * mac[5] = mac[0]; - * s0 = swap16(s0) - event.mac[2]; - * s1 = s1 + event.mac[2]; - * w0 = swap32(w0); - * b0 = b1 - * s2 = s0 + event.mac[2] - * b1 = b0 - * w1 = swap32(w1) - event.mac[2]; - * - * parm->mac[3] is the total event counts that host requested. - * - * - * event will be the same with the cmd's param. - * - */ - -/* CMD param Formart for DRV INTERNAL CMD HDL*/ -struct drvint_cmd_parm { - int i_cid; /*internal cmd id*/ - int sz; /* buf sz*/ - unsigned char *pbuf; -}; - -/*------------------- Below are used for RF/BB tuning ---------------------*/ - -struct setantenna_parm { - u8 tx_antset; - u8 rx_antset; - u8 tx_antenna; - u8 rx_antenna; -}; - -struct enrateadaptive_parm { - u32 en; -}; - -struct settxagctbl_parm { - u32 txagc[MAX_RATES_LENGTH]; -}; - -struct gettxagctbl_parm { - u32 rsvd; -}; - -struct gettxagctbl_rsp { - u32 txagc[MAX_RATES_LENGTH]; -}; - -struct setagcctrl_parm { - u32 agcctrl; /* 0: pure hw, 1: fw */ -}; - -struct setssup_parm { - u32 ss_ForceUp[MAX_RATES_LENGTH]; -}; - -struct getssup_parm { - u32 rsvd; -}; - -struct getssup_rsp { - u8 ss_ForceUp[MAX_RATES_LENGTH]; -}; - -struct setssdlevel_parm { - u8 ss_DLevel[MAX_RATES_LENGTH]; -}; - -struct getssdlevel_parm { - u32 rsvd; -}; - -struct getssdlevel_rsp { - u8 ss_DLevel[MAX_RATES_LENGTH]; -}; - -struct setssulevel_parm { - u8 ss_ULevel[MAX_RATES_LENGTH]; -}; - -struct getssulevel_parm { - u32 rsvd; -}; - -struct getssulevel_rsp { - u8 ss_ULevel[MAX_RATES_LENGTH]; -}; - -struct setcountjudge_parm { - u8 count_judge[MAX_RATES_LENGTH]; -}; - -struct getcountjudge_parm { - u32 rsvd; -}; - -struct getcountjudge_rsp { - u8 count_judge[MAX_RATES_LENGTH]; -}; - -struct setpwrmode_parm { - u8 mode; - u8 flag_low_traffic_en; - u8 flag_lpnav_en; - u8 flag_rf_low_snr_en; - u8 flag_dps_en; /* 1: dps, 0: 32k */ - u8 bcn_rx_en; - u8 bcn_pass_cnt; /* fw report one beacon information to - * driver when it receives bcn_pass_cnt - * beacons. - */ - u8 bcn_to; /* beacon TO (ms). ¡§=0¡¨ no limit.*/ - u16 bcn_itv; - u8 app_itv; /* only for VOIP mode. */ - u8 awake_bcn_itv; - u8 smart_ps; - u8 bcn_pass_time; /* unit: 100ms */ -}; - -struct setatim_parm { - u8 op; /*0: add, 1:del*/ - u8 txid; /* id of dest station.*/ -}; - -struct setratable_parm { - u8 ss_ForceUp[NumRates]; - u8 ss_ULevel[NumRates]; - u8 ss_DLevel[NumRates]; - u8 count_judge[NumRates]; -}; - -struct getratable_parm { - uint rsvd; -}; - -struct getratable_rsp { - u8 ss_ForceUp[NumRates]; - u8 ss_ULevel[NumRates]; - u8 ss_DLevel[NumRates]; - u8 count_judge[NumRates]; -}; - -/*to get TX,RX retry count*/ -struct gettxretrycnt_parm { - unsigned int rsvd; -}; - -struct gettxretrycnt_rsp { - unsigned long tx_retrycnt; -}; - -struct getrxretrycnt_parm { - unsigned int rsvd; -}; - -struct getrxretrycnt_rsp { - unsigned long rx_retrycnt; -}; - -/*to get BCNOK,BCNERR count*/ -struct getbcnokcnt_parm { - unsigned int rsvd; -}; - -struct getbcnokcnt_rsp { - unsigned long bcnokcnt; -}; - -struct getbcnerrcnt_parm { - unsigned int rsvd; -}; - -struct getbcnerrcnt_rsp { - unsigned long bcnerrcnt; -}; - -/* to get current TX power level*/ -struct getcurtxpwrlevel_parm { - unsigned int rsvd; -}; - -struct getcurtxpwrlevel_rsp { - unsigned short tx_power; -}; - -/*dynamic on/off DIG*/ -struct setdig_parm { - unsigned char dig_on; /* 1:on , 0:off */ -}; - -/*dynamic on/off RA*/ -struct setra_parm { - unsigned char ra_on; /* 1:on , 0:off */ -}; - -struct setprobereqextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct setassocreqextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct setproberspextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct setassocrspextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct addBaReq_parm { - unsigned int tid; -}; - -/*H2C Handler index: 46 */ -struct SetChannel_parm { - u32 curr_ch; -}; - -/*H2C Handler index: 61 */ -struct DisconnectCtrlEx_param { - /* MAXTIME = (2 * FirstStageTO) + (TryPktCnt * TryPktInterval) */ - unsigned char EnableDrvCtrl; - unsigned char TryPktCnt; - unsigned char TryPktInterval; /* Unit: ms */ - unsigned char rsvd; - unsigned int FirstStageTO; /* Unit: ms */ -}; - -#define GEN_CMD_CODE(cmd) cmd ## _CMD_ - -/* - * Result: - * 0x00: success - * 0x01: success, and check Response. - * 0x02: cmd ignored due to duplicated sequence number - * 0x03: cmd dropped due to invalid cmd code - * 0x04: reserved. - */ - -#define H2C_RSP_OFFSET 512 -#define H2C_SUCCESS 0x00 -#define H2C_SUCCESS_RSP 0x01 -#define H2C_DUPLICATED 0x02 -#define H2C_DROPPED 0x03 -#define H2C_PARAMETERS_ERROR 0x04 -#define H2C_REJECTED 0x05 -#define H2C_CMD_OVERFLOW 0x06 -#define H2C_RESERVED 0x07 - -void r8712_setMacAddr_cmd(struct _adapter *padapter, const u8 *mac_addr); -u8 r8712_sitesurvey_cmd(struct _adapter *padapter, struct ndis_802_11_ssid *pssid); -int r8712_createbss_cmd(struct _adapter *padapter); -void r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key); -int r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork); -void r8712_disassoc_cmd(struct _adapter *padapter); -void r8712_setopmode_cmd(struct _adapter *padapter, enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); -int r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset); -void r8712_set_chplan_cmd(struct _adapter *padapter, int chplan); -int r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval); -int r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val); -void r8712_addbareq_cmd(struct _adapter *padapter, u8 tid); -void r8712_wdg_wk_cmd(struct _adapter *padapter); -void r8712_survey_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_disassoc_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_joinbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_createbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_readtssi_cmdrsp_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter, struct cmd_obj *pcmd); -void r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl, u32 tryPktCnt, - u32 tryPktInterval, u32 firstStageTO); - -struct _cmd_callback { - u32 cmd_code; - void (*callback)(struct _adapter *padapter, struct cmd_obj *cmd); -}; - -#include "rtl8712_cmd.h" - -#endif /* _CMD_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_debug.h b/drivers/staging/rtl8712/rtl871x_debug.h deleted file mode 100644 index 69c631af2a2acf687e09f3e0beb8149087e8b78a..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_debug.h +++ /dev/null @@ -1,130 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_DEBUG_H__ -#define __RTL871X_DEBUG_H__ - -#include "osdep_service.h" -#include "drv_types.h" - -#define _drv_emerg_ 1 -#define _drv_alert_ 2 -#define _drv_crit_ 3 -#define _drv_err_ 4 -#define _drv_warning_ 5 -#define _drv_notice_ 6 -#define _drv_info_ 7 -#define _drv_dump_ 8 -#define _drv_debug_ 9 - -#define _module_rtl871x_xmit_c_ BIT(0) -#define _module_xmit_osdep_c_ BIT(1) -#define _module_rtl871x_recv_c_ BIT(2) -#define _module_recv_osdep_c_ BIT(3) -#define _module_rtl871x_mlme_c_ BIT(4) -#define _module_mlme_osdep_c_ BIT(5) -#define _module_rtl871x_sta_mgt_c_ BIT(6) -#define _module_rtl871x_cmd_c_ BIT(7) -#define _module_cmd_osdep_c_ BIT(8) -#define _module_rtl871x_io_c_ BIT(9) -#define _module_io_osdep_c_ BIT(10) -#define _module_os_intfs_c_ BIT(11) -#define _module_rtl871x_security_c_ BIT(12) -#define _module_rtl871x_eeprom_c_ BIT(13) -#define _module_hal_init_c_ BIT(14) -#define _module_hci_hal_init_c_ BIT(15) -#define _module_rtl871x_ioctl_c_ BIT(16) -#define _module_rtl871x_ioctl_set_c_ BIT(17) -#define _module_rtl871x_pwrctrl_c_ BIT(19) -#define _module_hci_intfs_c_ BIT(20) -#define _module_hci_ops_c_ BIT(21) -#define _module_osdep_service_c_ BIT(22) -#define _module_rtl871x_mp_ioctl_c_ BIT(23) -#define _module_hci_ops_os_c_ BIT(24) -#define _module_rtl871x_ioctl_os_c BIT(25) -#define _module_rtl8712_cmd_c_ BIT(26) -#define _module_rtl871x_mp_c_ BIT(27) -#define _module_rtl8712_xmit_c_ BIT(28) -#define _module_rtl8712_efuse_c_ BIT(29) -#define _module_rtl8712_recv_c_ BIT(30) -#define _module_rtl8712_led_c_ BIT(31) - -#undef _MODULE_DEFINE_ - -#if defined _RTL871X_XMIT_C_ - #define _MODULE_DEFINE_ _module_rtl871x_xmit_c_ -#elif defined _XMIT_OSDEP_C_ - #define _MODULE_DEFINE_ _module_xmit_osdep_c_ -#elif defined _RTL871X_RECV_C_ - #define _MODULE_DEFINE_ _module_rtl871x_recv_c_ -#elif defined _RECV_OSDEP_C_ - #define _MODULE_DEFINE_ _module_recv_osdep_c_ -#elif defined _RTL871X_MLME_C_ - #define _MODULE_DEFINE_ _module_rtl871x_mlme_c_ -#elif defined _MLME_OSDEP_C_ - #define _MODULE_DEFINE_ _module_mlme_osdep_c_ -#elif defined _RTL871X_STA_MGT_C_ - #define _MODULE_DEFINE_ _module_rtl871x_sta_mgt_c_ -#elif defined _RTL871X_CMD_C_ - #define _MODULE_DEFINE_ _module_rtl871x_cmd_c_ -#elif defined _CMD_OSDEP_C_ - #define _MODULE_DEFINE_ _module_cmd_osdep_c_ -#elif defined _RTL871X_IO_C_ - #define _MODULE_DEFINE_ _module_rtl871x_io_c_ -#elif defined _IO_OSDEP_C_ - #define _MODULE_DEFINE_ _module_io_osdep_c_ -#elif defined _OS_INTFS_C_ - #define _MODULE_DEFINE_ _module_os_intfs_c_ -#elif defined _RTL871X_SECURITY_C_ - #define _MODULE_DEFINE_ _module_rtl871x_security_c_ -#elif defined _RTL871X_EEPROM_C_ - #define _MODULE_DEFINE_ _module_rtl871x_eeprom_c_ -#elif defined _HAL_INIT_C_ - #define _MODULE_DEFINE_ _module_hal_init_c_ -#elif defined _HCI_HAL_INIT_C_ - #define _MODULE_DEFINE_ _module_hci_hal_init_c_ -#elif defined _RTL871X_IOCTL_C_ - #define _MODULE_DEFINE_ _module_rtl871x_ioctl_c_ -#elif defined _RTL871X_IOCTL_SET_C_ - #define _MODULE_DEFINE_ _module_rtl871x_ioctl_set_c_ -#elif defined _RTL871X_PWRCTRL_C_ - #define _MODULE_DEFINE_ _module_rtl871x_pwrctrl_c_ -#elif defined _HCI_INTF_C_ - #define _MODULE_DEFINE_ _module_hci_intfs_c_ -#elif defined _HCI_OPS_C_ - #define _MODULE_DEFINE_ _module_hci_ops_c_ -#elif defined _OSDEP_HCI_INTF_C_ - #define _MODULE_DEFINE_ _module_hci_intfs_c_ -#elif defined _OSDEP_SERVICE_C_ - #define _MODULE_DEFINE_ _module_osdep_service_c_ -#elif defined _RTL871X_MP_IOCTL_C_ - #define _MODULE_DEFINE_ _module_rtl871x_mp_ioctl_c_ -#elif defined _HCI_OPS_OS_C_ - #define _MODULE_DEFINE_ _module_hci_ops_os_c_ -#elif defined _RTL871X_IOCTL_LINUX_C_ - #define _MODULE_DEFINE_ _module_rtl871x_ioctl_os_c -#elif defined _RTL871X_MP_C_ - #define _MODULE_DEFINE_ _module_rtl871x_mp_c_ -#elif defined _RTL8712_CMD_C_ - #define _MODULE_DEFINE_ _module_rtl8712_cmd_c_ -#elif defined _RTL8712_XMIT_C_ - #define _MODULE_DEFINE_ _module_rtl8712_xmit_c_ -#elif defined _RTL8712_EFUSE_C_ - #define _MODULE_DEFINE_ _module_rtl8712_efuse_c_ -#elif defined _RTL8712_RECV_C_ - #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ -#else - #undef _MODULE_DEFINE_ -#endif - -#endif /*__RTL871X_DEBUG_H__*/ diff --git a/drivers/staging/rtl8712/rtl871x_eeprom.c b/drivers/staging/rtl8712/rtl871x_eeprom.c deleted file mode 100644 index 221bf92e1b1c3f3a2f00faf4be9b24d6708c380b..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_eeprom.c +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_eeprom.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_EEPROM_C_ - -#include "osdep_service.h" -#include "drv_types.h" - -static void up_clk(struct _adapter *padapter, u16 *x) -{ - *x = *x | _EESK; - r8712_write8(padapter, EE_9346CR, (u8)*x); - udelay(CLOCK_RATE); -} - -static void down_clk(struct _adapter *padapter, u16 *x) -{ - *x = *x & ~_EESK; - r8712_write8(padapter, EE_9346CR, (u8)*x); - udelay(CLOCK_RATE); -} - -static void shift_out_bits(struct _adapter *padapter, u16 data, u16 count) -{ - u16 x, mask; - - if (padapter->surprise_removed) - goto out; - mask = 0x01 << (count - 1); - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDO | _EEDI); - do { - x &= ~_EEDI; - if (data & mask) - x |= _EEDI; - if (padapter->surprise_removed) - goto out; - r8712_write8(padapter, EE_9346CR, (u8)x); - udelay(CLOCK_RATE); - up_clk(padapter, &x); - down_clk(padapter, &x); - mask >>= 1; - } while (mask); - if (padapter->surprise_removed) - goto out; - x &= ~_EEDI; - r8712_write8(padapter, EE_9346CR, (u8)x); -out:; -} - -static u16 shift_in_bits(struct _adapter *padapter) -{ - u16 x, d = 0, i; - - if (padapter->surprise_removed) - goto out; - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDO | _EEDI); - d = 0; - for (i = 0; i < 16; i++) { - d <<= 1; - up_clk(padapter, &x); - if (padapter->surprise_removed) - goto out; - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDI); - if (x & _EEDO) - d |= 1; - down_clk(padapter, &x); - } -out: - return d; -} - -static void standby(struct _adapter *padapter) -{ - u8 x; - - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EECS | _EESK); - r8712_write8(padapter, EE_9346CR, x); - udelay(CLOCK_RATE); - x |= _EECS; - r8712_write8(padapter, EE_9346CR, x); - udelay(CLOCK_RATE); -} - -static u16 wait_eeprom_cmd_done(struct _adapter *padapter) -{ - u8 x; - u16 i; - - standby(padapter); - for (i = 0; i < 200; i++) { - x = r8712_read8(padapter, EE_9346CR); - if (x & _EEDO) - return true; - udelay(CLOCK_RATE); - } - return false; -} - -static void eeprom_clean(struct _adapter *padapter) -{ - u16 x; - - if (padapter->surprise_removed) - return; - x = r8712_read8(padapter, EE_9346CR); - if (padapter->surprise_removed) - return; - x &= ~(_EECS | _EEDI); - r8712_write8(padapter, EE_9346CR, (u8)x); - if (padapter->surprise_removed) - return; - up_clk(padapter, &x); - if (padapter->surprise_removed) - return; - down_clk(padapter, &x); -} - -void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data) -{ - u8 x; - u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new; - - tmp8_ori = r8712_read8(padapter, 0x102502f1); - tmp8_new = tmp8_ori & 0xf7; - if (tmp8_ori != tmp8_new) - r8712_write8(padapter, 0x102502f1, tmp8_new); - tmp8_clk_ori = r8712_read8(padapter, 0x10250003); - tmp8_clk_new = tmp8_clk_ori | 0x20; - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_new); - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDI | _EEDO | _EESK | _EEM0); - x |= _EEM1 | _EECS; - r8712_write8(padapter, EE_9346CR, x); - shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5); - if (padapter->eeprom_address_size == 8) /*CF+ and SDIO*/ - shift_out_bits(padapter, 0, 6); - else /* USB */ - shift_out_bits(padapter, 0, 4); - standby(padapter); - /* Erase this particular word. Write the erase opcode and register - * number in that order. The opcode is 3bits in length; reg is 6 - * bits long. - */ - standby(padapter); - /* write the new word to the EEPROM - * send the write opcode the EEPORM - */ - shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3); - /* select which word in the EEPROM that we are writing to. */ - shift_out_bits(padapter, reg, padapter->eeprom_address_size); - /* write the data to the selected EEPROM word. */ - shift_out_bits(padapter, data, 16); - if (wait_eeprom_cmd_done(padapter)) { - standby(padapter); - shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5); - shift_out_bits(padapter, reg, 4); - eeprom_clean(padapter); - } - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_ori); - if (tmp8_new != tmp8_ori) - r8712_write8(padapter, 0x102502f1, tmp8_ori); -} - -u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg) /*ReadEEprom*/ -{ - u16 x; - u16 data = 0; - u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new; - - tmp8_ori = r8712_read8(padapter, 0x102502f1); - tmp8_new = tmp8_ori & 0xf7; - if (tmp8_ori != tmp8_new) - r8712_write8(padapter, 0x102502f1, tmp8_new); - tmp8_clk_ori = r8712_read8(padapter, 0x10250003); - tmp8_clk_new = tmp8_clk_ori | 0x20; - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_new); - if (padapter->surprise_removed) - goto out; - /* select EEPROM, reset bits, set _EECS */ - x = r8712_read8(padapter, EE_9346CR); - if (padapter->surprise_removed) - goto out; - x &= ~(_EEDI | _EEDO | _EESK | _EEM0); - x |= _EEM1 | _EECS; - r8712_write8(padapter, EE_9346CR, (unsigned char)x); - /* write the read opcode and register number in that order - * The opcode is 3bits in length, reg is 6 bits long - */ - shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); - shift_out_bits(padapter, reg, padapter->eeprom_address_size); - /* Now read the data (16 bits) in from the selected EEPROM word */ - data = shift_in_bits(padapter); - eeprom_clean(padapter); -out: - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_ori); - if (tmp8_new != tmp8_ori) - r8712_write8(padapter, 0x102502f1, tmp8_ori); - return data; -} diff --git a/drivers/staging/rtl8712/rtl871x_eeprom.h b/drivers/staging/rtl8712/rtl871x_eeprom.h deleted file mode 100644 index 7bdeb2aaa0259b83165365f114f7d2f4588adb9f..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_eeprom.h +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL871X_EEPROM_H__ -#define __RTL871X_EEPROM_H__ - -#include "osdep_service.h" - -#define RTL8712_EEPROM_ID 0x8712 -#define EEPROM_MAX_SIZE 256 -#define CLOCK_RATE 50 /*100us*/ - -/*- EEPROM opcodes*/ -#define EEPROM_READ_OPCODE 06 -#define EEPROM_WRITE_OPCODE 05 -#define EEPROM_ERASE_OPCODE 07 -#define EEPROM_EWEN_OPCODE 19 /* Erase/write enable*/ -#define EEPROM_EWDS_OPCODE 16 /* Erase/write disable*/ - -#define EEPROM_CID_DEFAULT 0x0 -#define EEPROM_CID_ALPHA 0x1 -#define EEPROM_CID_Senao 0x3 -#define EEPROM_CID_NetCore 0x5 -#define EEPROM_CID_CAMEO 0X8 -#define EEPROM_CID_SITECOM 0x9 -#define EEPROM_CID_COREGA 0xB -#define EEPROM_CID_EDIMAX_BELKIN 0xC -#define EEPROM_CID_SERCOMM_BELKIN 0xE -#define EEPROM_CID_CAMEO1 0xF -#define EEPROM_CID_WNC_COREGA 0x12 -#define EEPROM_CID_CLEVO 0x13 -#define EEPROM_CID_WHQL 0xFE - -enum RT_CUSTOMER_ID { - RT_CID_DEFAULT = 0, - RT_CID_8187_ALPHA0 = 1, - RT_CID_8187_SERCOMM_PS = 2, - RT_CID_8187_HW_LED = 3, - RT_CID_8187_NETGEAR = 4, - RT_CID_WHQL = 5, - RT_CID_819x_CAMEO = 6, - RT_CID_819x_RUNTOP = 7, - RT_CID_819x_Senao = 8, - RT_CID_TOSHIBA = 9, - RT_CID_819x_Netcore = 10, - RT_CID_Nettronix = 11, - RT_CID_DLINK = 12, - RT_CID_PRONET = 13, - RT_CID_COREGA = 14, - RT_CID_819x_ALPHA = 15, - RT_CID_819x_Sitecom = 16, - RT_CID_CCX = 17, - RT_CID_819x_Lenovo = 18, - RT_CID_819x_QMI = 19, - RT_CID_819x_Edimax_Belkin = 20, - RT_CID_819x_Sercomm_Belkin = 21, - RT_CID_819x_CAMEO1 = 22, - RT_CID_819x_MSI = 23, - RT_CID_819x_Acer = 24, - RT_CID_819x_AzWave_ASUS = 25, - RT_CID_819x_AzWave = 26, - RT_CID_819x_WNC_COREGA = 27, - RT_CID_819x_CLEVO = 28, -}; - -struct eeprom_priv { - u8 bautoload_fail_flag; - u8 bempty; - u8 sys_config; - u8 mac_addr[6]; - u8 config0; - u16 channel_plan; - u8 country_string[3]; - u8 tx_power_b[15]; - u8 tx_power_g[15]; - u8 tx_power_a[201]; - u8 efuse_eeprom_data[EEPROM_MAX_SIZE]; - enum RT_CUSTOMER_ID CustomerID; -}; - -void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data); -u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg); - -#endif /*__RTL871X_EEPROM_H__*/ - diff --git a/drivers/staging/rtl8712/rtl871x_event.h b/drivers/staging/rtl8712/rtl871x_event.h deleted file mode 100644 index 0cc780cf4341807ba2bafc768057400eff15f1ea..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_event.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871x_EVENT_H_ -#define _RTL871x_EVENT_H_ - -#include "osdep_service.h" - -#include "wlan_bssdef.h" -#include -#include - -/* - * Used to report a bss has been scanned - */ -struct survey_event { - struct wlan_bssid_ex bss; -}; - -/* - * Used to report that the requested site survey has been done. - * bss_cnt indicates the number of bss that has been reported. - */ -struct surveydone_event { - unsigned int bss_cnt; - -}; - -/* - * Used to report the link result of joining the given bss - * join_res: - * -1: authentication fail - * -2: association fail - * > 0: TID - */ -struct joinbss_event { - struct wlan_network network; -}; - -/* - * Used to report a given STA has joinned the created BSS. - * It is used in AP/Ad-HoC(M) mode. - */ -struct stassoc_event { - unsigned char macaddr[6]; - unsigned char rsvd[2]; - __le32 cam_id; -}; - -struct stadel_event { - unsigned char macaddr[6]; - unsigned char rsvd[2]; -}; - -struct addba_event { - unsigned int tid; -}; - -#define GEN_EVT_CODE(event) event ## _EVT_ - -struct fwevent { - u32 parmsize; - void (*event_callback)(struct _adapter *dev, u8 *pbuf); -}; - -#define C2HEVENT_SZ 32 -struct event_node { - unsigned char *node; - unsigned char evt_code; - unsigned short evt_sz; - /*volatile*/ int *caller_ff_tail; - int caller_ff_sz; -}; - -struct c2hevent_queue { - /*volatile*/ int head; - /*volatile*/ int tail; - struct event_node nodes[C2HEVENT_SZ]; - unsigned char seq; -}; - -#define NETWORK_QUEUE_SZ 4 - -struct network_queue { - /*volatile*/ int head; - /*volatile*/ int tail; - struct wlan_bssid_ex networks[NETWORK_QUEUE_SZ]; -}; - -struct ADDBA_Req_Report_parm { - unsigned char MacAddress[ETH_ALEN]; - unsigned short StartSeqNum; - unsigned char tid; -}; - -#include "rtl8712_event.h" - -#endif /* _WLANEVENT_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_ht.h b/drivers/staging/rtl8712/rtl871x_ht.h deleted file mode 100644 index ebd78665775dd02862b9d20af703b0b0e67435be..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_ht.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_HT_H_ -#define _RTL871X_HT_H_ - -#include "osdep_service.h" -#include "wifi.h" - -struct ht_priv { - unsigned int ht_option; - unsigned int ampdu_enable;/*for enable Tx A-MPDU*/ - unsigned char baddbareq_issued[16]; - unsigned int tx_amsdu_enable;/*for enable Tx A-MSDU */ - unsigned int tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */ - unsigned int rx_ampdu_maxlen; /* for rx reordering ctrl win_sz, - * updated when join_callback. - */ - struct ieee80211_ht_cap ht_cap; -}; - -#endif /*_RTL871X_HT_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c deleted file mode 100644 index 20e080e284dd43dc4abb26e5fbf4c21634aa6642..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_io.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_io.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -/* - * - * The purpose of rtl871x_io.c - * - * a. provides the API - * b. provides the protocol engine - * c. provides the software interface between caller and the hardware interface - * - * For r8712u, both sync/async operations are provided. - * - * Only sync read/write_mem operations are provided. - * - */ - -#define _RTL871X_IO_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_io.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -static uint _init_intf_hdl(struct _adapter *padapter, - struct intf_hdl *pintf_hdl) -{ - struct intf_priv *pintf_priv; - void (*set_intf_option)(u32 *poption) = NULL; - void (*set_intf_funs)(struct intf_hdl *pintf_hdl); - void (*set_intf_ops)(struct _io_ops *pops); - uint (*init_intf_priv)(struct intf_priv *pintfpriv); - - set_intf_option = &(r8712_usb_set_intf_option); - set_intf_funs = &(r8712_usb_set_intf_funs); - set_intf_ops = &r8712_usb_set_intf_ops; - init_intf_priv = &r8712_usb_init_intf_priv; - pintf_priv = kmalloc(sizeof(*pintf_priv), GFP_ATOMIC); - pintf_hdl->pintfpriv = pintf_priv; - if (!pintf_priv) - goto _init_intf_hdl_fail; - pintf_hdl->adapter = (u8 *)padapter; - set_intf_option(&pintf_hdl->intf_option); - set_intf_funs(pintf_hdl); - set_intf_ops(&pintf_hdl->io_ops); - pintf_priv->intf_dev = (u8 *)&padapter->dvobjpriv; - if (init_intf_priv(pintf_priv) == _FAIL) - goto _init_intf_hdl_fail; - return _SUCCESS; -_init_intf_hdl_fail: - kfree(pintf_priv); - return _FAIL; -} - -static void _unload_intf_hdl(struct intf_priv *pintfpriv) -{ - void (*unload_intf_priv)(struct intf_priv *pintfpriv); - - unload_intf_priv = &r8712_usb_unload_intf_priv; - unload_intf_priv(pintfpriv); - kfree(pintfpriv); -} - -static uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl) -{ - struct _adapter *adapter = (struct _adapter *)dev; - - pintfhdl->intf_option = 0; - pintfhdl->adapter = dev; - pintfhdl->intf_dev = (u8 *)&adapter->dvobjpriv; - if (!_init_intf_hdl(adapter, pintfhdl)) - goto register_intf_hdl_fail; - return _SUCCESS; -register_intf_hdl_fail: - return false; -} - -static void unregister_intf_hdl(struct intf_hdl *pintfhdl) -{ - _unload_intf_hdl(pintfhdl->pintfpriv); - memset((u8 *)pintfhdl, 0, sizeof(struct intf_hdl)); -} - -uint r8712_alloc_io_queue(struct _adapter *adapter) -{ - u32 i; - struct io_queue *pio_queue; - struct io_req *pio_req; - - pio_queue = kmalloc(sizeof(*pio_queue), GFP_ATOMIC); - if (!pio_queue) - goto alloc_io_queue_fail; - INIT_LIST_HEAD(&pio_queue->free_ioreqs); - INIT_LIST_HEAD(&pio_queue->processing); - INIT_LIST_HEAD(&pio_queue->pending); - spin_lock_init(&pio_queue->lock); - pio_queue->pallocated_free_ioreqs_buf = kzalloc(NUM_IOREQ * - (sizeof(struct io_req)) + 4, - GFP_ATOMIC); - if ((pio_queue->pallocated_free_ioreqs_buf) == NULL) - goto alloc_io_queue_fail; - pio_queue->free_ioreqs_buf = pio_queue->pallocated_free_ioreqs_buf + 4 - - ((addr_t)(pio_queue->pallocated_free_ioreqs_buf) - & 3); - pio_req = (struct io_req *)(pio_queue->free_ioreqs_buf); - for (i = 0; i < NUM_IOREQ; i++) { - INIT_LIST_HEAD(&pio_req->list); - list_add_tail(&pio_req->list, &pio_queue->free_ioreqs); - pio_req++; - } - if ((register_intf_hdl((u8 *)adapter, &pio_queue->intf)) == _FAIL) - goto alloc_io_queue_fail; - adapter->pio_queue = pio_queue; - return _SUCCESS; -alloc_io_queue_fail: - if (pio_queue) { - kfree(pio_queue->pallocated_free_ioreqs_buf); - kfree(pio_queue); - } - adapter->pio_queue = NULL; - return _FAIL; -} - -void r8712_free_io_queue(struct _adapter *adapter) -{ - struct io_queue *pio_queue = adapter->pio_queue; - - if (pio_queue) { - kfree(pio_queue->pallocated_free_ioreqs_buf); - adapter->pio_queue = NULL; - unregister_intf_hdl(&pio_queue->intf); - kfree(pio_queue); - } -} diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h deleted file mode 100644 index f09d50a29b82c6df740ea57ca2ea9725b7c51a3d..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_io.h +++ /dev/null @@ -1,236 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_IO_H_ -#define _RTL871X_IO_H_ - -#include "osdep_service.h" -#include "osdep_intf.h" - -#define NUM_IOREQ 8 - -#define MAX_PROT_SZ (64-16) - -#define _IOREADY 0 -#define _IO_WAIT_COMPLETE 1 -#define _IO_WAIT_RSP 2 - -/* IO COMMAND TYPE */ -#define _IOSZ_MASK_ (0x7F) -#define _IO_WRITE_ BIT(7) -#define _IO_FIXED_ BIT(8) -#define _IO_BURST_ BIT(9) -#define _IO_BYTE_ BIT(10) -#define _IO_HW_ BIT(11) -#define _IO_WORD_ BIT(12) -#define _IO_SYNC_ BIT(13) -#define _IO_CMDMASK_ (0x1F80) - -/* - * For prompt mode accessing, caller shall free io_req - * Otherwise, io_handler will free io_req - */ -/* IO STATUS TYPE */ -#define _IO_ERR_ BIT(2) -#define _IO_SUCCESS_ BIT(1) -#define _IO_DONE_ BIT(0) -#define IO_RD32 (_IO_SYNC_ | _IO_WORD_) -#define IO_RD16 (_IO_SYNC_ | _IO_HW_) -#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_) -#define IO_RD32_ASYNC (_IO_WORD_) -#define IO_RD16_ASYNC (_IO_HW_) -#define IO_RD8_ASYNC (_IO_BYTE_) -#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_) -#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_) -#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_) -#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_) -#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_) -#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_) -/* - * Only Sync. burst accessing is provided. - */ -#define IO_WR_BURST(x) (IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | \ - ((x) & _IOSZ_MASK_)) -#define IO_RD_BURST(x) (_IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_)) -/*below is for the intf_option bit definition...*/ -#define _INTF_ASYNC_ BIT(0) /*support async io*/ -struct intf_priv; -struct intf_hdl; -struct io_queue; -struct _io_ops { - uint (*_sdbus_read_bytes_to_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf); - uint (*_sdbus_read_blocks_to_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf); - u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); - u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); - u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); - uint (*_sdbus_write_blocks_from_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf, - u8 async); - uint (*_sdbus_write_bytes_from_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf); - u8 (*_cmd52r)(struct intf_priv *pintfpriv, u32 addr); - void (*_cmd52w)(struct intf_priv *pintfpriv, u32 addr, u8 val8); - u8 (*_cmdfunc152r)(struct intf_priv *pintfpriv, u32 addr); - void (*_cmdfunc152w)(struct intf_priv *pintfpriv, u32 addr, u8 val8); - void (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); - void (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); - void (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); - void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); - void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); - void (*_sync_irp_protocol_rw)(struct io_queue *pio_q); - u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); - u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); -}; - -struct io_req { - struct list_head list; - u32 addr; - /*volatile*/ u32 val; - u32 command; - u32 status; - u8 *pbuf; - void (*_async_io_callback)(struct _adapter *padapter, - struct io_req *pio_req, u8 *cnxt); - u8 *cnxt; -}; - -struct intf_hdl { - u32 intf_option; - u8 *adapter; - u8 *intf_dev; - struct intf_priv *pintfpriv; - void (*intf_hdl_init)(u8 *priv); - void (*intf_hdl_unload)(u8 *priv); - void (*intf_hdl_open)(u8 *priv); - void (*intf_hdl_close)(u8 *priv); - struct _io_ops io_ops; -}; - -struct reg_protocol_rd { -#ifdef __LITTLE_ENDIAN - /* DW1 */ - u32 NumOfTrans:4; - u32 Reserved1:4; - u32 Reserved2:24; - /* DW2 */ - u32 ByteCount:7; - u32 WriteEnable:1; /*0:read, 1:write*/ - u32 FixOrContinuous:1; /*0:continuous, 1: Fix*/ - u32 BurstMode:1; - u32 Byte1Access:1; - u32 Byte2Access:1; - u32 Byte4Access:1; - u32 Reserved3:3; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ -#else -/*DW1*/ - u32 Reserved1:4; - u32 NumOfTrans:4; - u32 Reserved2:24; - /*DW2*/ - u32 WriteEnable:1; - u32 ByteCount:7; - u32 Reserved3:3; - u32 Byte4Access:1; - u32 Byte2Access:1; - u32 Byte1Access:1; - u32 BurstMode:1; - u32 FixOrContinuous:1; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ -#endif -}; - -struct reg_protocol_wt { -#ifdef __LITTLE_ENDIAN - /*DW1*/ - u32 NumOfTrans:4; - u32 Reserved1:4; - u32 Reserved2:24; - /*DW2*/ - u32 ByteCount:7; - u32 WriteEnable:1; /*0:read, 1:write*/ - u32 FixOrContinuous:1; /*0:continuous, 1: Fix*/ - u32 BurstMode:1; - u32 Byte1Access:1; - u32 Byte2Access:1; - u32 Byte4Access:1; - u32 Reserved3:3; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ - u32 Value; -#else - /*DW1*/ - u32 Reserved1:4; - u32 NumOfTrans:4; - u32 Reserved2:24; - /*DW2*/ - u32 WriteEnable:1; - u32 ByteCount:7; - u32 Reserved3:3; - u32 Byte4Access:1; - u32 Byte2Access:1; - u32 Byte1Access:1; - u32 BurstMode:1; - u32 FixOrContinuous:1; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ - u32 Value; -#endif -}; - -/* - * Below is the data structure used by _io_handler - */ - -struct io_queue { - spinlock_t lock; - struct list_head free_ioreqs; - /*The io_req list that will be served in the single protocol r/w.*/ - struct list_head pending; - struct list_head processing; - u8 *free_ioreqs_buf; /* 4-byte aligned */ - u8 *pallocated_free_ioreqs_buf; - struct intf_hdl intf; -}; - -u8 r8712_read8(struct _adapter *adapter, u32 addr); -u16 r8712_read16(struct _adapter *adapter, u32 addr); -u32 r8712_read32(struct _adapter *adapter, u32 addr); -void r8712_read_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -void r8712_read_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -void r8712_write8(struct _adapter *adapter, u32 addr, u8 val); -void r8712_write16(struct _adapter *adapter, u32 addr, u16 val); -void r8712_write32(struct _adapter *adapter, u32 addr, u32 val); -void r8712_write_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -void r8712_write_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -/*ioreq */ -uint r8712_alloc_io_queue(struct _adapter *adapter); -void r8712_free_io_queue(struct _adapter *adapter); - -#endif /*_RTL871X_IO_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_ioctl.h b/drivers/staging/rtl8712/rtl871x_ioctl.h deleted file mode 100644 index d6332a8c7f4f71d7823d7d9a622028c213fe5f49..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IOCTL_H -#define __IOCTL_H - -#include "osdep_service.h" -#include "drv_types.h" - -#ifndef OID_802_11_CAPABILITY - #define OID_802_11_CAPABILITY 0x0d010122 -#endif - -#ifndef OID_802_11_PMKID - #define OID_802_11_PMKID 0x0d010123 -#endif - -/* For DDK-defined OIDs*/ -#define OID_NDIS_SEG1 0x00010100 -#define OID_NDIS_SEG2 0x00010200 -#define OID_NDIS_SEG3 0x00020100 -#define OID_NDIS_SEG4 0x01010100 -#define OID_NDIS_SEG5 0x01020100 -#define OID_NDIS_SEG6 0x01020200 -#define OID_NDIS_SEG7 0xFD010100 -#define OID_NDIS_SEG8 0x0D010100 -#define OID_NDIS_SEG9 0x0D010200 -#define OID_NDIS_SEG10 0x0D020200 -#define SZ_OID_NDIS_SEG1 23 -#define SZ_OID_NDIS_SEG2 3 -#define SZ_OID_NDIS_SEG3 6 -#define SZ_OID_NDIS_SEG4 6 -#define SZ_OID_NDIS_SEG5 4 -#define SZ_OID_NDIS_SEG6 8 -#define SZ_OID_NDIS_SEG7 7 -#define SZ_OID_NDIS_SEG8 36 -#define SZ_OID_NDIS_SEG9 24 -#define SZ_OID_NDIS_SEG10 19 - -/* For Realtek-defined OIDs*/ -#define OID_MP_SEG1 0xFF871100 -#define OID_MP_SEG2 0xFF818000 -#define OID_MP_SEG3 0xFF818700 -#define OID_MP_SEG4 0xFF011100 - -enum oid_type { - QUERY_OID, - SET_OID -}; - -struct oid_funs_node { - unsigned int oid_start; /*the starting number for OID*/ - unsigned int oid_end; /*the ending number for OID*/ - struct oid_obj_priv *node_array; - unsigned int array_sz; /*the size of node_array*/ - int query_counter; /*count the number of query hits for this segment*/ - int set_counter; /*count the number of set hits for this segment*/ -}; - -struct oid_par_priv { - void *adapter_context; - uint oid; - void *information_buf; - unsigned long information_buf_len; - unsigned long *bytes_rw; - unsigned long *bytes_needed; - enum oid_type type_of_oid; - unsigned int dbg; -}; - -struct oid_obj_priv { - unsigned char dbg; /* 0: without OID debug message - * 1: with OID debug message - */ - uint (*oidfuns)(struct oid_par_priv *poid_par_priv); -}; - -uint oid_null_function(struct oid_par_priv *poid_par_priv); - -extern struct iw_handler_def r871x_handlers_def; - -uint drv_query_info(struct net_device *MiniportAdapterContext, - uint Oid, - void *InformationBuffer, - u32 InformationBufferLength, - u32 *BytesWritten, - u32 *BytesNeeded); - -uint drv_set_info(struct net_device *MiniportAdapterContext, - uint Oid, - void *InformationBuffer, - u32 InformationBufferLength, - u32 *BytesRead, - u32 *BytesNeeded); - -#endif diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c deleted file mode 100644 index 0653aa27b1fa29ca4f3ecfe34da3321d7eabc510..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ /dev/null @@ -1,2275 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_ioctl_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_IOCTL_LINUX_C_ -#define _RTL871X_MP_IOCTL_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wlan_bssdef.h" -#include "rtl871x_debug.h" -#include "wifi.h" -#include "rtl871x_mlme.h" -#include "rtl871x_ioctl.h" -#include "rtl871x_ioctl_set.h" -#include "rtl871x_mp_ioctl.h" -#include "mlme_osdep.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E) - -#define SCAN_ITEM_SIZE 768 -#define MAX_CUSTOM_LEN 64 -#define RATE_COUNT 4 - -static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, - 6000000, 9000000, 12000000, 18000000, - 24000000, 36000000, 48000000, 54000000}; - -static const long ieee80211_wlan_frequencies[] = { - 2412, 2417, 2422, 2427, - 2432, 2437, 2442, 2447, - 2452, 2457, 2462, 2467, - 2472, 2484 -}; - -void r8712_indicate_wx_assoc_event(struct _adapter *padapter) -{ - union iwreq_data wrqu; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN); - wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); -} - -void r8712_indicate_wx_disassoc_event(struct _adapter *padapter) -{ - union iwreq_data wrqu; - - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - eth_zero_addr(wrqu.ap_addr.sa_data); - wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); -} - -static inline void handle_pairwise_key(struct sta_info *psta, - struct ieee_param *param, - struct _adapter *padapter) -{ - /* pairwise key */ - memcpy(psta->x_UncstKey.skey, param->u.crypt.key, - (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len)); - if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ - memcpy(psta->tkiptxmickey. skey, - ¶m->u.crypt.key[16], 8); - memcpy(psta->tkiprxmickey. skey, - ¶m->u.crypt.key[24], 8); - padapter->securitypriv. busetkipkey = false; - mod_timer(&padapter->securitypriv.tkip_timer, - jiffies + msecs_to_jiffies(50)); - } - r8712_setstakey_cmd(padapter, (unsigned char *)psta, true); -} - -static inline void handle_group_key(struct ieee_param *param, - struct _adapter *padapter) -{ - union Keytype *gk = padapter->securitypriv.XGrpKey; - union Keytype *gtk = padapter->securitypriv.XGrptxmickey; - union Keytype *grk = padapter->securitypriv.XGrprxmickey; - - if (param->u.crypt.idx > 0 && - param->u.crypt.idx < 3) { - /* group key idx is 1 or 2 */ - memcpy(gk[param->u.crypt.idx - 1].skey, - param->u.crypt.key, - (param->u.crypt.key_len > 16 ? 16 : - param->u.crypt.key_len)); - memcpy(gtk[param->u.crypt.idx - 1].skey, - ¶m->u.crypt.key[16], 8); - memcpy(grk[param->u.crypt.idx - 1].skey, - ¶m->u.crypt.key[24], 8); - padapter->securitypriv.binstallGrpkey = true; - r8712_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx); - if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) { - if (padapter->registrypriv.power_mgnt != padapter->pwrctrlpriv.pwr_mode) - mod_timer(&padapter->mlmepriv.dhcp_timer, - jiffies + msecs_to_jiffies(60000)); - } - } -} - -static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info, - struct wlan_network *pnetwork, - struct iw_event *iwe, - char *start, char *stop) -{ - /* parsing WPA/WPA2 IE */ - u8 buf[MAX_WPA_IE_LEN]; - u8 wpa_ie[255], rsn_ie[255]; - u16 wpa_len = 0, rsn_len = 0; - int n, i; - - r8712_get_sec_ie(pnetwork->network.IEs, - pnetwork->network.IELength, rsn_ie, &rsn_len, - wpa_ie, &wpa_len); - if (wpa_len > 0) { - memset(buf, 0, MAX_WPA_IE_LEN); - n = sprintf(buf, "wpa_ie="); - for (i = 0; i < wpa_len; i++) { - n += scnprintf(buf + n, MAX_WPA_IE_LEN - n, - "%02x", wpa_ie[i]); - if (n == MAX_WPA_IE_LEN - 1) - break; - } - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVCUSTOM; - iwe->u.data.length = (u16)strlen(buf); - start = iwe_stream_add_point(info, start, stop, iwe, buf); - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVGENIE; - iwe->u.data.length = (u16)wpa_len; - start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie); - } - if (rsn_len > 0) { - memset(buf, 0, MAX_WPA_IE_LEN); - n = sprintf(buf, "rsn_ie="); - for (i = 0; i < rsn_len; i++) { - n += scnprintf(buf + n, MAX_WPA_IE_LEN - n, - "%02x", rsn_ie[i]); - if (n == MAX_WPA_IE_LEN - 1) - break; - } - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVCUSTOM; - iwe->u.data.length = strlen(buf); - start = iwe_stream_add_point(info, start, stop, iwe, buf); - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVGENIE; - iwe->u.data.length = rsn_len; - start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie); - } - - return start; -} - -static noinline_for_stack char *translate_scan_wps(struct iw_request_info *info, - struct wlan_network *pnetwork, - struct iw_event *iwe, - char *start, char *stop) -{ - /* parsing WPS IE */ - u8 wps_ie[512]; - uint wps_ielen; - - if (r8712_get_wps_ie(pnetwork->network.IEs, pnetwork->network.IELength, wps_ie, &wps_ielen)) { - if (wps_ielen > 2) { - iwe->cmd = IWEVGENIE; - iwe->u.data.length = (u16)wps_ielen; - start = iwe_stream_add_point(info, start, stop, iwe, wps_ie); - } - } - - return start; -} - -static char *translate_scan(struct _adapter *padapter, - struct iw_request_info *info, - struct wlan_network *pnetwork, - char *start, char *stop) -{ - struct iw_event iwe; - char *current_val; - s8 *p; - u32 i = 0, ht_ielen = 0; - u16 cap, ht_cap = false; - u8 rssi; - - if ((pnetwork->network.Configuration.DSConfig < 1) || - (pnetwork->network.Configuration.DSConfig > 14)) { - if (pnetwork->network.Configuration.DSConfig < 1) - pnetwork->network.Configuration.DSConfig = 1; - else - pnetwork->network.Configuration.DSConfig = 14; - } - /* AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress); - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); - /* Add the ESSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32); - start = iwe_stream_add_point(info, start, stop, &iwe, - pnetwork->network.Ssid.Ssid); - /* parsing HT_CAP_IE */ - p = r8712_get_ie(&pnetwork->network.IEs[12], WLAN_EID_HT_CAPABILITY, - &ht_ielen, pnetwork->network.IELength - 12); - if (p && ht_ielen > 0) - ht_cap = true; - /* Add the protocol name */ - iwe.cmd = SIOCGIWNAME; - if (r8712_is_cckratesonly_included(pnetwork->network.rates)) { - if (ht_cap) - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn"); - else - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); - } else if (r8712_is_cckrates_included(pnetwork->network.rates)) { - if (ht_cap) - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); - else - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); - } else { - if (ht_cap) - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn"); - else - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); - } - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); - /* Add mode */ - iwe.cmd = SIOCGIWMODE; - memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs), 2); - le16_to_cpus(&cap); - if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_ESS)) { - if (cap & WLAN_CAPABILITY_ESS) - iwe.u.mode = (u32)IW_MODE_MASTER; - else - iwe.u.mode = (u32)IW_MODE_ADHOC; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); - } - /* Add frequency/channel */ - iwe.cmd = SIOCGIWFREQ; - { - /* check legal index */ - u8 dsconfig = pnetwork->network.Configuration.DSConfig; - - if (dsconfig >= 1 && dsconfig <= sizeof(ieee80211_wlan_frequencies) / sizeof(long)) - iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[dsconfig - 1] * 100000); - else - iwe.u.freq.m = 0; - } - iwe.u.freq.e = (s16)1; - iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig; - start = iwe_stream_add_event(info, start, stop, &iwe, - IW_EV_FREQ_LEN); - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (cap & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED | IW_ENCODE_NOKEY); - else - iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED); - iwe.u.data.length = (u16)0; - start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); - /*Add basic and extended rates */ - current_val = start + iwe_stream_lcp_len(info); - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = 0; - iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = 0; - i = 0; - while (pnetwork->network.rates[i] != 0) { - /* Bit rate given in 500 kb/s units */ - iwe.u.bitrate.value = (pnetwork->network.rates[i++] & 0x7F) * 500000; - current_val = iwe_stream_add_value(info, start, current_val, stop, &iwe, - IW_EV_PARAM_LEN); - } - /* Check if we added any event */ - if ((current_val - start) > iwe_stream_lcp_len(info)) - start = current_val; - - start = translate_scan_wpa(info, pnetwork, &iwe, start, stop); - - start = translate_scan_wps(info, pnetwork, &iwe, start, stop); - - /* Add quality statistics */ - iwe.cmd = IWEVQUAL; - rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi); - /* we only update signal_level (signal strength) that is rssi. */ - iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID); - iwe.u.qual.level = rssi; /* signal strength */ - iwe.u.qual.qual = 0; /* signal quality */ - iwe.u.qual.noise = 0; /* noise level */ - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); - /* how to translate rssi to ?% */ - return start; -} - -static int wpa_set_auth_algs(struct net_device *dev, u32 value) -{ - struct _adapter *padapter = netdev_priv(dev); - int ret = 0; - - if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeAutoSwitch; - padapter->securitypriv.AuthAlgrthm = 3; - } else if (value & AUTH_ALG_SHARED_KEY) { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; - padapter->securitypriv.AuthAlgrthm = 1; - } else if (value & AUTH_ALG_OPEN_SYSTEM) { - if (padapter->securitypriv.ndisauthtype < - Ndis802_11AuthModeWPAPSK) { - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeOpen; - padapter->securitypriv.AuthAlgrthm = 0; - } - } else { - ret = -EINVAL; - } - return ret; -} - -static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, - u32 param_len) -{ - int ret = 0; - u32 wep_key_idx, wep_key_len = 0; - struct NDIS_802_11_WEP *pwep = NULL; - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - param->u.crypt.err = 0; - param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; - if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) + - param->u.crypt.key_len) - return -EINVAL; - if (!is_broadcast_ether_addr(param->sta_addr)) - return -EINVAL; - - if (param->u.crypt.idx >= WEP_KEYS) { - /* for large key indices, set the default (0) */ - param->u.crypt.idx = 0; - } - if (strcmp(param->u.crypt.alg, "WEP") == 0) { - netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.PrivacyAlgrthm = _WEP40_; - padapter->securitypriv.XGrpPrivacy = _WEP40_; - wep_key_idx = param->u.crypt.idx; - wep_key_len = param->u.crypt.key_len; - if (wep_key_idx >= WEP_KEYS) - wep_key_idx = 0; - if (wep_key_len <= 0) - return -EINVAL; - - wep_key_len = wep_key_len <= 5 ? 5 : 13; - pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC); - if (!pwep) - return -ENOMEM; - pwep->KeyLength = wep_key_len; - pwep->Length = wep_key_len + - offsetof(struct NDIS_802_11_WEP, KeyMaterial); - if (wep_key_len == 13) { - padapter->securitypriv.PrivacyAlgrthm = _WEP104_; - padapter->securitypriv.XGrpPrivacy = _WEP104_; - } - pwep->KeyIndex = wep_key_idx; - pwep->KeyIndex |= 0x80000000; - memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); - if (param->u.crypt.set_tx) { - if (r8712_set_802_11_add_wep(padapter, pwep)) - ret = -EOPNOTSUPP; - } else { - /* don't update "psecuritypriv->PrivacyAlgrthm" and - * "psecuritypriv->PrivacyKeyIndex=keyid", but can - * r8712_set_key to fw/cam - */ - if (wep_key_idx >= WEP_KEYS) { - ret = -EOPNOTSUPP; - goto exit; - } - memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0], - pwep->KeyMaterial, - pwep->KeyLength); - psecuritypriv->DefKeylen[wep_key_idx] = - pwep->KeyLength; - r8712_set_key(padapter, psecuritypriv, wep_key_idx); - } - goto exit; - } - if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */ - struct sta_info *psta, *pbcmc_sta; - struct sta_priv *pstapriv = &padapter->stapriv; - struct security_priv *spriv = &padapter->securitypriv; - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | - WIFI_MP_STATE)) { /* sta mode */ - psta = r8712_get_stainfo(pstapriv, - get_bssid(pmlmepriv)); - if (psta) { - psta->ieee8021x_blocked = false; - if (spriv->ndisencryptstatus == - Ndis802_11Encryption2Enabled || - spriv->ndisencryptstatus == - Ndis802_11Encryption3Enabled) - psta->XPrivacy = spriv->PrivacyAlgrthm; - if (param->u.crypt.set_tx == 1) - handle_pairwise_key(psta, param, - padapter); - else /* group key */ - handle_group_key(param, padapter); - } - pbcmc_sta = r8712_get_bcmc_stainfo(padapter); - if (pbcmc_sta) { - pbcmc_sta->ieee8021x_blocked = false; - if (spriv->ndisencryptstatus == - Ndis802_11Encryption2Enabled || - spriv->ndisencryptstatus == - Ndis802_11Encryption3Enabled) - pbcmc_sta->XPrivacy = - spriv->PrivacyAlgrthm; - } - } - } -exit: - kfree(pwep); - return ret; -} - -static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, - unsigned short ielen) -{ - u8 *buf = NULL; - int group_cipher = 0, pairwise_cipher = 0; - int ret = 0; - - if (ielen > MAX_WPA_IE_LEN || !pie) - return -EINVAL; - if (ielen) { - buf = kmemdup(pie, ielen, GFP_ATOMIC); - if (!buf) - return -ENOMEM; - if (ielen < RSN_HEADER_LEN) { - ret = -EINVAL; - goto exit; - } - if (r8712_parse_wpa_ie(buf, ielen, &group_cipher, - &pairwise_cipher) == 0) { - padapter->securitypriv.AuthAlgrthm = 2; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPAPSK; - } - if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher, - &pairwise_cipher) == 0) { - padapter->securitypriv.AuthAlgrthm = 2; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPA2PSK; - } - switch (group_cipher) { - case WPA_CIPHER_NONE: - padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; - break; - case WPA_CIPHER_WEP40: - padapter->securitypriv.XGrpPrivacy = _WEP40_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; - break; - case WPA_CIPHER_TKIP: - padapter->securitypriv.XGrpPrivacy = _TKIP_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; - break; - case WPA_CIPHER_CCMP: - padapter->securitypriv.XGrpPrivacy = _AES_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; - break; - case WPA_CIPHER_WEP104: - padapter->securitypriv.XGrpPrivacy = _WEP104_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; - break; - } - switch (pairwise_cipher) { - case WPA_CIPHER_NONE: - padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; - break; - case WPA_CIPHER_WEP40: - padapter->securitypriv.PrivacyAlgrthm = _WEP40_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; - break; - case WPA_CIPHER_TKIP: - padapter->securitypriv.PrivacyAlgrthm = _TKIP_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; - break; - case WPA_CIPHER_CCMP: - padapter->securitypriv.PrivacyAlgrthm = _AES_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; - break; - case WPA_CIPHER_WEP104: - padapter->securitypriv.PrivacyAlgrthm = _WEP104_; - padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; - break; - } - padapter->securitypriv.wps_phase = false; - {/* set wps_ie */ - u16 cnt = 0; - u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - - while (cnt < ielen) { - eid = buf[cnt]; - - if ((eid == WLAN_EID_VENDOR_SPECIFIC) && - (!memcmp(&buf[cnt + 2], wps_oui, 4))) { - netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n"); - padapter->securitypriv.wps_ie_len = - ((buf[cnt + 1] + 2) < - (MAX_WPA_IE_LEN << 2)) ? - (buf[cnt + 1] + 2) : - (MAX_WPA_IE_LEN << 2); - memcpy(padapter->securitypriv.wps_ie, - &buf[cnt], - padapter->securitypriv.wps_ie_len); - padapter->securitypriv.wps_phase = - true; - netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n"); - cnt += buf[cnt + 1] + 2; - break; - } - - cnt += buf[cnt + 1] + 2; - } - } - } -exit: - kfree(buf); - return ret; -} - -static int r8711_wx_get_name(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 ht_ielen = 0; - char *p; - u8 ht_cap = false; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - u8 *prates; - - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == true) { - /* parsing HT_CAP_IE */ - p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, - &ht_ielen, pcur_bss->IELength - 12); - if (p && ht_ielen > 0) - ht_cap = true; - prates = pcur_bss->rates; - if (r8712_is_cckratesonly_included(prates)) { - if (ht_cap) - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11bn"); - else - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11b"); - } else if (r8712_is_cckrates_included(prates)) { - if (ht_cap) - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11bgn"); - else - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11bg"); - } else { - if (ht_cap) - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11gn"); - else - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11g"); - } - } else { - snprintf(wrqu->name, IFNAMSIZ, "unassociated"); - } - return 0; -} - -static const long frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, - 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, - 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, - 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, - 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805, - 5825 -}; - -static int r8711_wx_set_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_freq *fwrq = &wrqu->freq; - int rc = 0; - -/* If setting by frequency, convert to a channel */ - if ((fwrq->e == 1) && (fwrq->m >= 241200000) && (fwrq->m <= 248700000)) { - int f = fwrq->m / 100000; - int c = 0; - - while ((c < 14) && (f != frequency_list[c])) - c++; - fwrq->e = 0; - fwrq->m = c + 1; - } - /* Setting by channel number */ - if ((fwrq->m > 14) || (fwrq->e > 0)) { - rc = -EOPNOTSUPP; - } else { - int channel = fwrq->m; - - if ((channel < 1) || (channel > 14)) { - rc = -EINVAL; - } else { - /* Yes ! We can set it !!! */ - padapter->registrypriv.channel = channel; - } - } - return rc; -} - -static int r8711_wx_get_freq(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - - if (!check_fwstate(pmlmepriv, _FW_LINKED)) - return -ENOLINK; - - wrqu->freq.m = ieee80211_wlan_frequencies[ - pcur_bss->Configuration.DSConfig - 1] * 100000; - wrqu->freq.e = 1; - wrqu->freq.i = pcur_bss->Configuration.DSConfig; - - return 0; -} - -static int r8711_wx_set_mode(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct _adapter *padapter = netdev_priv(dev); - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; - - switch (wrqu->mode) { - case IW_MODE_AUTO: - networkType = Ndis802_11AutoUnknown; - break; - case IW_MODE_ADHOC: - networkType = Ndis802_11IBSS; - break; - case IW_MODE_MASTER: - networkType = Ndis802_11APMode; - break; - case IW_MODE_INFRA: - networkType = Ndis802_11Infrastructure; - break; - default: - return -EINVAL; - } - if (Ndis802_11APMode == networkType) - r8712_setopmode_cmd(padapter, networkType); - else - r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown); - - r8712_set_802_11_infrastructure_mode(padapter, networkType); - return 0; -} - -static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - wrqu->mode = IW_MODE_INFRA; - else if (check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)) - wrqu->mode = IW_MODE_ADHOC; - else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) - wrqu->mode = IW_MODE_MASTER; - else - wrqu->mode = IW_MODE_AUTO; - return 0; -} - -static int r871x_wx_set_pmkid(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct iw_pmksa *pPMK = (struct iw_pmksa *) extra; - struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList; - u8 strZeroMacAddress[ETH_ALEN] = {0x00}; - u8 strIssueBssid[ETH_ALEN] = {0x00}; - u8 j, blInserted = false; - int intReturn = false; - -/* - * There are the BSSID information in the bssid.sa_data array. - * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear - * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the - * wpa_supplicant wants to add a PMKID/BSSID to driver. - * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to - * remove a PMKID/BSSID from driver. - */ - if (!pPMK) - return -EINVAL; - memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); - switch (pPMK->cmd) { - case IW_PMKSA_ADD: - if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) - return intReturn; - intReturn = true; - blInserted = false; - /* overwrite PMKID */ - for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { - /* BSSID is matched, the same AP => rewrite - * with new PMKID. - */ - netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n", - __func__); - memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); - pl[j].bUsed = true; - psecuritypriv->PMKIDIndex = j + 1; - blInserted = true; - break; - } - } - if (!blInserted) { - /* Find a new entry */ - netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n", - __func__, psecuritypriv->PMKIDIndex); - memcpy(pl[psecuritypriv->PMKIDIndex].Bssid, - strIssueBssid, ETH_ALEN); - memcpy(pl[psecuritypriv->PMKIDIndex].PMKID, - pPMK->pmkid, IW_PMKID_LEN); - pl[psecuritypriv->PMKIDIndex].bUsed = true; - psecuritypriv->PMKIDIndex++; - if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE) - psecuritypriv->PMKIDIndex = 0; - } - break; - case IW_PMKSA_REMOVE: - intReturn = true; - for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { - /* BSSID is matched, the same AP => Remove - * this PMKID information and reset it. - */ - eth_zero_addr(pl[j].Bssid); - pl[j].bUsed = false; - break; - } - } - break; - case IW_PMKSA_FLUSH: - memset(psecuritypriv->PMKIDList, 0, - sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - psecuritypriv->PMKIDIndex = 0; - intReturn = true; - break; - default: - netdev_info(dev, "r8712u: %s: unknown Command\n", __func__); - intReturn = false; - break; - } - return intReturn; -} - -static int r8711_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->sens.value = 0; - wrqu->sens.fixed = 0; /* no auto select */ - wrqu->sens.disabled = 1; - return 0; -} - -static int r8711_wx_get_range(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - u16 val; - int i; - - wrqu->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - /* Let's try to keep this struct in the same order as in - * linux/include/wireless.h - */ - - /* TODO: See what values we can set, and remove the ones we can't - * set, or fill them with some default data. - */ - /* ~5 Mb/s real (802.11b) */ - range->throughput = 5 * 1000 * 1000; - /* TODO: 8711 sensitivity ? */ - /* signal level threshold range */ - /* percent values between 0 and 100. */ - range->max_qual.qual = 100; - range->max_qual.level = 100; - range->max_qual.noise = 100; - range->max_qual.updated = 7; /* Updated all three */ - range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ - range->avg_qual.level = 0x100 - 78; - range->avg_qual.noise = 0; - range->avg_qual.updated = 7; /* Updated all three */ - range->num_bitrates = RATE_COUNT; - for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = rtl8180_rates[i]; - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - range->pm_capa = 0; - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 16; - range->num_channels = 14; - for (i = 0, val = 0; i < 14; i++) { - /* Include only legal frequencies for some countries */ - range->freq[val].i = i + 1; - range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; - range->freq[val].e = 1; - val++; - if (val == IW_MAX_FREQUENCIES) - break; - } - range->num_frequency = val; - range->enc_capa = IW_ENC_CAPA_WPA | - IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | - IW_ENC_CAPA_CIPHER_CCMP; - return 0; -} - -static int r8711_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -static int r871x_wx_set_priv(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) -{ - int ret = 0, len = 0; - char *ext; - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *dwrq = (struct iw_point *)awrq; - - len = dwrq->length; - ext = strndup_user(dwrq->pointer, len); - if (IS_ERR(ext)) - return PTR_ERR(ext); - - if (!strcasecmp(ext, "RSSI")) { - /*Return received signal strength indicator in -db for */ - /* current AP */ - /* Rssi xx */ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct wlan_network *pcur_network = &pmlmepriv->cur_network; - /*static u8 xxxx; */ - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - sprintf(ext, "%s rssi %d", - pcur_network->network.Ssid.Ssid, - /*(xxxx=xxxx+10) */ - ((padapter->recvpriv.fw_rssi) >> 1) - 95 - /*pcur_network->network.Rssi */ - ); - } else { - sprintf(ext, "OK"); - } - } else if (!strcasecmp(ext, "LINKSPEED")) { - /*Return link speed in MBPS */ - /*LinkSpeed xx */ - union iwreq_data wrqd; - int ret_inner; - int mbps; - - ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra); - if (ret_inner != 0) - mbps = 0; - else - mbps = wrqd.bitrate.value / 1000000; - sprintf(ext, "LINKSPEED %d", mbps); - } else if (!strcasecmp(ext, "MACADDR")) { - /*Return mac address of the station */ - /* Macaddr = xx:xx:xx:xx:xx:xx */ - sprintf(ext, "MACADDR = %pM", dev->dev_addr); - } else if (!strcasecmp(ext, "SCAN-ACTIVE")) { - /*Set scan type to active */ - /*OK if successful */ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - pmlmepriv->passive_mode = 1; - sprintf(ext, "OK"); - } else if (!strcasecmp(ext, "SCAN-PASSIVE")) { - /*Set scan type to passive */ - /*OK if successful */ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - pmlmepriv->passive_mode = 0; - sprintf(ext, "OK"); - } else if (!strncmp(ext, "DCE-E", 5)) { - /*Set scan type to passive */ - /*OK if successful */ - r8712_disconnectCtrlEx_cmd(padapter - , 1 /*u32 enableDrvCtrl */ - , 5 /*u32 tryPktCnt */ - , 100 /*u32 tryPktInterval */ - , 5000 /*u32 firstStageTO */ - ); - sprintf(ext, "OK"); - } else if (!strncmp(ext, "DCE-D", 5)) { - /*Set scan type to passive */ - /*OK if successfu */ - r8712_disconnectCtrlEx_cmd(padapter - , 0 /*u32 enableDrvCtrl */ - , 5 /*u32 tryPktCnt */ - , 100 /*u32 tryPktInterval */ - , 5000 /*u32 firstStageTO */ - ); - sprintf(ext, "OK"); - } else { - netdev_info(dev, "r8712u: %s: unknown Command %s.\n", __func__, ext); - goto FREE_EXT; - } - if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (__u16)(strlen(ext) + 1)))) - ret = -EFAULT; - -FREE_EXT: - kfree(ext); - return ret; -} - -/* set bssid flow - * s1. set_802_11_infrastructure_mode() - * s2. set_802_11_authentication_mode() - * s3. set_802_11_encryption_mode() - * s4. set_802_11_bssid() - * - * This function intends to handle the Set AP command, which specifies the - * MAC# of a preferred Access Point. - * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl. - * - * For this operation to succeed, there is no need for the interface to be up. - * - */ -static int r8711_wx_set_wap(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *awrq, char *extra) -{ - int ret = -EINPROGRESS; - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct sockaddr *temp = (struct sockaddr *)awrq; - unsigned long irqL; - struct list_head *phead; - u8 *dst_bssid; - struct wlan_network *pnetwork = NULL; - enum NDIS_802_11_AUTHENTICATION_MODE authmode; - - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) - return -EBUSY; - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - return ret; - if (temp->sa_family != ARPHRD_ETHER) - return -EINVAL; - authmode = padapter->securitypriv.ndisauthtype; - spin_lock_irqsave(&queue->lock, irqL); - phead = &queue->queue; - pmlmepriv->pscanned = phead->next; - while (1) { - if (end_of_queue_search(phead, pmlmepriv->pscanned)) - break; - pnetwork = container_of(pmlmepriv->pscanned, - struct wlan_network, list); - pmlmepriv->pscanned = pmlmepriv->pscanned->next; - dst_bssid = pnetwork->network.MacAddress; - if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) { - r8712_set_802_11_infrastructure_mode(padapter, - pnetwork->network.InfrastructureMode); - break; - } - } - spin_unlock_irqrestore(&queue->lock, irqL); - if (!ret) { - if (!r8712_set_802_11_authentication_mode(padapter, authmode)) { - ret = -ENOMEM; - } else { - if (!r8712_set_802_11_bssid(padapter, temp->sa_data)) - ret = -1; - } - } - return ret; -} - -static int r8711_wx_get_wap(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - - wrqu->ap_addr.sa_family = ARPHRD_ETHER; - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) - ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress); - else - eth_zero_addr(wrqu->ap_addr.sa_data); - return 0; -} - -static int r871x_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct _adapter *padapter = netdev_priv(dev); - struct iw_mlme *mlme = (struct iw_mlme *) extra; - - if (!mlme) - return -1; - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - if (!r8712_set_802_11_disassociate(padapter)) - ret = -1; - break; - case IW_MLME_DISASSOC: - if (!r8712_set_802_11_disassociate(padapter)) - ret = -1; - break; - default: - return -EOPNOTSUPP; - } - return ret; -} - -/* - * - * This function intends to handle the Set Scan command. - * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl. - * - * For this operation to succeed, the interface is brought Up beforehand. - * - */ -static int r8711_wx_set_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 status = true; - - if (padapter->driver_stopped) { - netdev_info(dev, "In %s: driver_stopped=%d\n", - __func__, padapter->driver_stopped); - return -1; - } - if (!padapter->bup) - return -ENETDOWN; - if (!padapter->hw_init_completed) - return -1; - if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) || - (pmlmepriv->sitesurveyctrl.traffic_busy)) - return 0; - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct ndis_802_11_ssid ssid; - unsigned long irqL; - u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE); - - memset((unsigned char *)&ssid, 0, sizeof(struct ndis_802_11_ssid)); - memcpy(ssid.Ssid, req->essid, len); - ssid.SsidLength = len; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | - _FW_UNDER_LINKING)) || - (pmlmepriv->sitesurveyctrl.traffic_busy)) { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - status = false; - } else { - status = r8712_sitesurvey_cmd(padapter, &ssid); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - } - } else { - status = r8712_set_802_11_bssid_list_scan(padapter); - } - if (!status) - return -1; - return 0; -} - -static int r8711_wx_get_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct wlan_network *pnetwork = NULL; - unsigned long irqL; - struct list_head *plist, *phead; - char *ev = extra; - char *stop = ev + wrqu->data.length; - u32 ret = 0, cnt = 0; - - if (padapter->driver_stopped) - return -EINVAL; - while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) { - msleep(30); - cnt++; - if (cnt > 100) - break; - } - spin_lock_irqsave(&queue->lock, irqL); - phead = &queue->queue; - plist = phead->next; - while (1) { - if (end_of_queue_search(phead, plist)) - break; - if ((stop - ev) < SCAN_ITEM_SIZE) { - ret = -E2BIG; - break; - } - pnetwork = container_of(plist, struct wlan_network, list); - ev = translate_scan(padapter, a, pnetwork, ev, stop); - plist = plist->next; - } - spin_unlock_irqrestore(&queue->lock, irqL); - wrqu->data.length = ev - extra; - wrqu->data.flags = 0; - return ret; -} - -/* set ssid flow - * s1. set_802_11_infrastructure_mode() - * s2. set_802_11_authenticaion_mode() - * s3. set_802_11_encryption_mode() - * s4. set_802_11_ssid() - * - * This function intends to handle the Set ESSID command. - * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl. - * - * For this operation to succeed, there is no need for the interface to be Up. - * - */ -static int r8711_wx_set_essid(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct wlan_network *pnetwork = NULL; - enum NDIS_802_11_AUTHENTICATION_MODE authmode; - struct ndis_802_11_ssid ndis_ssid; - u8 *dst_ssid, *src_ssid; - struct list_head *phead; - u32 len; - - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) - return -EBUSY; - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - return 0; - if (wrqu->essid.length > IW_ESSID_MAX_SIZE) - return -E2BIG; - authmode = padapter->securitypriv.ndisauthtype; - if (wrqu->essid.flags && wrqu->essid.length) { - len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? - wrqu->essid.length : IW_ESSID_MAX_SIZE; - memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); - ndis_ssid.SsidLength = len; - memcpy(ndis_ssid.Ssid, extra, len); - src_ssid = ndis_ssid.Ssid; - phead = &queue->queue; - pmlmepriv->pscanned = phead->next; - while (1) { - if (end_of_queue_search(phead, pmlmepriv->pscanned)) - break; - pnetwork = container_of(pmlmepriv->pscanned, - struct wlan_network, list); - pmlmepriv->pscanned = pmlmepriv->pscanned->next; - dst_ssid = pnetwork->network.Ssid.Ssid; - if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) - && (pnetwork->network.Ssid.SsidLength == - ndis_ssid.SsidLength)) { - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - if (pnetwork->network. - InfrastructureMode - != - padapter->mlmepriv. - cur_network.network. - InfrastructureMode) - continue; - } - - r8712_set_802_11_infrastructure_mode( - padapter, - pnetwork->network.InfrastructureMode); - break; - } - } - r8712_set_802_11_authentication_mode(padapter, authmode); - r8712_set_802_11_ssid(padapter, &ndis_ssid); - } - return -EINPROGRESS; -} - -static int r8711_wx_get_essid(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - u32 len, ret = 0; - - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { - len = pcur_bss->Ssid.SsidLength; - wrqu->essid.length = len; - memcpy(extra, pcur_bss->Ssid.Ssid, len); - wrqu->essid.flags = 1; - } else { - ret = -ENOLINK; - } - return ret; -} - -static int r8711_wx_set_rate(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 target_rate = wrqu->bitrate.value; - u32 fixed = wrqu->bitrate.fixed; - u32 ratevalue = 0; - u8 datarates[NumRates]; - u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; - int i; - - if (target_rate == -1) { - ratevalue = 11; - goto set_rate; - } - target_rate = target_rate / 100000; - switch (target_rate) { - case 10: - ratevalue = 0; - break; - case 20: - ratevalue = 1; - break; - case 55: - ratevalue = 2; - break; - case 60: - ratevalue = 3; - break; - case 90: - ratevalue = 4; - break; - case 110: - ratevalue = 5; - break; - case 120: - ratevalue = 6; - break; - case 180: - ratevalue = 7; - break; - case 240: - ratevalue = 8; - break; - case 360: - ratevalue = 9; - break; - case 480: - ratevalue = 10; - break; - case 540: - ratevalue = 11; - break; - default: - ratevalue = 11; - break; - } -set_rate: - for (i = 0; i < NumRates; i++) { - if (ratevalue == mpdatarate[i]) { - datarates[i] = mpdatarate[i]; - if (fixed == 0) - break; - } else { - datarates[i] = 0xff; - } - } - return r8712_setdatarate_cmd(padapter, datarates); -} - -static int r8711_wx_get_rate(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - struct ieee80211_ht_cap *pht_capie; - unsigned char rf_type = padapter->registrypriv.rf_config; - int i; - u8 *p; - u16 rate, max_rate = 0, ht_cap = false; - u32 ht_ielen = 0; - u8 bw_40MHz = 0, short_GI = 0; - u16 mcs_rate = 0; - - i = 0; - if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) - return -ENOLINK; - p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, - pcur_bss->IELength - 12); - if (p && ht_ielen > 0) { - ht_cap = true; - pht_capie = (struct ieee80211_ht_cap *)(p + 2); - memcpy(&mcs_rate, &pht_capie->mcs, 2); - bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & - IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; - short_GI = (le16_to_cpu(pht_capie->cap_info) & - (IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; - } - while ((pcur_bss->rates[i] != 0) && - (pcur_bss->rates[i] != 0xFF)) { - rate = pcur_bss->rates[i] & 0x7F; - if (rate > max_rate) - max_rate = rate; - wrqu->bitrate.fixed = 0; /* no auto select */ - wrqu->bitrate.value = rate * 500000; - i++; - } - if (ht_cap) { - if (mcs_rate & 0x8000 /* MCS15 */ - && - rf_type == RTL8712_RF_2T2R) - max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : - ((short_GI) ? 144 : 130); - else /* default MCS7 */ - max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : - ((short_GI) ? 72 : 65); - max_rate *= 2; /* Mbps/2 */ - } - wrqu->bitrate.value = max_rate * 500000; - return 0; -} - -static int r8711_wx_get_rts(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - wrqu->rts.value = padapter->registrypriv.rts_thresh; - wrqu->rts.fixed = 0; /* no auto select */ - return 0; -} - -static int r8711_wx_set_frag(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - if (wrqu->frag.disabled) { - padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; - } else { - if (wrqu->frag.value < MIN_FRAG_THRESHOLD || - wrqu->frag.value > MAX_FRAG_THRESHOLD) - return -EINVAL; - padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; - } - return 0; -} - -static int r8711_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - wrqu->frag.value = padapter->xmitpriv.frag_len; - wrqu->frag.fixed = 0; /* no auto select */ - return 0; -} - -static int r8711_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->retry.value = 7; - wrqu->retry.fixed = 0; /* no auto select */ - wrqu->retry.disabled = 1; - return 0; -} - -static int r8711_wx_set_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - u32 key; - u32 keyindex_provided; - struct NDIS_802_11_WEP wep; - enum NDIS_802_11_AUTHENTICATION_MODE authmode; - struct iw_point *erq = &wrqu->encoding; - struct _adapter *padapter = netdev_priv(dev); - - key = erq->flags & IW_ENCODE_INDEX; - memset(&wep, 0, sizeof(struct NDIS_802_11_WEP)); - if (erq->flags & IW_ENCODE_DISABLED) { - netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11EncryptionDisabled; - padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; - padapter->securitypriv.AuthAlgrthm = 0; /* open system */ - authmode = Ndis802_11AuthModeOpen; - padapter->securitypriv.ndisauthtype = authmode; - return 0; - } - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - keyindex_provided = 1; - } else { - keyindex_provided = 0; - key = padapter->securitypriv.PrivacyKeyIndex; - } - /* set authentication mode */ - if (erq->flags & IW_ENCODE_OPEN) { - netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.AuthAlgrthm = 0; /* open system */ - padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; - authmode = Ndis802_11AuthModeOpen; - padapter->securitypriv.ndisauthtype = authmode; - } else if (erq->flags & IW_ENCODE_RESTRICTED) { - netdev_info(dev, - "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.AuthAlgrthm = 1; /* shared system */ - padapter->securitypriv.PrivacyAlgrthm = _WEP40_; - padapter->securitypriv.XGrpPrivacy = _WEP40_; - authmode = Ndis802_11AuthModeShared; - padapter->securitypriv.ndisauthtype = authmode; - } else { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.AuthAlgrthm = 0; /* open system */ - padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; - authmode = Ndis802_11AuthModeOpen; - padapter->securitypriv.ndisauthtype = authmode; - } - wep.KeyIndex = key; - if (erq->length > 0) { - wep.KeyLength = erq->length <= 5 ? 5 : 13; - wep.Length = wep.KeyLength + - offsetof(struct NDIS_802_11_WEP, KeyMaterial); - } else { - wep.KeyLength = 0; - if (keyindex_provided == 1) { /* set key_id only, no given - * KeyMaterial(erq->length==0). - */ - padapter->securitypriv.PrivacyKeyIndex = key; - switch (padapter->securitypriv.DefKeylen[key]) { - case 5: - padapter->securitypriv.PrivacyAlgrthm = - _WEP40_; - break; - case 13: - padapter->securitypriv.PrivacyAlgrthm = - _WEP104_; - break; - default: - padapter->securitypriv.PrivacyAlgrthm = - _NO_PRIVACY_; - break; - } - return 0; - } - } - wep.KeyIndex |= 0x80000000; /* transmit key */ - memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); - if (r8712_set_802_11_add_wep(padapter, &wep)) - return -EOPNOTSUPP; - return 0; -} - -static int r8711_wx_get_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - uint key; - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *erq = &wrqu->encoding; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - union Keytype *dk = padapter->securitypriv.DefKey; - - if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } - } - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - } else { - key = padapter->securitypriv.PrivacyKeyIndex; - } - erq->flags = key + 1; - switch (padapter->securitypriv.ndisencryptstatus) { - case Ndis802_11EncryptionNotSupported: - case Ndis802_11EncryptionDisabled: - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - break; - case Ndis802_11Encryption1Enabled: - erq->length = padapter->securitypriv.DefKeylen[key]; - if (erq->length) { - memcpy(keybuf, dk[key].skey, - padapter->securitypriv.DefKeylen[key]); - erq->flags |= IW_ENCODE_ENABLED; - if (padapter->securitypriv.ndisauthtype == - Ndis802_11AuthModeOpen) - erq->flags |= IW_ENCODE_OPEN; - else if (padapter->securitypriv.ndisauthtype == - Ndis802_11AuthModeShared) - erq->flags |= IW_ENCODE_RESTRICTED; - } else { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - } - break; - case Ndis802_11Encryption2Enabled: - case Ndis802_11Encryption3Enabled: - erq->length = 16; - erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | - IW_ENCODE_NOKEY); - break; - default: - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - break; - } - return 0; -} - -static int r8711_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->power.value = 0; - wrqu->power.fixed = 0; /* no auto select */ - wrqu->power.disabled = 1; - return 0; -} - -static int r871x_wx_set_gen_ie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - return r871x_set_wpa_ie(padapter, extra, wrqu->data.length); -} - -static int r871x_wx_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_param *param = (struct iw_param *)&wrqu->param; - int paramid; - int paramval; - int ret = 0; - - paramid = param->flags & IW_AUTH_INDEX; - paramval = param->value; - switch (paramid) { - case IW_AUTH_WPA_VERSION: - break; - case IW_AUTH_CIPHER_PAIRWISE: - break; - case IW_AUTH_CIPHER_GROUP: - break; - case IW_AUTH_KEY_MGMT: - /* - * ??? does not use these parameters - */ - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - if (paramval) { - /* wpa_supplicant is enabling tkip countermeasure. */ - padapter->securitypriv.btkip_countermeasure = true; - } else { - /* wpa_supplicant is disabling tkip countermeasure. */ - padapter->securitypriv.btkip_countermeasure = false; - } - break; - case IW_AUTH_DROP_UNENCRYPTED: - /* HACK: - * - * wpa_supplicant calls set_wpa_enabled when the driver - * is loaded and unloaded, regardless of if WPA is being - * used. No other calls are made which can be used to - * determine if encryption will be used or not prior to - * association being expected. If encryption is not being - * used, drop_unencrypted is set to false, else true -- we - * can use this to determine if the CAP_PRIVACY_ON bit should - * be set. - */ - if (padapter->securitypriv.ndisencryptstatus == - Ndis802_11Encryption1Enabled) { - /* it means init value, or using wep, - * ndisencryptstatus = - * Ndis802_11Encryption1Enabled, - * then it needn't reset it; - */ - break; - } - - if (paramval) { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11EncryptionDisabled; - padapter->securitypriv.PrivacyAlgrthm = - _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = - _NO_PRIVACY_; - padapter->securitypriv.AuthAlgrthm = 0; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeOpen; - } - break; - case IW_AUTH_80211_AUTH_ALG: - ret = wpa_set_auth_algs(dev, (u32)paramval); - break; - case IW_AUTH_WPA_ENABLED: - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; - case IW_AUTH_PRIVACY_INVOKED: - break; - default: - return -EOPNOTSUPP; - } - - return ret; -} - -static int r871x_wx_set_enc_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_point *pencoding = &wrqu->encoding; - struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; - struct ieee_param *param = NULL; - char *alg_name; - u32 param_len; - int ret = 0; - - switch (pext->alg) { - case IW_ENCODE_ALG_NONE: - alg_name = "none"; - break; - case IW_ENCODE_ALG_WEP: - alg_name = "WEP"; - break; - case IW_ENCODE_ALG_TKIP: - alg_name = "TKIP"; - break; - case IW_ENCODE_ALG_CCMP: - alg_name = "CCMP"; - break; - default: - return -EINVAL; - } - - param_len = sizeof(struct ieee_param) + pext->key_len; - param = kzalloc(param_len, GFP_ATOMIC); - if (!param) - return -ENOMEM; - param->cmd = IEEE_CMD_SET_ENCRYPTION; - eth_broadcast_addr(param->sta_addr); - strscpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); - if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) - param->u.crypt.set_tx = 0; - if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - param->u.crypt.set_tx = 1; - param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1; - if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) - memcpy(param->u.crypt.seq, pext->rx_seq, 8); - if (pext->key_len) { - param->u.crypt.key_len = pext->key_len; - memcpy(param + 1, pext + 1, pext->key_len); - } - ret = wpa_set_encryption(dev, param, param_len); - kfree(param); - return ret; -} - -static int r871x_wx_get_nick(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - if (extra) { - wrqu->data.length = 8; - wrqu->data.flags = 1; - memcpy(extra, "rtl_wifi", 8); - } - return 0; -} - -static int r8711_wx_read32(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 addr; - u32 data32; - - get_user(addr, (u32 __user *)wrqu->data.pointer); - data32 = r8712_read32(padapter, addr); - put_user(data32, (u32 __user *)wrqu->data.pointer); - wrqu->data.length = (data32 & 0xffff0000) >> 16; - wrqu->data.flags = data32 & 0xffff; - get_user(addr, (u32 __user *)wrqu->data.pointer); - return 0; -} - -static int r8711_wx_write32(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 addr; - u32 data32; - - get_user(addr, (u32 __user *)wrqu->data.pointer); - data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags; - r8712_write32(padapter, addr, data32); - return 0; -} - -static int dummy(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - return -EINVAL; -} - -static int r8711_drvext_hdl(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - return 0; -} - -static int r871x_mp_ioctl_hdl(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *p = &wrqu->data; - struct oid_par_priv oid_par; - struct mp_ioctl_handler *phandler; - struct mp_ioctl_param *poidparam; - unsigned long BytesRead, BytesWritten, BytesNeeded; - u8 *pparmbuf, bset; - u16 len; - uint status; - int ret = 0; - - if ((!p->length) || (!p->pointer)) - return -EINVAL; - - bset = (u8)(p->flags & 0xFFFF); - len = p->length; - pparmbuf = memdup_user(p->pointer, len); - if (IS_ERR(pparmbuf)) - return PTR_ERR(pparmbuf); - - poidparam = (struct mp_ioctl_param *)pparmbuf; - if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { - ret = -EINVAL; - goto _r871x_mp_ioctl_hdl_exit; - } - phandler = mp_ioctl_hdl + poidparam->subcode; - if ((phandler->paramsize != 0) && - (poidparam->len < phandler->paramsize)) { - ret = -EINVAL; - goto _r871x_mp_ioctl_hdl_exit; - } - if (phandler->oid == 0 && phandler->handler) { - status = phandler->handler(&oid_par); - } else if (phandler->handler) { - oid_par.adapter_context = padapter; - oid_par.oid = phandler->oid; - oid_par.information_buf = poidparam->data; - oid_par.information_buf_len = poidparam->len; - oid_par.dbg = 0; - BytesWritten = 0; - BytesNeeded = 0; - if (bset) { - oid_par.bytes_rw = &BytesRead; - oid_par.bytes_needed = &BytesNeeded; - oid_par.type_of_oid = SET_OID; - } else { - oid_par.bytes_rw = &BytesWritten; - oid_par.bytes_needed = &BytesNeeded; - oid_par.type_of_oid = QUERY_OID; - } - status = phandler->handler(&oid_par); - /* todo:check status, BytesNeeded, etc. */ - } else { - netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n", - __func__, poidparam->subcode, phandler->oid, - phandler->handler); - ret = -EFAULT; - goto _r871x_mp_ioctl_hdl_exit; - } - if (bset == 0x00) { /* query info */ - if (copy_to_user(p->pointer, pparmbuf, len)) - ret = -EFAULT; - } - if (status) { - ret = -EFAULT; - goto _r871x_mp_ioctl_hdl_exit; - } -_r871x_mp_ioctl_hdl_exit: - kfree(pparmbuf); - return ret; -} - -static int r871x_get_ap_info(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct iw_point *pdata = &wrqu->data; - struct wlan_network *pnetwork = NULL; - u32 cnt = 0, wpa_ielen; - unsigned long irqL; - struct list_head *plist, *phead; - unsigned char *pbuf; - u8 bssid[ETH_ALEN]; - char data[33]; - - if (padapter->driver_stopped || !pdata) - return -EINVAL; - while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | - _FW_UNDER_LINKING)) { - msleep(30); - cnt++; - if (cnt > 100) - break; - } - pdata->flags = 0; - if (pdata->length < 32) - return -EINVAL; - if (copy_from_user(data, pdata->pointer, 32)) - return -EINVAL; - data[32] = 0; - - spin_lock_irqsave(&pmlmepriv->scanned_queue.lock, irqL); - phead = &queue->queue; - plist = phead->next; - while (1) { - if (end_of_queue_search(phead, plist)) - break; - pnetwork = container_of(plist, struct wlan_network, list); - if (!mac_pton(data, bssid)) { - netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n", - (u8 *)data); - spin_unlock_irqrestore(&pmlmepriv->scanned_queue.lock, - irqL); - return -EINVAL; - } - netdev_info(dev, "r8712u: BSSID:%pM\n", bssid); - if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) { - /* BSSID match, then check if supporting wpa/wpa2 */ - pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12], - &wpa_ielen, pnetwork->network.IELength - 12); - if (pbuf && (wpa_ielen > 0)) { - pdata->flags = 1; - break; - } - pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12], - &wpa_ielen, pnetwork->network.IELength - 12); - if (pbuf && (wpa_ielen > 0)) { - pdata->flags = 2; - break; - } - } - plist = plist->next; - } - spin_unlock_irqrestore(&pmlmepriv->scanned_queue.lock, irqL); - if (pdata->length >= 34) { - if (copy_to_user((u8 __user *)pdata->pointer + 32, - (u8 *)&pdata->flags, 1)) - return -EINVAL; - } - return 0; -} - -static int r871x_set_pid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *pdata = &wrqu->data; - - if (padapter->driver_stopped || !pdata) - return -EINVAL; - if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int))) - return -EINVAL; - return 0; -} - -static int r871x_set_chplan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *pdata = &wrqu->data; - int ch_plan = -1; - - if (padapter->driver_stopped || !pdata) { - ret = -EINVAL; - goto exit; - } - ch_plan = (int)*extra; - r8712_set_chplan_cmd(padapter, ch_plan); - -exit: - - return ret; -} - -static int r871x_wps_start(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *pdata = &wrqu->data; - u32 u32wps_start = 0; - - if (padapter->driver_stopped || !pdata) - return -EINVAL; - if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) - return -EFAULT; - if (u32wps_start == 0) - u32wps_start = *extra; - if (u32wps_start == 1) /* WPS Start */ - padapter->ledpriv.LedControlHandler(padapter, - LED_CTL_START_WPS); - else if (u32wps_start == 2) /* WPS Stop because of wps success */ - padapter->ledpriv.LedControlHandler(padapter, - LED_CTL_STOP_WPS); - else if (u32wps_start == 3) /* WPS Stop because of wps fail */ - padapter->ledpriv.LedControlHandler(padapter, - LED_CTL_STOP_WPS_FAIL); - return 0; -} - -static int wpa_set_param(struct net_device *dev, u8 name, u32 value) -{ - struct _adapter *padapter = netdev_priv(dev); - - switch (name) { - case IEEE_PARAM_WPA_ENABLED: - padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */ - switch ((value) & 0xff) { - case 1: /* WPA */ - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPAPSK; /* WPA_PSK */ - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption2Enabled; - break; - case 2: /* WPA2 */ - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */ - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption3Enabled; - break; - } - break; - case IEEE_PARAM_TKIP_COUNTERMEASURES: - break; - case IEEE_PARAM_DROP_UNENCRYPTED: - /* HACK: - * - * wpa_supplicant calls set_wpa_enabled when the driver - * is loaded and unloaded, regardless of if WPA is being - * used. No other calls are made which can be used to - * determine if encryption will be used or not prior to - * association being expected. If encryption is not being - * used, drop_unencrypted is set to false, else true -- we - * can use this to determine if the CAP_PRIVACY_ON bit should - * be set. - */ - break; - case IEEE_PARAM_PRIVACY_INVOKED: - break; - case IEEE_PARAM_AUTH_ALGS: - return wpa_set_auth_algs(dev, value); - case IEEE_PARAM_IEEE_802_1X: - break; - case IEEE_PARAM_WPAX_SELECT: - /* added for WPA2 mixed mode */ - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) -{ - struct _adapter *padapter = netdev_priv(dev); - - switch (command) { - case IEEE_MLME_STA_DEAUTH: - if (!r8712_set_802_11_disassociate(padapter)) - return -1; - break; - case IEEE_MLME_STA_DISASSOC: - if (!r8712_set_802_11_disassociate(padapter)) - return -1; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) -{ - struct ieee_param *param; - int ret = 0; - struct _adapter *padapter = netdev_priv(dev); - - if (p->length < sizeof(struct ieee_param) || !p->pointer) - return -EINVAL; - param = memdup_user(p->pointer, p->length); - if (IS_ERR(param)) - return PTR_ERR(param); - switch (param->cmd) { - case IEEE_CMD_SET_WPA_PARAM: - ret = wpa_set_param(dev, param->u.wpa_param.name, - param->u.wpa_param.value); - break; - case IEEE_CMD_SET_WPA_IE: - ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data, - (u16)param->u.wpa_ie.len); - break; - case IEEE_CMD_SET_ENCRYPTION: - ret = wpa_set_encryption(dev, param, p->length); - break; - case IEEE_CMD_MLME: - ret = wpa_mlme(dev, param->u.mlme.command, - param->u.mlme.reason_code); - break; - default: - ret = -EOPNOTSUPP; - break; - } - if (ret == 0 && copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - kfree(param); - return ret; -} - -/* based on "driver_ipw" and for hostapd */ -int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct iwreq *wrq = (struct iwreq *)rq; - - switch (cmd) { - case RTL_IOCTL_WPA_SUPPLICANT: - return wpa_supplicant_ioctl(dev, &wrq->u.data); - default: - return -EOPNOTSUPP; - } - return 0; -} - -static iw_handler r8711_handlers[] = { - NULL, /* SIOCSIWCOMMIT */ - r8711_wx_get_name, /* SIOCGIWNAME */ - dummy, /* SIOCSIWNWID */ - dummy, /* SIOCGIWNWID */ - r8711_wx_set_freq, /* SIOCSIWFREQ */ - r8711_wx_get_freq, /* SIOCGIWFREQ */ - r8711_wx_set_mode, /* SIOCSIWMODE */ - r8711_wx_get_mode, /* SIOCGIWMODE */ - dummy, /* SIOCSIWSENS */ - r8711_wx_get_sens, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - r8711_wx_get_range, /* SIOCGIWRANGE */ - r871x_wx_set_priv, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - dummy, /* SIOCSIWSPY */ - dummy, /* SIOCGIWSPY */ - NULL, /* SIOCGIWTHRSPY */ - NULL, /* SIOCWIWTHRSPY */ - r8711_wx_set_wap, /* SIOCSIWAP */ - r8711_wx_get_wap, /* SIOCGIWAP */ - r871x_wx_set_mlme, /* request MLME operation; - * uses struct iw_mlme - */ - dummy, /* SIOCGIWAPLIST -- deprecated */ - r8711_wx_set_scan, /* SIOCSIWSCAN */ - r8711_wx_get_scan, /* SIOCGIWSCAN */ - r8711_wx_set_essid, /* SIOCSIWESSID */ - r8711_wx_get_essid, /* SIOCGIWESSID */ - dummy, /* SIOCSIWNICKN */ - r871x_wx_get_nick, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - r8711_wx_set_rate, /* SIOCSIWRATE */ - r8711_wx_get_rate, /* SIOCGIWRATE */ - dummy, /* SIOCSIWRTS */ - r8711_wx_get_rts, /* SIOCGIWRTS */ - r8711_wx_set_frag, /* SIOCSIWFRAG */ - r8711_wx_get_frag, /* SIOCGIWFRAG */ - dummy, /* SIOCSIWTXPOW */ - dummy, /* SIOCGIWTXPOW */ - dummy, /* SIOCSIWRETRY */ - r8711_wx_get_retry, /* SIOCGIWRETRY */ - r8711_wx_set_enc, /* SIOCSIWENCODE */ - r8711_wx_get_enc, /* SIOCGIWENCODE */ - dummy, /* SIOCSIWPOWER */ - r8711_wx_get_power, /* SIOCGIWPOWER */ - NULL, /*---hole---*/ - NULL, /*---hole---*/ - r871x_wx_set_gen_ie, /* SIOCSIWGENIE */ - NULL, /* SIOCGIWGENIE */ - r871x_wx_set_auth, /* SIOCSIWAUTH */ - NULL, /* SIOCGIWAUTH */ - r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ - NULL, /* SIOCGIWENCODEEXT */ - r871x_wx_set_pmkid, /* SIOCSIWPMKSA */ - NULL, /*---hole---*/ -}; - -static const struct iw_priv_args r8711_private_args[] = { - { - SIOCIWFIRSTPRIV + 0x0, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32" - }, - { - SIOCIWFIRSTPRIV + 0x1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32" - }, - { - SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" - }, - { - SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" - }, - { - SIOCIWFIRSTPRIV + 0x4, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" - }, - { - SIOCIWFIRSTPRIV + 0x5, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid" - }, - { - SIOCIWFIRSTPRIV + 0x6, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" - }, - { - SIOCIWFIRSTPRIV + 0x7, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan" - } -}; - -static iw_handler r8711_private_handler[] = { - r8711_wx_read32, - r8711_wx_write32, - r8711_drvext_hdl, - r871x_mp_ioctl_hdl, - r871x_get_ap_info, /*for MM DTV platform*/ - r871x_set_pid, - r871x_wps_start, - r871x_set_chplan -}; - -static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_statistics *piwstats = &padapter->iwstats; - int tmp_level = 0; - int tmp_qual = 0; - int tmp_noise = 0; - - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) { - piwstats->qual.qual = 0; - piwstats->qual.level = 0; - piwstats->qual.noise = 0; - } else { - /* show percentage, we need transfer dbm to original value. */ - tmp_level = padapter->recvpriv.fw_rssi; - tmp_qual = padapter->recvpriv.signal; - tmp_noise = padapter->recvpriv.noise; - piwstats->qual.level = tmp_level; - piwstats->qual.qual = tmp_qual; - piwstats->qual.noise = tmp_noise; - } - piwstats->qual.updated = IW_QUAL_ALL_UPDATED; - return &padapter->iwstats; -} - -struct iw_handler_def r871x_handlers_def = { - .standard = r8711_handlers, - .num_standard = ARRAY_SIZE(r8711_handlers), - .private = r8711_private_handler, - .private_args = (struct iw_priv_args *)r8711_private_args, - .num_private = ARRAY_SIZE(r8711_private_handler), - .num_private_args = sizeof(r8711_private_args) / - sizeof(struct iw_priv_args), - .get_wireless_stats = r871x_get_wireless_stats -}; diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c deleted file mode 100644 index 2b539335206aa1a259aeff51e55d0ed828b8ac19..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c +++ /dev/null @@ -1,519 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_ioctl_rtl.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_IOCTL_RTL_C_ - -#include -#include "osdep_service.h" -#include "drv_types.h" -#include "wlan_bssdef.h" -#include "wifi.h" -#include "rtl871x_ioctl.h" -#include "rtl871x_ioctl_set.h" -#include "rtl871x_ioctl_rtl.h" -#include "mp_custom_oid.h" -#include "rtl871x_mp.h" -#include "rtl871x_mp_ioctl.h" - -uint oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_smallpacket_crcerr; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_middlepacket_crcerr; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_largepacket_crcerr; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_pkts + - padapter->recvpriv.rx_drop; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(uint *)poid_par_priv->information_buf = - padapter->recvpriv.rx_icv_err; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - u32 preamblemode = 0; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - if (padapter->registrypriv.preamble == PREAMBLE_LONG) - preamblemode = 0; - else if (padapter->registrypriv.preamble == PREAMBLE_AUTO) - preamblemode = 1; - else if (padapter->registrypriv.preamble == PREAMBLE_SHORT) - preamblemode = 2; - *(u32 *)poid_par_priv->information_buf = preamblemode; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct eeprom_priv *peeprompriv = &padapter->eeprompriv; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - *(u16 *)poid_par_priv->information_buf = peeprompriv->channel_plan; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_channelplan_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct eeprom_priv *peeprompriv = &padapter->eeprompriv; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - peeprompriv->channel_plan = *(u16 *)poid_par_priv->information_buf; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_preamble_mode_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - u32 preamblemode = 0; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - preamblemode = *(u32 *)poid_par_priv->information_buf; - if (preamblemode == 0) - padapter->registrypriv.preamble = PREAMBLE_LONG; - else if (preamblemode == 1) - padapter->registrypriv.preamble = PREAMBLE_AUTO; - else if (preamblemode == 2) - padapter->registrypriv.preamble = PREAMBLE_SHORT; - *(u32 *)poid_par_priv->information_buf = preamblemode; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_dedicate_probe_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->xmitpriv.tx_bytes; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_bytes; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_current_tx_power_level_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct NDIS_802_11_CONFIGURATION *pnic_Config; - u32 channelnum; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (check_fwstate(pmlmepriv, _FW_LINKED) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) - pnic_Config = &pmlmepriv->cur_network.network.Configuration; - else - pnic_Config = &padapter->registrypriv.dev_network.Configuration; - channelnum = pnic_Config->DSConfig; - *(u32 *)poid_par_priv->information_buf = channelnum; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_supported_wireless_mode_hdl(struct oid_par_priv - *poid_par_priv) -{ - u32 ulInfo = 0; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - ulInfo |= 0x0100; /* WIRELESS_MODE_B */ - ulInfo |= 0x0200; /* WIRELESS_MODE_G */ - ulInfo |= 0x0400; /* WIRELESS_MODE_A */ - *(u32 *) poid_par_priv->information_buf = ulInfo; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv* - poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv* - poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - struct _adapter *Adapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */ - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len == - (sizeof(unsigned long) * 3)) { - if (r8712_setrfreg_cmd(Adapter, - *(unsigned char *)poid_par_priv->information_buf, - (unsigned long)(*((unsigned long *) - poid_par_priv->information_buf + 2)))) - status = RNDIS_STATUS_NOT_ACCEPTED; - } else { - status = RNDIS_STATUS_INVALID_LENGTH; - } - return status; -} - -uint oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - struct _adapter *Adapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */ - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len == (sizeof(unsigned long) * - 3)) { - if (Adapter->mppriv.act_in_progress) { - status = RNDIS_STATUS_NOT_ACCEPTED; - } else { - /* init workparam */ - Adapter->mppriv.act_in_progress = true; - Adapter->mppriv.workparam.bcompleted = false; - Adapter->mppriv.workparam.act_type = MPT_READ_RF; - Adapter->mppriv.workparam.io_offset = *(unsigned long *) - poid_par_priv->information_buf; - Adapter->mppriv.workparam.io_value = 0xcccccccc; - - /* RegOffsetValue - The offset of RF register to read. - * RegDataWidth - The data width of RF register to read. - * RegDataValue - The value to read. - * RegOffsetValue = *((unsigned long *)InformationBuffer); - * RegDataWidth = *((unsigned long *)InformationBuffer+1); - * RegDataValue = *((unsigned long *)InformationBuffer+2); - */ - if (r8712_getrfreg_cmd(Adapter, - *(unsigned char *)poid_par_priv->information_buf, - (unsigned char *)&Adapter->mppriv.workparam.io_value - )) - status = RNDIS_STATUS_NOT_ACCEPTED; - } - } else { - status = RNDIS_STATUS_INVALID_LENGTH; - } - return status; -} - -enum _CONNECT_STATE_ { - CHECKINGSTATUS, - ASSOCIATED, - ADHOCMODE, - NOTASSOCIATED -}; - -uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - u32 ulInfo; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - /* nStatus==0 CheckingStatus - * nStatus==1 Associated - * nStatus==2 AdHocMode - * nStatus==3 NotAssociated - */ - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - ulInfo = CHECKINGSTATUS; - else if (check_fwstate(pmlmepriv, _FW_LINKED)) - ulInfo = ASSOCIATED; - else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) - ulInfo = ADHOCMODE; - else - ulInfo = NOTASSOCIATED; - *(u32 *)poid_par_priv->information_buf = ulInfo; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h deleted file mode 100644 index 7c0b880ac68659859c86c336c2fe4773ba8eddd4..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_IOCTL_RTL_H -#define _RTL871X_IOCTL_RTL_H - -#include "osdep_service.h" -#include "drv_types.h" - -/*************** oid_rtl_seg_01_01 **************/ -uint oid_rt_get_signal_quality_hdl( - struct oid_par_priv *poid_par_priv);/*84*/ -uint oid_rt_get_small_packet_crc_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_middle_packet_crc_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_large_packet_crc_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_tx_retry_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_rx_retry_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_rx_total_packet_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_tx_beacon_ok_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_tx_beacon_err_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_rx_icv_err_hdl( - struct oid_par_priv *poid_par_priv);/*93*/ -uint oid_rt_set_encryption_algorithm_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_preamble_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_ap_ip_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_channelplan_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_channelplan_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_preamble_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_bcn_intvl_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_dedicate_probe_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_total_tx_bytes_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_total_rx_bytes_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_current_tx_power_level_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_enc_key_mismatch_count_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_enc_key_match_count_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_channel_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_hardware_radio_off_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_key_mismatch_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_supported_wireless_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_channel_list_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_scan_in_progress_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_forced_data_rate_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_wireless_mode_for_scan_list_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_bss_wireless_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_scan_with_magic_packet_hdl( - struct oid_par_priv *poid_par_priv); - -/************** oid_rtl_seg_01_03 section start **************/ -uint oid_rt_ap_get_associated_station_list_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_ap_switch_into_ap_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_ap_supported_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_ap_set_passphrase_hdl( - struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_01_11 */ -uint oid_rt_pro_rf_write_registry_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_rf_read_registry_hdl( - struct oid_par_priv *poid_par_priv); -/*************** oid_rtl_seg_03_00 section start **************/ -uint oid_rt_get_connect_state_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_default_key_id_hdl( - struct oid_par_priv *poid_par_priv); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c deleted file mode 100644 index 34c9a52b4c42a620d140f2df1e5e632b2d499741..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ /dev/null @@ -1,354 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_ioctl_set.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_IOCTL_SET_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_ioctl_set.h" -#include "usb_osintf.h" -#include "usb_ops.h" - -static u8 validate_ssid(struct ndis_802_11_ssid *ssid) -{ - u8 i; - - if (ssid->SsidLength > 32) - return false; - for (i = 0; i < ssid->SsidLength; i++) { - /* wifi, printable ascii code must be supported */ - if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) - return false; - } - return true; -} - -static u8 do_join(struct _adapter *padapter) -{ - struct list_head *plist, *phead; - u8 *pibss = NULL; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct __queue *queue = &(pmlmepriv->scanned_queue); - int ret; - - phead = &queue->queue; - plist = phead->next; - pmlmepriv->cur_network.join_res = -2; - pmlmepriv->fw_state |= _FW_UNDER_LINKING; - pmlmepriv->pscanned = plist; - pmlmepriv->to_join = true; - - /* adhoc mode will start with an empty queue, but skip checking */ - if (!check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) && - list_empty(&queue->queue)) { - if (pmlmepriv->fw_state & _FW_UNDER_LINKING) - pmlmepriv->fw_state ^= _FW_UNDER_LINKING; - /* when set_ssid/set_bssid for do_join(), but scanning queue - * is empty we try to issue sitesurvey firstly - */ - if (!pmlmepriv->sitesurveyctrl.traffic_busy) - r8712_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); - return true; - } - - ret = r8712_select_and_join_from_scan(pmlmepriv); - if (!ret) { - mod_timer(&pmlmepriv->assoc_timer, - jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT)); - } else { - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - /* submit r8712_createbss_cmd to change to an - * ADHOC_MASTER pmlmepriv->lock has been - * acquired by caller... - */ - struct wlan_bssid_ex *pdev_network = - &padapter->registrypriv.dev_network; - pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; - pibss = padapter->registrypriv.dev_network.MacAddress; - memcpy(&pdev_network->Ssid, - &pmlmepriv->assoc_ssid, - sizeof(struct ndis_802_11_ssid)); - r8712_update_registrypriv_dev_network(padapter); - r8712_generate_random_ibss(pibss); - if (r8712_createbss_cmd(padapter)) - return false; - pmlmepriv->to_join = false; - } else { - /* can't associate ; reset under-linking */ - if (pmlmepriv->fw_state & _FW_UNDER_LINKING) - pmlmepriv->fw_state ^= - _FW_UNDER_LINKING; - /* when set_ssid/set_bssid for do_join(), but - * there are no desired bss in scanning queue - * we try to issue sitesurvey first - */ - if (!pmlmepriv->sitesurveyctrl.traffic_busy) - r8712_sitesurvey_cmd(padapter, - &pmlmepriv->assoc_ssid); - } - } - return true; -} - -u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid) -{ - unsigned long irqL; - u8 status = true; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) { - status = false; - return status; - } - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | - _FW_UNDER_LINKING)) { - status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); - goto _Abort_Set_BSSID; - } - if (check_fwstate(pmlmepriv, - _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { - if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, - ETH_ALEN)) { - if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - /* driver is in - * WIFI_ADHOC_MASTER_STATE - */ - goto _Abort_Set_BSSID; - } else { - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, _FW_LINKED)) - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - if ((check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE))) { - _clr_fwstate_(pmlmepriv, - WIFI_ADHOC_MASTER_STATE); - set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); - } - } - } - memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); - pmlmepriv->assoc_by_bssid = true; - status = do_join(padapter); - goto done; -_Abort_Set_BSSID: -done: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return status; -} - -void r8712_set_802_11_ssid(struct _adapter *padapter, - struct ndis_802_11_ssid *ssid) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *pnetwork = &pmlmepriv->cur_network; - - if (!padapter->hw_init_completed) - return; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) { - check_fwstate(pmlmepriv, _FW_UNDER_LINKING); - goto _Abort_Set_SSID; - } - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { - if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && - (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, - ssid->SsidLength))) { - if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - if (!r8712_is_same_ibss(padapter, - pnetwork)) { - /* if in WIFI_ADHOC_MASTER_STATE or - * WIFI_ADHOC_STATE, create bss or - * rejoin again - */ - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, - _FW_LINKED)) - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE)) { - _clr_fwstate_(pmlmepriv, - WIFI_ADHOC_MASTER_STATE); - set_fwstate(pmlmepriv, - WIFI_ADHOC_STATE); - } - } else { - /* driver is in - * WIFI_ADHOC_MASTER_STATE - */ - goto _Abort_Set_SSID; - } - } - } else { - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, _FW_LINKED)) - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE)) { - _clr_fwstate_(pmlmepriv, - WIFI_ADHOC_MASTER_STATE); - set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); - } - } - } - if (padapter->securitypriv.btkip_countermeasure) - goto _Abort_Set_SSID; - if (!validate_ssid(ssid)) - goto _Abort_Set_SSID; - memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); - pmlmepriv->assoc_by_bssid = false; - do_join(padapter); - goto done; -_Abort_Set_SSID: -done: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_set_802_11_infrastructure_mode(struct _adapter *padapter, - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *cur_network = &pmlmepriv->cur_network; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = - &(cur_network->network.InfrastructureMode); - - if (*pold_state != networktype) { - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_LINKED) || - (*pold_state == Ndis802_11IBSS)) - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, - _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) - r8712_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, _FW_LINKED) || - (*pold_state == Ndis802_11Infrastructure) || - (*pold_state == Ndis802_11IBSS)) { - /* will clr Linked_state before this function, - * we must have checked whether issue dis-assoc_cmd or - * not - */ - r8712_ind_disconnect(padapter); - } - *pold_state = networktype; - /* clear WIFI_STATION_STATE; WIFI_AP_STATE; WIFI_ADHOC_STATE; - * WIFI_ADHOC_MASTER_STATE - */ - _clr_fwstate_(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE | - WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE); - switch (networktype) { - case Ndis802_11IBSS: - set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); - break; - case Ndis802_11Infrastructure: - set_fwstate(pmlmepriv, WIFI_STATION_STATE); - break; - case Ndis802_11APMode: - set_fwstate(pmlmepriv, WIFI_AP_STATE); - break; - case Ndis802_11AutoUnknown: - case Ndis802_11InfrastructureMax: - break; - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - } -} - -u8 r8712_set_802_11_disassociate(struct _adapter *padapter) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - r8712_disassoc_cmd(padapter); - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return true; -} - -u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter) -{ - struct mlme_priv *pmlmepriv = NULL; - unsigned long irqL; - u8 ret = true; - - if (!padapter) - return false; - pmlmepriv = &padapter->mlmepriv; - if (!padapter->hw_init_completed) - return false; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) || - pmlmepriv->sitesurveyctrl.traffic_busy) { - /* Scan or linking is in progress, do nothing. */ - ret = (u8)check_fwstate(pmlmepriv, _FW_UNDER_SURVEY); - } else { - r8712_free_network_queue(padapter); - ret = r8712_sitesurvey_cmd(padapter, NULL); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return ret; -} - -u8 r8712_set_802_11_authentication_mode(struct _adapter *padapter, - enum NDIS_802_11_AUTHENTICATION_MODE authmode) -{ - struct security_priv *psecuritypriv = &padapter->securitypriv; - u8 ret; - - psecuritypriv->ndisauthtype = authmode; - if (psecuritypriv->ndisauthtype > 3) - psecuritypriv->AuthAlgrthm = 2; /* 802.1x */ - if (r8712_set_auth(padapter, psecuritypriv)) - ret = false; - else - ret = true; - return ret; -} - -int r8712_set_802_11_add_wep(struct _adapter *padapter, - struct NDIS_802_11_WEP *wep) -{ - sint keyid; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - keyid = wep->KeyIndex & 0x3fffffff; - if (keyid >= WEP_KEYS) - return -EINVAL; - switch (wep->KeyLength) { - case 5: - psecuritypriv->PrivacyAlgrthm = _WEP40_; - break; - case 13: - psecuritypriv->PrivacyAlgrthm = _WEP104_; - break; - default: - psecuritypriv->PrivacyAlgrthm = _NO_PRIVACY_; - break; - } - memcpy(psecuritypriv->DefKey[keyid].skey, &wep->KeyMaterial, - wep->KeyLength); - psecuritypriv->DefKeylen[keyid] = wep->KeyLength; - psecuritypriv->PrivacyKeyIndex = keyid; - return r8712_set_key(padapter, psecuritypriv, keyid); -} diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.h b/drivers/staging/rtl8712/rtl871x_ioctl_set.h deleted file mode 100644 index e2de820f61d985df11d28eaa434f81cd9274ccc7..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __IOCTL_SET_H -#define __IOCTL_SET_H - -#include "drv_types.h" - -typedef u8 NDIS_802_11_PMKID_VALUE[16]; - -struct BSSIDInfo { - unsigned char BSSID[6]; - NDIS_802_11_PMKID_VALUE PMKID; -}; - -u8 r8712_set_802_11_authentication_mode(struct _adapter *pdapter, - enum NDIS_802_11_AUTHENTICATION_MODE authmode); - -u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid); - -int r8712_set_802_11_add_wep(struct _adapter *padapter, - struct NDIS_802_11_WEP *wep); - -u8 r8712_set_802_11_disassociate(struct _adapter *padapter); - -u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter); - -void r8712_set_802_11_infrastructure_mode(struct _adapter *padapter, - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); - -void r8712_set_802_11_ssid(struct _adapter *padapter, - struct ndis_802_11_ssid *ssid); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_led.h b/drivers/staging/rtl8712/rtl871x_led.h deleted file mode 100644 index 2f0768132ad8fff5148d2b0626d6f04683518513..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_led.h +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_LED_H -#define __RTL8712_LED_H - -#include "osdep_service.h" -#include "drv_types.h" - -/*=========================================================================== - * LED customization. - *=========================================================================== - */ -enum LED_CTL_MODE { - LED_CTL_POWER_ON = 1, - LED_CTL_LINK = 2, - LED_CTL_NO_LINK = 3, - LED_CTL_TX = 4, - LED_CTL_RX = 5, - LED_CTL_SITE_SURVEY = 6, - LED_CTL_POWER_OFF = 7, - LED_CTL_START_TO_LINK = 8, - LED_CTL_START_WPS = 9, - LED_CTL_STOP_WPS = 10, - LED_CTL_START_WPS_BOTTON = 11, - LED_CTL_STOP_WPS_FAIL = 12, - LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, -}; - -#define IS_LED_WPS_BLINKING(_LED_871x) \ - (((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS \ - || ((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS_STOP \ - || ((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress) - -#define IS_LED_BLINKING(_LED_871x) \ - (((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress \ - || ((struct LED_871x *)_LED_871x)->bLedScanBlinkInProgress) - -enum LED_PIN_871x { - LED_PIN_GPIO0, - LED_PIN_LED0, - LED_PIN_LED1 -}; - -/*=========================================================================== - * LED customization. - *=========================================================================== - */ -enum LED_STRATEGY_871x { - SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */ - SW_LED_MODE1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */ - SW_LED_MODE2, /* SW control 1 LED via GPIO0, - * custom for AzWave 8187 minicard. - */ - SW_LED_MODE3, /* SW control 1 LED via GPIO0, - * customized for Sercomm Printer Server case. - */ - SW_LED_MODE4, /*for Edimax / Belkin*/ - SW_LED_MODE5, /*for Sercomm / Belkin*/ - SW_LED_MODE6, /*for WNC / Corega*/ - HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different - * control modes, see MAC.CONFIG1 for details.) - */ -}; - -struct LED_871x { - struct _adapter *padapter; - enum LED_PIN_871x LedPin; /* Implementation for this SW led. */ - u32 CurrLedState; /* Current LED state. */ - u8 bLedOn; /* true if LED is ON */ - u8 bSWLedCtrl; - u8 bLedBlinkInProgress; /*true if blinking */ - u8 bLedNoLinkBlinkInProgress; - u8 bLedLinkBlinkInProgress; - u8 bLedStartToLinkBlinkInProgress; - u8 bLedScanBlinkInProgress; - u8 bLedWPSBlinkInProgress; - u32 BlinkTimes; /* No. times to toggle for blink.*/ - u32 BlinkingLedState; /* Next state for blinking, - * either LED_ON or OFF. - */ - - struct timer_list BlinkTimer; /* Timer object for led blinking.*/ - struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer */ -}; - -struct led_priv { - /* add for led control */ - struct LED_871x SwLed0; - struct LED_871x SwLed1; - enum LED_STRATEGY_871x LedStrategy; - u8 bRegUseLed; - void (*LedControlHandler)(struct _adapter *padapter, - enum LED_CTL_MODE LedAction); - /* add for led control */ -}; - -/*=========================================================================== - * Interface to manipulate LED objects. - *=========================================================================== - */ -void r8712_InitSwLeds(struct _adapter *padapter); -void r8712_DeInitSwLeds(struct _adapter *padapter); -void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction); -void r8712_flush_led_works(struct _adapter *padapter); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c deleted file mode 100644 index 70c295e97068572e3717e516b29f2e3011902041..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ /dev/null @@ -1,1710 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_mlme.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_MLME_C_ - -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "xmit_osdep.h" -#include "mlme_osdep.h" -#include "sta_info.h" -#include "wifi.h" -#include "wlan_bssdef.h" - -static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len); - -int r8712_init_mlme_priv(struct _adapter *padapter) -{ - sint i; - u8 *pbuf; - struct wlan_network *pnetwork; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); - pmlmepriv->nic_hdl = (u8 *)padapter; - pmlmepriv->pscanned = NULL; - pmlmepriv->fw_state = 0; - pmlmepriv->cur_network.network.InfrastructureMode = - Ndis802_11AutoUnknown; - /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/ - pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */ - spin_lock_init(&(pmlmepriv->lock)); - spin_lock_init(&(pmlmepriv->lock2)); - _init_queue(&(pmlmepriv->free_bss_pool)); - _init_queue(&(pmlmepriv->scanned_queue)); - set_scanned_network_val(pmlmepriv, 0); - memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); - pbuf = kmalloc_array(MAX_BSS_CNT, sizeof(struct wlan_network), - GFP_ATOMIC); - if (!pbuf) - return -ENOMEM; - pmlmepriv->free_bss_buf = pbuf; - pnetwork = (struct wlan_network *)pbuf; - for (i = 0; i < MAX_BSS_CNT; i++) { - INIT_LIST_HEAD(&(pnetwork->list)); - list_add_tail(&(pnetwork->list), - &(pmlmepriv->free_bss_pool.queue)); - pnetwork++; - } - pmlmepriv->sitesurveyctrl.last_rx_pkts = 0; - pmlmepriv->sitesurveyctrl.last_tx_pkts = 0; - pmlmepriv->sitesurveyctrl.traffic_busy = false; - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - r8712_init_mlme_timer(padapter); - return 0; -} - -struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv) -{ - unsigned long irqL; - struct wlan_network *pnetwork; - struct __queue *free_queue = &pmlmepriv->free_bss_pool; - - spin_lock_irqsave(&free_queue->lock, irqL); - pnetwork = list_first_entry_or_null(&free_queue->queue, - struct wlan_network, list); - if (pnetwork) { - list_del_init(&pnetwork->list); - pnetwork->last_scanned = jiffies; - pmlmepriv->num_of_scanned++; - } - spin_unlock_irqrestore(&free_queue->lock, irqL); - return pnetwork; -} - -static void _free_network(struct mlme_priv *pmlmepriv, - struct wlan_network *pnetwork) -{ - u32 curr_time, delta_time; - unsigned long irqL; - struct __queue *free_queue = &(pmlmepriv->free_bss_pool); - - if (!pnetwork) - return; - if (pnetwork->fixed) - return; - curr_time = jiffies; - delta_time = (curr_time - (u32)pnetwork->last_scanned) / HZ; - if (delta_time < SCANQUEUE_LIFETIME) - return; - spin_lock_irqsave(&free_queue->lock, irqL); - list_del_init(&pnetwork->list); - list_add_tail(&pnetwork->list, &free_queue->queue); - pmlmepriv->num_of_scanned--; - spin_unlock_irqrestore(&free_queue->lock, irqL); -} - -static void free_network_nolock(struct mlme_priv *pmlmepriv, - struct wlan_network *pnetwork) -{ - struct __queue *free_queue = &pmlmepriv->free_bss_pool; - - if (!pnetwork) - return; - if (pnetwork->fixed) - return; - list_del_init(&pnetwork->list); - list_add_tail(&pnetwork->list, &free_queue->queue); - pmlmepriv->num_of_scanned--; -} - -/* return the wlan_network with the matching addr - * Shall be called under atomic context... - * to avoid possible racing condition... - */ -static struct wlan_network *r8712_find_network(struct __queue *scanned_queue, - u8 *addr) -{ - unsigned long irqL; - struct list_head *phead, *plist; - struct wlan_network *pnetwork = NULL; - - if (is_zero_ether_addr(addr)) - return NULL; - spin_lock_irqsave(&scanned_queue->lock, irqL); - phead = &scanned_queue->queue; - list_for_each(plist, phead) { - pnetwork = list_entry(plist, struct wlan_network, list); - if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN)) - break; - } - if (plist == phead) - pnetwork = NULL; - spin_unlock_irqrestore(&scanned_queue->lock, irqL); - return pnetwork; -} - -void r8712_free_network_queue(struct _adapter *padapter) -{ - unsigned long irqL; - struct list_head *phead, *plist; - struct wlan_network *pnetwork; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *scanned_queue = &pmlmepriv->scanned_queue; - - spin_lock_irqsave(&scanned_queue->lock, irqL); - phead = &scanned_queue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - pnetwork = container_of(plist, struct wlan_network, list); - plist = plist->next; - _free_network(pmlmepriv, pnetwork); - } - spin_unlock_irqrestore(&scanned_queue->lock, irqL); -} - -sint r8712_if_up(struct _adapter *padapter) -{ - sint res; - - if (padapter->driver_stopped || padapter->surprise_removed || - !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { - res = false; - } else { - res = true; - } - return res; -} - -void r8712_generate_random_ibss(u8 *pibss) -{ - u32 curtime = jiffies; - - pibss[0] = 0x02; /*in ad-hoc mode bit1 must set to 1 */ - pibss[1] = 0x11; - pibss[2] = 0x87; - pibss[3] = (u8)(curtime & 0xff); - pibss[4] = (u8)((curtime >> 8) & 0xff); - pibss[5] = (u8)((curtime >> 16) & 0xff); -} - -uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) -{ - return sizeof(*bss) + bss->IELength - MAX_IE_SZ; -} - -u8 *r8712_get_capability_from_ie(u8 *ie) -{ - return ie + 8 + 2; -} - -void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv) -{ - kfree(pmlmepriv->free_bss_buf); -} - -static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv) -{ - return _r8712_alloc_network(pmlmepriv); -} - -int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork) -{ - int ret = true; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) && - (pnetwork->network.Privacy == cpu_to_le32(0))) - ret = false; - else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) && - (pnetwork->network.Privacy == cpu_to_le32(1))) - ret = false; - else - ret = true; - return ret; - -} - -static int is_same_network(struct wlan_bssid_ex *src, - struct wlan_bssid_ex *dst) -{ - u16 s_cap, d_cap; - - memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2); - memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2); - return (src->Ssid.SsidLength == dst->Ssid.SsidLength) && - (src->Configuration.DSConfig == - dst->Configuration.DSConfig) && - ((!memcmp(src->MacAddress, dst->MacAddress, - ETH_ALEN))) && - ((!memcmp(src->Ssid.Ssid, - dst->Ssid.Ssid, - src->Ssid.SsidLength))) && - ((s_cap & WLAN_CAPABILITY_IBSS) == - (d_cap & WLAN_CAPABILITY_IBSS)) && - ((s_cap & WLAN_CAPABILITY_ESS) == - (d_cap & WLAN_CAPABILITY_ESS)); - -} - -struct wlan_network *r8712_get_oldest_wlan_network( - struct __queue *scanned_queue) -{ - struct list_head *plist, *phead; - struct wlan_network *pwlan = NULL; - struct wlan_network *oldest = NULL; - - phead = &scanned_queue->queue; - plist = phead->next; - while (1) { - if (end_of_queue_search(phead, plist)) - break; - pwlan = container_of(plist, struct wlan_network, list); - if (!pwlan->fixed) { - if (!oldest || - time_after((unsigned long)oldest->last_scanned, - (unsigned long)pwlan->last_scanned)) - oldest = pwlan; - } - plist = plist->next; - } - return oldest; -} - -static void update_network(struct wlan_bssid_ex *dst, - struct wlan_bssid_ex *src, - struct _adapter *padapter) -{ - u32 last_evm = 0, tmpVal; - struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; - - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && - is_same_network(&(padapter->mlmepriv.cur_network.network), src)) { - if (padapter->recvpriv.signal_qual_data.total_num++ >= - PHY_LINKQUALITY_SLID_WIN_MAX) { - padapter->recvpriv.signal_qual_data.total_num = - PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = sqd->elements[sqd->index]; - padapter->recvpriv.signal_qual_data.total_val -= - last_evm; - } - padapter->recvpriv.signal_qual_data.total_val += src->Rssi; - - sqd->elements[sqd->index++] = src->Rssi; - if (padapter->recvpriv.signal_qual_data.index >= - PHY_LINKQUALITY_SLID_WIN_MAX) - padapter->recvpriv.signal_qual_data.index = 0; - /* <1> Showed on UI for user, in percentage. */ - tmpVal = padapter->recvpriv.signal_qual_data.total_val / - padapter->recvpriv.signal_qual_data.total_num; - padapter->recvpriv.signal = (u8)tmpVal; - - src->Rssi = padapter->recvpriv.signal; - } else { - src->Rssi = (src->Rssi + dst->Rssi) / 2; - } - memcpy((u8 *)dst, (u8 *)src, r8712_get_wlan_bssid_ex_sz(src)); -} - -static void update_current_network(struct _adapter *adapter, - struct wlan_bssid_ex *pnetwork) -{ - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - if (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)) { - update_network(&(pmlmepriv->cur_network.network), - pnetwork, adapter); - r8712_update_protection(adapter, - (pmlmepriv->cur_network.network.IEs) + - sizeof(struct NDIS_802_11_FIXED_IEs), - pmlmepriv->cur_network.network.IELength); - } -} - -/* Caller must hold pmlmepriv->lock first */ -static void update_scanned_network(struct _adapter *adapter, - struct wlan_bssid_ex *target) -{ - struct list_head *plist, *phead; - - u32 bssid_ex_sz; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct wlan_network *pnetwork = NULL; - struct wlan_network *oldest = NULL; - - phead = &queue->queue; - plist = phead->next; - - while (1) { - if (end_of_queue_search(phead, plist)) - break; - - pnetwork = container_of(plist, struct wlan_network, list); - if (is_same_network(&pnetwork->network, target)) - break; - if ((oldest == ((struct wlan_network *)0)) || - time_after((unsigned long)oldest->last_scanned, - (unsigned long)pnetwork->last_scanned)) - oldest = pnetwork; - - plist = plist->next; - } - - /* If we didn't find a match, then get a new network slot to initialize - * with this beacon's information - */ - if (end_of_queue_search(phead, plist)) { - if (list_empty(&pmlmepriv->free_bss_pool.queue)) { - /* If there are no more slots, expire the oldest */ - pnetwork = oldest; - target->Rssi = (pnetwork->network.Rssi + - target->Rssi) / 2; - memcpy(&pnetwork->network, target, - r8712_get_wlan_bssid_ex_sz(target)); - pnetwork->last_scanned = jiffies; - } else { - /* Otherwise just pull from the free list */ - /* update scan_time */ - pnetwork = alloc_network(pmlmepriv); - if (!pnetwork) - return; - bssid_ex_sz = r8712_get_wlan_bssid_ex_sz(target); - target->Length = bssid_ex_sz; - memcpy(&pnetwork->network, target, bssid_ex_sz); - list_add_tail(&pnetwork->list, &queue->queue); - } - } else { - /* we have an entry and we are going to update it. But - * this entry may be already expired. In this case we - * do the same as we found a new net and call the new_net - * handler - */ - update_network(&pnetwork->network, target, adapter); - pnetwork->last_scanned = jiffies; - } -} - -static void rtl8711_add_network(struct _adapter *adapter, - struct wlan_bssid_ex *pnetwork) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &(((struct _adapter *)adapter)->mlmepriv); - struct __queue *queue = &pmlmepriv->scanned_queue; - - spin_lock_irqsave(&queue->lock, irqL); - update_current_network(adapter, pnetwork); - update_scanned_network(adapter, pnetwork); - spin_unlock_irqrestore(&queue->lock, irqL); -} - -/*select the desired network based on the capability of the (i)bss. - * check items: (1) security - * (2) network_type - * (3) WMM - * (4) HT - * (5) others - */ -static int is_desired_network(struct _adapter *adapter, - struct wlan_network *pnetwork) -{ - u8 wps_ie[512]; - uint wps_ielen; - int bselected = true; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - if (psecuritypriv->wps_phase) { - if (r8712_get_wps_ie(pnetwork->network.IEs, - pnetwork->network.IELength, wps_ie, - &wps_ielen)) - return true; - return false; - } - if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) && - (pnetwork->network.Privacy == 0)) - bselected = false; - if (check_fwstate(&adapter->mlmepriv, WIFI_ADHOC_STATE)) { - if (pnetwork->network.InfrastructureMode != - adapter->mlmepriv.cur_network.network.InfrastructureMode) - bselected = false; - } - return bselected; -} - -/* TODO: Perry : For Power Management */ -void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf) -{ -} - -void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long flags; - u32 len; - struct wlan_bssid_ex *pnetwork; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - pnetwork = (struct wlan_bssid_ex *)pbuf; -#ifdef __BIG_ENDIAN - /* endian_convert */ - pnetwork->Length = le32_to_cpu(pnetwork->Length); - pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); - pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy); - pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); - pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse); - pnetwork->Configuration.ATIMWindow = - le32_to_cpu(pnetwork->Configuration.ATIMWindow); - pnetwork->Configuration.BeaconPeriod = - le32_to_cpu(pnetwork->Configuration.BeaconPeriod); - pnetwork->Configuration.DSConfig = - le32_to_cpu(pnetwork->Configuration.DSConfig); - pnetwork->Configuration.FHConfig.DwellTime = - le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); - pnetwork->Configuration.FHConfig.HopPattern = - le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); - pnetwork->Configuration.FHConfig.HopSet = - le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); - pnetwork->Configuration.FHConfig.Length = - le32_to_cpu(pnetwork->Configuration.FHConfig.Length); - pnetwork->Configuration.Length = - le32_to_cpu(pnetwork->Configuration.Length); - pnetwork->InfrastructureMode = - le32_to_cpu(pnetwork->InfrastructureMode); - pnetwork->IELength = le32_to_cpu(pnetwork->IELength); -#endif - len = r8712_get_wlan_bssid_ex_sz(pnetwork); - if (len > sizeof(struct wlan_bssid_ex)) - return; - spin_lock_irqsave(&pmlmepriv->lock2, flags); - /* update IBSS_network 's timestamp */ - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress), - pnetwork->MacAddress, ETH_ALEN)) { - struct wlan_network *ibss_wlan = NULL; - - memcpy(pmlmepriv->cur_network.network.IEs, - pnetwork->IEs, 8); - ibss_wlan = r8712_find_network( - &pmlmepriv->scanned_queue, - pnetwork->MacAddress); - if (ibss_wlan) { - memcpy(ibss_wlan->network.IEs, - pnetwork->IEs, 8); - goto exit; - } - } - } - /* lock pmlmepriv->lock when you accessing network_q */ - if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - if (pnetwork->Ssid.Ssid[0] != 0) { - rtl8711_add_network(adapter, pnetwork); - } else { - pnetwork->Ssid.SsidLength = 8; - memcpy(pnetwork->Ssid.Ssid, "", 8); - rtl8711_add_network(adapter, pnetwork); - } - } -exit: - spin_unlock_irqrestore(&pmlmepriv->lock2, flags); -} - -void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { - del_timer(&pmlmepriv->scan_to_timer); - - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); - } - - if (pmlmepriv->to_join) { - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); - - if (!r8712_select_and_join_from_scan(pmlmepriv)) { - mod_timer(&pmlmepriv->assoc_timer, jiffies + - msecs_to_jiffies(MAX_JOIN_TIMEOUT)); - } else { - struct wlan_bssid_ex *pdev_network = - &(adapter->registrypriv.dev_network); - u8 *pibss = - adapter->registrypriv.dev_network.MacAddress; - pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; - memcpy(&pdev_network->Ssid, - &pmlmepriv->assoc_ssid, - sizeof(struct - ndis_802_11_ssid)); - r8712_update_registrypriv_dev_network - (adapter); - r8712_generate_random_ibss(pibss); - pmlmepriv->fw_state = - WIFI_ADHOC_MASTER_STATE; - pmlmepriv->to_join = false; - } - } - } else { - pmlmepriv->to_join = false; - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); - if (!r8712_select_and_join_from_scan(pmlmepriv)) - mod_timer(&pmlmepriv->assoc_timer, jiffies + - msecs_to_jiffies(MAX_JOIN_TIMEOUT)); - else - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - } - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -/* - *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock - */ -void r8712_free_assoc_resources(struct _adapter *adapter) -{ - unsigned long irqL; - struct wlan_network *pwlan = NULL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct sta_priv *pstapriv = &adapter->stapriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - - pwlan = r8712_find_network(&pmlmepriv->scanned_queue, - tgt_network->network.MacAddress); - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { - struct sta_info *psta; - - psta = r8712_get_stainfo(&adapter->stapriv, - tgt_network->network.MacAddress); - - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - r8712_free_stainfo(adapter, psta); - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); - } - - if (check_fwstate(pmlmepriv, - WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) - r8712_free_all_stainfo(adapter); - if (pwlan) - pwlan->fixed = false; - - if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) && - (adapter->stapriv.asoc_sta_count == 1))) - free_network_nolock(pmlmepriv, pwlan); -} - -/* - * r8712_indicate_connect: the caller has to lock pmlmepriv->lock - */ -void r8712_indicate_connect(struct _adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - pmlmepriv->to_join = false; - set_fwstate(pmlmepriv, _FW_LINKED); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK); - r8712_os_indicate_connect(padapter); - if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) - mod_timer(&pmlmepriv->dhcp_timer, - jiffies + msecs_to_jiffies(60000)); -} - -/* - * r8712_ind_disconnect: the caller has to lock pmlmepriv->lock - */ -void r8712_ind_disconnect(struct _adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - _clr_fwstate_(pmlmepriv, _FW_LINKED); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); - r8712_os_indicate_disconnect(padapter); - } - if (padapter->pwrctrlpriv.pwr_mode != - padapter->registrypriv.power_mgnt) { - del_timer(&pmlmepriv->dhcp_timer); - r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, - padapter->registrypriv.smart_ps); - } -} - -/*Notes: - *pnetwork : returns from r8712_joinbss_event_callback - *ptarget_wlan: found from scanned_queue - *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if - * "ptarget_sta" & "ptarget_wlan" exist. - *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check - * if "ptarget_wlan" exist. - *if join_res > 0, update "cur_network->network" from - * "pnetwork->network" if (ptarget_wlan !=NULL). - */ -void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL = 0, irqL2; - struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct wlan_network *cur_network = &pmlmepriv->cur_network; - struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; - unsigned int the_same_macaddr = false; - struct wlan_network *pnetwork; - - if (sizeof(struct list_head) == 4 * sizeof(u32)) { - pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC); - if (!pnetwork) - return; - memcpy((u8 *)pnetwork + 16, (u8 *)pbuf + 8, - sizeof(struct wlan_network) - 16); - } else { - pnetwork = (struct wlan_network *)pbuf; - } - -#ifdef __BIG_ENDIAN - /* endian_convert */ - pnetwork->join_res = le32_to_cpu(pnetwork->join_res); - pnetwork->network_type = le32_to_cpu(pnetwork->network_type); - pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length); - pnetwork->network.Ssid.SsidLength = - le32_to_cpu(pnetwork->network.Ssid.SsidLength); - pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy); - pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi); - pnetwork->network.NetworkTypeInUse = - le32_to_cpu(pnetwork->network.NetworkTypeInUse); - pnetwork->network.Configuration.ATIMWindow = - le32_to_cpu(pnetwork->network.Configuration.ATIMWindow); - pnetwork->network.Configuration.BeaconPeriod = - le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod); - pnetwork->network.Configuration.DSConfig = - le32_to_cpu(pnetwork->network.Configuration.DSConfig); - pnetwork->network.Configuration.FHConfig.DwellTime = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime); - pnetwork->network.Configuration.FHConfig.HopPattern = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern); - pnetwork->network.Configuration.FHConfig.HopSet = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet); - pnetwork->network.Configuration.FHConfig.Length = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length); - pnetwork->network.Configuration.Length = - le32_to_cpu(pnetwork->network.Configuration.Length); - pnetwork->network.InfrastructureMode = - le32_to_cpu(pnetwork->network.InfrastructureMode); - pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength); -#endif - - the_same_macaddr = !memcmp(pnetwork->network.MacAddress, - cur_network->network.MacAddress, ETH_ALEN); - pnetwork->network.Length = - r8712_get_wlan_bssid_ex_sz(&pnetwork->network); - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) - goto ignore_joinbss_callback; - if (pnetwork->join_res > 0) { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - /*s1. find ptarget_wlan*/ - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (the_same_macaddr) { - ptarget_wlan = - r8712_find_network(&pmlmepriv->scanned_queue, - cur_network->network.MacAddress); - } else { - pcur_wlan = - r8712_find_network(&pmlmepriv->scanned_queue, - cur_network->network.MacAddress); - if (pcur_wlan) - pcur_wlan->fixed = false; - - pcur_sta = r8712_get_stainfo(pstapriv, - cur_network->network.MacAddress); - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL2); - r8712_free_stainfo(adapter, pcur_sta); - spin_unlock_irqrestore(&(pstapriv->sta_hash_lock), irqL2); - - ptarget_wlan = - r8712_find_network(&pmlmepriv->scanned_queue, - pnetwork->network.MacAddress); - if (ptarget_wlan) - ptarget_wlan->fixed = true; - } - } else { - ptarget_wlan = r8712_find_network(&pmlmepriv->scanned_queue, - pnetwork->network.MacAddress); - if (ptarget_wlan) - ptarget_wlan->fixed = true; - } - - if (!ptarget_wlan) { - if (check_fwstate(pmlmepriv, - _FW_UNDER_LINKING)) - pmlmepriv->fw_state ^= - _FW_UNDER_LINKING; - goto ignore_joinbss_callback; - } - - /*s2. find ptarget_sta & update ptarget_sta*/ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - if (the_same_macaddr) { - ptarget_sta = - r8712_get_stainfo(pstapriv, - pnetwork->network.MacAddress); - if (!ptarget_sta) - ptarget_sta = - r8712_alloc_stainfo(pstapriv, - pnetwork->network.MacAddress); - } else { - ptarget_sta = - r8712_alloc_stainfo(pstapriv, - pnetwork->network.MacAddress); - } - if (ptarget_sta) /*update ptarget_sta*/ { - ptarget_sta->aid = pnetwork->join_res; - ptarget_sta->qos_option = 1; - ptarget_sta->mac_id = 5; - if (adapter->securitypriv.AuthAlgrthm == 2) { - adapter->securitypriv.binstallGrpkey = false; - adapter->securitypriv.busetkipkey = false; - adapter->securitypriv.bgrpkey_handshake = false; - ptarget_sta->ieee8021x_blocked = true; - ptarget_sta->XPrivacy = - adapter->securitypriv.PrivacyAlgrthm; - memset((u8 *)&ptarget_sta->x_UncstKey, - 0, - sizeof(union Keytype)); - memset((u8 *)&ptarget_sta->tkiprxmickey, - 0, - sizeof(union Keytype)); - memset((u8 *)&ptarget_sta->tkiptxmickey, - 0, - sizeof(union Keytype)); - memset((u8 *)&ptarget_sta->txpn, - 0, - sizeof(union pn48)); - memset((u8 *)&ptarget_sta->rxpn, - 0, - sizeof(union pn48)); - } - } else { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - pmlmepriv->fw_state ^= - _FW_UNDER_LINKING; - goto ignore_joinbss_callback; - } - } - - /*s3. update cur_network & indicate connect*/ - memcpy(&cur_network->network, &pnetwork->network, - pnetwork->network.Length); - cur_network->aid = pnetwork->join_res; - /*update fw_state will clr _FW_UNDER_LINKING*/ - switch (pnetwork->network.InfrastructureMode) { - case Ndis802_11Infrastructure: - pmlmepriv->fw_state = WIFI_STATION_STATE; - break; - case Ndis802_11IBSS: - pmlmepriv->fw_state = WIFI_ADHOC_STATE; - break; - default: - pmlmepriv->fw_state = WIFI_NULL_STATE; - break; - } - r8712_update_protection(adapter, - (cur_network->network.IEs) + - sizeof(struct NDIS_802_11_FIXED_IEs), - (cur_network->network.IELength)); - /*TODO: update HT_Capability*/ - update_ht_cap(adapter, cur_network->network.IEs, - cur_network->network.IELength); - /*indicate connect*/ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - r8712_indicate_connect(adapter); - del_timer(&pmlmepriv->assoc_timer); - } else { - goto ignore_joinbss_callback; - } - } else { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - mod_timer(&pmlmepriv->assoc_timer, - jiffies + msecs_to_jiffies(1)); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - } - } -ignore_joinbss_callback: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - if (sizeof(struct list_head) == 4 * sizeof(u32)) - kfree(pnetwork); -} - -void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL; - struct sta_info *psta; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); - struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; - - /* to do: */ - if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr)) - return; - psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr); - if (psta) { - /*the sta have been in sta_info_queue => do nothing - *(between drv has received this event before and - * fw have not yet to set key to CAM_ENTRY) - */ - return; - } - - psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); - if (!psta) - return; - /* to do : init sta_info variable */ - psta->qos_option = 0; - psta->mac_id = le32_to_cpu(pstassoc->cam_id); - /* psta->aid = (uint)pstassoc->cam_id; */ - - if (adapter->securitypriv.AuthAlgrthm == 2) - psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm; - psta->ieee8021x_blocked = false; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - if (adapter->stapriv.asoc_sta_count == 2) { - /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ - r8712_indicate_connect(adapter); - } - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL, irqL2; - struct sta_info *psta; - struct wlan_network *pwlan = NULL; - struct wlan_bssid_ex *pdev_network = NULL; - u8 *pibss = NULL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct stadel_event *pstadel = (struct stadel_event *)pbuf; - struct sta_priv *pstapriv = &adapter->stapriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - - spin_lock_irqsave(&pmlmepriv->lock, irqL2); - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - r8712_ind_disconnect(adapter); - r8712_free_assoc_resources(adapter); - } - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | - WIFI_ADHOC_STATE)) { - psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr); - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - r8712_free_stainfo(adapter, psta); - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); - if (adapter->stapriv.asoc_sta_count == 1) { - /*a sta + bc/mc_stainfo (not Ibss_stainfo) */ - pwlan = r8712_find_network(&pmlmepriv->scanned_queue, - tgt_network->network.MacAddress); - if (pwlan) { - pwlan->fixed = false; - free_network_nolock(pmlmepriv, pwlan); - } - /*re-create ibss*/ - pdev_network = &(adapter->registrypriv.dev_network); - pibss = adapter->registrypriv.dev_network.MacAddress; - memcpy(pdev_network, &tgt_network->network, - r8712_get_wlan_bssid_ex_sz(&tgt_network->network)); - memcpy(&pdev_network->Ssid, - &pmlmepriv->assoc_ssid, - sizeof(struct ndis_802_11_ssid)); - r8712_update_registrypriv_dev_network(adapter); - r8712_generate_random_ibss(pibss); - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); - set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); - } - } - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL2); -} - -void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - struct reportpwrstate_parm *preportpwrstate = - (struct reportpwrstate_parm *)pbuf; - - preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80); - r8712_cpwm_int_hdl(adapter, preportpwrstate); -} - -/* When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send - * the ADDBA req frame with start seq control = 0 to wifi client after - * the WPA handshake and the sequence number of following data packet - * will be 0. In this case, the Rx reorder sequence is not longer than 0 - * and the WiFi client will drop the data with seq number 0. - * So, the 8712 firmware has to inform driver with receiving the - * ADDBA-Req frame so that the driver can reset the - * sequence value of Rx reorder control. - */ -void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - struct ADDBA_Req_Report_parm *pAddbareq_pram = - (struct ADDBA_Req_Report_parm *)pbuf; - struct sta_info *psta; - struct sta_priv *pstapriv = &adapter->stapriv; - struct recv_reorder_ctrl *precvreorder_ctrl = NULL; - - psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress); - if (psta) { - precvreorder_ctrl = - &psta->recvreorder_ctrl[pAddbareq_pram->tid]; - /* set the indicate_seq to 0xffff so that the rx reorder - * can store any following data packet. - */ - precvreorder_ctrl->indicate_seq = 0xffff; - } -} - -void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - if (!adapter->securitypriv.wps_hw_pbc_pressed) - adapter->securitypriv.wps_hw_pbc_pressed = true; -} - -void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter) -{ - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl; - struct registry_priv *pregistrypriv = &adapter->registrypriv; - u64 current_tx_pkts; - uint current_rx_pkts; - - current_tx_pkts = (adapter->xmitpriv.tx_pkts) - - (psitesurveyctrl->last_tx_pkts); - current_rx_pkts = (adapter->recvpriv.rx_pkts) - - (psitesurveyctrl->last_rx_pkts); - psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts; - psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts; - if ((current_tx_pkts > pregistrypriv->busy_thresh) || - (current_rx_pkts > pregistrypriv->busy_thresh)) - psitesurveyctrl->traffic_busy = true; - else - psitesurveyctrl->traffic_busy = false; -} - -void _r8712_join_timeout_handler(struct _adapter *adapter) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - if (adapter->driver_stopped || adapter->surprise_removed) - return; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - pmlmepriv->to_join = false; - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - r8712_os_indicate_disconnect(adapter); - _clr_fwstate_(pmlmepriv, _FW_LINKED); - } - if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) { - r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, - adapter->registrypriv.smart_ps); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_scan_timeout_handler (struct _adapter *adapter) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); - pmlmepriv->to_join = false; /* scan fail, so clear to_join flag */ - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void _r8712_dhcp_timeout_handler (struct _adapter *adapter) -{ - if (adapter->driver_stopped || adapter->surprise_removed) - return; - if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) - r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, - adapter->registrypriv.smart_ps); -} - -int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv) -{ - struct list_head *phead; - unsigned char *dst_ssid, *src_ssid; - struct _adapter *adapter; - struct __queue *queue = NULL; - struct wlan_network *pnetwork = NULL; - struct wlan_network *pnetwork_max_rssi = NULL; - - adapter = (struct _adapter *)pmlmepriv->nic_hdl; - queue = &pmlmepriv->scanned_queue; - phead = &queue->queue; - pmlmepriv->pscanned = phead->next; - while (1) { - if (end_of_queue_search(phead, pmlmepriv->pscanned)) { - if (pmlmepriv->assoc_by_rssi && pnetwork_max_rssi) { - pnetwork = pnetwork_max_rssi; - goto ask_for_joinbss; - } - return -EINVAL; - } - pnetwork = container_of(pmlmepriv->pscanned, - struct wlan_network, list); - pmlmepriv->pscanned = pmlmepriv->pscanned->next; - if (pmlmepriv->assoc_by_bssid) { - dst_ssid = pnetwork->network.MacAddress; - src_ssid = pmlmepriv->assoc_bssid; - if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (is_same_network(&pmlmepriv->cur_network.network, - &pnetwork->network)) { - _clr_fwstate_(pmlmepriv, - _FW_UNDER_LINKING); - /*r8712_indicate_connect again*/ - r8712_indicate_connect(adapter); - return 2; - } - r8712_disassoc_cmd(adapter); - r8712_ind_disconnect(adapter); - r8712_free_assoc_resources(adapter); - } - goto ask_for_joinbss; - } - } else if (pmlmepriv->assoc_ssid.SsidLength == 0) { - goto ask_for_joinbss; - } - dst_ssid = pnetwork->network.Ssid.Ssid; - src_ssid = pmlmepriv->assoc_ssid.Ssid; - if ((pnetwork->network.Ssid.SsidLength == - pmlmepriv->assoc_ssid.SsidLength) && - (!memcmp(dst_ssid, src_ssid, - pmlmepriv->assoc_ssid.SsidLength))) { - if (pmlmepriv->assoc_by_rssi) { - /* if the ssid is the same, select the bss - * which has the max rssi - */ - if (pnetwork_max_rssi) { - if (pnetwork->network.Rssi > - pnetwork_max_rssi->network.Rssi) - pnetwork_max_rssi = pnetwork; - } else { - pnetwork_max_rssi = pnetwork; - } - } else if (is_desired_network(adapter, pnetwork)) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - r8712_disassoc_cmd(adapter); - r8712_free_assoc_resources(adapter); - } - goto ask_for_joinbss; - } - } - } - -ask_for_joinbss: - return r8712_joinbss_cmd(adapter, pnetwork); -} - -int r8712_set_auth(struct _adapter *adapter, - struct security_priv *psecuritypriv) -{ - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - struct cmd_obj *pcmd; - struct setauth_parm *psetauthparm; - - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - - psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); - if (!psetauthparm) { - kfree(pcmd); - return -ENOMEM; - } - psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm; - pcmd->cmdcode = _SetAuth_CMD_; - pcmd->parmbuf = (unsigned char *)psetauthparm; - pcmd->cmdsz = sizeof(struct setauth_parm); - pcmd->rsp = NULL; - pcmd->rspsz = 0; - INIT_LIST_HEAD(&pcmd->list); - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; -} - -int r8712_set_key(struct _adapter *adapter, - struct security_priv *psecuritypriv, - sint keyid) -{ - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - struct cmd_obj *pcmd; - struct setkey_parm *psetkeyparm; - u8 keylen; - int ret; - - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC); - if (!psetkeyparm) { - ret = -ENOMEM; - goto err_free_cmd; - } - if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */ - psetkeyparm->algorithm = - (u8)psecuritypriv->XGrpPrivacy; - } else { /* WEP */ - psetkeyparm->algorithm = - (u8)psecuritypriv->PrivacyAlgrthm; - } - psetkeyparm->keyid = (u8)keyid; - - switch (psetkeyparm->algorithm) { - case _WEP40_: - keylen = 5; - memcpy(psetkeyparm->key, - psecuritypriv->DefKey[keyid].skey, keylen); - break; - case _WEP104_: - keylen = 13; - memcpy(psetkeyparm->key, - psecuritypriv->DefKey[keyid].skey, keylen); - break; - case _TKIP_: - if (keyid < 1 || keyid > 2) { - ret = -EINVAL; - goto err_free_parm; - } - keylen = 16; - memcpy(psetkeyparm->key, - &psecuritypriv->XGrpKey[keyid - 1], keylen); - psetkeyparm->grpkey = 1; - break; - case _AES_: - if (keyid < 1 || keyid > 2) { - ret = -EINVAL; - goto err_free_parm; - } - keylen = 16; - memcpy(psetkeyparm->key, - &psecuritypriv->XGrpKey[keyid - 1], keylen); - psetkeyparm->grpkey = 1; - break; - default: - ret = -EINVAL; - goto err_free_parm; - } - pcmd->cmdcode = _SetKey_CMD_; - pcmd->parmbuf = (u8 *)psetkeyparm; - pcmd->cmdsz = (sizeof(struct setkey_parm)); - pcmd->rsp = NULL; - pcmd->rspsz = 0; - INIT_LIST_HEAD(&pcmd->list); - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; - -err_free_parm: - kfree(psetkeyparm); -err_free_cmd: - kfree(pcmd); - return ret; -} - -/* adjust IEs for r8712_joinbss_cmd in WMM */ -int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie, - uint in_len, uint initial_out_len) -{ - unsigned int ielength = 0; - unsigned int i, j; - - i = 12; /* after the fixed IE */ - while (i < in_len) { - ielength = initial_out_len; - if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && - in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && - in_ie[i + 5] == 0x02 && i + 5 < in_len) { - /*WMM element ID and OUI*/ - for (j = i; j < i + 9; j++) { - out_ie[ielength] = in_ie[j]; - ielength++; - } - out_ie[initial_out_len + 1] = 0x07; - out_ie[initial_out_len + 6] = 0x00; - out_ie[initial_out_len + 8] = 0x00; - break; - } - i += (in_ie[i + 1] + 2); /* to the next IE element */ - } - return ielength; -} - -/* - * Ported from 8185: IsInPreAuthKeyList(). - * - * Search by BSSID, - * Return Value: - * -1 :if there is no pre-auth key in the table - * >=0 :if there is pre-auth key, and return the entry id - */ -static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid) -{ - struct security_priv *p = &Adapter->securitypriv; - int i; - - for (i = 0; i < NUM_PMKID_CACHE; i++) - if (p->PMKIDList[i].bUsed && !memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN)) - return i; - return -1; -} - -sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, - u8 *out_ie, uint in_len) -{ - u8 authmode = 0, match; - u8 sec_ie[IW_CUSTOM_MAX], uncst_oui[4], bkup_ie[255]; - u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; - uint ielength, cnt, remove_cnt; - int iEntry; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct security_priv *psecuritypriv = &adapter->securitypriv; - uint ndisauthmode = psecuritypriv->ndisauthtype; - uint ndissecuritytype = psecuritypriv->ndisencryptstatus; - - if ((ndisauthmode == Ndis802_11AuthModeWPA) || - (ndisauthmode == Ndis802_11AuthModeWPAPSK)) { - authmode = _WPA_IE_ID_; - uncst_oui[0] = 0x0; - uncst_oui[1] = 0x50; - uncst_oui[2] = 0xf2; - } - if ((ndisauthmode == Ndis802_11AuthModeWPA2) || - (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) { - authmode = _WPA2_IE_ID_; - uncst_oui[0] = 0x0; - uncst_oui[1] = 0x0f; - uncst_oui[2] = 0xac; - } - switch (ndissecuritytype) { - case Ndis802_11Encryption1Enabled: - case Ndis802_11Encryption1KeyAbsent: - uncst_oui[3] = 0x1; - break; - case Ndis802_11Encryption2Enabled: - case Ndis802_11Encryption2KeyAbsent: - uncst_oui[3] = 0x2; - break; - case Ndis802_11Encryption3Enabled: - case Ndis802_11Encryption3KeyAbsent: - uncst_oui[3] = 0x4; - break; - default: - break; - } - /*Search required WPA or WPA2 IE and copy to sec_ie[] */ - cnt = 12; - match = false; - while (cnt < in_len) { - if (in_ie[cnt] == authmode) { - if ((authmode == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { - memcpy(&sec_ie[0], &in_ie[cnt], - in_ie[cnt + 1] + 2); - match = true; - break; - } - if (authmode == _WPA2_IE_ID_) { - memcpy(&sec_ie[0], &in_ie[cnt], - in_ie[cnt + 1] + 2); - match = true; - break; - } - if (((authmode == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) || - (authmode == _WPA2_IE_ID_)) - memcpy(&bkup_ie[0], &in_ie[cnt], - in_ie[cnt + 1] + 2); - } - cnt += in_ie[cnt + 1] + 2; /*get next*/ - } - /*restruct WPA IE or WPA2 IE in sec_ie[] */ - if (match) { - if (sec_ie[0] == _WPA_IE_ID_) { - /* parsing SSN IE to select required encryption - * algorithm, and set the bc/mc encryption algorithm - */ - while (true) { - /*check wpa_oui tag*/ - if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) { - match = false; - break; - } - if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) { - /*IE Ver error*/ - match = false; - break; - } - if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) { - /* get bc/mc encryption type (group - * key type) - */ - switch (sec_ie[11]) { - case 0x0: /*none*/ - psecuritypriv->XGrpPrivacy = - _NO_PRIVACY_; - break; - case 0x1: /*WEP_40*/ - psecuritypriv->XGrpPrivacy = - _WEP40_; - break; - case 0x2: /*TKIP*/ - psecuritypriv->XGrpPrivacy = - _TKIP_; - break; - case 0x3: /*AESCCMP*/ - case 0x4: - psecuritypriv->XGrpPrivacy = - _AES_; - break; - case 0x5: /*WEP_104*/ - psecuritypriv->XGrpPrivacy = - _WEP104_; - break; - } - } else { - match = false; - break; - } - if (sec_ie[12] == 0x01) { - /*check the unicast encryption type*/ - if (memcmp(&sec_ie[14], - &uncst_oui[0], 4)) { - match = false; - break; - - } /*else the uncst_oui is match*/ - } else { /*mixed mode, unicast_enc_type > 1*/ - /*select the uncst_oui and remove - * the other uncst_oui - */ - cnt = sec_ie[12]; - remove_cnt = (cnt - 1) * 4; - sec_ie[12] = 0x01; - memcpy(&sec_ie[14], &uncst_oui[0], 4); - /*remove the other unicast suit*/ - memcpy(&sec_ie[18], - &sec_ie[18 + remove_cnt], - sec_ie[1] - 18 + 2 - - remove_cnt); - sec_ie[1] = sec_ie[1] - remove_cnt; - } - break; - } - } - if (authmode == _WPA2_IE_ID_) { - /* parsing RSN IE to select required encryption - * algorithm, and set the bc/mc encryption algorithm - */ - while (true) { - if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) { - /*IE Ver error*/ - match = false; - break; - } - if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) { - /*get bc/mc encryption type*/ - switch (sec_ie[7]) { - case 0x1: /*WEP_40*/ - psecuritypriv->XGrpPrivacy = - _WEP40_; - break; - case 0x2: /*TKIP*/ - psecuritypriv->XGrpPrivacy = - _TKIP_; - break; - case 0x4: /*AESWRAP*/ - psecuritypriv->XGrpPrivacy = - _AES_; - break; - case 0x5: /*WEP_104*/ - psecuritypriv->XGrpPrivacy = - _WEP104_; - break; - default: /*one*/ - psecuritypriv->XGrpPrivacy = - _NO_PRIVACY_; - break; - } - } else { - match = false; - break; - } - if (sec_ie[8] == 0x01) { - /*check the unicast encryption type*/ - if (memcmp(&sec_ie[10], - &uncst_oui[0], 4)) { - match = false; - break; - } /*else the uncst_oui is match*/ - } else { /*mixed mode, unicast_enc_type > 1*/ - /*select the uncst_oui and remove the - * other uncst_oui - */ - cnt = sec_ie[8]; - remove_cnt = (cnt - 1) * 4; - sec_ie[8] = 0x01; - memcpy(&sec_ie[10], &uncst_oui[0], 4); - /*remove the other unicast suit*/ - memcpy(&sec_ie[14], - &sec_ie[14 + remove_cnt], - (sec_ie[1] - 14 + 2 - - remove_cnt)); - sec_ie[1] = sec_ie[1] - remove_cnt; - } - break; - } - } - } - if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) { - /*copy fixed ie*/ - memcpy(out_ie, in_ie, 12); - ielength = 12; - /*copy RSN or SSN*/ - if (match) { - memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2); - ielength += sec_ie[1] + 2; - if (authmode == _WPA2_IE_ID_) { - /*the Pre-Authentication bit should be zero*/ - out_ie[ielength - 1] = 0; - out_ie[ielength - 2] = 0; - } - r8712_report_sec_ie(adapter, authmode, sec_ie); - } - } else { - /*copy fixed ie only*/ - memcpy(out_ie, in_ie, 12); - ielength = 12; - if (psecuritypriv->wps_phase) { - memcpy(out_ie + ielength, psecuritypriv->wps_ie, - psecuritypriv->wps_ie_len); - ielength += psecuritypriv->wps_ie_len; - } - } - iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); - if (iEntry < 0) - return ielength; - if (authmode == _WPA2_IE_ID_) { - out_ie[ielength] = 1; - ielength++; - out_ie[ielength] = 0; /*PMKID count = 0x0100*/ - ielength++; - memcpy(&out_ie[ielength], - &psecuritypriv->PMKIDList[iEntry].PMKID, 16); - ielength += 16; - out_ie[13] += 18;/*PMKID length = 2+16*/ - } - return ielength; -} - -void r8712_init_registrypriv_dev_network(struct _adapter *adapter) -{ - struct registry_priv *pregistrypriv = &adapter->registrypriv; - struct eeprom_priv *peepriv = &adapter->eeprompriv; - struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; - u8 *myhwaddr = myid(peepriv); - - memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); - memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, - sizeof(struct ndis_802_11_ssid)); - pdev_network->Configuration.Length = - sizeof(struct NDIS_802_11_CONFIGURATION); - pdev_network->Configuration.BeaconPeriod = 100; - pdev_network->Configuration.FHConfig.Length = 0; - pdev_network->Configuration.FHConfig.HopPattern = 0; - pdev_network->Configuration.FHConfig.HopSet = 0; - pdev_network->Configuration.FHConfig.DwellTime = 0; -} - -void r8712_update_registrypriv_dev_network(struct _adapter *adapter) -{ - int sz = 0; - struct registry_priv *pregistrypriv = &adapter->registrypriv; - struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; - struct security_priv *psecuritypriv = &adapter->securitypriv; - struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; - - pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm - > 0 ? 1 : 0); /* adhoc no 802.1x */ - pdev_network->Rssi = 0; - switch (pregistrypriv->wireless_mode) { - case WIRELESS_11B: - pdev_network->NetworkTypeInUse = Ndis802_11DS; - break; - case WIRELESS_11G: - case WIRELESS_11BG: - pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; - break; - case WIRELESS_11A: - pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; - break; - default: - /* TODO */ - break; - } - pdev_network->Configuration.DSConfig = pregistrypriv->channel; - if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) - pdev_network->Configuration.ATIMWindow = 3; - pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode; - /* 1. Supported rates - * 2. IE - */ - sz = r8712_generate_ie(pregistrypriv); - pdev_network->IELength = sz; - pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network); -} - -/*the function is at passive_level*/ -void r8712_joinbss_reset(struct _adapter *padapter) -{ - int i; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - /* todo: if you want to do something io/reg/hw setting before join_bss, - * please add code here - */ - phtpriv->ampdu_enable = false;/*reset to disabled*/ - for (i = 0; i < 16; i++) - phtpriv->baddbareq_issued[i] = false;/*reset it*/ - if (phtpriv->ht_option) { - /* validate usb rx aggregation */ - r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/ - } else { - /* invalidate usb rx aggregation */ - /* TH=1 => means that invalidate usb rx aggregation */ - r8712_write8(padapter, 0x102500D9, 1); - } -} - -/*the function is >= passive_level*/ -unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, - u8 *out_ie, uint in_len, uint *pout_len) -{ - u32 ielen, out_len; - unsigned char *p; - struct ieee80211_ht_cap ht_capie; - unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - phtpriv->ht_option = 0; - p = r8712_get_ie(in_ie + 12, WLAN_EID_HT_CAPABILITY, &ielen, in_len - 12); - if (p && (ielen > 0)) { - if (pqospriv->qos_option == 0) { - out_len = *pout_len; - r8712_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC, - _WMM_IE_Length_, WMM_IE, pout_len); - pqospriv->qos_option = 1; - } - out_len = *pout_len; - memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); - ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | - IEEE80211_HT_CAP_TX_STBC | - IEEE80211_HT_CAP_MAX_AMSDU | - IEEE80211_HT_CAP_DSSSCCK40); - ht_capie.ampdu_params_info = (IEEE80211_HT_AMPDU_PARM_FACTOR & - 0x03) | (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); - r8712_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY, - sizeof(struct ieee80211_ht_cap), - (unsigned char *)&ht_capie, pout_len); - phtpriv->ht_option = 1; - } - return phtpriv->ht_option; -} - -/* the function is > passive_level (in critical_section) */ -static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) -{ - u8 *p, max_ampdu_sz; - int i; - uint len; - struct sta_info *bmc_sta, *psta; - struct ieee80211_ht_cap *pht_capie; - struct recv_reorder_ctrl *preorder_ctrl; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - struct registry_priv *pregistrypriv = &padapter->registrypriv; - struct wlan_network *pcur_network = &(pmlmepriv->cur_network); - - if (!phtpriv->ht_option) - return; - /* maybe needs check if ap supports rx ampdu. */ - if (!phtpriv->ampdu_enable && - (pregistrypriv->ampdu_enable == 1)) - phtpriv->ampdu_enable = true; - /*check Max Rx A-MPDU Size*/ - len = 0; - p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), - WLAN_EID_HT_CAPABILITY, - &len, ie_len - - sizeof(struct NDIS_802_11_FIXED_IEs)); - if (p && len > 0) { - pht_capie = (struct ieee80211_ht_cap *)(p + 2); - max_ampdu_sz = (pht_capie->ampdu_params_info & - IEEE80211_HT_AMPDU_PARM_FACTOR); - /* max_ampdu_sz (kbytes); */ - max_ampdu_sz = 1 << (max_ampdu_sz + 3); - phtpriv->rx_ampdu_maxlen = max_ampdu_sz; - } - /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info - * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl - * wstart_b(indicate_seq) to default value=0xffff - * todo: check if AP can send A-MPDU packets - */ - bmc_sta = r8712_get_bcmc_stainfo(padapter); - if (bmc_sta) { - for (i = 0; i < 16; i++) { - preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->wend_b = 0xffff; - } - } - psta = r8712_get_stainfo(&padapter->stapriv, - pcur_network->network.MacAddress); - if (psta) { - for (i = 0; i < 16; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->wend_b = 0xffff; - } - } - len = 0; - p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), - WLAN_EID_HT_OPERATION, &len, - ie_len - sizeof(struct NDIS_802_11_FIXED_IEs)); -} - -void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) { - if (!phtpriv->baddbareq_issued[priority]) { - r8712_addbareq_cmd(padapter, (u8)priority); - phtpriv->baddbareq_issued[priority] = true; - } - } -} diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h deleted file mode 100644 index d7d25f240111fadf20365c72bb0297582a081d30..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_mlme.h +++ /dev/null @@ -1,205 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_MLME_H_ -#define __RTL871X_MLME_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wlan_bssdef.h" - -#define MAX_BSS_CNT 64 -#define MAX_JOIN_TIMEOUT 6000 - -#define SCANNING_TIMEOUT 4500 - -#define SCANQUEUE_LIFETIME 20 /* unit:sec */ - -#define WIFI_NULL_STATE 0x00000000 -#define WIFI_ASOC_STATE 0x00000001 /* Under Linked state...*/ -#define WIFI_REASOC_STATE 0x00000002 -#define WIFI_SLEEP_STATE 0x00000004 -#define WIFI_STATION_STATE 0x00000008 -#define WIFI_AP_STATE 0x00000010 -#define WIFI_ADHOC_STATE 0x00000020 -#define WIFI_ADHOC_MASTER_STATE 0x00000040 -#define WIFI_UNDER_LINKING 0x00000080 -#define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station - * is under site surveying - */ -#define WIFI_MP_STATE 0x00010000 -#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in cont. tx background*/ -#define WIFI_MP_CTX_ST 0x00040000 /* in cont. tx with - * single-tone - */ -#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in cont, tx - * background due - * to out of skb - */ -#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx*/ -#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in cont, tx with carrier - * suppression - */ -#define WIFI_MP_LPBK_STATE 0x00400000 - -#define _FW_UNDER_LINKING WIFI_UNDER_LINKING -#define _FW_LINKED WIFI_ASOC_STATE -#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR - -/* - * there are several "locks" in mlme_priv, - * since mlme_priv is a shared resource between many threads, - * like ISR/Call-Back functions, the OID handlers, and even timer functions. - * Each _queue has its own locks, already. - * Other items are protected by mlme_priv.lock. - * To avoid possible dead lock, any thread trying to modify mlme_priv - * SHALL not lock up more than one lock at a time! - */ - -#define traffic_threshold 10 -#define traffic_scan_period 500 - -struct sitesurvey_ctrl { - u64 last_tx_pkts; - uint last_rx_pkts; - sint traffic_busy; - struct timer_list sitesurvey_ctrl_timer; -}; - -struct mlme_priv { - spinlock_t lock; - spinlock_t lock2; - sint fw_state; /*shall we protect this variable? */ - u8 to_join; /*flag*/ - u8 *nic_hdl; - struct list_head *pscanned; - struct __queue free_bss_pool; - struct __queue scanned_queue; - u8 *free_bss_buf; - unsigned long num_of_scanned; - u8 passive_mode; /*add for Android's SCAN-ACTIVE/SCAN-PASSIVE */ - struct ndis_802_11_ssid assoc_ssid; - u8 assoc_bssid[6]; - struct wlan_network cur_network; - struct sitesurvey_ctrl sitesurveyctrl; - struct timer_list assoc_timer; - uint assoc_by_bssid; - uint assoc_by_rssi; - struct timer_list scan_to_timer; /* driver handles scan_timeout.*/ - struct timer_list dhcp_timer; /* set dhcp to if driver in ps mode.*/ - struct qos_priv qospriv; - struct ht_priv htpriv; - struct timer_list wdg_timer; /*watchdog periodic timer*/ -}; - -static inline u8 *get_bssid(struct mlme_priv *pmlmepriv) -{ - return pmlmepriv->cur_network.network.MacAddress; -} - -static inline u8 check_fwstate(struct mlme_priv *pmlmepriv, sint state) -{ - if (pmlmepriv->fw_state & state) - return true; - return false; -} - -static inline sint get_fwstate(struct mlme_priv *pmlmepriv) -{ - return pmlmepriv->fw_state; -} - -/* - * No Limit on the calling context, - * therefore set it to be the critical section... - * - * ### NOTE:#### (!!!!) - * TAKE CARE BEFORE CALLING THIS FUNC, LOCK pmlmepriv->lock - */ -static inline void set_fwstate(struct mlme_priv *pmlmepriv, sint state) -{ - pmlmepriv->fw_state |= state; -} - -static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) -{ - pmlmepriv->fw_state &= ~state; -} - -/* - * No Limit on the calling context, - * therefore set it to be the critical section... - */ -static inline void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) -{ - unsigned long irqL; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, state)) - pmlmepriv->fw_state ^= state; - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv, - sint val) -{ - unsigned long irqL; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - pmlmepriv->num_of_scanned = val; - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_free_network_queue(struct _adapter *adapter); -int r8712_init_mlme_priv(struct _adapter *adapter); -void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv); -int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv); -int r8712_set_key(struct _adapter *adapter, - struct security_priv *psecuritypriv, sint keyid); -int r8712_set_auth(struct _adapter *adapter, - struct security_priv *psecuritypriv); -uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss); -void r8712_generate_random_ibss(u8 *pibss); -u8 *r8712_get_capability_from_ie(u8 *ie); -struct wlan_network *r8712_get_oldest_wlan_network( - struct __queue *scanned_queue); -void r8712_free_assoc_resources(struct _adapter *adapter); -void r8712_ind_disconnect(struct _adapter *adapter); -void r8712_indicate_connect(struct _adapter *adapter); -int r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, - u8 *out_ie, uint in_len); -int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, - u8 *out_ie, uint in_len, uint initial_out_len); -void r8712_init_registrypriv_dev_network(struct _adapter *adapter); -void r8712_update_registrypriv_dev_network(struct _adapter *adapter); -void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter); -void _r8712_join_timeout_handler(struct _adapter *adapter); -void r8712_scan_timeout_handler(struct _adapter *adapter); -void _r8712_dhcp_timeout_handler(struct _adapter *adapter); -struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv); -sint r8712_if_up(struct _adapter *padapter); -void r8712_joinbss_reset(struct _adapter *padapter); -unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, - u8 *out_ie, uint in_len, uint *pout_len); -void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority); -int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork); - -#endif /*__RTL871X_MLME_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c deleted file mode 100644 index 099c512c8519fac29681eacd09335f8e76c70e77..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp.c +++ /dev/null @@ -1,724 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#define _RTL871X_MP_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_mp_phy_regdef.h" -#include "rtl8712_cmd.h" - -static void _init_mp_priv_(struct mp_priv *pmp_priv) -{ - pmp_priv->mode = _LOOPBOOK_MODE_; - pmp_priv->curr_ch = 1; - pmp_priv->curr_modem = MIXED_PHY; - pmp_priv->curr_rateidx = 0; - pmp_priv->curr_txpoweridx = 0x14; - pmp_priv->antenna_tx = ANTENNA_A; - pmp_priv->antenna_rx = ANTENNA_AB; - pmp_priv->check_mp_pkt = 0; - pmp_priv->tx_pktcount = 0; - pmp_priv->rx_pktcount = 0; - pmp_priv->rx_crcerrpktcount = 0; -} - -static int init_mp_priv(struct mp_priv *pmp_priv) -{ - int i; - struct mp_xmit_frame *pmp_xmitframe; - - _init_mp_priv_(pmp_priv); - _init_queue(&pmp_priv->free_mp_xmitqueue); - pmp_priv->pallocated_mp_xmitframe_buf = NULL; - pmp_priv->pallocated_mp_xmitframe_buf = kmalloc(NR_MP_XMITFRAME * - sizeof(struct mp_xmit_frame) + 4, - GFP_ATOMIC); - if (!pmp_priv->pallocated_mp_xmitframe_buf) - return -ENOMEM; - - pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf + - 4 - - ((addr_t)(pmp_priv->pallocated_mp_xmitframe_buf) & 3); - pmp_xmitframe = (struct mp_xmit_frame *)pmp_priv->pmp_xmtframe_buf; - for (i = 0; i < NR_MP_XMITFRAME; i++) { - INIT_LIST_HEAD(&(pmp_xmitframe->list)); - list_add_tail(&(pmp_xmitframe->list), - &(pmp_priv->free_mp_xmitqueue.queue)); - pmp_xmitframe->pkt = NULL; - pmp_xmitframe->frame_tag = MP_FRAMETAG; - pmp_xmitframe->padapter = pmp_priv->papdater; - pmp_xmitframe++; - } - pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME; - return 0; -} - -static int free_mp_priv(struct mp_priv *pmp_priv) -{ - kfree(pmp_priv->pallocated_mp_xmitframe_buf); - return 0; -} - -void mp871xinit(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - - pmppriv->papdater = padapter; - init_mp_priv(pmppriv); -} - -void mp871xdeinit(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - - free_mp_priv(pmppriv); -} - -/* - * Special for bb and rf reg read/write - */ -static u32 fw_iocmd_read(struct _adapter *pAdapter, struct IOCMD_STRUCT iocmd) -{ - u32 cmd32 = 0, val32 = 0; - u8 iocmd_class = iocmd.cmdclass; - u16 iocmd_value = iocmd.value; - u8 iocmd_idx = iocmd.index; - - cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx; - if (r8712_fw_cmd(pAdapter, cmd32)) - r8712_fw_cmd_data(pAdapter, &val32, 1); - else - val32 = 0; - return val32; -} - -static u8 fw_iocmd_write(struct _adapter *pAdapter, - struct IOCMD_STRUCT iocmd, u32 value) -{ - u32 cmd32 = 0; - u8 iocmd_class = iocmd.cmdclass; - u32 iocmd_value = iocmd.value; - u8 iocmd_idx = iocmd.index; - - r8712_fw_cmd_data(pAdapter, &value, 0); - msleep(100); - cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx; - return r8712_fw_cmd(pAdapter, cmd32); -} - -/* offset : 0X800~0XFFF */ -u32 r8712_bb_reg_read(struct _adapter *pAdapter, u16 offset) -{ - u8 shift = offset & 0x0003; /* 4 byte access */ - u16 bb_addr = offset & 0x0FFC; /* 4 byte access */ - u32 bb_val = 0; - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = bb_addr; - iocmd.index = IOCMD_BB_READ_IDX; - bb_val = fw_iocmd_read(pAdapter, iocmd); - if (shift != 0) { - u32 bb_val2 = 0; - - bb_val >>= (shift * 8); - iocmd.value += 4; - bb_val2 = fw_iocmd_read(pAdapter, iocmd); - bb_val2 <<= ((4 - shift) * 8); - bb_val |= bb_val2; - } - return bb_val; -} - -/* offset : 0X800~0XFFF */ -u8 r8712_bb_reg_write(struct _adapter *pAdapter, u16 offset, u32 value) -{ - u8 shift = offset & 0x0003; /* 4 byte access */ - u16 bb_addr = offset & 0x0FFC; /* 4 byte access */ - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = bb_addr; - iocmd.index = IOCMD_BB_WRITE_IDX; - if (shift != 0) { - u32 oldValue = 0; - u32 newValue = value; - - oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); - oldValue &= (0xFFFFFFFF >> ((4 - shift) * 8)); - value = oldValue | (newValue << (shift * 8)); - if (!fw_iocmd_write(pAdapter, iocmd, value)) - return false; - iocmd.value += 4; - oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); - oldValue &= (0xFFFFFFFF << (shift * 8)); - value = oldValue | (newValue >> ((4 - shift) * 8)); - } - return fw_iocmd_write(pAdapter, iocmd, value); -} - -/* offset : 0x00 ~ 0xFF */ -u32 r8712_rf_reg_read(struct _adapter *pAdapter, u8 path, u8 offset) -{ - u16 rf_addr = (path << 8) | offset; - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = rf_addr; - iocmd.index = IOCMD_RF_READ_IDX; - return fw_iocmd_read(pAdapter, iocmd); -} - -u8 r8712_rf_reg_write(struct _adapter *pAdapter, u8 path, u8 offset, u32 value) -{ - u16 rf_addr = (path << 8) | offset; - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = rf_addr; - iocmd.index = IOCMD_RF_WRIT_IDX; - return fw_iocmd_write(pAdapter, iocmd, value); -} - -static u32 bitshift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) - if (((bitmask >> i) & 0x1) == 1) - break; - return i; -} - -static u32 get_bb_reg(struct _adapter *pAdapter, u16 offset, u32 bitmask) -{ - u32 org_value, bit_shift; - - org_value = r8712_bb_reg_read(pAdapter, offset); - bit_shift = bitshift(bitmask); - return (org_value & bitmask) >> bit_shift; -} - -static u8 set_bb_reg(struct _adapter *pAdapter, - u16 offset, - u32 bitmask, - u32 value) -{ - u32 org_value, bit_shift, new_value; - - if (bitmask != bMaskDWord) { - org_value = r8712_bb_reg_read(pAdapter, offset); - bit_shift = bitshift(bitmask); - new_value = (org_value & (~bitmask)) | (value << bit_shift); - } else { - new_value = value; - } - return r8712_bb_reg_write(pAdapter, offset, new_value); -} - -static u32 get_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset, - u32 bitmask) -{ - u32 org_value, bit_shift; - - org_value = r8712_rf_reg_read(pAdapter, path, offset); - bit_shift = bitshift(bitmask); - return (org_value & bitmask) >> bit_shift; -} - -static u8 set_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset, u32 bitmask, - u32 value) -{ - u32 org_value, bit_shift, new_value; - - if (bitmask != bMaskDWord) { - org_value = r8712_rf_reg_read(pAdapter, path, offset); - bit_shift = bitshift(bitmask); - new_value = (org_value & (~bitmask)) | (value << bit_shift); - } else { - new_value = value; - } - return r8712_rf_reg_write(pAdapter, path, offset, new_value); -} - -/* - * SetChannel - * Description - * Use H2C command to change channel, - * not only modify rf register, but also other setting need to be done. - */ -void r8712_SetChannel(struct _adapter *pAdapter) -{ - struct cmd_priv *pcmdpriv = &pAdapter->cmdpriv; - struct cmd_obj *pcmd = NULL; - struct SetChannel_parm *pparm = NULL; - u16 code = GEN_CMD_CODE(_SetChannel); - - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return; - pparm = kmalloc(sizeof(*pparm), GFP_ATOMIC); - if (!pparm) { - kfree(pcmd); - return; - } - pparm->curr_ch = pAdapter->mppriv.curr_ch; - init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code); - r8712_enqueue_cmd(pcmdpriv, pcmd); -} - -static void SetCCKTxPower(struct _adapter *pAdapter, u8 TxPower) -{ - u16 TxAGC = 0; - - TxAGC = TxPower; - set_bb_reg(pAdapter, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); -} - -static void SetOFDMTxPower(struct _adapter *pAdapter, u8 TxPower) -{ - u32 TxAGC = 0; - - TxAGC |= ((TxPower << 24) | (TxPower << 16) | (TxPower << 8) | - TxPower); - set_bb_reg(pAdapter, rTxAGC_Rate18_06, bTxAGCRate18_06, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Rate54_24, bTxAGCRate54_24, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs03_Mcs00, bTxAGCRateMCS3_MCS0, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs07_Mcs04, bTxAGCRateMCS7_MCS4, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs11_Mcs08, bTxAGCRateMCS11_MCS8, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs15_Mcs12, bTxAGCRateMCS15_MCS12, TxAGC); -} - -void r8712_SetTxPower(struct _adapter *pAdapter) -{ - u8 TxPower = pAdapter->mppriv.curr_txpoweridx; - - SetCCKTxPower(pAdapter, TxPower); - SetOFDMTxPower(pAdapter, TxPower); -} - -void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset) -{ - u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D, tmpAGC; - - TxAGCOffset_B = ulTxAGCOffset & 0x000000ff; - TxAGCOffset_C = (ulTxAGCOffset & 0x0000ff00) >> 8; - TxAGCOffset_D = (ulTxAGCOffset & 0x00ff0000) >> 16; - tmpAGC = TxAGCOffset_D << 8 | TxAGCOffset_C << 4 | TxAGCOffset_B; - set_bb_reg(pAdapter, rFPGA0_TxGainStage, - (bXBTxAGC | bXCTxAGC | bXDTxAGC), tmpAGC); -} - -void r8712_SetDataRate(struct _adapter *pAdapter) -{ - u8 path = RF_PATH_A; - u8 offset = RF_SYN_G2; - u32 value; - - value = (pAdapter->mppriv.curr_rateidx < 4) ? 0x4440 : 0xF200; - r8712_rf_reg_write(pAdapter, path, offset, value); -} - -void r8712_SwitchBandwidth(struct _adapter *pAdapter) -{ - /* 3 1.Set MAC register : BWOPMODE bit2:1 20MhzBW */ - u8 regBwOpMode = 0; - u8 Bandwidth = pAdapter->mppriv.curr_bandwidth; - - regBwOpMode = r8712_read8(pAdapter, 0x10250203); - if (Bandwidth == HT_CHANNEL_WIDTH_20) - regBwOpMode |= BIT(2); - else - regBwOpMode &= ~(BIT(2)); - r8712_write8(pAdapter, 0x10250203, regBwOpMode); - /* 3 2.Set PHY related register */ - switch (Bandwidth) { - /* 20 MHz channel*/ - case HT_CHANNEL_WIDTH_20: - set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x0); - set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x0); - /* Use PHY_REG.txt default value. Do not need to change. - * Correct the tx power for CCK rate in 40M. - * It is set in Tx descriptor for 8192x series - */ - set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x58); - break; - /* 40 MHz channel*/ - case HT_CHANNEL_WIDTH_40: - set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x1); - set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x1); - /* Use PHY_REG.txt default value. Do not need to change. - * Correct the tx power for CCK rate in 40M. - * Set Control channel to upper or lower. These settings are - * required only for 40MHz - */ - set_bb_reg(pAdapter, rCCK0_System, bCCKSideBand, - (HAL_PRIME_CHNL_OFFSET_DONT_CARE >> 1)); - set_bb_reg(pAdapter, rOFDM1_LSTF, 0xC00, - HAL_PRIME_CHNL_OFFSET_DONT_CARE); - set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x18); - break; - default: - break; - } - - /* 3 3.Set RF related register */ - switch (Bandwidth) { - case HT_CHANNEL_WIDTH_20: - set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW, - BIT(10) | BIT(11), 0x01); - break; - case HT_CHANNEL_WIDTH_40: - set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW, - BIT(10) | BIT(11), 0x00); - break; - default: - break; - } -} - -/*------------------------------Define structure----------------------------*/ -struct R_ANTENNA_SELECT_OFDM { - u32 r_tx_antenna:4; - u32 r_ant_l:4; - u32 r_ant_non_ht:4; - u32 r_ant_ht1:4; - u32 r_ant_ht2:4; - u32 r_ant_ht_s1:4; - u32 r_ant_non_ht_s1:4; - u32 OFDM_TXSC:2; - u32 Reserved:2; -}; - -struct R_ANTENNA_SELECT_CCK { - u8 r_cckrx_enable_2:2; - u8 r_cckrx_enable:2; - u8 r_ccktx_enable:4; -}; - -void r8712_SwitchAntenna(struct _adapter *pAdapter) -{ - u32 ofdm_tx_en_val = 0, ofdm_tx_ant_sel_val = 0; - u8 ofdm_rx_ant_sel_val = 0; - u8 cck_ant_select_val = 0; - u32 cck_ant_sel_val = 0; - struct R_ANTENNA_SELECT_CCK *p_cck_txrx; - - p_cck_txrx = (struct R_ANTENNA_SELECT_CCK *)&cck_ant_select_val; - - switch (pAdapter->mppriv.antenna_tx) { - case ANTENNA_A: - /* From SD3 Willis suggestion !!! Set RF A=TX and B as standby*/ - set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); - set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1); - ofdm_tx_en_val = 0x3; - ofdm_tx_ant_sel_val = 0x11111111;/* Power save */ - p_cck_txrx->r_ccktx_enable = 0x8; - break; - case ANTENNA_B: - set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1); - set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); - ofdm_tx_en_val = 0x3; - ofdm_tx_ant_sel_val = 0x22222222;/* Power save */ - p_cck_txrx->r_ccktx_enable = 0x4; - break; - case ANTENNA_AB: /* For 8192S */ - set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); - set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); - ofdm_tx_en_val = 0x3; - ofdm_tx_ant_sel_val = 0x3321333; /* Disable Power save */ - p_cck_txrx->r_ccktx_enable = 0xC; - break; - default: - break; - } - /*OFDM Tx*/ - set_bb_reg(pAdapter, rFPGA1_TxInfo, 0xffffffff, ofdm_tx_ant_sel_val); - /*OFDM Tx*/ - set_bb_reg(pAdapter, rFPGA0_TxInfo, 0x0000000f, ofdm_tx_en_val); - switch (pAdapter->mppriv.antenna_rx) { - case ANTENNA_A: - ofdm_rx_ant_sel_val = 0x1; /* A */ - p_cck_txrx->r_cckrx_enable = 0x0; /* default: A */ - p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A */ - break; - case ANTENNA_B: - ofdm_rx_ant_sel_val = 0x2; /* B */ - p_cck_txrx->r_cckrx_enable = 0x1; /* default: B */ - p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option: B */ - break; - case ANTENNA_AB: - ofdm_rx_ant_sel_val = 0x3; /* AB */ - p_cck_txrx->r_cckrx_enable = 0x0; /* default:A */ - p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option:B */ - break; - default: - break; - } - /*OFDM Rx*/ - set_bb_reg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, - ofdm_rx_ant_sel_val); - /*OFDM Rx*/ - set_bb_reg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, - ofdm_rx_ant_sel_val); - - cck_ant_sel_val = cck_ant_select_val; - /*CCK TxRx*/ - set_bb_reg(pAdapter, rCCK0_AFESetting, bMaskByte3, cck_ant_sel_val); -} - -static void TriggerRFThermalMeter(struct _adapter *pAdapter) -{ - /* 0x24: RF Reg[6:5] */ - set_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); -} - -static u32 ReadRFThermalMeter(struct _adapter *pAdapter) -{ - /* 0x24: RF Reg[4:0] */ - return get_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, 0x1F); -} - -void r8712_GetThermalMeter(struct _adapter *pAdapter, u32 *value) -{ - TriggerRFThermalMeter(pAdapter); - msleep(1000); - *value = ReadRFThermalMeter(pAdapter); -} - -void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart) -{ - if (bStart) { /* Start Single Carrier. */ - /* 1. if OFDM block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) - /*set OFDM block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); - /* 2. set CCK test mode off, set to CCK normal mode */ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); - /* 3. turn on scramble setting */ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - /* 4. Turn On Single Carrier Tx and off the other test modes. */ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - } else { /* Stop Single Carrier.*/ - /* Turn off all test modes.*/ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - msleep(20); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } -} - -void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart) -{ - u8 rfPath; - - switch (pAdapter->mppriv.antenna_tx) { - case ANTENNA_B: - rfPath = RF_PATH_B; - break; - case ANTENNA_A: - default: - rfPath = RF_PATH_A; - break; - } - if (bStart) { /* Start Single Tone.*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bDisable); - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bDisable); - set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask, - 0xd4000); - msleep(100); - /* PAD all on.*/ - set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x2001f); - msleep(100); - } else { /* Stop Single Tone.*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable); - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); - set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask, - 0x54000); - msleep(100); - /* PAD all on.*/ - set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x30000); - msleep(100); - } -} - -void r8712_SetCarrierSuppressionTx(struct _adapter *pAdapter, u8 bStart) -{ - if (bStart) { /* Start Carrier Suppression.*/ - if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) { - /* 1. if CCK block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) { - /*set CCK block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, - bEnable); - } - /* Turn Off All Test Mode */ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, - bDisable); - /*transmit mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); - /*turn off scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, - bDisable); - /*Set CCK Tx Test Rate*/ - /*Set FTxRate to 1Mbps*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); - } - } else { /* Stop Carrier Suppression. */ - if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) { - /*normal mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); - /*turn on scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, - bEnable); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } - } -} - -static void SetCCKContinuousTx(struct _adapter *pAdapter, u8 bStart) -{ - u32 cckrate; - - if (bStart) { - /* 1. if CCK block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) { - /*set CCK block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable); - } - /* Turn Off All Test Mode */ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - /*Set CCK Tx Test Rate*/ - cckrate = pAdapter->mppriv.curr_rateidx; - set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); - /*transmit mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); - /*turn on scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - } else { - /*normal mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); - /*turn on scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } -} /* mpt_StartCckContTx */ - -static void SetOFDMContinuousTx(struct _adapter *pAdapter, u8 bStart) -{ - if (bStart) { - /* 1. if OFDM block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) { - /*set OFDM block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); - } - /* 2. set CCK test mode off, set to CCK normal mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); - /* 3. turn on scramble setting */ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - /* 4. Turn On Continue Tx and turn off the other test modes.*/ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - } else { - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - msleep(20); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } -} /* mpt_StartOfdmContTx */ - -void r8712_SetContinuousTx(struct _adapter *pAdapter, u8 bStart) -{ - /* ADC turn off [bit24-21] adc port0 ~ port1 */ - if (bStart) { - r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA, - r8712_bb_reg_read(pAdapter, - rRx_Wait_CCCA) & 0xFE1FFFFF); - msleep(100); - } - if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) - SetCCKContinuousTx(pAdapter, bStart); - else if ((pAdapter->mppriv.curr_rateidx >= MPT_RATE_6M) && - (pAdapter->mppriv.curr_rateidx <= MPT_RATE_MCS15)) - SetOFDMContinuousTx(pAdapter, bStart); - /* ADC turn on [bit24-21] adc port0 ~ port1 */ - if (!bStart) - r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA, - r8712_bb_reg_read(pAdapter, - rRx_Wait_CCCA) | 0x01E00000); -} - -void r8712_ResetPhyRxPktCount(struct _adapter *pAdapter) -{ - u32 i, phyrx_set = 0; - - for (i = OFDM_PPDU_BIT; i <= HT_MPDU_FAIL_BIT; i++) { - phyrx_set = 0; - phyrx_set |= (i << 28); /*select*/ - phyrx_set |= 0x08000000; /* set counter to zero*/ - r8712_write32(pAdapter, RXERR_RPT, phyrx_set); - } -} - -static u32 GetPhyRxPktCounts(struct _adapter *pAdapter, u32 selbit) -{ - /*selection*/ - u32 phyrx_set = 0; - u32 SelectBit; - - SelectBit = selbit << 28; - phyrx_set |= (SelectBit & 0xF0000000); - r8712_write32(pAdapter, RXERR_RPT, phyrx_set); - /*Read packet count*/ - return r8712_read32(pAdapter, RXERR_RPT) & RPTMaxCount; -} - -u32 r8712_GetPhyRxPktReceived(struct _adapter *pAdapter) -{ - u32 OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_OK_BIT); - u32 CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_OK_BIT); - u32 HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_OK_BIT); - - return OFDM_cnt + CCK_cnt + HT_cnt; -} - -u32 r8712_GetPhyRxPktCRC32Error(struct _adapter *pAdapter) -{ - u32 OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_FAIL_BIT); - u32 CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_FAIL_BIT); - u32 HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_FAIL_BIT); - - return OFDM_cnt + CCK_cnt + HT_cnt; -} diff --git a/drivers/staging/rtl8712/rtl871x_mp.h b/drivers/staging/rtl8712/rtl871x_mp.h deleted file mode 100644 index 0a60b1e6ccafc5a92b34fa8f19241e950e82c17d..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp.h +++ /dev/null @@ -1,275 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_MP_H_ -#define __RTL871X_MP_H_ - -#define MPT_NOOP 0 -#define MPT_READ_MAC_1BYTE 1 -#define MPT_READ_MAC_2BYTE 2 -#define MPT_READ_MAC_4BYTE 3 -#define MPT_WRITE_MAC_1BYTE 4 -#define MPT_WRITE_MAC_2BYTE 5 -#define MPT_WRITE_MAC_4BYTE 6 -#define MPT_READ_BB_CCK 7 -#define MPT_WRITE_BB_CCK 8 -#define MPT_READ_BB_OFDM 9 -#define MPT_WRITE_BB_OFDM 10 -#define MPT_READ_RF 11 -#define MPT_WRITE_RF 12 -#define MPT_READ_EEPROM_1BYTE 13 -#define MPT_WRITE_EEPROM_1BYTE 14 -#define MPT_READ_EEPROM_2BYTE 15 -#define MPT_WRITE_EEPROM_2BYTE 16 -#define MPT_SET_CSTHRESHOLD 21 -#define MPT_SET_INITGAIN 22 -#define MPT_SWITCH_BAND 23 -#define MPT_SWITCH_CHANNEL 24 -#define MPT_SET_DATARATE 25 -#define MPT_SWITCH_ANTENNA 26 -#define MPT_SET_TX_POWER 27 -#define MPT_SET_CONT_TX 28 -#define MPT_SET_SINGLE_CARRIER 29 -#define MPT_SET_CARRIER_SUPPRESSION 30 -#define MPT_GET_RATE_TABLE 31 -#define MPT_READ_TSSI 32 -#define MPT_GET_THERMAL_METER 33 -#define MAX_MP_XMITBUF_SZ 2048 -#define NR_MP_XMITFRAME 8 - -struct mp_xmit_frame { - struct list_head list; - struct pkt_attrib attrib; - _pkt *pkt; - int frame_tag; - struct _adapter *padapter; - u8 *mem_addr; - u16 sz[8]; - struct urb *pxmit_urb[8]; - u8 bpending[8]; - u8 last[8]; -}; - -struct mp_wiparam { - u32 bcompleted; - u32 act_type; - u32 io_offset; - u32 io_value; -}; - -struct mp_priv { - struct _adapter *papdater; - /*OID cmd handler*/ - struct mp_wiparam workparam; - u8 act_in_progress; - /*Tx Section*/ - u8 TID; - u32 tx_pktcount; - /*Rx Section*/ - u32 rx_pktcount; - u32 rx_crcerrpktcount; - u32 rx_pktloss; - struct recv_stat rxstat; - /*RF/BB relative*/ - u32 curr_ch; - u32 curr_rateidx; - u8 curr_bandwidth; - u8 curr_modem; - u8 curr_txpoweridx; - u32 curr_crystalcap; - u16 antenna_tx; - u16 antenna_rx; - u8 curr_rfpath; - u8 check_mp_pkt; - uint ForcedDataRate; - struct wlan_network mp_network; - unsigned char network_macaddr[6]; - /*Testing Flag*/ - u32 mode;/*0 for normal type packet, - * 1 for loopback packet (16bytes TXCMD) - */ - sint prev_fw_state; - u8 *pallocated_mp_xmitframe_buf; - u8 *pmp_xmtframe_buf; - struct __queue free_mp_xmitqueue; - u32 free_mp_xmitframe_cnt; -}; - -struct IOCMD_STRUCT { - u8 cmdclass; - u16 value; - u8 index; -}; - -struct rf_reg_param { - u32 path; - u32 offset; - u32 value; -}; - -struct bb_reg_param { - u32 offset; - u32 value; -}; - -/* ======================================================================= */ - -#define LOWER true -#define RAISE false -#define IOCMD_CTRL_REG 0x10250370 -#define IOCMD_DATA_REG 0x10250374 -#define IOCMD_GET_THERMAL_METER 0xFD000028 -#define IOCMD_CLASS_BB_RF 0xF0 -#define IOCMD_BB_READ_IDX 0x00 -#define IOCMD_BB_WRITE_IDX 0x01 -#define IOCMD_RF_READ_IDX 0x02 -#define IOCMD_RF_WRIT_IDX 0x03 -#define BB_REG_BASE_ADDR 0x800 -#define RF_PATH_A 0 -#define RF_PATH_B 1 -#define RF_PATH_C 2 -#define RF_PATH_D 3 -#define MAX_RF_PATH_NUMS 2 -#define _2MAC_MODE_ 0 -#define _LOOPBOOK_MODE_ 1 - -/* MP set force data rate base on the definition. */ -enum { - /* CCK rate. */ - MPT_RATE_1M, /* 0 */ - MPT_RATE_2M, - MPT_RATE_55M, - MPT_RATE_11M, /* 3 */ - - /* OFDM rate. */ - MPT_RATE_6M, /* 4 */ - MPT_RATE_9M, - MPT_RATE_12M, - MPT_RATE_18M, - MPT_RATE_24M, - MPT_RATE_36M, - MPT_RATE_48M, - MPT_RATE_54M, /* 11 */ - - /* HT rate. */ - MPT_RATE_MCS0, /* 12 */ - MPT_RATE_MCS1, - MPT_RATE_MCS2, - MPT_RATE_MCS3, - MPT_RATE_MCS4, - MPT_RATE_MCS5, - MPT_RATE_MCS6, - MPT_RATE_MCS7, /* 19 */ - MPT_RATE_MCS8, - MPT_RATE_MCS9, - MPT_RATE_MCS10, - MPT_RATE_MCS11, - MPT_RATE_MCS12, - MPT_RATE_MCS13, - MPT_RATE_MCS14, - MPT_RATE_MCS15, /* 27 */ - MPT_RATE_LAST -}; - -/* Represent Channel Width in HT Capabilities */ -enum HT_CHANNEL_WIDTH { - HT_CHANNEL_WIDTH_20 = 0, - HT_CHANNEL_WIDTH_40 = 1, -}; - -#define MAX_TX_PWR_INDEX_N_MODE 64 /* 0x3F */ - -enum POWER_MODE { - POWER_LOW = 0, - POWER_NORMAL -}; - -#define RX_PKT_BROADCAST 1 -#define RX_PKT_DEST_ADDR 2 -#define RX_PKT_PHY_MATCH 3 - -#define RPTMaxCount 0x000FFFFF - -/* parameter 1 : BitMask - * bit 0 : OFDM PPDU - * bit 1 : OFDM False Alarm - * bit 2 : OFDM MPDU OK - * bit 3 : OFDM MPDU Fail - * bit 4 : CCK PPDU - * bit 5 : CCK False Alarm - * bit 6 : CCK MPDU ok - * bit 7 : CCK MPDU fail - * bit 8 : HT PPDU counter - * bit 9 : HT false alarm - * bit 10 : HT MPDU total - * bit 11 : HT MPDU OK - * bit 12 : HT MPDU fail - * bit 15 : RX full drop - */ -enum RXPHY_BITMASK { - OFDM_PPDU_BIT = 0, - OFDM_MPDU_OK_BIT, - OFDM_MPDU_FAIL_BIT, - CCK_PPDU_BIT, - CCK_MPDU_OK_BIT, - CCK_MPDU_FAIL_BIT, - HT_PPDU_BIT, - HT_MPDU_BIT, - HT_MPDU_OK_BIT, - HT_MPDU_FAIL_BIT, -}; - -enum ENCRY_CTRL_STATE { - HW_CONTROL, /*hw encryption& decryption*/ - SW_CONTROL, /*sw encryption& decryption*/ - HW_ENCRY_SW_DECRY, /*hw encryption & sw decryption*/ - SW_ENCRY_HW_DECRY /*sw encryption & hw decryption*/ -}; - -/* Bandwidth Offset */ -#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 -#define HAL_PRIME_CHNL_OFFSET_UPPER 2 -/*=======================================================================*/ -void mp871xinit(struct _adapter *padapter); -void mp871xdeinit(struct _adapter *padapter); -u32 r8712_bb_reg_read(struct _adapter *Adapter, u16 offset); -u8 r8712_bb_reg_write(struct _adapter *Adapter, u16 offset, u32 value); -u32 r8712_rf_reg_read(struct _adapter *Adapter, u8 path, u8 offset); -u8 r8712_rf_reg_write(struct _adapter *Adapter, u8 path, - u8 offset, u32 value); -u32 r8712_get_bb_reg(struct _adapter *Adapter, u16 offset, u32 bitmask); -u8 r8712_set_bb_reg(struct _adapter *Adapter, u16 offset, - u32 bitmask, u32 value); -u32 r8712_get_rf_reg(struct _adapter *Adapter, u8 path, u8 offset, - u32 bitmask); -u8 r8712_set_rf_reg(struct _adapter *Adapter, u8 path, u8 offset, - u32 bitmask, u32 value); - -void r8712_SetChannel(struct _adapter *pAdapter); -void r8712_SetTxPower(struct _adapter *pAdapte); -void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset); -void r8712_SetDataRate(struct _adapter *pAdapter); -void r8712_SwitchBandwidth(struct _adapter *pAdapter); -void r8712_SwitchAntenna(struct _adapter *pAdapter); -void r8712_GetThermalMeter(struct _adapter *pAdapter, u32 *value); -void r8712_SetContinuousTx(struct _adapter *pAdapter, u8 bStart); -void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart); -void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart); -void r8712_SetCarrierSuppressionTx(struct _adapter *pAdapter, u8 bStart); -void r8712_ResetPhyRxPktCount(struct _adapter *pAdapter); -u32 r8712_GetPhyRxPktReceived(struct _adapter *pAdapter); -u32 r8712_GetPhyRxPktCRC32Error(struct _adapter *pAdapter); - -#endif /*__RTL871X_MP_H_*/ - diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c deleted file mode 100644 index 26fa09b45c908090c8d43504a58bfb1f51efedbb..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c +++ /dev/null @@ -1,883 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_mp_ioctl.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#include -#include "osdep_service.h" -#include "drv_types.h" -#include "mlme_osdep.h" -#include "rtl871x_mp.h" -#include "rtl871x_mp_ioctl.h" - -uint oid_null_function(struct oid_par_priv *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid == SET_OID) { - if (poid_par_priv->information_buf_len >= sizeof(u8)) - Adapter->registrypriv.wireless_mode = - *(u8 *)poid_par_priv->information_buf; - else - status = RNDIS_STATUS_INVALID_LENGTH; - } else if (poid_par_priv->type_of_oid == QUERY_OID) { - if (poid_par_priv->information_buf_len >= sizeof(u8)) { - *(u8 *)poid_par_priv->information_buf = - Adapter->registrypriv.wireless_mode; - *poid_par_priv->bytes_rw = - poid_par_priv->information_buf_len; - } else { - status = RNDIS_STATUS_INVALID_LENGTH; - } - } else { - status = RNDIS_STATUS_NOT_ACCEPTED; - } - return status; -} - -uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct bb_reg_param *pbbreg; - u16 offset; - u32 value; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); - offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/ - if (offset < BB_REG_BASE_ADDR) - offset |= BB_REG_BASE_ADDR; - value = pbbreg->value; - r8712_bb_reg_write(Adapter, offset, value); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct bb_reg_param *pbbreg; - u16 offset; - u32 value; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); - offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/ - if (offset < BB_REG_BASE_ADDR) - offset |= BB_REG_BASE_ADDR; - value = r8712_bb_reg_read(Adapter, offset); - pbbreg->value = value; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct rf_reg_param *pbbreg; - u8 path; - u8 offset; - u32 value; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); - path = (u8)pbbreg->path; - if (path > RF_PATH_B) - return RNDIS_STATUS_NOT_ACCEPTED; - offset = (u8)pbbreg->offset; - value = pbbreg->value; - r8712_rf_reg_write(Adapter, path, offset, value); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct rf_reg_param *pbbreg; - u8 path; - u8 offset; - u32 value; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); - path = (u8)pbbreg->path; - if (path > RF_PATH_B) /* 1T2R path_a /path_b */ - return RNDIS_STATUS_NOT_ACCEPTED; - offset = (u8)pbbreg->offset; - value = r8712_rf_reg_read(Adapter, path, offset); - pbbreg->value = value; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -/*This function initializes the DUT to the MP test mode*/ -static int mp_start_test(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - struct wlan_bssid_ex *bssid; - struct sta_info *psta; - unsigned long length; - unsigned long irqL; - int res = 0; - - bssid = kzalloc(sizeof(*bssid), GFP_KERNEL); - if (!bssid) - return -ENOMEM; - - /* 3 1. initialize a new struct wlan_bssid_ex */ - memcpy(bssid->MacAddress, pmppriv->network_macaddr, ETH_ALEN); - bssid->Ssid.SsidLength = 16; - memcpy(bssid->Ssid.Ssid, (unsigned char *)"mp_pseudo_adhoc", - bssid->Ssid.SsidLength); - bssid->InfrastructureMode = Ndis802_11IBSS; - bssid->NetworkTypeInUse = Ndis802_11DS; - bssid->IELength = 0; - length = r8712_get_wlan_bssid_ex_sz(bssid); - if (length % 4) { - /*round up to multiple of 4 bytes.*/ - bssid->Length = ((length >> 2) + 1) << 2; - } else { - bssid->Length = length; - } - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - goto end_of_mp_start_test; - /*init mp_start_test status*/ - pmppriv->prev_fw_state = get_fwstate(pmlmepriv); - pmlmepriv->fw_state = WIFI_MP_STATE; - if (pmppriv->mode == _LOOPBOOK_MODE_) - set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/ - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); - /* 3 2. create a new psta for mp driver */ - /* clear psta in the cur_network, if any */ - psta = r8712_get_stainfo(&padapter->stapriv, - tgt_network->network.MacAddress); - if (psta) - r8712_free_stainfo(padapter, psta); - psta = r8712_alloc_stainfo(&padapter->stapriv, bssid->MacAddress); - if (!psta) { - res = -ENOMEM; - goto end_of_mp_start_test; - } - /* 3 3. join pseudo AdHoc */ - tgt_network->join_res = 1; - tgt_network->aid = psta->aid = 1; - memcpy(&tgt_network->network, bssid, length); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - r8712_os_indicate_connect(padapter); - /* Set to LINKED STATE for MP TRX Testing */ - set_fwstate(pmlmepriv, _FW_LINKED); -end_of_mp_start_test: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - kfree(bssid); - return res; -} - -/*This function change the DUT from the MP test mode into normal mode */ -static int mp_stop_test(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - struct sta_info *psta; - unsigned long irqL; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (!check_fwstate(pmlmepriv, WIFI_MP_STATE)) - goto end_of_mp_stop_test; - /* 3 1. disconnect pseudo AdHoc */ - r8712_os_indicate_disconnect(padapter); - /* 3 2. clear psta used in mp test mode. */ - psta = r8712_get_stainfo(&padapter->stapriv, - tgt_network->network.MacAddress); - if (psta) - r8712_free_stainfo(padapter, psta); - /* 3 3. return to normal state (default:station mode) */ - pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE;*/ - /*flush the cur_network*/ - memset(tgt_network, 0, sizeof(struct wlan_network)); -end_of_mp_stop_test: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return _SUCCESS; -} - -uint oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 ratevalue; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - ratevalue = *((u32 *)poid_par_priv->information_buf); - if (ratevalue >= MPT_RATE_LAST) - return RNDIS_STATUS_INVALID_DATA; - Adapter->mppriv.curr_rateidx = ratevalue; - r8712_SetDataRate(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - u32 mode; - u8 val8; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - mode = *((u32 *)poid_par_priv->information_buf); - Adapter->mppriv.mode = mode;/* 1 for loopback*/ - if (mp_start_test(Adapter)) - status = RNDIS_STATUS_NOT_ACCEPTED; - r8712_write8(Adapter, MSR, 1); /* Link in ad hoc network, 0x1025004C */ - r8712_write8(Adapter, RCR, 0); /* RCR : disable all pkt, 0x10250048 */ - /* RCR disable Check BSSID, 0x1025004a */ - r8712_write8(Adapter, RCR + 2, 0x57); - /* disable RX filter map , mgt frames will put in RX FIFO 0 */ - r8712_write16(Adapter, RXFLTMAP0, 0x0); - val8 = r8712_read8(Adapter, EE_9346CR); - if (!(val8 & _9356SEL)) { /*boot from EFUSE*/ - r8712_efuse_reg_init(Adapter); - r8712_efuse_change_max_size(Adapter); - r8712_efuse_reg_uninit(Adapter); - } - return status; -} - -uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (mp_stop_test(Adapter) == _FAIL) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 Channel; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - Channel = *((u32 *)poid_par_priv->information_buf); - if (Channel > 14) - return RNDIS_STATUS_NOT_ACCEPTED; - Adapter->mppriv.curr_ch = Channel; - r8712_SetChannel(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 antenna; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - antenna = *((u32 *)poid_par_priv->information_buf); - Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16); - Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF); - r8712_SwitchAntenna(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 tx_pwr_idx; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - tx_pwr_idx = *((u32 *)poid_par_priv->information_buf); - if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE) - return RNDIS_STATUS_NOT_ACCEPTED; - Adapter->mppriv.curr_txpoweridx = (u8)tx_pwr_idx; - r8712_SetTxPower(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len == sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.tx_pktcount; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len == sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.rx_pktcount; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len == sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.rx_crcerrpktcount; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - Adapter->mppriv.tx_pktcount = 0; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len == sizeof(u32)) { - Adapter->mppriv.rx_pktcount = 0; - Adapter->mppriv.rx_crcerrpktcount = 0; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - r8712_ResetPhyRxPktCount(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(u32 *)poid_par_priv->information_buf = - r8712_GetPhyRxPktReceived(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(u32 *)poid_par_priv->information_buf = - r8712_GetPhyRxPktCRC32Error(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - Adapter->mppriv.curr_modem = *((u8 *)poid_par_priv->information_buf); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetContinuousTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetSingleCarrierTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetCarrierSuppressionTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetSingleToneTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - struct mp_rw_reg *RegRWStruct; - u16 offset; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; - if ((RegRWStruct->offset >= 0x10250800) && - (RegRWStruct->offset <= 0x10250FFF)) { - /*baseband register*/ - /*0ffset :0x800~0xfff*/ - offset = (u16)(RegRWStruct->offset) & 0xFFF; - RegRWStruct->value = r8712_bb_reg_read(Adapter, offset); - } else { - switch (RegRWStruct->width) { - case 1: - RegRWStruct->value = r8712_read8(Adapter, - RegRWStruct->offset); - break; - case 2: - RegRWStruct->value = r8712_read16(Adapter, - RegRWStruct->offset); - break; - case 4: - RegRWStruct->value = r8712_read32(Adapter, - RegRWStruct->offset); - break; - default: - status = RNDIS_STATUS_NOT_ACCEPTED; - break; - } - } - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return status; -} - -uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - struct mp_rw_reg *RegRWStruct; - u16 offset; - u32 value; - u32 oldValue = 0; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; - if ((RegRWStruct->offset >= 0x10250800) && - (RegRWStruct->offset <= 0x10250FFF)) { - /*baseband register*/ - offset = (u16)(RegRWStruct->offset) & 0xFFF; - value = RegRWStruct->value; - switch (RegRWStruct->width) { - case 1: - oldValue = r8712_bb_reg_read(Adapter, offset); - oldValue &= 0xFFFFFF00; - value &= 0x000000FF; - value |= oldValue; - break; - case 2: - oldValue = r8712_bb_reg_read(Adapter, offset); - oldValue &= 0xFFFF0000; - value &= 0x0000FFFF; - value |= oldValue; - break; - } - r8712_bb_reg_write(Adapter, offset, value); - } else { - switch (RegRWStruct->width) { - case 1: - r8712_write8(Adapter, RegRWStruct->offset, - (unsigned char)RegRWStruct->value); - break; - case 2: - r8712_write16(Adapter, RegRWStruct->offset, - (unsigned short)RegRWStruct->value); - break; - case 4: - r8712_write32(Adapter, RegRWStruct->offset, - (unsigned int)RegRWStruct->value); - break; - default: - status = RNDIS_STATUS_NOT_ACCEPTED; - break; - } - } - return status; -} - -uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (Adapter->mppriv.act_in_progress) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len < sizeof(u8)) - return RNDIS_STATUS_INVALID_LENGTH; - /*init workparam*/ - Adapter->mppriv.act_in_progress = true; - Adapter->mppriv.workparam.bcompleted = false; - Adapter->mppriv.workparam.act_type = MPT_GET_THERMAL_METER; - Adapter->mppriv.workparam.io_offset = 0; - Adapter->mppriv.workparam.io_value = 0xFFFFFFFF; - r8712_GetThermalMeter(Adapter, &Adapter->mppriv.workparam.io_value); - Adapter->mppriv.workparam.bcompleted = true; - Adapter->mppriv.act_in_progress = false; - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.workparam.io_value; - *poid_par_priv->bytes_rw = sizeof(u32); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - uint status = RNDIS_STATUS_SUCCESS; - - struct EFUSE_ACCESS_STRUCT *pefuse; - u8 *data; - u16 addr = 0, cnts = 0; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < - sizeof(struct EFUSE_ACCESS_STRUCT)) - return RNDIS_STATUS_INVALID_LENGTH; - pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf; - addr = pefuse->start_addr; - cnts = pefuse->cnts; - data = pefuse->data; - memset(data, 0xFF, cnts); - if ((addr > 511) || (cnts < 1) || (cnts > 512) || (addr + cnts) > - EFUSE_MAX_SIZE) - return RNDIS_STATUS_NOT_ACCEPTED; - if (!r8712_efuse_access(Adapter, true, addr, cnts, data)) - status = RNDIS_STATUS_FAILURE; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return status; -} - -/*------------------------------------------------------------------------*/ -uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - uint status = RNDIS_STATUS_SUCCESS; - - struct EFUSE_ACCESS_STRUCT *pefuse; - u8 *data; - u16 addr = 0, cnts = 0; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf; - addr = pefuse->start_addr; - cnts = pefuse->cnts; - data = pefuse->data; - - if ((addr > 511) || (cnts < 1) || (cnts > 512) || - (addr + cnts) > r8712_efuse_get_max_size(Adapter)) - return RNDIS_STATUS_NOT_ACCEPTED; - if (!r8712_efuse_access(Adapter, false, addr, cnts, data)) - status = RNDIS_STATUS_FAILURE; - return status; -} - -/*----------------------------------------------------------------------*/ - -uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(int)) - return RNDIS_STATUS_INVALID_LENGTH; - r8712_efuse_reg_init(Adapter); - *(int *)poid_par_priv->information_buf = - r8712_efuse_get_current_size(Adapter); - r8712_efuse_reg_uninit(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(int *)poid_par_priv->information_buf = - r8712_efuse_get_max_size(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - - if (poid_par_priv->type_of_oid == QUERY_OID) - status = oid_rt_pro_read_efuse_hdl(poid_par_priv); - else - status = oid_rt_pro_write_efuse_hdl(poid_par_priv); - return status; -} - -uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - u8 *data; - - *poid_par_priv->bytes_rw = 0; - if (poid_par_priv->information_buf_len < EFUSE_MAP_MAX_SIZE) - return RNDIS_STATUS_INVALID_LENGTH; - data = (u8 *)poid_par_priv->information_buf; - if (poid_par_priv->type_of_oid == QUERY_OID) { - if (r8712_efuse_map_read(Adapter, 0, EFUSE_MAP_MAX_SIZE, data)) - *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE; - else - status = RNDIS_STATUS_FAILURE; - } else { - /* SET_OID */ - if (r8712_efuse_reg_init(Adapter)) { - if (r8712_efuse_map_write(Adapter, 0, - EFUSE_MAP_MAX_SIZE, data)) - *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE; - else - status = RNDIS_STATUS_FAILURE; - r8712_efuse_reg_uninit(Adapter); - } else { - status = RNDIS_STATUS_FAILURE; - } - } - return status; -} - -uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bandwidth; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - bandwidth = *((u32 *)poid_par_priv->information_buf);/*4*/ - if (bandwidth != HT_CHANNEL_WIDTH_20) - bandwidth = HT_CHANNEL_WIDTH_40; - Adapter->mppriv.curr_bandwidth = (u8)bandwidth; - r8712_SwitchBandwidth(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u8 rx_pkt_type; - u32 rcr_val32; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u8)) - return RNDIS_STATUS_INVALID_LENGTH; - rx_pkt_type = *((u8 *)poid_par_priv->information_buf);/*4*/ - rcr_val32 = r8712_read32(Adapter, RCR);/*RCR = 0x10250048*/ - rcr_val32 &= ~(RCR_CBSSID | RCR_AB | RCR_AM | RCR_APM | RCR_AAP); - switch (rx_pkt_type) { - case RX_PKT_BROADCAST: - rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32); - break; - case RX_PKT_DEST_ADDR: - rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32); - break; - case RX_PKT_PHY_MATCH: - rcr_val32 |= (RCR_APM | RCR_ACRC32); - break; - default: - rcr_val32 &= ~(RCR_AAP | - RCR_APM | - RCR_AM | - RCR_AB | - RCR_ACRC32); - break; - } - if (rx_pkt_type == RX_PKT_DEST_ADDR) - Adapter->mppriv.check_mp_pkt = 1; - else - Adapter->mppriv.check_mp_pkt = 0; - r8712_write32(Adapter, RCR, rcr_val32); - return RNDIS_STATUS_SUCCESS; -} - -/*--------------------------------------------------------------------------*/ -/*Linux*/ -unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) -{ - return _SUCCESS; -} - -/*-------------------------------------------------------------------------*/ -uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - /*CALL the power_down function*/ - return RNDIS_STATUS_SUCCESS; -} - -/*-------------------------------------------------------------------------- */ -uint oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(int *)poid_par_priv->information_buf = - Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h deleted file mode 100644 index aa4d5ce471f2fa55379cf1421784dec4f6eb0ee2..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h +++ /dev/null @@ -1,328 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_MP_IOCTL_H -#define _RTL871X_MP_IOCTL_H - -#include "osdep_service.h" -#include "drv_types.h" -#include "mp_custom_oid.h" -#include "rtl871x_ioctl.h" -#include "rtl871x_ioctl_rtl.h" -#include "rtl8712_efuse.h" - -#define TESTFWCMDNUMBER 1000000 -#define TEST_H2CINT_WAIT_TIME 500 -#define TEST_C2HINT_WAIT_TIME 500 -#define HCI_TEST_SYSCFG_HWMASK 1 -#define _BUSCLK_40M (4 << 2) - -struct CFG_DBG_MSG_STRUCT { - u32 DebugLevel; - u32 DebugComponent_H32; - u32 DebugComponent_L32; -}; - -struct mp_rw_reg { - uint offset; - uint width; - u32 value; -}; - -/* for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM */ -struct eeprom_rw_param { - uint offset; - u16 value; -}; - -struct EFUSE_ACCESS_STRUCT { - u16 start_addr; - u16 cnts; - u8 data[]; -}; - -struct burst_rw_reg { - uint offset; - uint len; - u8 Data[256]; -}; - -struct usb_vendor_req { - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; - u8 u8Dir;/*0:OUT, 1:IN */ - u8 u8InData; -}; - -struct DR_VARIABLE_STRUCT { - u8 offset; - u32 variable; -}; - -/* oid_rtl_seg_87_11_00 */ -uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_80_00 */ -uint oid_rt_pro_set_data_rate_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_channel_direct_call_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_antenna_bb_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_tx_power_control_hdl( - struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_80_20 */ -uint oid_rt_pro_query_tx_packet_sent_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_query_rx_packet_received_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_query_rx_packet_crc32_error_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_reset_tx_packet_sent_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_reset_rx_packet_received_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_continuous_tx_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_single_carrier_tx_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_carrier_suppression_tx_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_single_tone_tx_hdl( - struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_87 */ -uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_85 */ -uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_get_efuse_current_size_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_get_thermal_meter_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_reset_phy_rx_packet_count_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_phy_rx_packet_received_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_phy_rx_packet_crc32_error_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_power_down_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_power_mode_hdl( - struct oid_par_priv *poid_par_priv); -#ifdef _RTL871X_MP_IOCTL_C_ /* CAUTION!!! */ -/* This ifdef _MUST_ be left in!! */ - -#else /* _RTL871X_MP_IOCTL_C_ */ -extern struct oid_obj_priv oid_rtl_seg_81_87[5]; -extern struct oid_obj_priv oid_rtl_seg_87_11_00[32]; -extern struct oid_obj_priv oid_rtl_seg_87_11_20[5]; -extern struct oid_obj_priv oid_rtl_seg_87_11_50[2]; -extern struct oid_obj_priv oid_rtl_seg_87_11_80[1]; -extern struct oid_obj_priv oid_rtl_seg_87_11_B0[1]; -extern struct oid_obj_priv oid_rtl_seg_87_11_F0[16]; -extern struct oid_obj_priv oid_rtl_seg_87_12_00[32]; - -#endif /* _RTL871X_MP_IOCTL_C_ */ - -enum MP_MODE { - MP_START_MODE, - MP_STOP_MODE, - MP_ERR_MODE -}; - -struct rwreg_param { - unsigned int offset; - unsigned int width; - unsigned int value; -}; - -struct bbreg_param { - unsigned int offset; - unsigned int phymask; - unsigned int value; -}; - -struct txpower_param { - unsigned int pwr_index; -}; - -struct datarate_param { - unsigned int rate_index; -}; - -struct rfintfs_parm { - unsigned int rfintfs; -}; - -struct mp_xmit_packet { - unsigned int len; -}; - -struct psmode_param { - unsigned int ps_mode; - unsigned int smart_ps; -}; - -struct mp_ioctl_handler { - unsigned int paramsize; - unsigned int (*handler)(struct oid_par_priv *poid_par_priv); - unsigned int oid; -}; - -struct mp_ioctl_param { - unsigned int subcode; - unsigned int len; - unsigned char data[]; -}; - -#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_ - -enum RTL871X_MP_IOCTL_SUBCODE { - GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/ - GEN_MP_IOCTL_SUBCODE(MP_STOP), /*1*/ - GEN_MP_IOCTL_SUBCODE(READ_REG), /*2*/ - GEN_MP_IOCTL_SUBCODE(WRITE_REG), - GEN_MP_IOCTL_SUBCODE(SET_CHANNEL), /*4*/ - GEN_MP_IOCTL_SUBCODE(SET_TXPOWER), /*5*/ - GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*6*/ - GEN_MP_IOCTL_SUBCODE(READ_BB_REG), /*7*/ - GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG), - GEN_MP_IOCTL_SUBCODE(READ_RF_REG), /*9*/ - GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG), - GEN_MP_IOCTL_SUBCODE(SET_RF_INTFS), - GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET), /*12*/ - GEN_MP_IOCTL_SUBCODE(PS_STATE), /*13*/ - GEN_MP_IOCTL_SUBCODE(READ16_EEPROM), /*14*/ - GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM), /*15*/ - GEN_MP_IOCTL_SUBCODE(SET_PTM), /*16*/ - GEN_MP_IOCTL_SUBCODE(READ_TSSI), /*17*/ - GEN_MP_IOCTL_SUBCODE(CNTU_TX), /*18*/ - GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH), /*19*/ - GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE), /*20*/ - GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT), /*21*/ - GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*22*/ - GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR), /*23*/ - GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*24*/ - GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER), /*25*/ - GEN_MP_IOCTL_SUBCODE(GET_POWER_MODE), /*26*/ - GEN_MP_IOCTL_SUBCODE(EFUSE), /*27*/ - GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*28*/ - GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE), /*29*/ - GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE), /*30*/ - GEN_MP_IOCTL_SUBCODE(SC_TX), /*31*/ - GEN_MP_IOCTL_SUBCODE(CS_TX), /*32*/ - GEN_MP_IOCTL_SUBCODE(ST_TX), /*33*/ - GEN_MP_IOCTL_SUBCODE(SET_ANTENNA), /*34*/ - MAX_MP_IOCTL_SUBCODE, -}; - -unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv); - -#ifdef _RTL871X_MP_IOCTL_C_ /* CAUTION!!! */ -/* This ifdef _MUST_ be left in!! */ - -static struct mp_ioctl_handler mp_ioctl_hdl[] = { - {sizeof(u32), oid_rt_pro_start_test_hdl, - OID_RT_PRO_START_TEST},/*0*/ - {sizeof(u32), oid_rt_pro_stop_test_hdl, - OID_RT_PRO_STOP_TEST},/*1*/ - {sizeof(struct rwreg_param), - oid_rt_pro_read_register_hdl, - OID_RT_PRO_READ_REGISTER},/*2*/ - {sizeof(struct rwreg_param), - oid_rt_pro_write_register_hdl, - OID_RT_PRO_WRITE_REGISTER}, - {sizeof(u32), - oid_rt_pro_set_channel_direct_call_hdl, - OID_RT_PRO_SET_CHANNEL_DIRECT_CALL}, - {sizeof(struct txpower_param), - oid_rt_pro_set_tx_power_control_hdl, - OID_RT_PRO_SET_TX_POWER_CONTROL}, - {sizeof(u32), - oid_rt_pro_set_data_rate_hdl, - OID_RT_PRO_SET_DATA_RATE}, - {sizeof(struct bb_reg_param), - oid_rt_pro_read_bb_reg_hdl, - OID_RT_PRO_READ_BB_REG},/*7*/ - {sizeof(struct bb_reg_param), - oid_rt_pro_write_bb_reg_hdl, - OID_RT_PRO_WRITE_BB_REG}, - {sizeof(struct rwreg_param), - oid_rt_pro_read_rf_reg_hdl, - OID_RT_PRO_RF_READ_REGISTRY},/*9*/ - {sizeof(struct rwreg_param), - oid_rt_pro_write_rf_reg_hdl, - OID_RT_PRO_RF_WRITE_REGISTRY}, - {sizeof(struct rfintfs_parm), NULL, 0}, - {0, mp_ioctl_xmit_packet_hdl, 0},/*12*/ - {sizeof(struct psmode_param), NULL, 0},/*13*/ - {sizeof(struct eeprom_rw_param), NULL, 0},/*14*/ - {sizeof(struct eeprom_rw_param), NULL, 0},/*15*/ - {sizeof(unsigned char), NULL, 0},/*16*/ - {sizeof(u32), NULL, 0},/*17*/ - {sizeof(u32), oid_rt_pro_set_continuous_tx_hdl, - OID_RT_PRO_SET_CONTINUOUS_TX},/*18*/ - {sizeof(u32), oid_rt_set_bandwidth_hdl, - OID_RT_SET_BANDWIDTH},/*19*/ - {sizeof(u32), oid_rt_set_rx_packet_type_hdl, - OID_RT_SET_RX_PACKET_TYPE},/*20*/ - {0, oid_rt_reset_phy_rx_packet_count_hdl, - OID_RT_RESET_PHY_RX_PACKET_COUNT},/*21*/ - {sizeof(u32), oid_rt_get_phy_rx_packet_received_hdl, - OID_RT_GET_PHY_RX_PACKET_RECEIVED},/*22*/ - {sizeof(u32), oid_rt_get_phy_rx_packet_crc32_error_hdl, - OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR},/*23*/ - {sizeof(unsigned char), oid_rt_set_power_down_hdl, - OID_RT_SET_POWER_DOWN},/*24*/ - {sizeof(u32), oid_rt_get_thermal_meter_hdl, - OID_RT_PRO_GET_THERMAL_METER},/*25*/ - {sizeof(u32), oid_rt_get_power_mode_hdl, - OID_RT_GET_POWER_MODE},/*26*/ - {sizeof(struct EFUSE_ACCESS_STRUCT), - oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE},/*27*/ - {EFUSE_MAP_MAX_SIZE, oid_rt_pro_efuse_map_hdl, - OID_RT_PRO_EFUSE_MAP},/*28*/ - {sizeof(u32), oid_rt_get_efuse_max_size_hdl, - OID_RT_GET_EFUSE_MAX_SIZE},/*29*/ - {sizeof(u32), oid_rt_get_efuse_current_size_hdl, - OID_RT_GET_EFUSE_CURRENT_SIZE},/*30*/ - {sizeof(u32), oid_rt_pro_set_single_carrier_tx_hdl, - OID_RT_PRO_SET_SINGLE_CARRIER_TX},/*31*/ - {sizeof(u32), oid_rt_pro_set_carrier_suppression_tx_hdl, - OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX},/*32*/ - {sizeof(u32), oid_rt_pro_set_single_tone_tx_hdl, - OID_RT_PRO_SET_SINGLE_TONE_TX},/*33*/ - {sizeof(u32), oid_rt_pro_set_antenna_bb_hdl, - OID_RT_PRO_SET_ANTENNA_BB},/*34*/ -}; - -#else /* _RTL871X_MP_IOCTL_C_ */ -extern struct mp_ioctl_handler mp_ioctl_hdl[]; -#endif /* _RTL871X_MP_IOCTL_C_ */ - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h deleted file mode 100644 index bb9f83d58225dc3727121c690224dfe9308cd0f5..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h +++ /dev/null @@ -1,1034 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/***************************************************************************** - * Copyright(c) 2008, RealTEK Technology Inc. All Right Reserved. - * - * Module: __INC_HAL8192SPHYREG_H - * - * - * Note: 1. Define PMAC/BB register map - * 2. Define RF register map - * 3. PMAC/BB register bit mask. - * 4. RF reg bit mask. - * 5. Other BB/RF relative definition. - * - * - * Export: Constants, macro, functions(API), global variables(None). - * - * Abbrev: - * - * History: - * Data Who Remark - * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. - * 2. Reorganize code architecture. - * 09/25/2008 MH 1. Add RL6052 register definition - * - *****************************************************************************/ -#ifndef __RTL871X_MP_PHY_REGDEF_H -#define __RTL871X_MP_PHY_REGDEF_H - -/*--------------------------Define Parameters-------------------------------*/ - -/*============================================================ - * 8192S Register offset definition - *============================================================ - * - * - * BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF - * 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF - * 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 - * 3. RF register 0x00-2E - * 4. Bit Mask for BB/RF register - * 5. Other definition for BB/RF R/W - * - * 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF - * 1. Page1(0x100) - */ -#define rPMAC_Reset 0x100 -#define rPMAC_TxStart 0x104 -#define rPMAC_TxLegacySIG 0x108 -#define rPMAC_TxHTSIG1 0x10c -#define rPMAC_TxHTSIG2 0x110 -#define rPMAC_PHYDebug 0x114 -#define rPMAC_TxPacketNum 0x118 -#define rPMAC_TxIdle 0x11c -#define rPMAC_TxMACHeader0 0x120 -#define rPMAC_TxMACHeader1 0x124 -#define rPMAC_TxMACHeader2 0x128 -#define rPMAC_TxMACHeader3 0x12c -#define rPMAC_TxMACHeader4 0x130 -#define rPMAC_TxMACHeader5 0x134 -#define rPMAC_TxDataType 0x138 -#define rPMAC_TxRandomSeed 0x13c -#define rPMAC_CCKPLCPPreamble 0x140 -#define rPMAC_CCKPLCPHeader 0x144 -#define rPMAC_CCKCRC16 0x148 -#define rPMAC_OFDMRxCRC32OK 0x170 -#define rPMAC_OFDMRxCRC32Er 0x174 -#define rPMAC_OFDMRxParityEr 0x178 -#define rPMAC_OFDMRxCRC8Er 0x17c -#define rPMAC_CCKCRxRC16Er 0x180 -#define rPMAC_CCKCRxRC32Er 0x184 -#define rPMAC_CCKCRxRC32OK 0x188 -#define rPMAC_TxStatus 0x18c - -/* - * 2. Page2(0x200) - * - * The following two definition are only used for USB interface. - *#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. - *#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. - * - * - * 3. Page8(0x800) - */ -#define rFPGA0_RFMOD 0x800 /*RF mode & CCK TxSC RF - * BW Setting?? - */ -#define rFPGA0_TxInfo 0x804 /* Status report?? */ -#define rFPGA0_PSDFunction 0x808 -#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */ -#define rFPGA0_RFTiming1 0x810 /* Useless now */ -#define rFPGA0_RFTiming2 0x814 -#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */ -#define rFPGA0_XA_HSSIParameter2 0x824 -#define rFPGA0_XB_HSSIParameter1 0x828 -#define rFPGA0_XB_HSSIParameter2 0x82c -#define rFPGA0_XC_HSSIParameter1 0x830 -#define rFPGA0_XC_HSSIParameter2 0x834 -#define rFPGA0_XD_HSSIParameter1 0x838 -#define rFPGA0_XD_HSSIParameter2 0x83c -#define rFPGA0_XA_LSSIParameter 0x840 -#define rFPGA0_XB_LSSIParameter 0x844 -#define rFPGA0_XC_LSSIParameter 0x848 -#define rFPGA0_XD_LSSIParameter 0x84c - -#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */ -#define rFPGA0_RFSleepUpParameter 0x854 - -#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */ -#define rFPGA0_XCD_SwitchControl 0x85c - -#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */ -#define rFPGA0_XB_RFInterfaceOE 0x864 -#define rFPGA0_XC_RFInterfaceOE 0x868 -#define rFPGA0_XD_RFInterfaceOE 0x86c -#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Interface Software Ctrl */ -#define rFPGA0_XCD_RFInterfaceSW 0x874 - -#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */ -#define rFPGA0_XCD_RFParameter 0x87c - -#define rFPGA0_AnalogParameter1 0x880 /* Crystal cap setting - * RF-R/W protection - * for parameter4?? - */ -#define rFPGA0_AnalogParameter2 0x884 -#define rFPGA0_AnalogParameter3 0x888 /* Useless now */ -#define rFPGA0_AnalogParameter4 0x88c - -#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Transceiver LSSI Readback */ -#define rFPGA0_XB_LSSIReadBack 0x8a4 -#define rFPGA0_XC_LSSIReadBack 0x8a8 -#define rFPGA0_XD_LSSIReadBack 0x8ac - -#define rFPGA0_PSDReport 0x8b4 /* Useless now */ -#define rFPGA0_XAB_RFInterfaceRB 0x8e0 /* Useless now */ -#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */ - -/* - * 4. Page9(0x900) - */ -#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC */ - -#define rFPGA1_TxBlock 0x904 /* Useless now */ -#define rFPGA1_DebugSelect 0x908 /* Useless now */ -#define rFPGA1_TxInfo 0x90c /* Useless now */ - -/* - * 5. PageA(0xA00) - * - * Set Control channel to upper or lower. - * These settings are required only for 40MHz - */ -#define rCCK0_System 0xa00 - -#define rCCK0_AFESetting 0xa04 /* Disable init gain now */ -#define rCCK0_CCA 0xa08 /* Disable init gain now */ - -#define rCCK0_RxAGC1 0xa0c -/* AGC default value, saturation level - * Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. - * Not the same as 90 series - */ -#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ - -#define rCCK0_RxHP 0xa14 - -#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel - * estimation threshold - */ -#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ - -#define rCCK0_TxFilter1 0xa20 -#define rCCK0_TxFilter2 0xa24 -#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ -#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now 0xa30-a4f - * channel report - */ -#define rCCK0_TRSSIReport 0xa50 -#define rCCK0_RxReport 0xa54 /* 0xa57 */ -#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ -#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ - -/* - * 6. PageC(0xC00) - */ -#define rOFDM0_LSTF 0xc00 -#define rOFDM0_TRxPathEnable 0xc04 -#define rOFDM0_TRMuxPar 0xc08 -#define rOFDM0_TRSWIsolation 0xc0c - -/*RxIQ DC offset, Rx digital filter, DC notch filter */ -#define rOFDM0_XARxAFE 0xc10 -#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imbalance matrix */ -#define rOFDM0_XBRxAFE 0xc18 -#define rOFDM0_XBRxIQImbalance 0xc1c -#define rOFDM0_XCRxAFE 0xc20 -#define rOFDM0_XCRxIQImbalance 0xc24 -#define rOFDM0_XDRxAFE 0xc28 -#define rOFDM0_XDRxIQImbalance 0xc2c - -#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD DM tune - * init gain - */ -#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */ -#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */ -#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & - * Short-GI - */ - -#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ -#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ -#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ -#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ - -#define rOFDM0_XAAGCCore1 0xc50 /* DIG */ -#define rOFDM0_XAAGCCore2 0xc54 -#define rOFDM0_XBAGCCore1 0xc58 -#define rOFDM0_XBAGCCore2 0xc5c -#define rOFDM0_XCAGCCore1 0xc60 -#define rOFDM0_XCAGCCore2 0xc64 -#define rOFDM0_XDAGCCore1 0xc68 -#define rOFDM0_XDAGCCore2 0xc6c -#define rOFDM0_AGCParameter1 0xc70 -#define rOFDM0_AGCParameter2 0xc74 -#define rOFDM0_AGCRSSITable 0xc78 -#define rOFDM0_HTSTFAGC 0xc7c - -#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */ -#define rOFDM0_XATxAFE 0xc84 -#define rOFDM0_XBTxIQImbalance 0xc88 -#define rOFDM0_XBTxAFE 0xc8c -#define rOFDM0_XCTxIQImbalance 0xc90 -#define rOFDM0_XCTxAFE 0xc94 -#define rOFDM0_XDTxIQImbalance 0xc98 -#define rOFDM0_XDTxAFE 0xc9c - -#define rOFDM0_RxHPParameter 0xce0 -#define rOFDM0_TxPseudoNoiseWgt 0xce4 -#define rOFDM0_FrameSync 0xcf0 -#define rOFDM0_DFSReport 0xcf4 -#define rOFDM0_TxCoeff1 0xca4 -#define rOFDM0_TxCoeff2 0xca8 -#define rOFDM0_TxCoeff3 0xcac -#define rOFDM0_TxCoeff4 0xcb0 -#define rOFDM0_TxCoeff5 0xcb4 -#define rOFDM0_TxCoeff6 0xcb8 - -/* - * 7. PageD(0xD00) - */ -#define rOFDM1_LSTF 0xd00 -#define rOFDM1_TRxPathEnable 0xd04 - -#define rOFDM1_CFO 0xd08 /* No setting now */ -#define rOFDM1_CSI1 0xd10 -#define rOFDM1_SBD 0xd14 -#define rOFDM1_CSI2 0xd18 -#define rOFDM1_CFOTracking 0xd2c -#define rOFDM1_TRxMesaure1 0xd34 -#define rOFDM1_IntfDet 0xd3c -#define rOFDM1_PseudoNoiseStateAB 0xd50 -#define rOFDM1_PseudoNoiseStateCD 0xd54 -#define rOFDM1_RxPseudoNoiseWgt 0xd58 - -#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ -#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ -#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ -#define rOFDM_ShortCFOAB 0xdac /* No setting now */ -#define rOFDM_ShortCFOCD 0xdb0 -#define rOFDM_LongCFOAB 0xdb4 -#define rOFDM_LongCFOCD 0xdb8 -#define rOFDM_TailCFOAB 0xdbc -#define rOFDM_TailCFOCD 0xdc0 -#define rOFDM_PWMeasure1 0xdc4 -#define rOFDM_PWMeasure2 0xdc8 -#define rOFDM_BWReport 0xdcc -#define rOFDM_AGCReport 0xdd0 -#define rOFDM_RxSNR 0xdd4 -#define rOFDM_RxEVMCSI 0xdd8 -#define rOFDM_SIGReport 0xddc - -/* - * 8. PageE(0xE00) - */ -#define rTxAGC_Rate18_06 0xe00 -#define rTxAGC_Rate54_24 0xe04 -#define rTxAGC_CCK_Mcs32 0xe08 -#define rTxAGC_Mcs03_Mcs00 0xe10 -#define rTxAGC_Mcs07_Mcs04 0xe14 -#define rTxAGC_Mcs11_Mcs08 0xe18 -#define rTxAGC_Mcs15_Mcs12 0xe1c - -/* Analog- control in RX_WAIT_CCA : REG: EE0 - * [Analog- Power & Control Register] - */ -#define rRx_Wait_CCCA 0xe70 -#define rAnapar_Ctrl_BB 0xee0 - -/* - * 7. RF Register 0x00-0x2E (RF 8256) - * RF-0222D 0x00-3F - * - * Zebra1 - */ -#define rZebra1_HSSIEnable 0x0 /* Useless now */ -#define rZebra1_TRxEnable1 0x1 -#define rZebra1_TRxEnable2 0x2 -#define rZebra1_AGC 0x4 -#define rZebra1_ChargePump 0x5 -#define rZebra1_Channel 0x7 /* RF channel switch */ -#define rZebra1_TxGain 0x8 /* Useless now */ -#define rZebra1_TxLPF 0x9 -#define rZebra1_RxLPF 0xb -#define rZebra1_RxHPFCorner 0xc - -/* Zebra4 */ -#define rGlobalCtrl 0 /* Useless now */ -#define rRTL8256_TxLPF 19 -#define rRTL8256_RxLPF 11 - -/* RTL8258 */ -#define rRTL8258_TxLPF 0x11 /* Useless now */ -#define rRTL8258_RxLPF 0x13 -#define rRTL8258_RSSILPF 0xa - -/* RL6052 Register definition */ -#define RF_AC 0x00 -#define RF_IQADJ_G1 0x01 -#define RF_IQADJ_G2 0x02 -#define RF_POW_TRSW 0x05 - -#define RF_GAIN_RX 0x06 -#define RF_GAIN_TX 0x07 - -#define RF_TXM_IDAC 0x08 -#define RF_BS_IQGEN 0x0F - -#define RF_MODE1 0x10 -#define RF_MODE2 0x11 - -#define RF_RX_AGC_HP 0x12 -#define RF_TX_AGC 0x13 -#define RF_BIAS 0x14 -#define RF_IPA 0x15 -#define RF_POW_ABILITY 0x17 -#define RF_MODE_AG 0x18 -#define rRfChannel 0x18 /* RF channel and BW switch */ -#define RF_CHNLBW 0x18 /* RF channel and BW switch */ -#define RF_TOP 0x19 -#define RF_RX_G1 0x1A -#define RF_RX_G2 0x1B -#define RF_RX_BB2 0x1C -#define RF_RX_BB1 0x1D - -#define RF_RCK1 0x1E -#define RF_RCK2 0x1F - -#define RF_TX_G1 0x20 -#define RF_TX_G2 0x21 -#define RF_TX_G3 0x22 - -#define RF_TX_BB1 0x23 -#define RF_T_METER 0x24 - -#define RF_SYN_G1 0x25 /* RF TX Power control */ -#define RF_SYN_G2 0x26 /* RF TX Power control */ -#define RF_SYN_G3 0x27 /* RF TX Power control */ -#define RF_SYN_G4 0x28 /* RF TX Power control */ -#define RF_SYN_G5 0x29 /* RF TX Power control */ -#define RF_SYN_G6 0x2A /* RF TX Power control */ -#define RF_SYN_G7 0x2B /* RF TX Power control */ -#define RF_SYN_G8 0x2C /* RF TX Power control */ - -#define RF_RCK_OS 0x30 /* RF TX PA control */ - -#define RF_TXPA_G1 0x31 /* RF TX PA control */ -#define RF_TXPA_G2 0x32 /* RF TX PA control */ -#define RF_TXPA_G3 0x33 /* RF TX PA control */ - -/* - * Bit Mask - * - * 1. Page1(0x100) - */ -#define bBBResetB 0x100 /* Useless now? */ -#define bGlobalResetB 0x200 -#define bOFDMTxStart 0x4 -#define bCCKTxStart 0x8 -#define bCRC32Debug 0x100 -#define bPMACLoopback 0x10 -#define bTxLSIG 0xffffff -#define bOFDMTxRate 0xf -#define bOFDMTxReserved 0x10 -#define bOFDMTxLength 0x1ffe0 -#define bOFDMTxParity 0x20000 -#define bTxHTSIG1 0xffffff -#define bTxHTMCSRate 0x7f -#define bTxHTBW 0x80 -#define bTxHTLength 0xffff00 -#define bTxHTSIG2 0xffffff -#define bTxHTSmoothing 0x1 -#define bTxHTSounding 0x2 -#define bTxHTReserved 0x4 -#define bTxHTAggreation 0x8 -#define bTxHTSTBC 0x30 -#define bTxHTAdvanceCoding 0x40 -#define bTxHTShortGI 0x80 -#define bTxHTNumberHT_LTF 0x300 -#define bTxHTCRC8 0x3fc00 -#define bCounterReset 0x10000 -#define bNumOfOFDMTx 0xffff -#define bNumOfCCKTx 0xffff0000 -#define bTxIdleInterval 0xffff -#define bOFDMService 0xffff0000 -#define bTxMACHeader 0xffffffff -#define bTxDataInit 0xff -#define bTxHTMode 0x100 -#define bTxDataType 0x30000 -#define bTxRandomSeed 0xffffffff -#define bCCKTxPreamble 0x1 -#define bCCKTxSFD 0xffff0000 -#define bCCKTxSIG 0xff -#define bCCKTxService 0xff00 -#define bCCKLengthExt 0x8000 -#define bCCKTxLength 0xffff0000 -#define bCCKTxCRC16 0xffff -#define bCCKTxStatus 0x1 -#define bOFDMTxStatus 0x2 -#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && \ - (_Offset <= 0xfff)) - -/* 2. Page8(0x800) */ -#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */ -#define bJapanMode 0x2 -#define bCCKTxSC 0x30 -#define bCCKEn 0x1000000 -#define bOFDMEn 0x2000000 - -#define bOFDMRxADCPhase 0x10000 /* Useless now */ -#define bOFDMTxDACPhase 0x40000 -#define bXATxAGC 0x3f -#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */ -#define bXCTxAGC 0xf000 -#define bXDTxAGC 0xf0000 - -#define bPAStart 0xf0000000 /* Useless now */ -#define bTRStart 0x00f00000 -#define bRFStart 0x0000f000 -#define bBBStart 0x000000f0 -#define bBBCCKStart 0x0000000f -#define bPAEnd 0xf /* Reg0x814 */ -#define bTREnd 0x0f000000 -#define bRFEnd 0x000f0000 -#define bCCAMask 0x000000f0 /* T2R */ -#define bR2RCCAMask 0x00000f00 -#define bHSSI_R2TDelay 0xf8000000 -#define bHSSI_T2RDelay 0xf80000 -#define bContTxHSSI 0x400 /* change gain at continue Tx */ -#define bIGFromCCK 0x200 -#define bAGCAddress 0x3f -#define bRxHPTx 0x7000 -#define bRxHPT2R 0x38000 -#define bRxHPCCKIni 0xc0000 -#define bAGCTxCode 0xc00000 -#define bAGCRxCode 0x300000 -#define b3WireDataLength 0x800 /* Reg 0x820~84f rFPGA0_XA_HSSIParm1 */ -#define b3WireAddressLength 0x400 -#define b3WireRFPowerDown 0x1 /* Useless now */ -#define b5GPAPEPolarity 0x40000000 -#define b2GPAPEPolarity 0x80000000 -#define bRFSW_TxDefaultAnt 0x3 -#define bRFSW_TxOptionAnt 0x30 -#define bRFSW_RxDefaultAnt 0x300 -#define bRFSW_RxOptionAnt 0x3000 -#define bRFSI_3WireData 0x1 -#define bRFSI_3WireClock 0x2 -#define bRFSI_3WireLoad 0x4 -#define bRFSI_3WireRW 0x8 -#define bRFSI_3Wire 0xf -#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */ -#define bRFSI_TRSW 0x20 /* Useless now */ -#define bRFSI_TRSWB 0x40 -#define bRFSI_ANTSW 0x100 -#define bRFSI_ANTSWB 0x200 -#define bRFSI_PAPE 0x400 -#define bRFSI_PAPE5G 0x800 -#define bBandSelect 0x1 -#define bHTSIG2_GI 0x80 -#define bHTSIG2_Smoothing 0x01 -#define bHTSIG2_Sounding 0x02 -#define bHTSIG2_Aggreaton 0x08 -#define bHTSIG2_STBC 0x30 -#define bHTSIG2_AdvCoding 0x40 -#define bHTSIG2_NumOfHTLTF 0x300 -#define bHTSIG2_CRC8 0x3fc -#define bHTSIG1_MCS 0x7f -#define bHTSIG1_BandWidth 0x80 -#define bHTSIG1_HTLength 0xffff -#define bLSIG_Rate 0xf -#define bLSIG_Reserved 0x10 -#define bLSIG_Length 0x1fffe -#define bLSIG_Parity 0x20 -#define bCCKRxPhase 0x4 -#define bLSSIReadAddress 0x7f800000 /* T65 RF */ -#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ -#define bLSSIReadBackData 0xfffff /* T65 RF */ -#define bLSSIReadOKFlag 0x1000 /* Useless now */ -#define bCCKSampleRate 0x8 /*0: 44MHz, 1:88MHz*/ -#define bRegulator0Standby 0x1 -#define bRegulatorPLLStandby 0x2 -#define bRegulator1Standby 0x4 -#define bPLLPowerUp 0x8 -#define bDPLLPowerUp 0x10 -#define bDA10PowerUp 0x20 -#define bAD7PowerUp 0x200 -#define bDA6PowerUp 0x2000 -#define bXtalPowerUp 0x4000 -#define b40MDClkPowerUP 0x8000 -#define bDA6DebugMode 0x20000 -#define bDA6Swing 0x380000 - -/* Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */ -#define bADClkPhase 0x4000000 - -#define b80MClkDelay 0x18000000 /* Useless */ -#define bAFEWatchDogEnable 0x20000000 - -/* Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */ -#define bXtalCap01 0xc0000000 -#define bXtalCap23 0x3 -#define bXtalCap92x 0x0f000000 -#define bXtalCap 0x0f000000 -#define bIntDifClkEnable 0x400 /* Useless */ -#define bExtSigClkEnable 0x800 -#define bBandgapMbiasPowerUp 0x10000 -#define bAD11SHGain 0xc0000 -#define bAD11InputRange 0x700000 -#define bAD11OPCurrent 0x3800000 -#define bIPathLoopback 0x4000000 -#define bQPathLoopback 0x8000000 -#define bAFELoopback 0x10000000 -#define bDA10Swing 0x7e0 -#define bDA10Reverse 0x800 -#define bDAClkSource 0x1000 -#define bAD7InputRange 0x6000 -#define bAD7Gain 0x38000 -#define bAD7OutputCMMode 0x40000 -#define bAD7InputCMMode 0x380000 -#define bAD7Current 0xc00000 -#define bRegulatorAdjust 0x7000000 -#define bAD11PowerUpAtTx 0x1 -#define bDA10PSAtTx 0x10 -#define bAD11PowerUpAtRx 0x100 -#define bDA10PSAtRx 0x1000 -#define bCCKRxAGCFormat 0x200 -#define bPSDFFTSamplepPoint 0xc000 -#define bPSDAverageNum 0x3000 -#define bIQPathControl 0xc00 -#define bPSDFreq 0x3ff -#define bPSDAntennaPath 0x30 -#define bPSDIQSwitch 0x40 -#define bPSDRxTrigger 0x400000 -#define bPSDTxTrigger 0x80000000 -#define bPSDSineToneScale 0x7f000000 -#define bPSDReport 0xffff - -/* 3. Page9(0x900) */ -#define bOFDMTxSC 0x30000000 /* Useless */ -#define bCCKTxOn 0x1 -#define bOFDMTxOn 0x2 -#define bDebugPage 0xfff /* reset debug page and HWord, LWord */ -#define bDebugItem 0xff /* reset debug page and LWord */ -#define bAntL 0x10 -#define bAntNonHT 0x100 -#define bAntHT1 0x1000 -#define bAntHT2 0x10000 -#define bAntHT1S1 0x100000 -#define bAntNonHTS1 0x1000000 - -/* 4. PageA(0xA00) */ -#define bCCKBBMode 0x3 /* Useless */ -#define bCCKTxPowerSaving 0x80 -#define bCCKRxPowerSaving 0x40 - -#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0_System 20/40 switch*/ -#define bCCKScramble 0x8 /* Useless */ -#define bCCKAntDiversity 0x8000 -#define bCCKCarrierRecovery 0x4000 -#define bCCKTxRate 0x3000 -#define bCCKDCCancel 0x0800 -#define bCCKISICancel 0x0400 -#define bCCKMatchFilter 0x0200 -#define bCCKEqualizer 0x0100 -#define bCCKPreambleDetect 0x800000 -#define bCCKFastFalseCCA 0x400000 -#define bCCKChEstStart 0x300000 -#define bCCKCCACount 0x080000 -#define bCCKcs_lim 0x070000 -#define bCCKBistMode 0x80000000 -#define bCCKCCAMask 0x40000000 -#define bCCKTxDACPhase 0x4 -#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ -#define bCCKr_cp_mode0 0x0100 -#define bCCKTxDCOffset 0xf0 -#define bCCKRxDCOffset 0xf -#define bCCKCCAMode 0xc000 -#define bCCKFalseCS_lim 0x3f00 -#define bCCKCS_ratio 0xc00000 -#define bCCKCorgBit_sel 0x300000 -#define bCCKPD_lim 0x0f0000 -#define bCCKNewCCA 0x80000000 -#define bCCKRxHPofIG 0x8000 -#define bCCKRxIG 0x7f00 -#define bCCKLNAPolarity 0x800000 -#define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 /* CCK Rx initial gain polarity */ -#define bCCKRxAGCSatLevel 0x1f000000 -#define bCCKRxAGCSatCount 0xe0 -#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ -#define bCCKFixedRxAGC 0x8000 -#define bCCKAntennaPolarity 0x2000 -#define bCCKTxFilterType 0x0c00 -#define bCCKRxAGCReportType 0x0300 -#define bCCKRxDAGCEn 0x80000000 -#define bCCKRxDAGCPeriod 0x20000000 -#define bCCKRxDAGCSatLevel 0x1f000000 -#define bCCKTimingRecovery 0x800000 -#define bCCKTxC0 0x3f0000 -#define bCCKTxC1 0x3f000000 -#define bCCKTxC2 0x3f -#define bCCKTxC3 0x3f00 -#define bCCKTxC4 0x3f0000 -#define bCCKTxC5 0x3f000000 -#define bCCKTxC6 0x3f -#define bCCKTxC7 0x3f00 -#define bCCKDebugPort 0xff0000 -#define bCCKDACDebug 0x0f000000 -#define bCCKFalseAlarmEnable 0x8000 -#define bCCKFalseAlarmRead 0x4000 -#define bCCKTRSSI 0x7f -#define bCCKRxAGCReport 0xfe -#define bCCKRxReport_AntSel 0x80000000 -#define bCCKRxReport_MFOff 0x40000000 -#define bCCKRxRxReport_SQLoss 0x20000000 -#define bCCKRxReport_Pktloss 0x10000000 -#define bCCKRxReport_Lockedbit 0x08000000 -#define bCCKRxReport_RateError 0x04000000 -#define bCCKRxReport_RxRate 0x03000000 -#define bCCKRxFACounterLower 0xff -#define bCCKRxFACounterUpper 0xff000000 -#define bCCKRxHPAGCStart 0xe000 -#define bCCKRxHPAGCFinal 0x1c00 -#define bCCKRxFalseAlarmEnable 0x8000 -#define bCCKFACounterFreeze 0x4000 -#define bCCKTxPathSel 0x10000000 -#define bCCKDefaultRxPath 0xc000000 -#define bCCKOptionRxPath 0x3000000 - -/* 5. PageC(0xC00) */ -#define bNumOfSTF 0x3 /* Useless */ -#define bShift_L 0xc0 -#define bGI_TH 0xc -#define bRxPathA 0x1 -#define bRxPathB 0x2 -#define bRxPathC 0x4 -#define bRxPathD 0x8 -#define bTxPathA 0x1 -#define bTxPathB 0x2 -#define bTxPathC 0x4 -#define bTxPathD 0x8 -#define bTRSSIFreq 0x200 -#define bADCBackoff 0x3000 -#define bDFIRBackoff 0xc000 -#define bTRSSILatchPhase 0x10000 -#define bRxIDCOffset 0xff -#define bRxQDCOffset 0xff00 -#define bRxDFIRMode 0x1800000 -#define bRxDCNFType 0xe000000 -#define bRXIQImb_A 0x3ff -#define bRXIQImb_B 0xfc00 -#define bRXIQImb_C 0x3f0000 -#define bRXIQImb_D 0xffc00000 -#define bDC_dc_Notch 0x60000 -#define bRxNBINotch 0x1f000000 -#define bPD_TH 0xf -#define bPD_TH_Opt2 0xc000 -#define bPWED_TH 0x700 -#define bIfMF_Win_L 0x800 -#define bPD_Option 0x1000 -#define bMF_Win_L 0xe000 -#define bBW_Search_L 0x30000 -#define bwin_enh_L 0xc0000 -#define bBW_TH 0x700000 -#define bED_TH2 0x3800000 -#define bBW_option 0x4000000 -#define bRatio_TH 0x18000000 -#define bWindow_L 0xe0000000 -#define bSBD_Option 0x1 -#define bFrame_TH 0x1c -#define bFS_Option 0x60 -#define bDC_Slope_check 0x80 -#define bFGuard_Counter_DC_L 0xe00 -#define bFrame_Weight_Short 0x7000 -#define bSub_Tune 0xe00000 -#define bFrame_DC_Length 0xe000000 -#define bSBD_start_offset 0x30000000 -#define bFrame_TH_2 0x7 -#define bFrame_GI2_TH 0x38 -#define bGI2_Sync_en 0x40 -#define bSarch_Short_Early 0x300 -#define bSarch_Short_Late 0xc00 -#define bSarch_GI2_Late 0x70000 -#define bCFOAntSum 0x1 -#define bCFOAcc 0x2 -#define bCFOStartOffset 0xc -#define bCFOLookBack 0x70 -#define bCFOSumWeight 0x80 -#define bDAGCEnable 0x10000 -#define bTXIQImb_A 0x3ff -#define bTXIQImb_B 0xfc00 -#define bTXIQImb_C 0x3f0000 -#define bTXIQImb_D 0xffc00000 -#define bTxIDCOffset 0xff -#define bTxQDCOffset 0xff00 -#define bTxDFIRMode 0x10000 -#define bTxPesudoNoiseOn 0x4000000 -#define bTxPesudoNoise_A 0xff -#define bTxPesudoNoise_B 0xff00 -#define bTxPesudoNoise_C 0xff0000 -#define bTxPesudoNoise_D 0xff000000 -#define bCCADropOption 0x20000 -#define bCCADropThres 0xfff00000 -#define bEDCCA_H 0xf -#define bEDCCA_L 0xf0 -#define bLambda_ED 0x300 -#define bRxInitialGain 0x7f -#define bRxAntDivEn 0x80 -#define bRxAGCAddressForLNA 0x7f00 -#define bRxHighPowerFlow 0x8000 -#define bRxAGCFreezeThres 0xc0000 -#define bRxFreezeStep_AGC1 0x300000 -#define bRxFreezeStep_AGC2 0xc00000 -#define bRxFreezeStep_AGC3 0x3000000 -#define bRxFreezeStep_AGC0 0xc000000 -#define bRxRssi_Cmp_En 0x10000000 -#define bRxQuickAGCEn 0x20000000 -#define bRxAGCFreezeThresMode 0x40000000 -#define bRxOverFlowCheckType 0x80000000 -#define bRxAGCShift 0x7f -#define bTRSW_Tri_Only 0x80 -#define bPowerThres 0x300 -#define bRxAGCEn 0x1 -#define bRxAGCTogetherEn 0x2 -#define bRxAGCMin 0x4 -#define bRxHP_Ini 0x7 -#define bRxHP_TRLNA 0x70 -#define bRxHP_RSSI 0x700 -#define bRxHP_BBP1 0x7000 -#define bRxHP_BBP2 0x70000 -#define bRxHP_BBP3 0x700000 -#define bRSSI_H 0x7f0000 /* the threshold for high power */ -#define bRSSI_Gen 0x7f000000 /* the threshold for ant divers */ -#define bRxSettle_TRSW 0x7 -#define bRxSettle_LNA 0x38 -#define bRxSettle_RSSI 0x1c0 -#define bRxSettle_BBP 0xe00 -#define bRxSettle_RxHP 0x7000 -#define bRxSettle_AntSW_RSSI 0x38000 -#define bRxSettle_AntSW 0xc0000 -#define bRxProcessTime_DAGC 0x300000 -#define bRxSettle_HSSI 0x400000 -#define bRxProcessTime_BBPPW 0x800000 -#define bRxAntennaPowerShift 0x3000000 -#define bRSSITableSelect 0xc000000 -#define bRxHP_Final 0x7000000 -#define bRxHTSettle_BBP 0x7 -#define bRxHTSettle_HSSI 0x8 -#define bRxHTSettle_RxHP 0x70 -#define bRxHTSettle_BBPPW 0x80 -#define bRxHTSettle_Idle 0x300 -#define bRxHTSettle_Reserved 0x1c00 -#define bRxHTRxHPEn 0x8000 -#define bRxHTAGCFreezeThres 0x30000 -#define bRxHTAGCTogetherEn 0x40000 -#define bRxHTAGCMin 0x80000 -#define bRxHTAGCEn 0x100000 -#define bRxHTDAGCEn 0x200000 -#define bRxHTRxHP_BBP 0x1c00000 -#define bRxHTRxHP_Final 0xe0000000 -#define bRxPWRatioTH 0x3 -#define bRxPWRatioEn 0x4 -#define bRxMFHold 0x3800 -#define bRxPD_Delay_TH1 0x38 -#define bRxPD_Delay_TH2 0x1c0 -#define bRxPD_DC_COUNT_MAX 0x600 -#define bRxPD_Delay_TH 0x8000 -#define bRxProcess_Delay 0xf0000 -#define bRxSearchrange_GI2_Early 0x700000 -#define bRxFrame_Guard_Counter_L 0x3800000 -#define bRxSGI_Guard_L 0xc000000 -#define bRxSGI_Search_L 0x30000000 -#define bRxSGI_TH 0xc0000000 -#define bDFSCnt0 0xff -#define bDFSCnt1 0xff00 -#define bDFSFlag 0xf0000 -#define bMFWeightSum 0x300000 -#define bMinIdxTH 0x7f000000 -#define bDAFormat 0x40000 -#define bTxChEmuEnable 0x01000000 -#define bTRSWIsolation_A 0x7f -#define bTRSWIsolation_B 0x7f00 -#define bTRSWIsolation_C 0x7f0000 -#define bTRSWIsolation_D 0x7f000000 -#define bExtLNAGain 0x7c00 - -/* 6. PageE(0xE00) */ -#define bSTBCEn 0x4 /* Useless */ -#define bAntennaMapping 0x10 -#define bNss 0x20 -#define bCFOAntSumD 0x200 -#define bPHYCounterReset 0x8000000 -#define bCFOReportGet 0x4000000 -#define bOFDMContinueTx 0x10000000 -#define bOFDMSingleCarrier 0x20000000 -#define bOFDMSingleTone 0x40000000 -#define bHTDetect 0x100 -#define bCFOEn 0x10000 -#define bCFOValue 0xfff00000 -#define bSigTone_Re 0x3f -#define bSigTone_Im 0x7f00 -#define bCounter_CCA 0xffff -#define bCounter_ParityFail 0xffff0000 -#define bCounter_RateIllegal 0xffff -#define bCounter_CRC8Fail 0xffff0000 -#define bCounter_MCSNoSupport 0xffff -#define bCounter_FastSync 0xffff -#define bShortCFO 0xfff -#define bShortCFOTLength 12 /* total */ -#define bShortCFOFLength 11 /* fraction */ -#define bLongCFO 0x7ff -#define bLongCFOTLength 11 -#define bLongCFOFLength 11 -#define bTailCFO 0x1fff -#define bTailCFOTLength 13 -#define bTailCFOFLength 12 -#define bmax_en_pwdB 0xffff -#define bCC_power_dB 0xffff0000 -#define bnoise_pwdB 0xffff -#define bPowerMeasTLength 10 -#define bPowerMeasFLength 3 -#define bRx_HT_BW 0x1 -#define bRxSC 0x6 -#define bRx_HT 0x8 -#define bNB_intf_det_on 0x1 -#define bIntf_win_len_cfg 0x30 -#define bNB_Intf_TH_cfg 0x1c0 -#define bRFGain 0x3f -#define bTableSel 0x40 -#define bTRSW 0x80 -#define bRxSNR_A 0xff -#define bRxSNR_B 0xff00 -#define bRxSNR_C 0xff0000 -#define bRxSNR_D 0xff000000 -#define bSNREVMTLength 8 -#define bSNREVMFLength 1 -#define bCSI1st 0xff -#define bCSI2nd 0xff00 -#define bRxEVM1st 0xff0000 -#define bRxEVM2nd 0xff000000 -#define bSIGEVM 0xff -#define bPWDB 0xff00 -#define bSGIEN 0x10000 - -#define bSFactorQAM1 0xf /* Useless */ -#define bSFactorQAM2 0xf0 -#define bSFactorQAM3 0xf00 -#define bSFactorQAM4 0xf000 -#define bSFactorQAM5 0xf0000 -#define bSFactorQAM6 0xf0000 -#define bSFactorQAM7 0xf00000 -#define bSFactorQAM8 0xf000000 -#define bSFactorQAM9 0xf0000000 -#define bCSIScheme 0x100000 - -#define bNoiseLvlTopSet 0x3 /* Useless */ -#define bChSmooth 0x4 -#define bChSmoothCfg1 0x38 -#define bChSmoothCfg2 0x1c0 -#define bChSmoothCfg3 0xe00 -#define bChSmoothCfg4 0x7000 -#define bMRCMode 0x800000 -#define bTHEVMCfg 0x7000000 - -#define bLoopFitType 0x1 /* Useless */ -#define bUpdCFO 0x40 -#define bUpdCFOOffData 0x80 -#define bAdvUpdCFO 0x100 -#define bAdvTimeCtrl 0x800 -#define bUpdClko 0x1000 -#define bFC 0x6000 -#define bTrackingMode 0x8000 -#define bPhCmpEnable 0x10000 -#define bUpdClkoLTF 0x20000 -#define bComChCFO 0x40000 -#define bCSIEstiMode 0x80000 -#define bAdvUpdEqz 0x100000 -#define bUChCfg 0x7000000 -#define bUpdEqz 0x8000000 - -#define bTxAGCRate18_06 0x7f7f7f7f /* Useless */ -#define bTxAGCRate54_24 0x7f7f7f7f -#define bTxAGCRateMCS32 0x7f -#define bTxAGCRateCCK 0x7f00 -#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f -#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f -#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f -#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f - -/* Rx Pseduo noise */ -#define bRxPesudoNoiseOn 0x20000000 /* Useless */ -#define bRxPesudoNoise_A 0xff -#define bRxPesudoNoise_B 0xff00 -#define bRxPesudoNoise_C 0xff0000 -#define bRxPesudoNoise_D 0xff000000 -#define bPesudoNoiseState_A 0xffff -#define bPesudoNoiseState_B 0xffff0000 -#define bPesudoNoiseState_C 0xffff -#define bPesudoNoiseState_D 0xffff0000 - -/* 7. RF Register - * Zebra1 - */ -#define bZebra1_HSSIEnable 0x8 /* Useless */ -#define bZebra1_TRxControl 0xc00 -#define bZebra1_TRxGainSetting 0x07f -#define bZebra1_RxCorner 0xc00 -#define bZebra1_TxChargePump 0x38 -#define bZebra1_RxChargePump 0x7 -#define bZebra1_ChannelNum 0xf80 -#define bZebra1_TxLPFBW 0x400 -#define bZebra1_RxLPFBW 0x600 - -/*Zebra4 */ -#define bRTL8256RegModeCtrl1 0x100 /* Useless */ -#define bRTL8256RegModeCtrl0 0x40 -#define bRTL8256_TxLPFBW 0x18 -#define bRTL8256_RxLPFBW 0x600 - -/* RTL8258 */ -#define bRTL8258_TxLPFBW 0xc /* Useless */ -#define bRTL8258_RxLPFBW 0xc00 -#define bRTL8258_RSSILPFBW 0xc0 - -/* - * Other Definition - */ - -/* byte endable for sb_write */ -#define bByte0 0x1 /* Useless */ -#define bByte1 0x2 -#define bByte2 0x4 -#define bByte3 0x8 -#define bWord0 0x3 -#define bWord1 0xc -#define bDWord 0xf - -/* for PutRegsetting & GetRegSetting BitMask */ -#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */ -#define bMaskByte1 0xff00 -#define bMaskByte2 0xff0000 -#define bMaskByte3 0xff000000 -#define bMaskHWord 0xffff0000 -#define bMaskLWord 0x0000ffff -#define bMaskDWord 0xffffffff - -/* for PutRFRegsetting & GetRFRegSetting BitMask */ -#define bRFRegOffsetMask 0xfffff -#define bEnable 0x1 /* Useless */ -#define bDisable 0x0 - -#define LeftAntenna 0x0 /* Useless */ -#define RightAntenna 0x1 - -#define tCheckTxStatus 500 /* 500ms Useless */ -#define tUpdateRxCounter 100 /* 100ms */ - -#define rateCCK 0 /* Useless */ -#define rateOFDM 1 -#define rateHT 2 - -/* define Register-End */ -#define bPMAC_End 0x1ff /* Useless */ -#define bFPGAPHY0_End 0x8ff -#define bFPGAPHY1_End 0x9ff -#define bCCKPHY0_End 0xaff -#define bOFDMPHY0_End 0xcff -#define bOFDMPHY1_End 0xdff - -#define bPMACControl 0x0 /* Useless */ -#define bWMACControl 0x1 -#define bWNICControl 0x2 - -#define ANTENNA_A 0x1 /* Useless */ -#define ANTENNA_B 0x2 -#define ANTENNA_AB 0x3 /* ANTENNA_A |ANTENNA_B */ - -#define ANTENNA_C 0x4 -#define ANTENNA_D 0x8 - -/* accept all physical address */ -#define RCR_AAP BIT(0) -#define RCR_APM BIT(1) /* accept physical match */ -#define RCR_AM BIT(2) /* accept multicast */ -#define RCR_AB BIT(3) /* accept broadcast */ -#define RCR_ACRC32 BIT(5) /* accept error packet */ -#define RCR_9356SEL BIT(6) -#define RCR_AICV BIT(12) /* Accept ICV error packet */ -#define RCR_RXFTH0 (BIT(13)|BIT(14)|BIT(15)) /* Rx FIFO threshold */ -#define RCR_ADF BIT(18) /* Accept Data(frame type) frame */ -#define RCR_ACF BIT(19) /* Accept control frame */ -#define RCR_AMF BIT(20) /* Accept management frame */ -#define RCR_ADD3 BIT(21) -#define RCR_APWRMGT BIT(22) /* Accept power management packet */ -#define RCR_CBSSID BIT(23) /* Accept BSSID match packet */ -#define RCR_ENMARP BIT(28) /* enable mac auto reset phy */ -#define RCR_EnCS1 BIT(29) /* enable carrier sense method 1 */ -#define RCR_EnCS2 BIT(30) /* enable carrier sense method 2 */ -/* Rx Early mode is performed for packet size greater than 1536 */ -#define RCR_OnlyErlPkt BIT(31) - -/*--------------------------Define Parameters-------------------------------*/ - -#endif /*__INC_HAL8192SPHYREG_H */ - diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c deleted file mode 100644 index cd6d9ff0bebca7c2d4dbaf0b001628eb84db08d3..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_pwrctrl.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_PWRCTRL_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" - -#define RTL8712_SDIO_LOCAL_BASE 0X10100000 -#define SDIO_HCPWM (RTL8712_SDIO_LOCAL_BASE + 0x0081) - -void r8712_set_rpwm(struct _adapter *padapter, u8 val8) -{ - u8 rpwm; - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - - if (pwrpriv->rpwm == val8) { - if (pwrpriv->rpwm_retry == 0) - return; - } - if (padapter->driver_stopped || padapter->surprise_removed) - return; - rpwm = val8 | pwrpriv->tog; - switch (val8) { - case PS_STATE_S1: - pwrpriv->cpwm = val8; - break; - case PS_STATE_S2:/* only for USB normal powersave mode use, - * temp mark some code. - */ - case PS_STATE_S3: - case PS_STATE_S4: - pwrpriv->cpwm = val8; - break; - default: - break; - } - pwrpriv->rpwm_retry = 0; - pwrpriv->rpwm = val8; - r8712_write8(padapter, 0x1025FE58, rpwm); - pwrpriv->tog += 0x80; -} - -void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode, uint smart_ps) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - - if (ps_mode > PM_Card_Disable) - return; - /* if driver is in active state, we dont need set smart_ps.*/ - if (ps_mode == PS_MODE_ACTIVE) - smart_ps = 0; - if ((pwrpriv->pwr_mode != ps_mode) || (pwrpriv->smart_ps != smart_ps)) { - if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) - pwrpriv->bSleep = true; - else - pwrpriv->bSleep = false; - pwrpriv->pwr_mode = ps_mode; - pwrpriv->smart_ps = smart_ps; - schedule_work(&pwrpriv->SetPSModeWorkItem); - } -} - -/* - * Caller:ISR handler... - * - * This will be called when CPWM interrupt is up. - * - * using to update cpwn of drv; and drv will make a decision to up or - * down pwr level - */ -void r8712_cpwm_int_hdl(struct _adapter *padapter, - struct reportpwrstate_parm *preportpwrstate) -{ - struct pwrctrl_priv *pwrpriv = &(padapter->pwrctrlpriv); - struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); - - if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80)) - return; - del_timer(&padapter->pwrctrlpriv.rpwm_check_timer); - mutex_lock(&pwrpriv->mutex_lock); - pwrpriv->cpwm = (preportpwrstate->state) & 0xf; - if (pwrpriv->cpwm >= PS_STATE_S2) { - if (pwrpriv->alives & CMD_ALIVE) - complete(&(pcmdpriv->cmd_queue_comp)); - } - pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80; - mutex_unlock(&pwrpriv->mutex_lock); -} - -static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, uint tag) -{ - pwrctrl->alives |= tag; -} - -static inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, uint tag) -{ - if (pwrctrl->alives & tag) - pwrctrl->alives ^= tag; -} - -static void _rpwm_check_handler (struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - - if (padapter->driver_stopped || padapter->surprise_removed) - return; - if (pwrpriv->cpwm != pwrpriv->rpwm) - schedule_work(&pwrpriv->rpwm_workitem); -} - -static void SetPSModeWorkItemCallback(struct work_struct *work) -{ - struct pwrctrl_priv *pwrpriv = container_of(work, - struct pwrctrl_priv, SetPSModeWorkItem); - struct _adapter *padapter = container_of(pwrpriv, - struct _adapter, pwrctrlpriv); - if (!pwrpriv->bSleep) { - mutex_lock(&pwrpriv->mutex_lock); - if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) - r8712_set_rpwm(padapter, PS_STATE_S4); - mutex_unlock(&pwrpriv->mutex_lock); - } -} - -static void rpwm_workitem_callback(struct work_struct *work) -{ - struct pwrctrl_priv *pwrpriv = container_of(work, - struct pwrctrl_priv, rpwm_workitem); - struct _adapter *padapter = container_of(pwrpriv, - struct _adapter, pwrctrlpriv); - if (pwrpriv->cpwm != pwrpriv->rpwm) { - mutex_lock(&pwrpriv->mutex_lock); - r8712_read8(padapter, SDIO_HCPWM); - pwrpriv->rpwm_retry = 1; - r8712_set_rpwm(padapter, pwrpriv->rpwm); - mutex_unlock(&pwrpriv->mutex_lock); - } -} - -static void rpwm_check_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, pwrctrlpriv.rpwm_check_timer); - - _rpwm_check_handler(adapter); -} - -void r8712_init_pwrctrl_priv(struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; - - memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv)); - mutex_init(&pwrctrlpriv->mutex_lock); - pwrctrlpriv->cpwm = PS_STATE_S4; - pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; - pwrctrlpriv->smart_ps = 0; - pwrctrlpriv->tog = 0x80; -/* clear RPWM to ensure driver and fw back to initial state. */ - r8712_write8(padapter, 0x1025FE58, 0); - INIT_WORK(&pwrctrlpriv->SetPSModeWorkItem, SetPSModeWorkItemCallback); - INIT_WORK(&pwrctrlpriv->rpwm_workitem, rpwm_workitem_callback); - timer_setup(&pwrctrlpriv->rpwm_check_timer, rpwm_check_handler, 0); -} - -/* - * Caller: r8712_cmd_thread - * Check if the fw_pwrstate is okay for issuing cmd. - * If not (cpwm should be is less than P2 state), then the sub-routine - * will raise the cpwm to be greater than or equal to P2. - * Calling Context: Passive - * Return Value: - * 0: r8712_cmd_thread can issue cmds to firmware afterwards. - * -EINVAL: r8712_cmd_thread can not do anything. - */ -int r8712_register_cmd_alive(struct _adapter *padapter) -{ - int res = 0; - struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv; - - mutex_lock(&pwrctrl->mutex_lock); - register_task_alive(pwrctrl, CMD_ALIVE); - if (pwrctrl->cpwm < PS_STATE_S2) { - r8712_set_rpwm(padapter, PS_STATE_S3); - res = -EINVAL; - } - mutex_unlock(&pwrctrl->mutex_lock); - return res; -} - -/* - * Caller: ISR - * If ISR's txdone, - * No more pkts for TX, - * Then driver shall call this fun. to power down firmware again. - */ -void r8712_unregister_cmd_alive(struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv; - - mutex_lock(&pwrctrl->mutex_lock); - unregister_task_alive(pwrctrl, CMD_ALIVE); - if ((pwrctrl->cpwm > PS_STATE_S2) && - (pwrctrl->pwr_mode > PS_MODE_ACTIVE)) { - if ((pwrctrl->alives == 0) && - (check_fwstate(&padapter->mlmepriv, - _FW_UNDER_LINKING) != true)) { - r8712_set_rpwm(padapter, PS_STATE_S0); - } - } - mutex_unlock(&pwrctrl->mutex_lock); -} - -void r8712_flush_rwctrl_works(struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv; - - flush_work(&pwrctrl->SetPSModeWorkItem); - flush_work(&pwrctrl->rpwm_workitem); -} diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h deleted file mode 100644 index b35b9c7920ebbf3eceb252872fd06ff7c176ff40..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h +++ /dev/null @@ -1,113 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_PWRCTRL_H_ -#define __RTL871X_PWRCTRL_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define CMD_ALIVE BIT(2) - -enum Power_Mgnt { - PS_MODE_ACTIVE = 0, - PS_MODE_MIN, - PS_MODE_MAX, - PS_MODE_DTIM, - PS_MODE_VOIP, - PS_MODE_UAPSD_WMM, - PS_MODE_UAPSD, - PS_MODE_IBSS, - PS_MODE_WWLAN, - PM_Radio_Off, - PM_Card_Disable, - PS_MODE_NUM -}; - -/* - * BIT[2:0] = HW state - * BIT[3] = Protocol PS state, 0: register active state, - * 1: register sleep state - * BIT[4] = sub-state - */ - -#define PS_DPS BIT(0) -#define PS_LCLK (PS_DPS) -#define PS_RF_OFF BIT(1) -#define PS_ALL_ON BIT(2) -#define PS_ST_ACTIVE BIT(3) -#define PS_LP BIT(4) /* low performance */ - -#define PS_STATE_MASK (0x0F) -#define PS_STATE_HW_MASK (0x07) -#define PS_SEQ_MASK (0xc0) - -#define PS_STATE(x) (PS_STATE_MASK & (x)) -#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) -#define PS_SEQ(x) (PS_SEQ_MASK & (x)) - -#define PS_STATE_S0 (PS_DPS) -#define PS_STATE_S1 (PS_LCLK) -#define PS_STATE_S2 (PS_RF_OFF) -#define PS_STATE_S3 (PS_ALL_ON) -#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) - -#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) -#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) -#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) - -struct reportpwrstate_parm { - unsigned char mode; - unsigned char state; /* the CPWM value */ - unsigned short rsvd; -}; - -struct pwrctrl_priv { - struct mutex mutex_lock; - /*volatile*/ u8 rpwm; /* requested power state for fw */ - /* fw current power state. updated when 1. read from HCPWM or - * 2. driver lowers power level - */ - /*volatile*/ u8 cpwm; - /*volatile*/ u8 tog; /* toggling */ - /*volatile*/ u8 cpwm_tog; /* toggling */ - /*volatile*/ u8 tgt_rpwm; /* wanted power state */ - uint pwr_mode; - uint smart_ps; - uint alives; - uint ImrContent; /* used to store original imr. */ - uint bSleep; /* sleep -> active is different from active -> sleep. */ - - struct work_struct SetPSModeWorkItem; - struct work_struct rpwm_workitem; - struct timer_list rpwm_check_timer; - u8 rpwm_retry; - uint bSetPSModeWorkItemInProgress; - - spinlock_t pnp_pwr_mgnt_lock; - s32 pnp_current_pwr_state; - u8 pnp_bstop_trx; - u8 pnp_wwirp_pending; -}; - -void r8712_init_pwrctrl_priv(struct _adapter *adapter); -int r8712_register_cmd_alive(struct _adapter *padapter); -void r8712_unregister_cmd_alive(struct _adapter *padapter); -void r8712_cpwm_int_hdl(struct _adapter *padapter, - struct reportpwrstate_parm *preportpwrstate); -void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode, - uint smart_ps); -void r8712_set_rpwm(struct _adapter *padapter, u8 val8); -void r8712_flush_rwctrl_works(struct _adapter *padapter); - -#endif /* __RTL871X_PWRCTRL_H_ */ diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c deleted file mode 100644 index 8a3566214af726ec347772a817b67de545f8a669..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ /dev/null @@ -1,671 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_recv.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_RECV_C_ - -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" -#include "ethernet.h" -#include "usb_ops.h" -#include "wifi.h" - -static const u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; - -/* Datagram Delivery Protocol */ -static const u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; - -void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) -{ - memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); - spin_lock_init(&psta_recvpriv->lock); - _init_queue(&psta_recvpriv->defrag_q); -} - -int _r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter) -{ - int ret; - sint i; - union recv_frame *precvframe; - - memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv)); - spin_lock_init(&precvpriv->lock); - _init_queue(&precvpriv->free_recv_queue); - _init_queue(&precvpriv->recv_pending_queue); - precvpriv->adapter = padapter; - precvpriv->free_recvframe_cnt = NR_RECVFRAME; - precvpriv->pallocated_frame_buf = kzalloc(NR_RECVFRAME * - sizeof(union recv_frame) + RXFRAME_ALIGN_SZ, - GFP_ATOMIC); - if (!precvpriv->pallocated_frame_buf) - return -ENOMEM; - precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + - RXFRAME_ALIGN_SZ - - ((addr_t)(precvpriv->pallocated_frame_buf) & - (RXFRAME_ALIGN_SZ - 1)); - precvframe = (union recv_frame *)precvpriv->precv_frame_buf; - for (i = 0; i < NR_RECVFRAME; i++) { - INIT_LIST_HEAD(&(precvframe->u.list)); - list_add_tail(&(precvframe->u.list), - &(precvpriv->free_recv_queue.queue)); - r8712_os_recv_resource_alloc(padapter, precvframe); - precvframe->u.hdr.adapter = padapter; - precvframe++; - } - precvpriv->rx_pending_cnt = 1; - ret = r8712_init_recv_priv(precvpriv, padapter); - if (ret) - kfree(precvpriv->pallocated_frame_buf); - - return ret; -} - -void _r8712_free_recv_priv(struct recv_priv *precvpriv) -{ - kfree(precvpriv->pallocated_frame_buf); - r8712_free_recv_priv(precvpriv); -} - -union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue) -{ - unsigned long irqL; - union recv_frame *precvframe; - struct _adapter *padapter; - struct recv_priv *precvpriv; - - spin_lock_irqsave(&pfree_recv_queue->lock, irqL); - precvframe = list_first_entry_or_null(&pfree_recv_queue->queue, - union recv_frame, u.hdr.list); - if (precvframe) { - list_del_init(&precvframe->u.hdr.list); - padapter = precvframe->u.hdr.adapter; - if (padapter) { - precvpriv = &padapter->recvpriv; - if (pfree_recv_queue == &precvpriv->free_recv_queue) - precvpriv->free_recvframe_cnt--; - } - } - spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL); - return precvframe; -} - -/* - * caller : defrag; recvframe_chk_defrag in recv_thread (passive) - * pframequeue: defrag_queue : will be accessed in recv_thread (passive) - * using spin_lock to protect - */ -void r8712_free_recvframe_queue(struct __queue *pframequeue, - struct __queue *pfree_recv_queue) -{ - union recv_frame *precvframe; - struct list_head *plist, *phead; - - spin_lock(&pframequeue->lock); - phead = &pframequeue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - precvframe = container_of(plist, union recv_frame, u.list); - plist = plist->next; - r8712_free_recvframe(precvframe, pfree_recv_queue); - } - spin_unlock(&pframequeue->lock); -} - -sint r8712_recvframe_chkmic(struct _adapter *adapter, - union recv_frame *precvframe) -{ - sint i, res = _SUCCESS; - u32 datalen; - u8 miccode[8]; - u8 bmic_err = false; - u8 *pframe, *payload, *pframemic; - u8 *mickey, idx, *iv; - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - stainfo = r8712_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); - if (prxattrib->encrypt == _TKIP_) { - /* calculate mic code */ - if (stainfo) { - if (is_multicast_ether_addr(prxattrib->ra)) { - iv = precvframe->u.hdr.rx_data + - prxattrib->hdrlen; - idx = iv[3]; - mickey = &psecuritypriv->XGrprxmickey[(((idx >> - 6) & 0x3)) - 1].skey[0]; - if (!psecuritypriv->binstallGrpkey) - return _FAIL; - } else { - mickey = &stainfo->tkiprxmickey.skey[0]; - } - /*icv_len included the mic code*/ - datalen = precvframe->u.hdr.len - prxattrib->hdrlen - - prxattrib->iv_len - prxattrib->icv_len - 8; - pframe = precvframe->u.hdr.rx_data; - payload = pframe + prxattrib->hdrlen + - prxattrib->iv_len; - seccalctkipmic(mickey, pframe, payload, datalen, - &miccode[0], - (unsigned char)prxattrib->priority); - pframemic = payload + datalen; - bmic_err = false; - for (i = 0; i < 8; i++) { - if (miccode[i] != *(pframemic + i)) - bmic_err = true; - } - if (bmic_err) { - if (prxattrib->bdecrypted) - r8712_handle_tkip_mic_err(adapter, - (u8)is_multicast_ether_addr(prxattrib->ra)); - res = _FAIL; - } else { - /* mic checked ok */ - if (!psecuritypriv->bcheck_grpkey && - is_multicast_ether_addr(prxattrib->ra)) - psecuritypriv->bcheck_grpkey = true; - } - recvframe_pull_tail(precvframe, 8); - } - } - return res; -} - -/* decrypt and set the ivlen,icvlen of the recv_frame */ -union recv_frame *r8712_decryptor(struct _adapter *padapter, - union recv_frame *precv_frame) -{ - struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - union recv_frame *return_packet = precv_frame; - - if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || - psecuritypriv->sw_decrypt)) { - psecuritypriv->hw_decrypted = false; - switch (prxattrib->encrypt) { - case _WEP40_: - case _WEP104_: - r8712_wep_decrypt(padapter, (u8 *)precv_frame); - break; - case _TKIP_: - r8712_tkip_decrypt(padapter, (u8 *)precv_frame); - break; - case _AES_: - r8712_aes_decrypt(padapter, (u8 *)precv_frame); - break; - default: - break; - } - } else if (prxattrib->bdecrypted == 1) { - psecuritypriv->hw_decrypted = true; - } - return return_packet; -} - -/*###set the security information in the recv_frame */ -union recv_frame *r8712_portctrl(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - u8 *psta_addr, *ptr; - uint auth_alg; - struct recv_frame_hdr *pfhdr; - struct sta_info *psta; - struct sta_priv *pstapriv; - union recv_frame *prtnframe; - u16 ether_type; - - pstapriv = &adapter->stapriv; - ptr = precv_frame->u.hdr.rx_data; - pfhdr = &precv_frame->u.hdr; - psta_addr = pfhdr->attrib.ta; - psta = r8712_get_stainfo(pstapriv, psta_addr); - auth_alg = adapter->securitypriv.AuthAlgrthm; - if (auth_alg == 2) { - /* get ether_type */ - ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; - ether_type = get_unaligned_be16(ptr); - - if (psta && psta->ieee8021x_blocked) { - /* blocked - * only accept EAPOL frame - */ - if (ether_type == 0x888e) { - prtnframe = precv_frame; - } else { - /*free this frame*/ - r8712_free_recvframe(precv_frame, - &adapter->recvpriv.free_recv_queue); - prtnframe = NULL; - } - } else { - /* allowed - * check decryption status, and decrypt the - * frame if needed - */ - prtnframe = precv_frame; - /* check is the EAPOL frame or not (Rekey) */ - if (ether_type == 0x888e) { - /* check Rekey */ - prtnframe = precv_frame; - } - } - } else { - prtnframe = precv_frame; - } - return prtnframe; -} - -static sint recv_decache(union recv_frame *precv_frame, u8 bretry, - struct stainfo_rxcache *prxcache) -{ - sint tid = precv_frame->u.hdr.attrib.priority; - u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) | - (precv_frame->u.hdr.attrib.frag_num & 0xf); - - if (tid > 15) - return _FAIL; - if (seq_ctrl == prxcache->tid_rxseq[tid]) - return _FAIL; - prxcache->tid_rxseq[tid] = seq_ctrl; - return _SUCCESS; -} - -static sint sta2sta_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta) -{ - u8 *ptr = precv_frame->u.hdr.rx_data; - sint ret = _SUCCESS; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *mybssid = get_bssid(pmlmepriv); - u8 *myhwaddr = myid(&adapter->eeprompriv); - u8 *sta_addr = NULL; - bool bmcast = is_multicast_ether_addr(pattrib->dst); - - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - /* filter packets that SA is myself or multicast or broadcast */ - if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) - return _FAIL; - if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) - return _FAIL; - if (is_zero_ether_addr(pattrib->bssid) || - is_zero_ether_addr(mybssid) || - (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) - return _FAIL; - sta_addr = pattrib->src; - } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - /* For Station mode, sa and bssid should always be BSSID, - * and DA is my mac-address - */ - if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) - return _FAIL; - sta_addr = pattrib->bssid; - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - if (bmcast) { - /* For AP mode, if DA == MCAST, then BSSID should - * be also MCAST - */ - if (!is_multicast_ether_addr(pattrib->bssid)) - return _FAIL; - } else { /* not mc-frame */ - /* For AP mode, if DA is non-MCAST, then it must be - * BSSID, and bssid == BSSID - */ - if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) - return _FAIL; - sta_addr = pattrib->src; - } - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); - memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - sta_addr = mybssid; - } else { - ret = _FAIL; - } - if (bmcast) - *psta = r8712_get_bcmc_stainfo(adapter); - else - *psta = r8712_get_stainfo(pstapriv, sta_addr); /* get ap_info */ - if (!*psta) { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - adapter->mppriv.rx_pktloss++; - return _FAIL; - } - return ret; -} - -static sint ap2sta_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta) -{ - u8 *ptr = precv_frame->u.hdr.rx_data; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *mybssid = get_bssid(pmlmepriv); - u8 *myhwaddr = myid(&adapter->eeprompriv); - bool bmcast = is_multicast_ether_addr(pattrib->dst); - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && - check_fwstate(pmlmepriv, _FW_LINKED)) { - /* if NULL-frame, drop packet */ - if ((GetFrameSubType(ptr)) == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC)) - return _FAIL; - /* drop QoS-SubType Data, including QoS NULL, - * excluding QoS-Data - */ - if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == - WIFI_QOS_DATA_TYPE) { - if (GetFrameSubType(ptr) & (BIT(4) | BIT(5) | BIT(6))) - return _FAIL; - } - - /* filter packets that SA is myself or multicast or broadcast */ - if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) - return _FAIL; - - /* da should be for me */ - if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) - return _FAIL; - /* check BSSID */ - if (is_zero_ether_addr(pattrib->bssid) || - is_zero_ether_addr(mybssid) || - (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) - return _FAIL; - if (bmcast) - *psta = r8712_get_bcmc_stainfo(adapter); - else - *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); - if (!*psta) - return _FAIL; - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && - check_fwstate(pmlmepriv, _FW_LINKED)) { - memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); - memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - memcpy(pattrib->bssid, mybssid, ETH_ALEN); - *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); - if (!*psta) - return _FAIL; - } else { - return _FAIL; - } - return _SUCCESS; -} - -static sint sta2ap_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta) -{ - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - unsigned char *mybssid = get_bssid(pmlmepriv); - - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - /* For AP mode, if DA is non-MCAST, then it must be BSSID, - * and bssid == BSSID - * For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR - */ - if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) - return _FAIL; - *psta = r8712_get_stainfo(pstapriv, pattrib->src); - if (!*psta) - return _FAIL; - } - return _SUCCESS; -} - -static sint validate_recv_ctrl_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - return _FAIL; -} - -static sint validate_recv_mgnt_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - return _FAIL; -} - -static sint validate_recv_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - int res; - u8 bretry; - u8 *psa, *pda, *pbssid; - struct sta_info *psta = NULL; - u8 *ptr = precv_frame->u.hdr.rx_data; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - bretry = GetRetry(ptr); - pda = ieee80211_get_DA((struct ieee80211_hdr *)ptr); - psa = ieee80211_get_SA((struct ieee80211_hdr *)ptr); - pbssid = get_hdr_bssid(ptr); - if (!pbssid) - return _FAIL; - memcpy(pattrib->dst, pda, ETH_ALEN); - memcpy(pattrib->src, psa, ETH_ALEN); - memcpy(pattrib->bssid, pbssid, ETH_ALEN); - switch (pattrib->to_fr_ds) { - case 0: - memcpy(pattrib->ra, pda, ETH_ALEN); - memcpy(pattrib->ta, psa, ETH_ALEN); - res = sta2sta_data_frame(adapter, precv_frame, &psta); - break; - case 1: - memcpy(pattrib->ra, pda, ETH_ALEN); - memcpy(pattrib->ta, pbssid, ETH_ALEN); - res = ap2sta_data_frame(adapter, precv_frame, &psta); - break; - case 2: - memcpy(pattrib->ra, pbssid, ETH_ALEN); - memcpy(pattrib->ta, psa, ETH_ALEN); - res = sta2ap_data_frame(adapter, precv_frame, &psta); - break; - case 3: - memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); - return _FAIL; - default: - return _FAIL; - } - if (res == _FAIL) - return _FAIL; - if (!psta) - return _FAIL; - precv_frame->u.hdr.psta = psta; - pattrib->amsdu = 0; - /* parsing QC field */ - if (pattrib->qos == 1) { - pattrib->priority = GetPriority((ptr + 24)); - pattrib->ack_policy = GetAckpolicy((ptr + 24)); - pattrib->amsdu = GetAMsdu((ptr + 24)); - pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26; - } else { - pattrib->priority = 0; - pattrib->hdrlen = (pattrib->to_fr_ds == 3) ? 30 : 24; - } - - if (pattrib->order)/*HT-CTRL 11n*/ - pattrib->hdrlen += 4; - precv_frame->u.hdr.preorder_ctrl = - &psta->recvreorder_ctrl[pattrib->priority]; - - /* decache, drop duplicate recv packets */ - if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == - _FAIL) - return _FAIL; - - if (pattrib->privacy) { - GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, - is_multicast_ether_addr(pattrib->ra)); - SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, - pattrib->encrypt); - } else { - pattrib->encrypt = 0; - pattrib->iv_len = pattrib->icv_len = 0; - } - return _SUCCESS; -} - -sint r8712_validate_recv_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - /*shall check frame subtype, to / from ds, da, bssid */ - /*then call check if rx seq/frag. duplicated.*/ - - u8 type; - u8 subtype; - sint retval = _SUCCESS; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - - u8 *ptr = precv_frame->u.hdr.rx_data; - u8 ver = (unsigned char)(*ptr) & 0x3; - - /*add version chk*/ - if (ver != 0) - return _FAIL; - type = GetFrameType(ptr); - subtype = GetFrameSubType(ptr); /*bit(7)~bit(2)*/ - pattrib->to_fr_ds = get_tofr_ds(ptr); - pattrib->frag_num = GetFragNum(ptr); - pattrib->seq_num = GetSequence(ptr); - pattrib->pw_save = GetPwrMgt(ptr); - pattrib->mfrag = GetMFrag(ptr); - pattrib->mdata = GetMData(ptr); - pattrib->privacy = GetPrivacy(ptr); - pattrib->order = GetOrder(ptr); - switch (type) { - case IEEE80211_FTYPE_MGMT: - retval = validate_recv_mgnt_frame(adapter, precv_frame); - break; - case IEEE80211_FTYPE_CTL: - retval = validate_recv_ctrl_frame(adapter, precv_frame); - break; - case IEEE80211_FTYPE_DATA: - pattrib->qos = (subtype & BIT(7)) ? 1 : 0; - retval = validate_recv_data_frame(adapter, precv_frame); - break; - default: - return _FAIL; - } - return retval; -} - -int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) -{ - /*remove the wlanhdr and add the eth_hdr*/ - sint rmv_len; - u16 len; - u8 bsnaphdr; - u8 *psnap_type; - struct ieee80211_snap_hdr *psnap; - struct _adapter *adapter = precvframe->u.hdr.adapter; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - u8 *ptr = precvframe->u.hdr.rx_data; /*point to frame_ctrl field*/ - struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; - - if (pattrib->encrypt) - recvframe_pull_tail(precvframe, pattrib->icv_len); - psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + - pattrib->iv_len); - psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; - /* convert hdr + possible LLC headers into Ethernet header */ - if ((!memcmp(psnap, (void *)rfc1042_header, SNAP_SIZE) && - (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_IPX, 2)) && - (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_APPLETALK_AARP, 2))) || - !memcmp(psnap, (void *)bridge_tunnel_header, SNAP_SIZE)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType - */ - bsnaphdr = true; - } else { - /* Leave Ethernet header part of hdr and full payload */ - bsnaphdr = false; - } - rmv_len = pattrib->hdrlen + pattrib->iv_len + - (bsnaphdr ? SNAP_SIZE : 0); - len = precvframe->u.hdr.len - rmv_len; - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - ptr += rmv_len; - *ptr = 0x87; - *(ptr + 1) = 0x12; - /* append rx status for mp test packets */ - ptr = recvframe_pull(precvframe, (rmv_len - - sizeof(struct ethhdr) + 2) - 24); - if (!ptr) - return -ENOMEM; - memcpy(ptr, get_rxmem(precvframe), 24); - ptr += 24; - } else { - ptr = recvframe_pull(precvframe, (rmv_len - - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - if (!ptr) - return -ENOMEM; - } - - memcpy(ptr, pattrib->dst, ETH_ALEN); - memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); - if (!bsnaphdr) { - __be16 be_tmp = htons(len); - - memcpy(ptr + 12, &be_tmp, 2); - } - return 0; -} - -void r8712_recv_entry(union recv_frame *precvframe) -{ - struct _adapter *padapter; - struct recv_priv *precvpriv; - - s32 ret = _SUCCESS; - - padapter = precvframe->u.hdr.adapter; - precvpriv = &(padapter->recvpriv); - - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX); - - ret = recv_func(padapter, precvframe); - if (ret == _FAIL) - goto _recv_entry_drop; - precvpriv->rx_pkts++; - precvpriv->rx_bytes += (uint)(precvframe->u.hdr.rx_tail - - precvframe->u.hdr.rx_data); - return; -_recv_entry_drop: - precvpriv->rx_drop++; - padapter->mppriv.rx_pktloss = precvpriv->rx_drop; -} diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h deleted file mode 100644 index 0760bccbf389c131b0b802c49c1bdbd239b1a353..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ /dev/null @@ -1,208 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _RTL871X_RECV_H_ -#define _RTL871X_RECV_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define NR_RECVFRAME 256 - -#define RXFRAME_ALIGN 8 -#define RXFRAME_ALIGN_SZ (1 << RXFRAME_ALIGN) - -#define MAX_SUBFRAME_COUNT 64 - -/* for Rx reordering buffer control */ -struct recv_reorder_ctrl { - struct _adapter *padapter; - u16 indicate_seq; /* =wstart_b, init_value=0xffff */ - u16 wend_b; - u8 wsize_b; - struct __queue pending_recvframe_queue; - struct timer_list reordering_ctrl_timer; -}; - -struct stainfo_rxcache { - u16 tid_rxseq[16]; -}; - -#define PHY_RSSI_SLID_WIN_MAX 100 -#define PHY_LINKQUALITY_SLID_WIN_MAX 20 - -struct smooth_rssi_data { - u32 elements[100]; /* array to store values */ - u32 index; /* index to current array to store */ - u32 total_num; /* num of valid elements */ - u32 total_val; /* sum of valid elements */ -}; - -struct rx_pkt_attrib { - u8 amsdu; - u8 order; - u8 qos; - u8 to_fr_ds; - u8 frag_num; - u16 seq_num; - u8 pw_save; - u8 mfrag; - u8 mdata; - u8 privacy; /* in frame_ctrl field */ - u8 bdecrypted; - int hdrlen; /* the WLAN Header Len */ - int encrypt; /* 0 no encrypt. != 0 encrypt algorithm */ - int iv_len; - int icv_len; - int priority; - int ack_policy; - u8 crc_err; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 ta[ETH_ALEN]; - u8 ra[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - u8 tcpchk_valid; /* 0: invalid, 1: valid */ - u8 ip_chkrpt; /* 0: incorrect, 1: correct */ - u8 tcp_chkrpt; /* 0: incorrect, 1: correct */ - u8 signal_qual; - s8 rx_mimo_signal_qual[2]; - u8 mcs_rate; - u8 htc; - u8 signal_strength; -}; - -/* - * accesser of recv_priv: recv_entry(dispatch / passive level); - * recv_thread(passive) ; returnpkt(dispatch) - * ; halt(passive) ; - * - * using enter_critical section to protect - */ -struct recv_priv { - spinlock_t lock; - struct __queue free_recv_queue; - struct __queue recv_pending_queue; - u8 *pallocated_frame_buf; - u8 *precv_frame_buf; - uint free_recvframe_cnt; - struct _adapter *adapter; - uint rx_bytes; - uint rx_pkts; - uint rx_drop; - uint rx_icv_err; - uint rx_largepacket_crcerr; - uint rx_smallpacket_crcerr; - uint rx_middlepacket_crcerr; - u8 rx_pending_cnt; - uint ff_hwaddr; - struct tasklet_struct recv_tasklet; - struct sk_buff_head free_recv_skb_queue; - struct sk_buff_head rx_skb_queue; - u8 *pallocated_recv_buf; - u8 *precv_buf; /* 4 alignment */ - struct __queue free_recv_buf_queue; - u32 free_recv_buf_queue_cnt; - /* For the phy information */ - s8 rssi; - u8 signal; - u8 noise; - u8 fw_rssi; - struct smooth_rssi_data signal_qual_data; - struct smooth_rssi_data signal_strength_data; -}; - -struct sta_recv_priv { - spinlock_t lock; - sint option; - struct __queue defrag_q; /* keeping the fragment frame until defrag */ - struct stainfo_rxcache rxcache; - uint sta_rx_bytes; - uint sta_rx_pkts; - uint sta_rx_fail; -}; - -#include "rtl8712_recv.h" - -/* get a free recv_frame from pfree_recv_queue */ -union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue); -void r8712_free_recvframe(union recv_frame *precvframe, - struct __queue *pfree_recv_queue); -void r8712_free_recvframe_queue(struct __queue *pframequeue, - struct __queue *pfree_recv_queue); -int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe); -int recv_func(struct _adapter *padapter, void *pcontext); - -static inline u8 *get_rxmem(union recv_frame *precvframe) -{ - /* always return rx_head... */ - if (!precvframe) - return NULL; - return precvframe->u.hdr.rx_head; -} - -static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz) -{ - /* used for extract sz bytes from rx_data, update rx_data and return - * the updated rx_data to the caller - */ - if (!precvframe) - return NULL; - precvframe->u.hdr.rx_data += sz; - if (precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) { - precvframe->u.hdr.rx_data -= sz; - return NULL; - } - precvframe->u.hdr.len -= sz; - return precvframe->u.hdr.rx_data; -} - -static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz) -{ - /* used for append sz bytes from ptr to rx_tail, update rx_tail and - * return the updated rx_tail to the caller - * after putting, rx_tail must be still larger than rx_end. - */ - if (!precvframe) - return NULL; - precvframe->u.hdr.rx_tail += sz; - if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) { - precvframe->u.hdr.rx_tail -= sz; - return NULL; - } - precvframe->u.hdr.len += sz; - return precvframe->u.hdr.rx_tail; -} - -static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) -{ - /* rmv data from rx_tail (by yitsen) - * used for extract sz bytes from rx_end, update rx_end and return the - * updated rx_end to the caller - * after pulling, rx_end must be still larger than rx_data. - */ - if (!precvframe) - return NULL; - precvframe->u.hdr.rx_tail -= sz; - if (precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) { - precvframe->u.hdr.rx_tail += sz; - return NULL; - } - precvframe->u.hdr.len -= sz; - return precvframe->u.hdr.rx_tail; -} - -struct sta_info; - -void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); -sint r8712_recvframe_chkmic(struct _adapter *adapter, - union recv_frame *precvframe); -union recv_frame *r8712_decryptor(struct _adapter *adapter, - union recv_frame *precv_frame); -union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *adapter, - union recv_frame *precv_frame); -int r8712_validate_recv_frame(struct _adapter *adapter, - union recv_frame *precv_frame); -union recv_frame *r8712_portctrl(struct _adapter *adapter, - union recv_frame *precv_frame); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_rf.h b/drivers/staging/rtl8712/rtl871x_rf.h deleted file mode 100644 index 7d98921a48fac022b7f456b423375ed3bc5a96cf..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_rf.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_RF_H_ -#define __RTL871X_RF_H_ - -#include "rtl871x_cmd.h" -#include "rtl871x_mp_phy_regdef.h" - -#define OFDM_PHY 1 -#define MIXED_PHY 2 -#define CCK_PHY 3 -#define NumRates (13) -#define RTL8711_RF_MAX_SENS 6 -#define RTL8711_RF_DEF_SENS 4 -#define NUM_CHANNELS 15 - -struct regulatory_class { - u32 starting_freq; /*MHz, */ - u8 channel_set[NUM_CHANNELS]; - u8 channel_cck_power[NUM_CHANNELS]; /*dbm*/ - u8 channel_ofdm_power[NUM_CHANNELS];/*dbm*/ - u8 txpower_limit; /*dbm*/ - u8 channel_spacing; /*MHz*/ - u8 modem; -}; - -enum _REG_PREAMBLE_MODE { - PREAMBLE_LONG = 1, - PREAMBLE_AUTO = 2, - PREAMBLE_SHORT = 3, -}; - -enum { - RTL8712_RFC_1T = 0x10, - RTL8712_RFC_2T = 0x20, - RTL8712_RFC_1R = 0x01, - RTL8712_RFC_2R = 0x02, - RTL8712_RFC_1T1R = 0x11, - RTL8712_RFC_1T2R = 0x12, - RTL8712_RFC_TURBO = 0x92, - RTL8712_RFC_2T2R = 0x22 -}; - -#endif /*__RTL871X_RF_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c deleted file mode 100644 index e46a5dbc7b65fa53108ff5f8834cc5873cc27704..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ /dev/null @@ -1,1386 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_security.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_SECURITY_C_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" - -/* =====WEP related===== */ - -struct arc4context { - u32 x; - u32 y; - u8 state[256]; -}; - -static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) -{ - u32 t, u; - u32 keyindex; - u32 stateindex; - u8 *state; - u32 counter; - - state = parc4ctx->state; - parc4ctx->x = 0; - parc4ctx->y = 0; - for (counter = 0; counter < 256; counter++) - state[counter] = (u8)counter; - keyindex = 0; - stateindex = 0; - for (counter = 0; counter < 256; counter++) { - t = state[counter]; - stateindex = (stateindex + key[keyindex] + t) & 0xff; - u = state[stateindex]; - state[stateindex] = (u8)t; - state[counter] = (u8)u; - if (++keyindex >= key_len) - keyindex = 0; - } -} - -static u32 arcfour_byte(struct arc4context *parc4ctx) -{ - u32 x; - u32 y; - u32 sx, sy; - u8 *state; - - state = parc4ctx->state; - x = (parc4ctx->x + 1) & 0xff; - sx = state[x]; - y = (sx + parc4ctx->y) & 0xff; - sy = state[y]; - parc4ctx->x = x; - parc4ctx->y = y; - state[y] = (u8)sx; - state[x] = (u8)sy; - return state[(sx + sy) & 0xff]; -} - -static void arcfour_encrypt(struct arc4context *parc4ctx, - u8 *dest, u8 *src, u32 len) -{ - u32 i; - - for (i = 0; i < len; i++) - dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx); -} - -static sint bcrc32initialized; -static u32 crc32_table[256]; - -static u8 crc32_reverseBit(u8 data) -{ - return ((u8)(data << 7) & 0x80) | ((data << 5) & 0x40) | ((data << 3) - & 0x20) | ((data << 1) & 0x10) | ((data >> 1) & 0x08) | - ((data >> 3) & 0x04) | ((data >> 5) & 0x02) | ((data >> 7) & - 0x01); -} - -static void crc32_init(void) -{ - sint i, j; - u32 c; - u8 *p = (u8 *)&c, *p1; - u8 k; - - if (bcrc32initialized == 1) - return; - - for (i = 0; i < 256; ++i) { - k = crc32_reverseBit((u8)i); - for (c = ((u32)k) << 24, j = 8; j > 0; --j) - c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY_BE : (c << 1); - p1 = (u8 *)&crc32_table[i]; - p1[0] = crc32_reverseBit(p[3]); - p1[1] = crc32_reverseBit(p[2]); - p1[2] = crc32_reverseBit(p[1]); - p1[3] = crc32_reverseBit(p[0]); - } - bcrc32initialized = 1; -} - -static u32 getcrc32(u8 *buf, u32 len) -{ - u8 *p; - u32 crc; - - if (!bcrc32initialized) - crc32_init(); - crc = 0xffffffff; /* preload shift register, per CRC-32 spec */ - for (p = buf; len > 0; ++p, --len) - crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8); - return ~crc; /* transmit complement, per CRC-32 spec */ -} - -/* - * Need to consider the fragment situation - */ -void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) -{ /* exclude ICV */ - unsigned char crc[4]; - struct arc4context mycontext; - u32 curfragnum, length, keylength, pki; - u8 *pframe, *payload, *iv; /*,*wepkey*/ - u8 wepkey[16]; - struct pkt_attrib *pattrib = &((struct xmit_frame *) - pxmitframe)->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) - return; - pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; - /*start to encrypt each fragment*/ - if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) { - pki = psecuritypriv->PrivacyKeyIndex; - keylength = psecuritypriv->DefKeylen[pki]; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - iv = pframe + pattrib->hdrlen; - memcpy(&wepkey[0], iv, 3); - memcpy(&wepkey[3], &psecuritypriv->DefKey[ - psecuritypriv->PrivacyKeyIndex].skey[0], - keylength); - payload = pframe + pattrib->iv_len + pattrib->hdrlen; - if ((curfragnum + 1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32(getcrc32( - payload, length)); - arcfour_init(&mycontext, wepkey, 3 + keylength); - arcfour_encrypt(&mycontext, payload, payload, - length); - arcfour_encrypt(&mycontext, payload + length, - crc, 4); - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32(getcrc32( - payload, length)); - arcfour_init(&mycontext, wepkey, 3 + keylength); - arcfour_encrypt(&mycontext, payload, payload, - length); - arcfour_encrypt(&mycontext, payload + length, - crc, 4); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((addr_t)(pframe)); - } - } - } -} - -void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe) -{ - /* exclude ICV */ - u8 crc[4]; - struct arc4context mycontext; - u32 length, keylength; - u8 *pframe, *payload, *iv, wepkey[16]; - u8 keyindex; - struct rx_pkt_attrib *prxattrib = &(((union recv_frame *) - precvframe)->u.hdr.attrib); - struct security_priv *psecuritypriv = &padapter->securitypriv; - - pframe = (unsigned char *)((union recv_frame *)precvframe)-> - u.hdr.rx_data; - /* start to decrypt recvframe */ - if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == - _WEP104_)) { - iv = pframe + prxattrib->hdrlen; - keyindex = (iv[3] & 0x3); - keylength = psecuritypriv->DefKeylen[keyindex]; - memcpy(&wepkey[0], iv, 3); - memcpy(&wepkey[3], &psecuritypriv->DefKey[ - psecuritypriv->PrivacyKeyIndex].skey[0], - keylength); - length = ((union recv_frame *)precvframe)-> - u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len; - payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; - /* decrypt payload include icv */ - arcfour_init(&mycontext, wepkey, 3 + keylength); - arcfour_encrypt(&mycontext, payload, payload, length); - /* calculate icv and compare the icv */ - *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4)); - } -} - -/* 3 =====TKIP related===== */ - -static u32 secmicgetuint32(u8 *p) -/* Convert from Byte[] to Us4Byte32 in a portable way */ -{ - s32 i; - u32 res = 0; - - for (i = 0; i < 4; i++) - res |= ((u32)(*p++)) << (8 * i); - return res; -} - -static void secmicputuint32(u8 *p, u32 val) -/* Convert from Us4Byte32 to Byte[] in a portable way */ -{ - long i; - - for (i = 0; i < 4; i++) { - *p++ = (u8)(val & 0xff); - val >>= 8; - } -} - -static void secmicclear(struct mic_data *pmicdata) -{ -/* Reset the state to the empty message. */ - pmicdata->L = pmicdata->K0; - pmicdata->R = pmicdata->K1; - pmicdata->nBytesInM = 0; - pmicdata->M = 0; -} - -void r8712_secmicsetkey(struct mic_data *pmicdata, u8 *key) -{ - /* Set the key */ - pmicdata->K0 = secmicgetuint32(key); - pmicdata->K1 = secmicgetuint32(key + 4); - /* and reset the message */ - secmicclear(pmicdata); -} - -static void secmicappendbyte(struct mic_data *pmicdata, u8 b) -{ - /* Append the byte to our word-sized buffer */ - pmicdata->M |= ((u32)b) << (8 * pmicdata->nBytesInM); - pmicdata->nBytesInM++; - /* Process the word if it is full. */ - if (pmicdata->nBytesInM >= 4) { - pmicdata->L ^= pmicdata->M; - pmicdata->R ^= ROL32(pmicdata->L, 17); - pmicdata->L += pmicdata->R; - pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | - ((pmicdata->L & 0x00ff00ff) << 8); - pmicdata->L += pmicdata->R; - pmicdata->R ^= ROL32(pmicdata->L, 3); - pmicdata->L += pmicdata->R; - pmicdata->R ^= ROR32(pmicdata->L, 2); - pmicdata->L += pmicdata->R; - /* Clear the buffer */ - pmicdata->M = 0; - pmicdata->nBytesInM = 0; - } -} - -void r8712_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes) -{ - /* This is simple */ - while (nbytes > 0) { - secmicappendbyte(pmicdata, *src++); - nbytes--; - } -} - -void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst) -{ - /* Append the minimum padding */ - secmicappendbyte(pmicdata, 0x5a); - secmicappendbyte(pmicdata, 0); - secmicappendbyte(pmicdata, 0); - secmicappendbyte(pmicdata, 0); - secmicappendbyte(pmicdata, 0); - /* and then zeroes until the length is a multiple of 4 */ - while (pmicdata->nBytesInM != 0) - secmicappendbyte(pmicdata, 0); - /* The appendByte function has already computed the result. */ - secmicputuint32(dst, pmicdata->L); - secmicputuint32(dst + 4, pmicdata->R); - /* Reset to the empty message. */ - secmicclear(pmicdata); -} - -void seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, - u8 pri) -{ - - struct mic_data micdata; - u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; - - r8712_secmicsetkey(&micdata, key); - priority[0] = pri; - /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ - if (header[1] & 1) { /* ToDS==1 */ - r8712_secmicappend(&micdata, &header[16], 6); /* DA */ - if (header[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, &header[24], 6); - else - r8712_secmicappend(&micdata, &header[10], 6); - } else { /* ToDS==0 */ - r8712_secmicappend(&micdata, &header[4], 6); /* DA */ - if (header[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, &header[16], 6); - else - r8712_secmicappend(&micdata, &header[10], 6); - } - r8712_secmicappend(&micdata, &priority[0], 4); - r8712_secmicappend(&micdata, data, data_len); - r8712_secgetmic(&micdata, mic_code); -} - -/* macros for extraction/creation of unsigned char/unsigned short values */ -#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) -#define Lo8(v16) ((u8)((v16) & 0x00FF)) -#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF)) -#define Lo16(v32) ((u16)((v32) & 0xFFFF)) -#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF)) -#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8)) - -/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */ -#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)]) - -/* S-box lookup: 16 bits --> 16 bits */ -#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)]) - -/* fixed algorithm "parameters" */ -#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */ -#define TA_SIZE 6 /* 48-bit transmitter address */ -#define TK_SIZE 16 /* 128-bit temporal key */ -#define P1K_SIZE 10 /* 80-bit Phase1 key */ -#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */ - -/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ -static const unsigned short Sbox1[2][256] = {/* Sbox for hash (can be in ROM) */ - { - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, - }, - { /* second half is unsigned char-reversed version of first! */ - 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, - 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, - 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, - 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, - 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, - 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, - 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, - 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, - 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, - 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, - 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, - 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, - 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, - 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, - 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, - 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, - 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, - 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, - 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, - 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, - 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, - 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, - 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, - 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, - 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, - 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, - 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, - 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, - 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, - 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, - 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, - 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C, - } -}; - -/* - ********************************************************************** - * Routine: Phase 1 -- generate P1K, given TA, TK, IV32 - * - * Inputs: - * tk[] = temporal key [128 bits] - * ta[] = transmitter's MAC address [ 48 bits] - * iv32 = upper 32 bits of IV [ 32 bits] - * Output: - * p1k[] = Phase 1 key [ 80 bits] - * - * Note: - * This function only needs to be called every 2**16 packets, - * although in theory it could be called every packet. - * - ********************************************************************** - */ -static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32) -{ - sint i; - - /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */ - p1k[0] = Lo16(iv32); - p1k[1] = Hi16(iv32); - p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */ - p1k[3] = Mk16(ta[3], ta[2]); - p1k[4] = Mk16(ta[5], ta[4]); - /* Now compute an unbalanced Feistel cipher with 80-bit block */ - /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ - for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add is mod 2**16 */ - p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0)); - p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2)); - p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4)); - p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6)); - p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0)); - p1k[4] += (unsigned short)i; /* avoid "slide attacks" */ - } -} - -/* - ********************************************************************** - * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 - * - * Inputs: - * tk[] = Temporal key [128 bits] - * p1k[] = Phase 1 output key [ 80 bits] - * iv16 = low 16 bits of IV counter [ 16 bits] - * Output: - * rc4key[] = the key used to encrypt the packet [128 bits] - * - * Note: - * The value {TA,IV32,IV16} for Phase1/Phase2 must be unique - * across all packets using the same key TK value. Then, for a - * given value of TK[], this TKIP48 construction guarantees that - * the final RC4KEY value is unique across all packets. - * - * Suggested implementation optimization: if PPK[] is "overlaid" - * appropriately on RC4KEY[], there is no need for the final - * for loop below that copies the PPK[] result into RC4KEY[]. - * - ********************************************************************** - */ -static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16) -{ - sint i; - u16 PPK[6]; /* temporary key for mixing */ - - /* Note: all adds in the PPK[] equations below are mod 2**16 */ - for (i = 0; i < 5; i++) - PPK[i] = p1k[i]; /* first, copy P1K to PPK */ - PPK[5] = p1k[4] + iv16; /* next, add in IV16 */ - /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */ - PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */ - PPK[1] += _S_(PPK[0] ^ TK16(1)); - PPK[2] += _S_(PPK[1] ^ TK16(2)); - PPK[3] += _S_(PPK[2] ^ TK16(3)); - PPK[4] += _S_(PPK[3] ^ TK16(4)); - PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */ - /* Final sweep: bijective, "linear". Rotates kill LSB correlations */ - PPK[0] += RotR1(PPK[5] ^ TK16(6)); - PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */ - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - /* Note: At this point, for a given key TK[0..15], the 96-bit output */ - /* value PPK[0..5] is guaranteed to be unique, as a function */ - /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */ - /* is now a keyed permutation of {TA,IV32,IV16}. */ - /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */ - rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */ - rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */ - rc4key[2] = Lo8(iv16); - rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); - /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ - for (i = 0; i < 6; i++) { - rc4key[4 + 2 * i] = Lo8(PPK[i]); - rc4key[5 + 2 * i] = Hi8(PPK[i]); - } -} - -/*The hlen isn't include the IV*/ -u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) -{ /* exclude ICV */ - u16 pnl; - u32 pnh; - u8 rc4key[16]; - u8 ttkey[16]; - u8 crc[4]; - struct arc4context mycontext; - u32 curfragnum, length; - - u8 *pframe, *payload, *iv, *prwskey; - union pn48 txpn; - struct sta_info *stainfo; - struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u32 res = _SUCCESS; - - if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) - return _FAIL; - - pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; - /* 4 start to encrypt each fragment */ - if (pattrib->encrypt == _TKIP_) { - if (pattrib->psta) - stainfo = pattrib->psta; - else - stainfo = r8712_get_stainfo(&padapter->stapriv, - &pattrib->ra[0]); - if (stainfo) { - prwskey = &stainfo->x_UncstKey.skey[0]; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - iv = pframe + pattrib->hdrlen; - payload = pframe + pattrib->iv_len + - pattrib->hdrlen; - GET_TKIP_PN(iv, txpn); - pnl = (u16)(txpn.val); - pnh = (u32)(txpn.val >> 16); - phase1((u16 *)&ttkey[0], prwskey, - &pattrib->ta[0], pnh); - phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], - pnl); - if ((curfragnum + 1) == pattrib->nr_frags) { - /* 4 the last fragment */ - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32( - getcrc32(payload, length)); - arcfour_init(&mycontext, rc4key, 16); - arcfour_encrypt(&mycontext, payload, - payload, length); - arcfour_encrypt(&mycontext, payload + - length, crc, 4); - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32(getcrc32( - payload, length)); - arcfour_init(&mycontext, rc4key, 16); - arcfour_encrypt(&mycontext, payload, - payload, length); - arcfour_encrypt(&mycontext, - payload + length, crc, - 4); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((addr_t)(pframe)); - } - } - } else { - res = _FAIL; - } - } - return res; -} - -/* The hlen doesn't include the IV */ -void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) -{ /* exclude ICV */ - u16 pnl; - u32 pnh; - u8 rc4key[16]; - u8 ttkey[16]; - u8 crc[4]; - struct arc4context mycontext; - u32 length; - u8 *pframe, *payload, *iv, *prwskey, idx = 0; - union pn48 txpn; - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &((union recv_frame *) - precvframe)->u.hdr.attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - pframe = (unsigned char *)((union recv_frame *) - precvframe)->u.hdr.rx_data; - /* 4 start to decrypt recvframe */ - if (prxattrib->encrypt == _TKIP_) { - stainfo = r8712_get_stainfo(&padapter->stapriv, - &prxattrib->ta[0]); - if (stainfo) { - iv = pframe + prxattrib->hdrlen; - payload = pframe + prxattrib->iv_len + - prxattrib->hdrlen; - length = ((union recv_frame *)precvframe)-> - u.hdr.len - prxattrib->hdrlen - - prxattrib->iv_len; - if (is_multicast_ether_addr(prxattrib->ra)) { - idx = iv[3]; - prwskey = &psecuritypriv->XGrpKey[ - ((idx >> 6) & 0x3) - 1].skey[0]; - if (!psecuritypriv->binstallGrpkey) - return; - } else { - prwskey = &stainfo->x_UncstKey.skey[0]; - } - GET_TKIP_PN(iv, txpn); - pnl = (u16)(txpn.val); - pnh = (u32)(txpn.val >> 16); - phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], - pnh); - phase2(&rc4key[0], prwskey, (unsigned short *) - &ttkey[0], pnl); - /* 4 decrypt payload include icv */ - arcfour_init(&mycontext, rc4key, 16); - arcfour_encrypt(&mycontext, payload, payload, length); - *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, - length - 4)); - } - } -} - -/* 3 =====AES related===== */ - -#define MAX_MSG_SIZE 2048 -/*****************************/ -/******** SBOX Table *********/ -/*****************************/ - -static const u8 sbox_table[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -/****************************************/ -/* aes128k128d() */ -/* Performs a 128 bit AES encrypt with */ -/* 128 bit data. */ -/****************************************/ -static void xor_128(u8 *a, u8 *b, u8 *out) -{ - sint i; - - for (i = 0; i < 16; i++) - out[i] = a[i] ^ b[i]; -} - -static void xor_32(u8 *a, u8 *b, u8 *out) -{ - sint i; - - for (i = 0; i < 4; i++) - out[i] = a[i] ^ b[i]; -} - -static u8 sbox(u8 a) -{ - return sbox_table[(sint)a]; -} - -static void next_key(u8 *key, sint round) -{ - u8 rcon; - u8 sbox_key[4]; - static const u8 rcon_table[12] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x36, 0x36 - }; - - sbox_key[0] = sbox(key[13]); - sbox_key[1] = sbox(key[14]); - sbox_key[2] = sbox(key[15]); - sbox_key[3] = sbox(key[12]); - rcon = rcon_table[round]; - xor_32(&key[0], sbox_key, &key[0]); - key[0] = key[0] ^ rcon; - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); -} - -static void byte_sub(u8 *in, u8 *out) -{ - sint i; - - for (i = 0; i < 16; i++) - out[i] = sbox(in[i]); -} - -static void shift_row(u8 *in, u8 *out) -{ - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; -} - -static void mix_column(u8 *in, u8 *out) -{ - sint i; - u8 add1b[4]; - u8 add1bf7[4]; - u8 rotl[4]; - u8 swap_halves[4]; - u8 andf7[4]; - u8 rotr[4]; - u8 temp[4]; - u8 tempb[4]; - - for (i = 0; i < 4; i++) { - if ((in[i] & 0x80) == 0x80) - add1b[i] = 0x1b; - else - add1b[i] = 0x00; - } - swap_halves[0] = in[2]; /* Swap halves */ - swap_halves[1] = in[3]; - swap_halves[2] = in[0]; - swap_halves[3] = in[1]; - rotl[0] = in[3]; /* Rotate left 8 bits */ - rotl[1] = in[0]; - rotl[2] = in[1]; - rotl[3] = in[2]; - andf7[0] = in[0] & 0x7f; - andf7[1] = in[1] & 0x7f; - andf7[2] = in[2] & 0x7f; - andf7[3] = in[3] & 0x7f; - for (i = 3; i > 0; i--) { /* logical shift left 1 bit */ - andf7[i] = andf7[i] << 1; - if ((andf7[i - 1] & 0x80) == 0x80) - andf7[i] = (andf7[i] | 0x01); - } - andf7[0] = andf7[0] << 1; - andf7[0] = andf7[0] & 0xfe; - xor_32(add1b, andf7, add1bf7); - xor_32(in, add1bf7, rotr); - temp[0] = rotr[0]; /* Rotate right 8 bits */ - rotr[0] = rotr[1]; - rotr[1] = rotr[2]; - rotr[2] = rotr[3]; - rotr[3] = temp[0]; - xor_32(add1bf7, rotr, temp); - xor_32(swap_halves, rotl, tempb); - xor_32(temp, tempb, out); -} - -static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) -{ - sint round; - sint i; - u8 intermediatea[16]; - u8 intermediateb[16]; - u8 round_key[16]; - - for (i = 0; i < 16; i++) - round_key[i] = key[i]; - for (round = 0; round < 11; round++) { - if (round == 0) { - xor_128(round_key, data, ciphertext); - next_key(round_key, round); - } else if (round == 10) { - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - xor_128(intermediateb, round_key, ciphertext); - } else { /* 1 - 9 */ - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - mix_column(&intermediateb[0], &intermediatea[0]); - mix_column(&intermediateb[4], &intermediatea[4]); - mix_column(&intermediateb[8], &intermediatea[8]); - mix_column(&intermediateb[12], &intermediatea[12]); - xor_128(intermediatea, round_key, ciphertext); - next_key(round_key, round); - } - } -} - -/************************************************/ -/* construct_mic_iv() */ -/* Builds the MIC IV from header fields and PN */ -/************************************************/ -static void construct_mic_iv(u8 *mic_iv, sint qc_exists, sint a4_exists, - u8 *mpdu, uint payload_length, u8 *pn_vector) -{ - sint i; - - mic_iv[0] = 0x59; - if (qc_exists && a4_exists) - mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ - if (qc_exists && !a4_exists) - mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ - if (!qc_exists) - mic_iv[1] = 0x00; - for (i = 2; i < 8; i++) - mic_iv[i] = mpdu[i + 8]; - for (i = 8; i < 14; i++) - mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ - mic_iv[14] = (unsigned char)(payload_length / 256); - mic_iv[15] = (unsigned char)(payload_length % 256); -} - -/************************************************/ -/* construct_mic_header1() */ -/* Builds the first MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_mic_header1(u8 *mic_header1, sint header_length, u8 *mpdu) -{ - mic_header1[0] = (u8)((header_length - 2) / 256); - mic_header1[1] = (u8)((header_length - 2) % 256); - mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ - /* Mute retry, more data and pwr mgt bits */ - mic_header1[3] = mpdu[1] & 0xc7; - mic_header1[4] = mpdu[4]; /* A1 */ - mic_header1[5] = mpdu[5]; - mic_header1[6] = mpdu[6]; - mic_header1[7] = mpdu[7]; - mic_header1[8] = mpdu[8]; - mic_header1[9] = mpdu[9]; - mic_header1[10] = mpdu[10]; /* A2 */ - mic_header1[11] = mpdu[11]; - mic_header1[12] = mpdu[12]; - mic_header1[13] = mpdu[13]; - mic_header1[14] = mpdu[14]; - mic_header1[15] = mpdu[15]; -} - -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, sint a4_exists, - sint qc_exists) -{ - sint i; - - for (i = 0; i < 16; i++) - mic_header2[i] = 0x00; - mic_header2[0] = mpdu[16]; /* A3 */ - mic_header2[1] = mpdu[17]; - mic_header2[2] = mpdu[18]; - mic_header2[3] = mpdu[19]; - mic_header2[4] = mpdu[20]; - mic_header2[5] = mpdu[21]; - mic_header2[6] = 0x00; - mic_header2[7] = 0x00; /* mpdu[23]; */ - if (!qc_exists && a4_exists) - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ - if (qc_exists && !a4_exists) { - mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ - mic_header2[9] = mpdu[25] & 0x00; - } - if (qc_exists && a4_exists) { - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ - mic_header2[14] = mpdu[30] & 0x0f; - mic_header2[15] = mpdu[31] & 0x00; - } -} - -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_ctr_preload(u8 *ctr_preload, - sint a4_exists, sint qc_exists, - u8 *mpdu, u8 *pn_vector, sint c) -{ - sint i; - - for (i = 0; i < 16; i++) - ctr_preload[i] = 0x00; - i = 0; - ctr_preload[0] = 0x01; /* flag */ - if (qc_exists && a4_exists) - ctr_preload[1] = mpdu[30] & 0x0f; - if (qc_exists && !a4_exists) - ctr_preload[1] = mpdu[24] & 0x0f; - for (i = 2; i < 8; i++) - ctr_preload[i] = mpdu[i + 8]; - for (i = 8; i < 14; i++) - ctr_preload[i] = pn_vector[13 - i]; - ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ - ctr_preload[15] = (unsigned char)(c % 256); -} - -/************************************/ -/* bitwise_xor() */ -/* A 128 bit, bitwise exclusive or */ -/************************************/ -static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) -{ - sint i; - - for (i = 0; i < 16; i++) - out[i] = ina[i] ^ inb[i]; -} - -static void aes_cipher(u8 *key, uint hdrlen, - u8 *pframe, uint plen) -{ - uint qc_exists, a4_exists, i, j, payload_remainder; - uint num_blocks, payload_index; - - u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; - - /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; - u8 mic[8]; - u16 frtype = GetFrameType(pframe); - u16 frsubtype = GetFrameSubType(pframe); - - frsubtype >>= 4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) - a4_exists = 0; - else - a4_exists = 1; - - if ((frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACK)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFPOLL)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACKPOLL))) { - qc_exists = 1; - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - } else if ((frsubtype == 0x08) || - (frsubtype == 0x09) || - (frsubtype == 0x0a) || - (frsubtype == 0x0b)) { - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - qc_exists = 1; - } else { - qc_exists = 0; - } - pn_vector[0] = pframe[hdrlen]; - pn_vector[1] = pframe[hdrlen + 1]; - pn_vector[2] = pframe[hdrlen + 4]; - pn_vector[3] = pframe[hdrlen + 5]; - pn_vector[4] = pframe[hdrlen + 6]; - pn_vector[5] = pframe[hdrlen + 7]; - construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector); - construct_mic_header1(mic_header1, hdrlen, pframe); - construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists); - payload_remainder = plen % 16; - num_blocks = plen / 16; - /* Find start of payload */ - payload_index = hdrlen + 8; - /* Calculate MIC */ - aes128k128d(key, mic_iv, aes_out); - bitwise_xor(aes_out, mic_header1, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - bitwise_xor(aes_out, mic_header2, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - for (i = 0; i < num_blocks; i++) { - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); - payload_index += 16; - aes128k128d(key, chain_buffer, aes_out); - } - /* Add on the final payload block if it needs padding */ - if (payload_remainder > 0) { - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index++]; - bitwise_xor(aes_out, padded_buffer, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - } - for (j = 0; j < 8; j++) - mic[j] = aes_out[j]; - /* Insert MIC into payload */ - for (j = 0; j < 8; j++) - pframe[payload_index + j] = mic[j]; - payload_index = hdrlen + 8; - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, i + 1); - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); - for (j = 0; j < 16; j++) - pframe[payload_index++] = chain_buffer[j]; - } - if (payload_remainder > 0) { /* If short final block, then pad it,*/ - /* encrypt and copy unpadded part back */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, num_blocks + 1); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index + j]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < payload_remainder; j++) - pframe[payload_index++] = chain_buffer[j]; - } - /* Encrypt the MIC */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, 0); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < 8; j++) - padded_buffer[j] = pframe[j + hdrlen + 8 + plen]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < 8; j++) - pframe[payload_index++] = chain_buffer[j]; -} - -u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) -{ /* exclude ICV */ - /* Intermediate Buffers */ - sint curfragnum, length; - u8 *pframe, *prwskey; - struct sta_info *stainfo; - struct pkt_attrib *pattrib = &((struct xmit_frame *) - pxmitframe)->attrib; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u32 res = _SUCCESS; - - if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) - return _FAIL; - pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; - /* 4 start to encrypt each fragment */ - if (pattrib->encrypt == _AES_) { - if (pattrib->psta) - stainfo = pattrib->psta; - else - stainfo = r8712_get_stainfo(&padapter->stapriv, - &pattrib->ra[0]); - if (stainfo) { - prwskey = &stainfo->x_UncstKey.skey[0]; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - if ((curfragnum + 1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - aes_cipher(prwskey, pattrib->hdrlen, - pframe, length); - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - aes_cipher(prwskey, pattrib->hdrlen, - pframe, length); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((addr_t)(pframe)); - } - } - } else { - res = _FAIL; - } - } - return res; -} - -static void aes_decipher(u8 *key, uint hdrlen, - u8 *pframe, uint plen) -{ - static u8 message[MAX_MSG_SIZE]; - uint qc_exists, a4_exists, i, j, payload_remainder; - uint num_blocks, payload_index; - u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; - /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; - u8 mic[8]; - uint frtype = GetFrameType(pframe); - uint frsubtype = GetFrameSubType(pframe); - - frsubtype >>= 4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - /* start to decrypt the payload */ - /*(plen including llc, payload and mic) */ - num_blocks = (plen - 8) / 16; - payload_remainder = (plen - 8) % 16; - pn_vector[0] = pframe[hdrlen]; - pn_vector[1] = pframe[hdrlen + 1]; - pn_vector[2] = pframe[hdrlen + 4]; - pn_vector[3] = pframe[hdrlen + 5]; - pn_vector[4] = pframe[hdrlen + 6]; - pn_vector[5] = pframe[hdrlen + 7]; - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) - a4_exists = 0; - else - a4_exists = 1; - if ((frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACK)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFPOLL)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACKPOLL))) { - qc_exists = 1; - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - } else if ((frsubtype == 0x08) || - (frsubtype == 0x09) || - (frsubtype == 0x0a) || - (frsubtype == 0x0b)) { - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - qc_exists = 1; - } else { - qc_exists = 0; - } - /* now, decrypt pframe with hdrlen offset and plen long */ - payload_index = hdrlen + 8; /* 8 is for extiv */ - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, i + 1); - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); - for (j = 0; j < 16; j++) - pframe[payload_index++] = chain_buffer[j]; - } - if (payload_remainder > 0) { /* If short final block, pad it,*/ - /* encrypt it and copy the unpadded part back */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, num_blocks + 1); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index + j]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < payload_remainder; j++) - pframe[payload_index++] = chain_buffer[j]; - } - /* start to calculate the mic */ - memcpy((void *)message, pframe, (hdrlen + plen + 8)); - pn_vector[0] = pframe[hdrlen]; - pn_vector[1] = pframe[hdrlen + 1]; - pn_vector[2] = pframe[hdrlen + 4]; - pn_vector[3] = pframe[hdrlen + 5]; - pn_vector[4] = pframe[hdrlen + 6]; - pn_vector[5] = pframe[hdrlen + 7]; - construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen - 8, - pn_vector); - construct_mic_header1(mic_header1, hdrlen, message); - construct_mic_header2(mic_header2, message, a4_exists, qc_exists); - payload_remainder = (plen - 8) % 16; - num_blocks = (plen - 8) / 16; - /* Find start of payload */ - payload_index = hdrlen + 8; - /* Calculate MIC */ - aes128k128d(key, mic_iv, aes_out); - bitwise_xor(aes_out, mic_header1, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - bitwise_xor(aes_out, mic_header2, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - for (i = 0; i < num_blocks; i++) { - bitwise_xor(aes_out, &message[payload_index], chain_buffer); - payload_index += 16; - aes128k128d(key, chain_buffer, aes_out); - } - /* Add on the final payload block if it needs padding */ - if (payload_remainder > 0) { - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = message[payload_index++]; - bitwise_xor(aes_out, padded_buffer, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - } - for (j = 0; j < 8; j++) - mic[j] = aes_out[j]; - /* Insert MIC into payload */ - for (j = 0; j < 8; j++) - message[payload_index + j] = mic[j]; - payload_index = hdrlen + 8; - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - message, pn_vector, i + 1); - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, &message[payload_index], chain_buffer); - for (j = 0; j < 16; j++) - message[payload_index++] = chain_buffer[j]; - } - if (payload_remainder > 0) { /* If short final block, pad it,*/ - /* encrypt and copy unpadded part back */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - message, pn_vector, num_blocks + 1); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = message[payload_index + j]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < payload_remainder; j++) - message[payload_index++] = chain_buffer[j]; - } - /* Encrypt the MIC */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, - pn_vector, 0); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < 8; j++) - padded_buffer[j] = message[j + hdrlen + plen]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < 8; j++) - message[payload_index++] = chain_buffer[j]; - /* compare the mic */ -} - -void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) -{ /* exclude ICV */ - /* Intermediate Buffers */ - sint length; - u8 *pframe, *prwskey, *iv, idx; - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &((union recv_frame *) - precvframe)->u.hdr.attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - pframe = (unsigned char *)((union recv_frame *)precvframe)-> - u.hdr.rx_data; - /* 4 start to encrypt each fragment */ - if (prxattrib->encrypt == _AES_) { - stainfo = r8712_get_stainfo(&padapter->stapriv, - &prxattrib->ta[0]); - if (stainfo) { - if (is_multicast_ether_addr(prxattrib->ra)) { - iv = pframe + prxattrib->hdrlen; - idx = iv[3]; - prwskey = &psecuritypriv->XGrpKey[ - ((idx >> 6) & 0x3) - 1].skey[0]; - if (!psecuritypriv->binstallGrpkey) - return; - - } else { - prwskey = &stainfo->x_UncstKey.skey[0]; - } - length = ((union recv_frame *)precvframe)-> - u.hdr.len - prxattrib->hdrlen - - prxattrib->iv_len; - aes_decipher(prwskey, prxattrib->hdrlen, pframe, - length); - } - } -} - -void r8712_use_tkipkey_handler(struct timer_list *t) -{ - struct _adapter *padapter = - from_timer(padapter, t, securitypriv.tkip_timer); - - padapter->securitypriv.busetkipkey = true; -} diff --git a/drivers/staging/rtl8712/rtl871x_security.h b/drivers/staging/rtl8712/rtl871x_security.h deleted file mode 100644 index 8461b7f05359a0d97ab7ae8ff5ad75a8ee28a3a2..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_security.h +++ /dev/null @@ -1,218 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_SECURITY_H_ -#define __RTL871X_SECURITY_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define _NO_PRIVACY_ 0x0 -#define _WEP40_ 0x1 -#define _TKIP_ 0x2 -#define _TKIP_WTMIC_ 0x3 -#define _AES_ 0x4 -#define _WEP104_ 0x5 - -#define _WPA_IE_ID_ 0xdd -#define _WPA2_IE_ID_ 0x30 - -#ifndef Ndis802_11AuthModeWPA2 -#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1) -#endif - -#ifndef Ndis802_11AuthModeWPA2PSK -#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2) -#endif - -union pn48 { - u64 val; -#if defined(__BIG_ENDIAN) - struct { - u8 TSC7; - u8 TSC6; - u8 TSC5; - u8 TSC4; - u8 TSC3; - u8 TSC2; - u8 TSC1; - u8 TSC0; - } _byte_; -#else - struct { - u8 TSC0; - u8 TSC1; - u8 TSC2; - u8 TSC3; - u8 TSC4; - u8 TSC5; - u8 TSC6; - u8 TSC7; - } _byte_; -#endif -}; - -union Keytype { - u8 skey[16]; - u32 lkey[4]; -}; - -struct RT_PMKID_LIST { - u8 bUsed; - u8 Bssid[6]; - u8 PMKID[16]; - u8 SsidBuf[33]; - u8 *ssid_octet; - u16 ssid_length; -}; - -struct security_priv { - u32 AuthAlgrthm; /* 802.11 auth, could be open, shared, - * 8021x and authswitch - */ - u32 PrivacyAlgrthm; /* This specify the privacy for shared - * auth. algorithm. - */ - u32 PrivacyKeyIndex; /* this is only valid for legendary - * wep, 0~3 for key id. - */ - union Keytype DefKey[4]; /* this is only valid for def. key */ - u32 DefKeylen[4]; - u32 XGrpPrivacy; /* This specify the privacy algthm. - * used for Grp key - */ - u32 XGrpKeyid; /* key id used for Grp Key */ - union Keytype XGrpKey[2]; /* 802.1x Group Key, for - * inx0 and inx1 - */ - union Keytype XGrptxmickey[2]; - union Keytype XGrprxmickey[2]; - union pn48 Grptxpn; /* PN48 used for Grp Key xmit. */ - union pn48 Grprxpn; /* PN48 used for Grp Key recv. */ - u8 wps_hw_pbc_pressed;/*for hw pbc pressed*/ - u8 wps_phase;/*for wps*/ - u8 wps_ie[MAX_WPA_IE_LEN << 2]; - int wps_ie_len; - u8 binstallGrpkey; - u8 busetkipkey; - struct timer_list tkip_timer; - u8 bcheck_grpkey; - u8 bgrpkey_handshake; - s32 sw_encrypt; /* from registry_priv */ - s32 sw_decrypt; /* from registry_priv */ - s32 hw_decrypted; /* if the rx packets is hw_decrypted==false, - * it means the hw has not been ready. - */ - u32 ndisauthtype; /* keeps the auth_type & enc_status from upper - * layer ioctl(wpa_supplicant or wzc) - */ - u32 ndisencryptstatus; - struct wlan_bssid_ex sec_bss; /* for joinbss (h2c buffer) usage */ - struct NDIS_802_11_WEP ndiswep; - u8 assoc_info[600]; - u8 szofcapability[256]; /* for wpa2 usage */ - u8 oidassociation[512]; /* for wpa/wpa2 usage */ - u8 authenticator_ie[256]; /* store ap security information element */ - u8 supplicant_ie[256]; /* store sta security information element */ - /* for tkip countermeasure */ - u32 last_mic_err_time; - u8 btkip_countermeasure; - u8 btkip_wait_report; - u32 btkip_countermeasure_time; - /*------------------------------------------------------------------- - * For WPA2 Pre-Authentication. - *------------------------------------------------------------------ - **/ - struct RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE]; - u8 PMKIDIndex; -}; - -#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst) \ -do { \ - switch (psecuritypriv->AuthAlgrthm) { \ - case 0: \ - case 1: \ - case 3: \ - encry_algo = (u8)psecuritypriv->PrivacyAlgrthm; \ - break; \ - case 2: \ - if (bmcst) \ - encry_algo = (u8)psecuritypriv->XGrpPrivacy; \ - else \ - encry_algo = (u8)psta->XPrivacy; \ - break; \ - } \ -} while (0) -#define SET_ICE_IV_LEN(iv_len, icv_len, encrypt)\ -do {\ - switch (encrypt) { \ - case _WEP40_: \ - case _WEP104_: \ - iv_len = 4; \ - icv_len = 4; \ - break; \ - case _TKIP_: \ - iv_len = 8; \ - icv_len = 4; \ - break; \ - case _AES_: \ - iv_len = 8; \ - icv_len = 8; \ - break; \ - default: \ - iv_len = 0; \ - icv_len = 0; \ - break; \ - } \ -} while (0) -#define GET_TKIP_PN(iv, txpn) \ -do {\ - txpn._byte_.TSC0 = iv[2];\ - txpn._byte_.TSC1 = iv[0];\ - txpn._byte_.TSC2 = iv[4];\ - txpn._byte_.TSC3 = iv[5];\ - txpn._byte_.TSC4 = iv[6];\ - txpn._byte_.TSC5 = iv[7];\ -} while (0) - -#define ROL32(A, n) (((A) << (n)) | (((A) >> (32 - (n))) & ((1UL << (n)) - 1))) -#define ROR32(A, n) ROL32((A), 32 - (n)) - -struct mic_data { - u32 K0, K1; /* Key */ - u32 L, R; /* Current state */ - u32 M; /* Message accumulator (single word) */ - u32 nBytesInM; /* # bytes in M */ -}; - -void seccalctkipmic( - u8 *key, - u8 *header, - u8 *data, - u32 data_len, - u8 *Miccode, - u8 priority); - -void r8712_secmicsetkey(struct mic_data *pmicdata, u8 *key); -void r8712_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nBytes); -void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst); -u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe); -u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe); -void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe); -void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe); -void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe); -void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe); -void r8712_use_tkipkey_handler(struct timer_list *t); - -#endif /*__RTL871X_SECURITY_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c deleted file mode 100644 index 2c806a0105bf6c7cf0b02079ea377e9c851e5ec8..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ /dev/null @@ -1,263 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_sta_mgt.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_STA_MGT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "xmit_osdep.h" -#include "sta_info.h" - -static void _init_stainfo(struct sta_info *psta) -{ - memset((u8 *)psta, 0, sizeof(struct sta_info)); - spin_lock_init(&psta->lock); - INIT_LIST_HEAD(&psta->list); - INIT_LIST_HEAD(&psta->hash_list); - _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); - _r8712_init_sta_recv_priv(&psta->sta_recvpriv); - INIT_LIST_HEAD(&psta->asoc_list); - INIT_LIST_HEAD(&psta->auth_list); -} - -int _r8712_init_sta_priv(struct sta_priv *pstapriv) -{ - struct sta_info *psta; - s32 i; - - pstapriv->pallocated_stainfo_buf = kmalloc(sizeof(struct sta_info) * - NUM_STA + 4, GFP_ATOMIC); - if (!pstapriv->pallocated_stainfo_buf) - return -ENOMEM; - pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 - - ((addr_t)(pstapriv->pallocated_stainfo_buf) & 3); - _init_queue(&pstapriv->free_sta_queue); - spin_lock_init(&pstapriv->sta_hash_lock); - pstapriv->asoc_sta_count = 0; - _init_queue(&pstapriv->sleep_q); - _init_queue(&pstapriv->wakeup_q); - psta = (struct sta_info *)(pstapriv->pstainfo_buf); - for (i = 0; i < NUM_STA; i++) { - _init_stainfo(psta); - INIT_LIST_HEAD(&(pstapriv->sta_hash[i])); - list_add_tail(&psta->list, &pstapriv->free_sta_queue.queue); - psta++; - } - INIT_LIST_HEAD(&pstapriv->asoc_list); - INIT_LIST_HEAD(&pstapriv->auth_list); - return 0; -} - -/* this function is used to free the memory of lock || sema for all stainfos */ -static void mfree_all_stainfo(struct sta_priv *pstapriv) -{ - unsigned long irqL; - struct list_head *plist, *phead; - - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - phead = &pstapriv->free_sta_queue.queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) - plist = plist->next; - - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); -} - -void _r8712_free_sta_priv(struct sta_priv *pstapriv) -{ - if (pstapriv) { - /* be done before free sta_hash_lock */ - mfree_all_stainfo(pstapriv); - kfree(pstapriv->pallocated_stainfo_buf); - } -} - -struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) -{ - s32 index; - struct list_head *phash_list; - struct sta_info *psta; - struct __queue *pfree_sta_queue; - struct recv_reorder_ctrl *preorder_ctrl; - int i = 0; - u16 wRxSeqInitialValue = 0xffff; - unsigned long flags; - - pfree_sta_queue = &pstapriv->free_sta_queue; - spin_lock_irqsave(&pfree_sta_queue->lock, flags); - psta = list_first_entry_or_null(&pfree_sta_queue->queue, - struct sta_info, list); - if (psta) { - list_del_init(&psta->list); - _init_stainfo(psta); - memcpy(psta->hwaddr, hwaddr, ETH_ALEN); - index = wifi_mac_hash(hwaddr); - if (index >= NUM_STA) { - psta = NULL; - goto exit; - } - phash_list = &pstapriv->sta_hash[index]; - list_add_tail(&psta->hash_list, phash_list); - pstapriv->asoc_sta_count++; - -/* For the SMC router, the sequence number of first packet of WPS handshake - * will be 0. In this case, this packet will be dropped by recv_decache function - * if we use the 0x00 as the default value for tid_rxseq variable. So, we - * initialize the tid_rxseq variable as the 0xffff. - */ - for (i = 0; i < 16; i++) - memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], - &wRxSeqInitialValue, 2); - /* for A-MPDU Rx reordering buffer control */ - for (i = 0; i < 16; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - preorder_ctrl->padapter = pstapriv->padapter; - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->wend_b = 0xffff; - preorder_ctrl->wsize_b = 64; - _init_queue(&preorder_ctrl->pending_recvframe_queue); - r8712_init_recv_timer(preorder_ctrl); - } - } -exit: - spin_unlock_irqrestore(&pfree_sta_queue->lock, flags); - return psta; -} - -/* using pstapriv->sta_hash_lock to protect */ -void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta) -{ - int i; - unsigned long irqL0; - struct __queue *pfree_sta_queue; - struct recv_reorder_ctrl *preorder_ctrl; - struct sta_xmit_priv *pstaxmitpriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct sta_priv *pstapriv = &padapter->stapriv; - - if (!psta) - return; - pfree_sta_queue = &pstapriv->free_sta_queue; - pstaxmitpriv = &psta->sta_xmitpriv; - spin_lock_irqsave(&(pxmitpriv->vo_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); - list_del_init(&(pstaxmitpriv->vo_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->vo_pending.lock), irqL0); - spin_lock_irqsave(&(pxmitpriv->vi_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); - list_del_init(&(pstaxmitpriv->vi_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->vi_pending.lock), irqL0); - spin_lock_irqsave(&(pxmitpriv->bk_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); - list_del_init(&(pstaxmitpriv->bk_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->bk_pending.lock), irqL0); - spin_lock_irqsave(&(pxmitpriv->be_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending); - list_del_init(&(pstaxmitpriv->be_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->be_pending.lock), irqL0); - list_del_init(&psta->hash_list); - pstapriv->asoc_sta_count--; - /* re-init sta_info; 20061114 */ - _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); - _r8712_init_sta_recv_priv(&psta->sta_recvpriv); - /* for A-MPDU Rx reordering buffer control, - * cancel reordering_ctrl_timer - */ - for (i = 0; i < 16; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - del_timer(&preorder_ctrl->reordering_ctrl_timer); - } - spin_lock(&(pfree_sta_queue->lock)); - /* insert into free_sta_queue; 20061114 */ - list_add_tail(&psta->list, &pfree_sta_queue->queue); - spin_unlock(&(pfree_sta_queue->lock)); -} - -/* free all stainfo which in sta_hash[all] */ -void r8712_free_all_stainfo(struct _adapter *padapter) -{ - unsigned long irqL; - struct list_head *plist, *phead; - s32 index; - struct sta_info *psta = NULL; - struct sta_priv *pstapriv = &padapter->stapriv; - struct sta_info *pbcmc_stainfo = r8712_get_bcmc_stainfo(padapter); - - if (pstapriv->asoc_sta_count == 1) - return; - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - for (index = 0; index < NUM_STA; index++) { - phead = &(pstapriv->sta_hash[index]); - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - psta = container_of(plist, - struct sta_info, hash_list); - plist = plist->next; - if (pbcmc_stainfo != psta) - r8712_free_stainfo(padapter, psta); - } - } - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); -} - -/* any station allocated can be searched by hash list */ -struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) -{ - unsigned long irqL; - struct list_head *plist, *phead; - struct sta_info *psta = NULL; - u32 index; - - if (!hwaddr) - return NULL; - index = wifi_mac_hash(hwaddr); - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - phead = &(pstapriv->sta_hash[index]); - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - psta = container_of(plist, struct sta_info, hash_list); - if ((!memcmp(psta->hwaddr, hwaddr, ETH_ALEN))) { - /* if found the matched address */ - break; - } - psta = NULL; - plist = plist->next; - } - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); - return psta; -} - -void r8712_init_bcmc_stainfo(struct _adapter *padapter) -{ - unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - struct sta_priv *pstapriv = &padapter->stapriv; - - r8712_alloc_stainfo(pstapriv, bcast_addr); -} - -struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - return r8712_get_stainfo(pstapriv, bc_addr); -} - -u8 r8712_access_ctrl(struct wlan_acl_pool *pacl_list, u8 *mac_addr) -{ - return true; -} diff --git a/drivers/staging/rtl8712/rtl871x_wlan_sme.h b/drivers/staging/rtl8712/rtl871x_wlan_sme.h deleted file mode 100644 index 97ea1451426c05c6c675c3b8c14f880c8ff0691c..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_wlan_sme.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_WLAN_SME_H_ -#define _RTL871X_WLAN_SME_H_ - -#define MSR_APMODE 0x0C -#define MSR_STAMODE 0x08 -#define MSR_ADHOCMODE 0x04 -#define MSR_NOLINKMODE 0x00 -#define _1M_RATE_ 0 -#define _2M_RATE_ 1 -#define _5M_RATE_ 2 -#define _11M_RATE_ 3 -#define _6M_RATE_ 4 -#define _9M_RATE_ 5 -#define _12M_RATE_ 6 -#define _18M_RATE_ 7 -#define _24M_RATE_ 8 -#define _36M_RATE_ 9 -#define _48M_RATE_ 10 -#define _54M_RATE_ 11 - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c deleted file mode 100644 index 408616e9afcfffe134e2da881cac587ae6e2b0f3..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ /dev/null @@ -1,1056 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_xmit.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_XMIT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -#include -#include - -static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8}; -static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00}; -static void init_hwxmits(struct hw_xmit *phwxmit, sint entry); -static void alloc_hwxmits(struct _adapter *padapter); -static void free_hwxmits(struct _adapter *padapter); - -static void _init_txservq(struct tx_servq *ptxservq) -{ - INIT_LIST_HEAD(&ptxservq->tx_pending); - _init_queue(&ptxservq->sta_pending); - ptxservq->qcnt = 0; -} - -void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) -{ - memset((unsigned char *)psta_xmitpriv, 0, - sizeof(struct sta_xmit_priv)); - spin_lock_init(&psta_xmitpriv->lock); - _init_txservq(&psta_xmitpriv->be_q); - _init_txservq(&psta_xmitpriv->bk_q); - _init_txservq(&psta_xmitpriv->vi_q); - _init_txservq(&psta_xmitpriv->vo_q); - INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz); - INIT_LIST_HEAD(&psta_xmitpriv->apsd); -} - -int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, - struct _adapter *padapter) -{ - sint i; - struct xmit_buf *pxmitbuf; - struct xmit_frame *pxframe; - int j; - - memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); - spin_lock_init(&pxmitpriv->lock); - /* - *Please insert all the queue initialization using _init_queue below - */ - pxmitpriv->adapter = padapter; - _init_queue(&pxmitpriv->be_pending); - _init_queue(&pxmitpriv->bk_pending); - _init_queue(&pxmitpriv->vi_pending); - _init_queue(&pxmitpriv->vo_pending); - _init_queue(&pxmitpriv->bm_pending); - _init_queue(&pxmitpriv->legacy_dz_queue); - _init_queue(&pxmitpriv->apsd_queue); - _init_queue(&pxmitpriv->free_xmit_queue); - /* - * Please allocate memory with sz = (struct xmit_frame) * NR_XMITFRAME, - * and initialize free_xmit_frame below. - * Please also apply free_txobj to link_up all the xmit_frames... - */ - pxmitpriv->pallocated_frame_buf = - kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4, - GFP_ATOMIC); - if (!pxmitpriv->pallocated_frame_buf) { - pxmitpriv->pxmit_frame_buf = NULL; - return -ENOMEM; - } - pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - - ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3); - pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf; - for (i = 0; i < NR_XMITFRAME; i++) { - INIT_LIST_HEAD(&(pxframe->list)); - pxframe->padapter = padapter; - pxframe->frame_tag = DATA_FRAMETAG; - pxframe->pkt = NULL; - pxframe->buf_addr = NULL; - pxframe->pxmitbuf = NULL; - list_add_tail(&(pxframe->list), - &(pxmitpriv->free_xmit_queue.queue)); - pxframe++; - } - pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME; - /* - * init xmit hw_txqueue - */ - _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX); - pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; - pxmitpriv->txirp_cnt = 1; - /*per AC pending irp*/ - pxmitpriv->beq_cnt = 0; - pxmitpriv->bkq_cnt = 0; - pxmitpriv->viq_cnt = 0; - pxmitpriv->voq_cnt = 0; - /*init xmit_buf*/ - _init_queue(&pxmitpriv->free_xmitbuf_queue); - _init_queue(&pxmitpriv->pending_xmitbuf_queue); - pxmitpriv->pxmitbuf = kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf), GFP_ATOMIC); - if (!pxmitpriv->pxmitbuf) - goto clean_up_frame_buf; - pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; - for (i = 0; i < NR_XMITBUFF; i++) { - INIT_LIST_HEAD(&pxmitbuf->list); - pxmitbuf->pallocated_buf = - kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC); - if (!pxmitbuf->pallocated_buf) { - j = 0; - goto clean_up_alloc_buf; - } - pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ - - ((addr_t) (pxmitbuf->pallocated_buf) & - (XMITBUF_ALIGN_SZ - 1)); - if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) { - j = 1; - goto clean_up_alloc_buf; - } - list_add_tail(&pxmitbuf->list, - &(pxmitpriv->free_xmitbuf_queue.queue)); - pxmitbuf++; - } - pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF; - INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter); - alloc_hwxmits(padapter); - init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); - tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh); - return 0; - -clean_up_alloc_buf: - if (j) { - /* failure happened in r8712_xmit_resource_alloc() - * delete extra pxmitbuf->pallocated_buf - */ - kfree(pxmitbuf->pallocated_buf); - } - for (j = 0; j < i; j++) { - int k; - - pxmitbuf--; /* reset pointer */ - kfree(pxmitbuf->pallocated_buf); - for (k = 0; k < 8; k++) /* delete xmit urb's */ - usb_free_urb(pxmitbuf->pxmit_urb[k]); - } - kfree(pxmitpriv->pxmitbuf); - pxmitpriv->pxmitbuf = NULL; -clean_up_frame_buf: - kfree(pxmitpriv->pallocated_frame_buf); - pxmitpriv->pallocated_frame_buf = NULL; - return -ENOMEM; -} - -void _free_xmit_priv(struct xmit_priv *pxmitpriv) -{ - int i; - struct _adapter *padapter = pxmitpriv->adapter; - struct xmit_frame *pxmitframe = (struct xmit_frame *) - pxmitpriv->pxmit_frame_buf; - struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; - - if (!pxmitpriv->pxmit_frame_buf) - return; - for (i = 0; i < NR_XMITFRAME; i++) { - r8712_xmit_complete(padapter, pxmitframe); - pxmitframe++; - } - for (i = 0; i < NR_XMITBUFF; i++) { - r8712_xmit_resource_free(padapter, pxmitbuf); - kfree(pxmitbuf->pallocated_buf); - pxmitbuf++; - } - kfree(pxmitpriv->pallocated_frame_buf); - kfree(pxmitpriv->pxmitbuf); - free_hwxmits(padapter); -} - -int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, - struct pkt_attrib *pattrib) -{ - struct pkt_file pktfile; - struct sta_info *psta = NULL; - struct ethhdr etherhdr; - - struct tx_cmd txdesc; - - bool bmcast; - struct sta_priv *pstapriv = &padapter->stapriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - - _r8712_open_pktfile(pkt, &pktfile); - - _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN); - - pattrib->ether_type = ntohs(etherhdr.h_proto); - - /* - * If driver xmit ARP packet, driver can set ps mode to initial - * setting. It stands for getting DHCP or fix IP. - */ - if (pattrib->ether_type == 0x0806) { - if (padapter->pwrctrlpriv.pwr_mode != - padapter->registrypriv.power_mgnt) { - del_timer_sync(&pmlmepriv->dhcp_timer); - r8712_set_ps_mode(padapter, - padapter->registrypriv.power_mgnt, - padapter->registrypriv.smart_ps); - } - } - - memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); - memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); - pattrib->pctrl = 0; - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - /*firstly, filter packet not belongs to mp*/ - if (pattrib->ether_type != 0x8712) - return -EINVAL; - /* for mp storing the txcmd per packet, - * according to the info of txcmd to update pattrib - */ - /*get MP_TXDESC_SIZE bytes txcmd per packet*/ - _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - pattrib->pctrl = 1; - } - /* r8712_xmitframe_coalesce() overwrite this!*/ - pattrib->pktlen = pktfile.pkt_len; - if (pattrib->ether_type == ETH_P_IP) { - /* The following is for DHCP and ARP packet, we use cck1M to - * tx these packets and let LPS awake some time - * to prevent DHCP protocol fail - */ - u8 tmp[24]; - - _r8712_pktfile_read(&pktfile, &tmp[0], 24); - pattrib->dhcp_pkt = 0; - if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/ - if (pattrib->ether_type == ETH_P_IP) {/* IP header*/ - if (((tmp[21] == 68) && (tmp[23] == 67)) || - ((tmp[21] == 67) && (tmp[23] == 68))) { - /* 68 : UDP BOOTP client - * 67 : UDP BOOTP server - * Use low rate to send DHCP packet. - */ - pattrib->dhcp_pkt = 1; - } - } - } - } - bmcast = is_multicast_ether_addr(pattrib->ra); - /* get sta_info*/ - if (bmcast) { - psta = r8712_get_bcmc_stainfo(padapter); - pattrib->mac_id = 4; - } else { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - psta = r8712_get_stainfo(pstapriv, - get_bssid(pmlmepriv)); - pattrib->mac_id = 5; - } else { - psta = r8712_get_stainfo(pstapriv, pattrib->ra); - if (!psta) /* drop the pkt */ - return -ENOMEM; - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - pattrib->mac_id = 5; - else - pattrib->mac_id = psta->mac_id; - } - } - - if (psta) { - pattrib->psta = psta; - } else { - /* if we cannot get psta => drrp the pkt */ - return -ENOMEM; - } - - pattrib->ack_policy = 0; - /* get ether_hdr_len */ - pattrib->pkt_hdrlen = ETH_HLEN; - - if (pqospriv->qos_option) { - r8712_set_qos(&pktfile, pattrib); - } else { - pattrib->hdrlen = WLAN_HDR_A3_LEN; - pattrib->subtype = IEEE80211_FTYPE_DATA; - pattrib->priority = 0; - } - if (psta->ieee8021x_blocked) { - pattrib->encrypt = 0; - if ((pattrib->ether_type != 0x888e) && - !check_fwstate(pmlmepriv, WIFI_MP_STATE)) - return -EINVAL; - } else { - GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); - } - switch (pattrib->encrypt) { - case _WEP40_: - case _WEP104_: - pattrib->iv_len = 4; - pattrib->icv_len = 4; - break; - case _TKIP_: - pattrib->iv_len = 8; - pattrib->icv_len = 4; - if (padapter->securitypriv.busetkipkey == _FAIL) - return -EINVAL; - break; - case _AES_: - pattrib->iv_len = 8; - pattrib->icv_len = 8; - break; - default: - pattrib->iv_len = 0; - pattrib->icv_len = 0; - break; - } - - if (pattrib->encrypt && - (padapter->securitypriv.sw_encrypt || - !psecuritypriv->hw_decrypted)) - pattrib->bswenc = true; - else - pattrib->bswenc = false; - /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite - * some settings above. - */ - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - pattrib->priority = - (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f; - return 0; -} - -static int xmitframe_addmic(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - u32 curfragnum, length; - u8 *pframe, *payload, mic[8]; - struct mic_data micdata; - struct sta_info *stainfo; - struct qos_priv *pqospriv = &(padapter->mlmepriv.qospriv); - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct security_priv *psecpriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u8 priority[4] = {}; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (pattrib->psta) - stainfo = pattrib->psta; - else - stainfo = r8712_get_stainfo(&padapter->stapriv, - &pattrib->ra[0]); - if (pattrib->encrypt == _TKIP_) { - /*encode mic code*/ - if (stainfo) { - u8 null_key[16] = {}; - - pframe = pxmitframe->buf_addr + TXDESC_OFFSET; - if (bmcst) { - if (!memcmp(psecpriv->XGrptxmickey - [psecpriv->XGrpKeyid].skey, - null_key, 16)) - return -ENOMEM; - /*start to calculate the mic code*/ - r8712_secmicsetkey(&micdata, - psecpriv->XGrptxmickey - [psecpriv->XGrpKeyid].skey); - } else { - if (!memcmp(&stainfo->tkiptxmickey.skey[0], - null_key, 16)) - return -ENOMEM; - /* start to calculate the mic code */ - r8712_secmicsetkey(&micdata, - &stainfo->tkiptxmickey.skey[0]); - } - if (pframe[1] & 1) { /* ToDS==1 */ - r8712_secmicappend(&micdata, - &pframe[16], 6); /*DA*/ - if (pframe[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, - &pframe[24], 6); - else - r8712_secmicappend(&micdata, - &pframe[10], 6); - } else { /* ToDS==0 */ - r8712_secmicappend(&micdata, - &pframe[4], 6); /* DA */ - if (pframe[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, - &pframe[16], 6); - else - r8712_secmicappend(&micdata, - &pframe[10], 6); - } - if (pqospriv->qos_option == 1) - priority[0] = (u8)pxmitframe->attrib.priority; - r8712_secmicappend(&micdata, &priority[0], 4); - payload = pframe; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - payload = (u8 *)RND4((addr_t)(payload)); - payload += pattrib->hdrlen + pattrib->iv_len; - if ((curfragnum + 1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - ((psecpriv->sw_encrypt) - ? pattrib->icv_len : 0); - r8712_secmicappend(&micdata, payload, - length); - payload = payload + length; - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - pattrib->iv_len - - ((psecpriv->sw_encrypt) ? - pattrib->icv_len : 0); - r8712_secmicappend(&micdata, payload, - length); - payload = payload + length + - pattrib->icv_len; - } - } - r8712_secgetmic(&micdata, &(mic[0])); - /* add mic code and add the mic code length in - * last_txcmdsz - */ - memcpy(payload, &(mic[0]), 8); - pattrib->last_txcmdsz += 8; - payload = payload - pattrib->last_txcmdsz + 8; - } - } - return 0; -} - -static sint xmitframe_swencrypt(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - if (pattrib->bswenc) { - switch (pattrib->encrypt) { - case _WEP40_: - case _WEP104_: - r8712_wep_encrypt(padapter, (u8 *)pxmitframe); - break; - case _TKIP_: - r8712_tkip_encrypt(padapter, (u8 *)pxmitframe); - break; - case _AES_: - r8712_aes_encrypt(padapter, (u8 *)pxmitframe); - break; - default: - break; - } - } - return _SUCCESS; -} - -static int make_wlanhdr(struct _adapter *padapter, u8 *hdr, - struct pkt_attrib *pattrib) -{ - u16 *qc; - - struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - __le16 *fctrl = &pwlanhdr->frame_control; - u8 *bssid; - - memset(hdr, 0, WLANHDR_OFFSET); - SetFrameSubType(fctrl, pattrib->subtype); - if (!(pattrib->subtype & IEEE80211_FTYPE_DATA)) - return 0; - - bssid = get_bssid(pmlmepriv); - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - /* to_ds = 1, fr_ds = 0; */ - SetToDs(fctrl); - ether_addr_copy(pwlanhdr->addr1, bssid); - ether_addr_copy(pwlanhdr->addr2, pattrib->src); - ether_addr_copy(pwlanhdr->addr3, pattrib->dst); - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - /* to_ds = 0, fr_ds = 1; */ - SetFrDs(fctrl); - ether_addr_copy(pwlanhdr->addr1, pattrib->dst); - ether_addr_copy(pwlanhdr->addr2, bssid); - ether_addr_copy(pwlanhdr->addr3, pattrib->src); - } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - ether_addr_copy(pwlanhdr->addr1, pattrib->dst); - ether_addr_copy(pwlanhdr->addr2, pattrib->src); - ether_addr_copy(pwlanhdr->addr3, bssid); - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - ether_addr_copy(pwlanhdr->addr1, pattrib->dst); - ether_addr_copy(pwlanhdr->addr2, pattrib->src); - ether_addr_copy(pwlanhdr->addr3, bssid); - } else { - return -EINVAL; - } - - if (pattrib->encrypt) - SetPrivacy(fctrl); - if (pqospriv->qos_option) { - qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); - if (pattrib->priority) - SetPriority(qc, pattrib->priority); - SetAckpolicy(qc, pattrib->ack_policy); - } - /* TODO: fill HT Control Field */ - /* Update Seq Num will be handled by f/w */ - { - struct sta_info *psta; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (pattrib->psta) - psta = pattrib->psta; - else if (bmcst) - psta = r8712_get_bcmc_stainfo(padapter); - else - psta = r8712_get_stainfo(&padapter->stapriv, - pattrib->ra); - - if (psta) { - u16 *txtid = psta->sta_xmitpriv.txseq_tid; - - txtid[pattrib->priority]++; - txtid[pattrib->priority] &= 0xFFF; - pattrib->seqnum = txtid[pattrib->priority]; - SetSeqNum(hdr, pattrib->seqnum); - } - } - - return 0; -} - -static sint r8712_put_snap(u8 *data, u16 h_proto) -{ - struct ieee80211_snap_hdr *snap; - const u8 *oui; - - snap = (struct ieee80211_snap_hdr *)data; - snap->dsap = 0xaa; - snap->ssap = 0xaa; - snap->ctrl = 0x03; - if (h_proto == 0x8137 || h_proto == 0x80f3) - oui = P802_1H_OUI; - else - oui = RFC1042_OUI; - snap->oui[0] = oui[0]; - snap->oui[1] = oui[1]; - snap->oui[2] = oui[2]; - *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); - return SNAP_SIZE + sizeof(u16); -} - -/* - * This sub-routine will perform all the following: - * 1. remove 802.3 header. - * 2. create wlan_header, based on the info in pxmitframe - * 3. append sta's iv/ext-iv - * 4. append LLC - * 5. move frag chunk from pframe to pxmitframe->mem - * 6. apply sw-encrypt, if necessary. - */ -sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, - struct xmit_frame *pxmitframe) -{ - struct pkt_file pktfile; - - sint frg_len, mpdu_len, llc_sz; - u32 mem_sz; - u8 frg_inx; - addr_t addr; - u8 *pframe, *mem_start, *ptxdesc; - struct sta_info *psta; - struct security_priv *psecpriv = &padapter->securitypriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - u8 *pbuf_start; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (!pattrib->psta) - return _FAIL; - psta = pattrib->psta; - if (!pxmitframe->buf_addr) - return _FAIL; - pbuf_start = pxmitframe->buf_addr; - ptxdesc = pbuf_start; - mem_start = pbuf_start + TXDESC_OFFSET; - if (make_wlanhdr(padapter, mem_start, pattrib)) - return _FAIL; - _r8712_open_pktfile(pkt, &pktfile); - _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen); - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */ - if (pattrib->ether_type == 0x8712) { - /* take care - update_txdesc overwrite this */ - _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE); - } - } - pattrib->pktlen = pktfile.pkt_len; - frg_inx = 0; - frg_len = pxmitpriv->frag_len - 4; - while (1) { - llc_sz = 0; - mpdu_len = frg_len; - pframe = mem_start; - SetMFrag(mem_start); - pframe += pattrib->hdrlen; - mpdu_len -= pattrib->hdrlen; - /* adding icv, if necessary...*/ - if (pattrib->iv_len) { - if (psta) { - switch (pattrib->encrypt) { - case _WEP40_: - case _WEP104_: - WEP_IV(pattrib->iv, psta->txpn, - (u8)psecpriv->PrivacyKeyIndex); - break; - case _TKIP_: - if (bmcst) - TKIP_IV(pattrib->iv, - psta->txpn, - (u8)psecpriv->XGrpKeyid); - else - TKIP_IV(pattrib->iv, psta->txpn, - 0); - break; - case _AES_: - if (bmcst) - AES_IV(pattrib->iv, psta->txpn, - (u8)psecpriv->XGrpKeyid); - else - AES_IV(pattrib->iv, psta->txpn, - 0); - break; - } - } - memcpy(pframe, pattrib->iv, pattrib->iv_len); - pframe += pattrib->iv_len; - mpdu_len -= pattrib->iv_len; - } - if (frg_inx == 0) { - llc_sz = r8712_put_snap(pframe, pattrib->ether_type); - pframe += llc_sz; - mpdu_len -= llc_sz; - } - if ((pattrib->icv_len > 0) && (pattrib->bswenc)) - mpdu_len -= pattrib->icv_len; - if (bmcst) - mem_sz = _r8712_pktfile_read(&pktfile, pframe, - pattrib->pktlen); - else - mem_sz = _r8712_pktfile_read(&pktfile, pframe, - mpdu_len); - pframe += mem_sz; - if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { - memcpy(pframe, pattrib->icv, pattrib->icv_len); - pframe += pattrib->icv_len; - } - frg_inx++; - if (bmcst || r8712_endofpktfile(&pktfile)) { - pattrib->nr_frags = frg_inx; - pattrib->last_txcmdsz = pattrib->hdrlen + - pattrib->iv_len + - ((pattrib->nr_frags == 1) ? - llc_sz : 0) + - ((pattrib->bswenc) ? - pattrib->icv_len : 0) + mem_sz; - ClearMFrag(mem_start); - break; - } - addr = (addr_t)(pframe); - mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET; - memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen); - } - - if (xmitframe_addmic(padapter, pxmitframe)) - return _FAIL; - xmitframe_swencrypt(padapter, pxmitframe); - return _SUCCESS; -} - -void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len) -{ - uint protection; - u8 *perp; - uint erp_len; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct registry_priv *pregistrypriv = &padapter->registrypriv; - - switch (pxmitpriv->vcs_setting) { - case DISABLE_VCS: - pxmitpriv->vcs = NONE_VCS; - break; - case ENABLE_VCS: - break; - case AUTO_VCS: - default: - perp = r8712_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len); - if (!perp) { - pxmitpriv->vcs = NONE_VCS; - } else { - protection = (*(perp + 2)) & BIT(1); - if (protection) { - if (pregistrypriv->vcs_type == RTS_CTS) - pxmitpriv->vcs = RTS_CTS; - else - pxmitpriv->vcs = CTS_TO_SELF; - } else { - pxmitpriv->vcs = NONE_VCS; - } - } - break; - } -} - -struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv) -{ - unsigned long irqL; - struct xmit_buf *pxmitbuf; - struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; - - spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); - pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue, - struct xmit_buf, list); - if (pxmitbuf) { - list_del_init(&pxmitbuf->list); - pxmitpriv->free_xmitbuf_cnt--; - } - spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL); - return pxmitbuf; -} - -void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) -{ - unsigned long irqL; - struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; - - if (!pxmitbuf) - return; - spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); - list_del_init(&pxmitbuf->list); - list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue); - pxmitpriv->free_xmitbuf_cnt++; - spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL); -} - -/* - * Calling context: - * 1. OS_TXENTRY - * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack) - * - * If we turn on USE_RXTHREAD, then, no need for critical section. - * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... - * - * Must be very very cautious... - * - */ -struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv) -{ - /* - * Please remember to use all the osdep_service api, - * and lock/unlock or _enter/_exit critical to protect - * pfree_xmit_queue - */ - unsigned long irqL; - struct xmit_frame *pxframe; - struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; - - spin_lock_irqsave(&pfree_xmit_queue->lock, irqL); - pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue, - struct xmit_frame, list); - if (pxframe) { - list_del_init(&pxframe->list); - pxmitpriv->free_xmitframe_cnt--; - pxframe->buf_addr = NULL; - pxframe->pxmitbuf = NULL; - pxframe->attrib.psta = NULL; - pxframe->pkt = NULL; - } - spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL); - return pxframe; -} - -void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe) -{ - unsigned long irqL; - struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; - struct _adapter *padapter = pxmitpriv->adapter; - - if (!pxmitframe) - return; - spin_lock_irqsave(&pfree_xmit_queue->lock, irqL); - list_del_init(&pxmitframe->list); - if (pxmitframe->pkt) - pxmitframe->pkt = NULL; - list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue); - pxmitpriv->free_xmitframe_cnt++; - spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL); - if (netif_queue_stopped(padapter->pnetdev)) - netif_wake_queue(padapter->pnetdev); -} - -void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe) -{ - if (!pxmitframe) - return; - if (pxmitframe->frame_tag == DATA_FRAMETAG) - r8712_free_xmitframe(pxmitpriv, pxmitframe); -} - -void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv, - struct __queue *pframequeue) -{ - unsigned long irqL; - struct list_head *plist, *phead; - struct xmit_frame *pxmitframe; - - spin_lock_irqsave(&(pframequeue->lock), irqL); - phead = &pframequeue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - pxmitframe = container_of(plist, struct xmit_frame, list); - plist = plist->next; - r8712_free_xmitframe(pxmitpriv, pxmitframe); - } - spin_unlock_irqrestore(&(pframequeue->lock), irqL); -} - -static inline struct tx_servq *get_sta_pending(struct _adapter *padapter, - struct __queue **ppstapending, - struct sta_info *psta, sint up) -{ - struct tx_servq *ptxservq; - struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; - - switch (up) { - case 1: - case 2: - ptxservq = &(psta->sta_xmitpriv.bk_q); - *ppstapending = &padapter->xmitpriv.bk_pending; - (phwxmits + 3)->accnt++; - break; - case 4: - case 5: - ptxservq = &(psta->sta_xmitpriv.vi_q); - *ppstapending = &padapter->xmitpriv.vi_pending; - (phwxmits + 1)->accnt++; - break; - case 6: - case 7: - ptxservq = &(psta->sta_xmitpriv.vo_q); - *ppstapending = &padapter->xmitpriv.vo_pending; - (phwxmits + 0)->accnt++; - break; - case 0: - case 3: - default: - ptxservq = &(psta->sta_xmitpriv.be_q); - *ppstapending = &padapter->xmitpriv.be_pending; - (phwxmits + 2)->accnt++; - break; - } - return ptxservq; -} - -/* - * Will enqueue pxmitframe to the proper queue, and indicate it - * to xx_pending list..... - */ -int r8712_xmit_classifier(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - unsigned long irqL0; - struct __queue *pstapending; - struct sta_info *psta; - struct tx_servq *ptxservq; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (pattrib->psta) { - psta = pattrib->psta; - } else { - if (bmcst) { - psta = r8712_get_bcmc_stainfo(padapter); - } else { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - psta = r8712_get_stainfo(pstapriv, - get_bssid(pmlmepriv)); - else - psta = r8712_get_stainfo(pstapriv, pattrib->ra); - } - } - if (!psta) - return -EINVAL; - ptxservq = get_sta_pending(padapter, &pstapending, - psta, pattrib->priority); - spin_lock_irqsave(&pstapending->lock, irqL0); - if (list_empty(&ptxservq->tx_pending)) - list_add_tail(&ptxservq->tx_pending, &pstapending->queue); - list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue); - ptxservq->qcnt++; - spin_unlock_irqrestore(&pstapending->lock, irqL0); - return 0; -} - -static void alloc_hwxmits(struct _adapter *padapter) -{ - struct hw_xmit *hwxmits; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - pxmitpriv->hwxmit_entry = HWXMIT_ENTRY; - pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry, - sizeof(struct hw_xmit), GFP_ATOMIC); - if (!pxmitpriv->hwxmits) - return; - hwxmits = pxmitpriv->hwxmits; - if (pxmitpriv->hwxmit_entry == 5) { - pxmitpriv->bmc_txqueue.head = 0; - hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; - hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; - pxmitpriv->vo_txqueue.head = 0; - hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; - hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; - pxmitpriv->vi_txqueue.head = 0; - hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; - hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; - pxmitpriv->bk_txqueue.head = 0; - hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; - pxmitpriv->be_txqueue.head = 0; - hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; - hwxmits[4] .sta_queue = &pxmitpriv->be_pending; - } else if (pxmitpriv->hwxmit_entry == 4) { - pxmitpriv->vo_txqueue.head = 0; - hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; - hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; - pxmitpriv->vi_txqueue.head = 0; - hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; - hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; - pxmitpriv->be_txqueue.head = 0; - hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; - hwxmits[2] .sta_queue = &pxmitpriv->be_pending; - pxmitpriv->bk_txqueue.head = 0; - hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; - } -} - -static void free_hwxmits(struct _adapter *padapter) -{ - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - kfree(pxmitpriv->hwxmits); -} - -static void init_hwxmits(struct hw_xmit *phwxmit, sint entry) -{ - sint i; - - for (i = 0; i < entry; i++, phwxmit++) { - spin_lock_init(&phwxmit->xmit_lock); - INIT_LIST_HEAD(&phwxmit->pending); - phwxmit->txcmdcnt = 0; - phwxmit->accnt = 0; - } -} - -void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe, - struct xmit_buf *pxmitbuf) -{ - /* pxmitbuf attach to pxmitframe */ - pxmitframe->pxmitbuf = pxmitbuf; - /* urb and irp connection */ - pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0]; - /* buffer addr assoc */ - pxmitframe->buf_addr = pxmitbuf->pbuf; - /* pxmitframe attach to pxmitbuf */ - pxmitbuf->priv_data = pxmitframe; -} - -/* - * tx_action == 0 == no frames to transmit - * tx_action > 0 ==> we have frames to transmit - * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough - * to transmit 1 frame. - */ - -int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe) -{ - unsigned long irqL; - int ret; - struct xmit_buf *pxmitbuf = NULL; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - r8712_do_queue_select(padapter, pattrib); - spin_lock_irqsave(&pxmitpriv->lock, irqL); - if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) { - ret = false; - r8712_xmit_enqueue(padapter, pxmitframe); - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - return ret; - } - pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv); - if (!pxmitbuf) { /*enqueue packet*/ - ret = false; - r8712_xmit_enqueue(padapter, pxmitframe); - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - } else { /*dump packet directly*/ - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - ret = true; - xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf); - r8712_xmit_direct(padapter, pxmitframe); - } - return ret; -} diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h deleted file mode 100644 index 784172c385e37c4dc182f15351784f288116a322..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/rtl871x_xmit.h +++ /dev/null @@ -1,287 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_XMIT_H_ -#define _RTL871X_XMIT_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "xmit_osdep.h" - -#ifdef CONFIG_R8712_TX_AGGR -#define MAX_XMITBUF_SZ (16384) -#else -#define MAX_XMITBUF_SZ (2048) -#endif - -#define NR_XMITBUFF (4) - -#ifdef CONFIG_R8712_TX_AGGR -#define AGGR_NR_HIGH_BOUND (4) /*(8) */ -#define AGGR_NR_LOW_BOUND (2) -#endif - -#define XMITBUF_ALIGN_SZ 512 -#define TX_GUARD_BAND 5 -#define MAX_NUMBLKS (1) - -/* Fixed the Big Endian bug when using the software driver encryption.*/ -#define WEP_IV(pattrib_iv, txpn, keyidx)\ -do { \ - pattrib_iv[0] = txpn._byte_.TSC0;\ - pattrib_iv[1] = txpn._byte_.TSC1;\ - pattrib_iv[2] = txpn._byte_.TSC2;\ - pattrib_iv[3] = ((keyidx & 0x3) << 6);\ - txpn.val = (txpn.val == 0xffffff) ? 0 : (txpn.val + 1);\ -} while (0) - -/* Fixed the Big Endian bug when doing the Tx. - * The Linksys WRH54G will check this. - */ -#define TKIP_IV(pattrib_iv, txpn, keyidx)\ -do { \ - pattrib_iv[0] = txpn._byte_.TSC1;\ - pattrib_iv[1] = (txpn._byte_.TSC1 | 0x20) & 0x7f;\ - pattrib_iv[2] = txpn._byte_.TSC0;\ - pattrib_iv[3] = BIT(5) | ((keyidx & 0x3) << 6);\ - pattrib_iv[4] = txpn._byte_.TSC2;\ - pattrib_iv[5] = txpn._byte_.TSC3;\ - pattrib_iv[6] = txpn._byte_.TSC4;\ - pattrib_iv[7] = txpn._byte_.TSC5;\ - txpn.val = txpn.val == 0xffffffffffffULL ? 0 : \ - (txpn.val + 1);\ -} while (0) - -#define AES_IV(pattrib_iv, txpn, keyidx)\ -do { \ - pattrib_iv[0] = txpn._byte_.TSC0;\ - pattrib_iv[1] = txpn._byte_.TSC1;\ - pattrib_iv[2] = 0;\ - pattrib_iv[3] = BIT(5) | ((keyidx & 0x3) << 6);\ - pattrib_iv[4] = txpn._byte_.TSC2;\ - pattrib_iv[5] = txpn._byte_.TSC3;\ - pattrib_iv[6] = txpn._byte_.TSC4;\ - pattrib_iv[7] = txpn._byte_.TSC5;\ - txpn.val = txpn.val == 0xffffffffffffULL ? 0 : \ - (txpn.val + 1);\ -} while (0) - -struct hw_xmit { - spinlock_t xmit_lock; - struct list_head pending; - struct __queue *sta_queue; - struct hw_txqueue *phwtxqueue; - sint txcmdcnt; - int accnt; -}; - -struct pkt_attrib { - u8 type; - u8 subtype; - u8 bswenc; - u8 dhcp_pkt; - - u16 seqnum; - u16 ether_type; - u16 pktlen; /* the original 802.3 pkt raw_data len - * (not include ether_hdr data) - */ - u16 last_txcmdsz; - - u8 pkt_hdrlen; /*the original 802.3 pkt header len*/ - u8 hdrlen; /*the WLAN Header Len*/ - u8 nr_frags; - u8 ack_policy; - u8 mac_id; - u8 vcs_mode; /*virtual carrier sense method*/ - u8 pctrl;/*per packet txdesc control enable*/ - u8 qsel; - - u8 priority; - u8 encrypt; /* when 0 indicate no encrypt. when non-zero, - * indicate the encrypt algorithm - */ - u8 iv_len; - u8 icv_len; - unsigned char iv[8]; - unsigned char icv[8]; - u8 dst[ETH_ALEN] __aligned(2); /* for ether_addr_copy */ - u8 src[ETH_ALEN]; - u8 ta[ETH_ALEN]; - u8 ra[ETH_ALEN]; - struct sta_info *psta; -}; - -#define WLANHDR_OFFSET 64 -#define DATA_FRAMETAG 0x01 -#define L2_FRAMETAG 0x02 -#define MGNT_FRAMETAG 0x03 -#define AMSDU_FRAMETAG 0x04 -#define EII_FRAMETAG 0x05 -#define IEEE8023_FRAMETAG 0x06 -#define MP_FRAMETAG 0x07 -#define TXAGG_FRAMETAG 0x08 - -struct xmit_buf { - struct list_head list; - - u8 *pallocated_buf; - u8 *pbuf; - void *priv_data; - struct urb *pxmit_urb[8]; - u32 aggr_nr; -}; - -struct xmit_frame { - struct list_head list; - struct pkt_attrib attrib; - _pkt *pkt; - int frame_tag; - struct _adapter *padapter; - u8 *buf_addr; - struct xmit_buf *pxmitbuf; - u8 *mem_addr; - u16 sz[8]; - struct urb *pxmit_urb[8]; - u8 bpending[8]; - u8 last[8]; -}; - -struct tx_servq { - struct list_head tx_pending; - struct __queue sta_pending; - int qcnt; -}; - -struct sta_xmit_priv { - spinlock_t lock; - sint option; - sint apsd_setting; /* When bit mask is on, the associated edca - * queue supports APSD. - */ - struct tx_servq be_q; /* priority == 0,3 */ - struct tx_servq bk_q; /* priority == 1,2*/ - struct tx_servq vi_q; /*priority == 4,5*/ - struct tx_servq vo_q; /*priority == 6,7*/ - struct list_head legacy_dz; - struct list_head apsd; - u16 txseq_tid[16]; - uint sta_tx_bytes; - u64 sta_tx_pkts; - uint sta_tx_fail; -}; - -struct hw_txqueue { - sint head; - sint tail; - sint free_sz; /* in units of 64 bytes */ - sint free_cmdsz; - sint txsz[8]; - uint ff_hwaddr; - uint cmd_hwaddr; - sint ac_tag; -}; - -struct xmit_priv { - spinlock_t lock; - struct __queue be_pending; - struct __queue bk_pending; - struct __queue vi_pending; - struct __queue vo_pending; - struct __queue bm_pending; - struct __queue legacy_dz_queue; - struct __queue apsd_queue; - u8 *pallocated_frame_buf; - u8 *pxmit_frame_buf; - uint free_xmitframe_cnt; - uint mapping_addr; - uint pkt_sz; - struct __queue free_xmit_queue; - struct hw_txqueue be_txqueue; - struct hw_txqueue bk_txqueue; - struct hw_txqueue vi_txqueue; - struct hw_txqueue vo_txqueue; - struct hw_txqueue bmc_txqueue; - uint frag_len; - struct _adapter *adapter; - u8 vcs_setting; - u8 vcs; - u8 vcs_type; - u16 rts_thresh; - uint tx_bytes; - u64 tx_pkts; - uint tx_drop; - struct hw_xmit *hwxmits; - u8 hwxmit_entry; - u8 txirp_cnt; - struct tasklet_struct xmit_tasklet; - struct work_struct xmit_pipe4_reset_wi; - struct work_struct xmit_pipe6_reset_wi; - struct work_struct xmit_piped_reset_wi; - /*per AC pending irp*/ - int beq_cnt; - int bkq_cnt; - int viq_cnt; - int voq_cnt; - struct __queue free_amsdu_xmit_queue; - u8 *pallocated_amsdu_frame_buf; - u8 *pxmit_amsdu_frame_buf; - uint free_amsdu_xmitframe_cnt; - struct __queue free_txagg_xmit_queue; - u8 *pallocated_txagg_frame_buf; - u8 *pxmit_txagg_frame_buf; - uint free_txagg_xmitframe_cnt; - int cmdseq; - struct __queue free_xmitbuf_queue; - struct __queue pending_xmitbuf_queue; - u8 *pxmitbuf; - uint free_xmitbuf_cnt; -}; - -void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, - struct xmit_buf *pxmitbuf); -struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv); -void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len); -struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv); -void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe); -void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv, - struct __queue *pframequeue); -int r8712_xmit_classifier(struct _adapter *padapter, - struct xmit_frame *pxmitframe); -sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, - struct xmit_frame *pxmitframe); -sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag); -void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); -int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, - struct pkt_attrib *pattrib); -int r8712_txframes_sta_ac_pending(struct _adapter *padapter, - struct pkt_attrib *pattrib); -int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, - struct _adapter *padapter); -void _free_xmit_priv(struct xmit_priv *pxmitpriv); -void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe); -int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe); -int r8712_xmit_enqueue(struct _adapter *padapter, - struct xmit_frame *pxmitframe); -void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe); -void r8712_xmit_bh(struct tasklet_struct *t); - -void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe, - struct xmit_buf *pxmitbuf); - -#include "rtl8712_xmit.h" - -#endif /*_RTL871X_XMIT_H_*/ - diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h deleted file mode 100644 index 6286c622475e59ace9a25064044df22db60ab632..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/sta_info.h +++ /dev/null @@ -1,132 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __STA_INFO_H_ -#define __STA_INFO_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wifi.h" - -#define NUM_STA 32 -#define NUM_ACL 64 - -/* if mode ==0, then the sta is allowed once the addr is hit. - * if mode ==1, then the sta is rejected once the addr is non-hit. - */ -struct wlan_acl_node { - struct list_head list; - u8 addr[ETH_ALEN]; - u8 mode; -}; - -struct wlan_acl_pool { - struct wlan_acl_node aclnode[NUM_ACL]; -}; - -struct stainfo_stats { - uint rx_pkts; - uint rx_bytes; - u64 tx_pkts; - uint tx_bytes; -}; - -struct sta_info { - spinlock_t lock; - struct list_head list; /*free_sta_queue*/ - struct list_head hash_list; /*sta_hash*/ - struct sta_xmit_priv sta_xmitpriv; - struct sta_recv_priv sta_recvpriv; - uint state; - uint aid; - uint mac_id; - uint qos_option; - u8 hwaddr[ETH_ALEN]; - uint ieee8021x_blocked; /*0: allowed, 1:blocked */ - uint XPrivacy; /*aes, tkip...*/ - union Keytype tkiptxmickey; - union Keytype tkiprxmickey; - union Keytype x_UncstKey; - union pn48 txpn; /* PN48 used for Unicast xmit.*/ - union pn48 rxpn; /* PN48 used for Unicast recv.*/ - u8 bssrateset[16]; - uint bssratelen; - s32 rssi; - s32 signal_quality; - struct stainfo_stats sta_stats; - /*for A-MPDU Rx reordering buffer control */ - struct recv_reorder_ctrl recvreorder_ctrl[16]; - struct ht_priv htpriv; - /* Notes: - * STA_Mode: - * curr_network(mlme_priv/security_priv/qos/ht) - * + sta_info: (STA & AP) CAP/INFO - * scan_q: AP CAP/INFO - * AP_Mode: - * curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO - * sta_info: (AP & STA) CAP/INFO - */ - struct list_head asoc_list; - struct list_head auth_list; - unsigned int expire_to; - unsigned int auth_seq; - unsigned int authalg; - unsigned char chg_txt[128]; - unsigned int tx_ra_bitmap; -}; - -struct sta_priv { - u8 *pallocated_stainfo_buf; - u8 *pstainfo_buf; - struct __queue free_sta_queue; - spinlock_t sta_hash_lock; - struct list_head sta_hash[NUM_STA]; - int asoc_sta_count; - struct __queue sleep_q; - struct __queue wakeup_q; - struct _adapter *padapter; - struct list_head asoc_list; - struct list_head auth_list; - unsigned int auth_to; /* sec, time to expire in authenticating. */ - unsigned int assoc_to; /* sec, time to expire before associating. */ - unsigned int expire_to; /* sec , time to expire after associated. */ -}; - -static inline u32 wifi_mac_hash(u8 *mac) -{ - u32 x; - - x = mac[0]; - x = (x << 2) ^ mac[1]; - x = (x << 2) ^ mac[2]; - x = (x << 2) ^ mac[3]; - x = (x << 2) ^ mac[4]; - x = (x << 2) ^ mac[5]; - x ^= x >> 8; - x = x & (NUM_STA - 1); - return x; -} - -int _r8712_init_sta_priv(struct sta_priv *pstapriv); -void _r8712_free_sta_priv(struct sta_priv *pstapriv); -struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, - u8 *hwaddr); -void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta); -void r8712_free_all_stainfo(struct _adapter *padapter); -struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); -void r8712_init_bcmc_stainfo(struct _adapter *padapter); -struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter); -u8 r8712_access_ctrl(struct wlan_acl_pool *pacl_list, u8 *mac_addr); - -#endif /* _STA_INFO_H_ */ - diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c deleted file mode 100644 index 313c569748e99b5db4e845479321c985e9f00bf5..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/usb_halinit.c +++ /dev/null @@ -1,307 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_halinit.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_HAL_INIT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "usb_ops.h" -#include "usb_osintf.h" - -u8 r8712_usb_hal_bus_init(struct _adapter *adapter) -{ - u8 val8 = 0; - u8 ret = _SUCCESS; - int PollingCnt = 20; - struct registry_priv *registrypriv = &adapter->registrypriv; - - if (registrypriv->chip_version == RTL8712_FPGA) { - val8 = 0x01; - /* switch to 80M clock */ - r8712_write8(adapter, SYS_CLKR, val8); - val8 = r8712_read8(adapter, SPS1_CTRL); - val8 = val8 | 0x01; - /* enable VSPS12 LDO Macro block */ - r8712_write8(adapter, SPS1_CTRL, val8); - val8 = r8712_read8(adapter, AFE_MISC); - val8 = val8 | 0x01; - /* Enable AFE Macro Block's Bandgap */ - r8712_write8(adapter, AFE_MISC, val8); - val8 = r8712_read8(adapter, LDOA15_CTRL); - val8 = val8 | 0x01; - /* enable LDOA15 block */ - r8712_write8(adapter, LDOA15_CTRL, val8); - val8 = r8712_read8(adapter, SPS1_CTRL); - val8 = val8 | 0x02; - /* Enable VSPS12_SW Macro Block */ - r8712_write8(adapter, SPS1_CTRL, val8); - val8 = r8712_read8(adapter, AFE_MISC); - val8 = val8 | 0x02; - /* Enable AFE Macro Block's Mbias */ - r8712_write8(adapter, AFE_MISC, val8); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - val8 = val8 | 0x08; - /* isolate PCIe Analog 1.2V to PCIe 3.3V and PCIE Digital */ - r8712_write8(adapter, SYS_ISO_CTRL + 1, val8); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - val8 = val8 & 0xEF; - /* attach AFE PLL to MACTOP/BB/PCIe Digital */ - r8712_write8(adapter, SYS_ISO_CTRL + 1, val8); - val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1); - val8 = val8 & 0xFB; - /* enable AFE clock */ - r8712_write8(adapter, AFE_XTAL_CTRL + 1, val8); - val8 = r8712_read8(adapter, AFE_PLL_CTRL); - val8 = val8 | 0x01; - /* Enable AFE PLL Macro Block */ - r8712_write8(adapter, AFE_PLL_CTRL, val8); - val8 = 0xEE; - /* release isolation AFE PLL & MD */ - r8712_write8(adapter, SYS_ISO_CTRL, val8); - val8 = r8712_read8(adapter, SYS_CLKR + 1); - val8 = val8 | 0x08; - /* enable MAC clock */ - r8712_write8(adapter, SYS_CLKR + 1, val8); - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - val8 = val8 | 0x08; - /* enable Core digital and enable IOREG R/W */ - r8712_write8(adapter, SYS_FUNC_EN + 1, val8); - val8 = val8 | 0x80; - /* enable REG_EN */ - r8712_write8(adapter, SYS_FUNC_EN + 1, val8); - val8 = r8712_read8(adapter, SYS_CLKR + 1); - val8 = (val8 | 0x80) & 0xBF; - /* switch the control path */ - r8712_write8(adapter, SYS_CLKR + 1, val8); - val8 = 0xFC; - r8712_write8(adapter, CR, val8); - val8 = 0x37; - r8712_write8(adapter, CR + 1, val8); - /* reduce EndPoint & init it */ - r8712_write8(adapter, 0x102500ab, r8712_read8(adapter, - 0x102500ab) | BIT(6) | BIT(7)); - /* consideration of power consumption - init */ - r8712_write8(adapter, 0x10250008, r8712_read8(adapter, - 0x10250008) & 0xfffffffb); - } else if (registrypriv->chip_version == RTL8712_1stCUT) { - /* Initialization for power on sequence, */ - r8712_write8(adapter, SPS0_CTRL + 1, 0x53); - r8712_write8(adapter, SPS0_CTRL, 0x57); - /* Enable AFE Macro Block's Bandgap and Enable AFE Macro - * Block's Mbias - */ - val8 = r8712_read8(adapter, AFE_MISC); - r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN | - AFE_MISC_MBEN)); - /* Enable LDOA15 block */ - val8 = r8712_read8(adapter, LDOA15_CTRL); - r8712_write8(adapter, LDOA15_CTRL, (val8 | LDA15_EN)); - val8 = r8712_read8(adapter, SPS1_CTRL); - r8712_write8(adapter, SPS1_CTRL, (val8 | SPS1_LDEN)); - msleep(20); - /* Enable Switch Regulator Block */ - val8 = r8712_read8(adapter, SPS1_CTRL); - r8712_write8(adapter, SPS1_CTRL, (val8 | SPS1_SWEN)); - r8712_write32(adapter, SPS1_CTRL, 0x00a7b267); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 | 0x08)); - /* Engineer Packet CP test Enable */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x20)); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 & 0x6F)); - /* Enable AFE clock */ - val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1); - r8712_write8(adapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb)); - /* Enable AFE PLL Macro Block */ - val8 = r8712_read8(adapter, AFE_PLL_CTRL); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11)); - /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ - val8 = r8712_read8(adapter, SYS_ISO_CTRL); - r8712_write8(adapter, SYS_ISO_CTRL, (val8 & 0xEE)); - /* Switch to 40M clock */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, val8 & (~SYS_CLKSEL)); - /* SSC Disable */ - val8 = r8712_read8(adapter, SYS_CLKR); - /* Enable MAC clock */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x18)); - /* Revised POS, */ - r8712_write8(adapter, PMC_FSM, 0x02); - /* Enable Core digital and enable IOREG R/W */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x08)); - /* Enable REG_EN */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x80)); - /* Switch the control path to FW */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF); - r8712_write8(adapter, CR, 0xFC); - r8712_write8(adapter, CR + 1, 0x37); - /* Fix the RX FIFO issue(usb error), */ - val8 = r8712_read8(adapter, 0x1025FE5c); - r8712_write8(adapter, 0x1025FE5c, (val8 | BIT(7))); - val8 = r8712_read8(adapter, 0x102500ab); - r8712_write8(adapter, 0x102500ab, (val8 | BIT(6) | BIT(7))); - /* For power save, used this in the bit file after 970621 */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, val8 & (~CPU_CLKSEL)); - } else if (registrypriv->chip_version == RTL8712_2ndCUT || - registrypriv->chip_version == RTL8712_3rdCUT) { - /* Initialization for power on sequence, - * E-Fuse leakage prevention sequence - */ - r8712_write8(adapter, 0x37, 0xb0); - msleep(20); - r8712_write8(adapter, 0x37, 0x30); - /* Set control path switch to HW control and reset Digital Core, - * CPU Core and MAC I/O to solve FW download fail when system - * from resume sate. - */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - if (val8 & 0x80) { - val8 &= 0x3f; - r8712_write8(adapter, SYS_CLKR + 1, val8); - } - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - val8 &= 0x73; - r8712_write8(adapter, SYS_FUNC_EN + 1, val8); - msleep(20); - /* Revised POS, */ - /* Enable AFE Macro Block's Bandgap and Enable AFE Macro - * Block's Mbias - */ - r8712_write8(adapter, SPS0_CTRL + 1, 0x53); - r8712_write8(adapter, SPS0_CTRL, 0x57); - val8 = r8712_read8(adapter, AFE_MISC); - /*Bandgap*/ - r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN)); - r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN | - AFE_MISC_MBEN | AFE_MISC_I32_EN)); - /* Enable PLL Power (LDOA15V) */ - val8 = r8712_read8(adapter, LDOA15_CTRL); - r8712_write8(adapter, LDOA15_CTRL, (val8 | LDA15_EN)); - /* Enable LDOV12D block */ - val8 = r8712_read8(adapter, LDOV12D_CTRL); - r8712_write8(adapter, LDOV12D_CTRL, (val8 | LDV12_EN)); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 | 0x08)); - /* Engineer Packet CP test Enable */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x20)); - /* Support 64k IMEM */ - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 & 0x68)); - /* Enable AFE clock */ - val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1); - r8712_write8(adapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb)); - /* Enable AFE PLL Macro Block */ - val8 = r8712_read8(adapter, AFE_PLL_CTRL); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11)); - /* Some sample will download fw failure. The clock will be - * stable with 500 us delay after reset the PLL - * TODO: When usleep is added to kernel, change next 3 - * udelay(500) to usleep(500) - */ - udelay(500); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x51)); - udelay(500); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11)); - udelay(500); - /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ - val8 = r8712_read8(adapter, SYS_ISO_CTRL); - r8712_write8(adapter, SYS_ISO_CTRL, (val8 & 0xEE)); - /* Switch to 40M clock */ - r8712_write8(adapter, SYS_CLKR, 0x00); - /* CPU Clock and 80M Clock SSC Disable to overcome FW download - * fail timing issue. - */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, (val8 | 0xa0)); - /* Enable MAC clock */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x18)); - /* Revised POS, */ - r8712_write8(adapter, PMC_FSM, 0x02); - /* Enable Core digital and enable IOREG R/W */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x08)); - /* Enable REG_EN */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x80)); - /* Switch the control path to FW */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF); - r8712_write8(adapter, CR, 0xFC); - r8712_write8(adapter, CR + 1, 0x37); - /* Fix the RX FIFO issue(usb error), 970410 */ - val8 = r8712_read8(adapter, 0x1025FE5c); - r8712_write8(adapter, 0x1025FE5c, (val8 | BIT(7))); - /* For power save, used this in the bit file after 970621 */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, val8 & (~CPU_CLKSEL)); - /* Revised for 8051 ROM code wrong operation. */ - r8712_write8(adapter, 0x1025fe1c, 0x80); - /* To make sure that TxDMA can ready to download FW. - * We should reset TxDMA if IMEM RPT was not ready. - */ - do { - val8 = r8712_read8(adapter, TCR); - if ((val8 & _TXDMA_INIT_VALUE) == _TXDMA_INIT_VALUE) - break; - udelay(5); /* PlatformStallExecution(5); */ - } while (PollingCnt--); /* Delay 1ms */ - - if (PollingCnt <= 0) { - val8 = r8712_read8(adapter, CR); - r8712_write8(adapter, CR, val8 & (~_TXDMA_EN)); - udelay(2); /* PlatformStallExecution(2); */ - /* Reset TxDMA */ - r8712_write8(adapter, CR, val8 | _TXDMA_EN); - } - } else { - ret = _FAIL; - } - return ret; -} - -unsigned int r8712_usb_inirp_init(struct _adapter *adapter) -{ - u8 i; - struct recv_buf *recvbuf; - struct intf_hdl *intfhdl = &adapter->pio_queue->intf; - struct recv_priv *recvpriv = &(adapter->recvpriv); - - recvpriv->ff_hwaddr = RTL8712_DMA_RX0FF; /* mapping rx fifo address */ - /* issue Rx irp to receive data */ - recvbuf = (struct recv_buf *)recvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - if (r8712_usb_read_port(intfhdl, recvpriv->ff_hwaddr, 0, - (unsigned char *)recvbuf) == false) - return _FAIL; - recvbuf++; - recvpriv->free_recv_buf_queue_cnt--; - } - return _SUCCESS; -} - -unsigned int r8712_usb_inirp_deinit(struct _adapter *adapter) -{ - r8712_usb_read_port_cancel(adapter); - return _SUCCESS; -} diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c deleted file mode 100644 index df05213f922f45b031f27b79959e4e08da626dcf..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/usb_intf.c +++ /dev/null @@ -1,638 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_intf.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_INTF_C_ - -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "xmit_osdep.h" -#include "rtl8712_efuse.h" -#include "usb_ops.h" -#include "usb_osintf.h" - -static struct usb_interface *pintf; - -static int r871xu_drv_init(struct usb_interface *pusb_intf, - const struct usb_device_id *pdid); - -static void r871xu_dev_remove(struct usb_interface *pusb_intf); - -static const struct usb_device_id rtl871x_usb_id_tbl[] = { -/* RTL8188SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8171)}, - {USB_DEVICE(0x0bda, 0x8173)}, - {USB_DEVICE(0x0bda, 0x8712)}, - {USB_DEVICE(0x0bda, 0x8713)}, - {USB_DEVICE(0x0bda, 0xC512)}, - /* Abocom */ - {USB_DEVICE(0x07B8, 0x8188)}, - /* ASUS */ - {USB_DEVICE(0x0B05, 0x1786)}, - {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */ - /* Belkin */ - {USB_DEVICE(0x050D, 0x945A)}, - /* ISY IWL - Belkin clone */ - {USB_DEVICE(0x050D, 0x11F1)}, - /* Corega */ - {USB_DEVICE(0x07AA, 0x0047)}, - /* D-Link */ - {USB_DEVICE(0x2001, 0x3306)}, - {USB_DEVICE(0x07D1, 0x3306)}, /* 11n mode disable */ - /* Edimax */ - {USB_DEVICE(0x7392, 0x7611)}, - /* EnGenius */ - {USB_DEVICE(0x1740, 0x9603)}, - /* Hawking */ - {USB_DEVICE(0x0E66, 0x0016)}, - /* Hercules */ - {USB_DEVICE(0x06F8, 0xE034)}, - {USB_DEVICE(0x06F8, 0xE032)}, - /* Logitec */ - {USB_DEVICE(0x0789, 0x0167)}, - /* PCI */ - {USB_DEVICE(0x2019, 0xAB28)}, - {USB_DEVICE(0x2019, 0xED16)}, - /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x0057)}, - {USB_DEVICE(0x0DF6, 0x0045)}, - {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ - {USB_DEVICE(0x0DF6, 0x004B)}, - {USB_DEVICE(0x0DF6, 0x005B)}, - {USB_DEVICE(0x0DF6, 0x005D)}, - {USB_DEVICE(0x0DF6, 0x0063)}, - /* Sweex */ - {USB_DEVICE(0x177F, 0x0154)}, - /* Thinkware */ - {USB_DEVICE(0x0BDA, 0x5077)}, - /* Toshiba */ - {USB_DEVICE(0x1690, 0x0752)}, - /* - */ - {USB_DEVICE(0x20F4, 0x646B)}, - {USB_DEVICE(0x083A, 0xC512)}, - {USB_DEVICE(0x25D4, 0x4CA1)}, - {USB_DEVICE(0x25D4, 0x4CAB)}, - -/* RTL8191SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8172)}, - {USB_DEVICE(0x0BDA, 0x8192)}, - /* Amigo */ - {USB_DEVICE(0x0EB0, 0x9061)}, - /* ASUS/EKB */ - {USB_DEVICE(0x13D3, 0x3323)}, - {USB_DEVICE(0x13D3, 0x3311)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3342)}, - /* ASUS/EKBLenovo */ - {USB_DEVICE(0x13D3, 0x3333)}, - {USB_DEVICE(0x13D3, 0x3334)}, - {USB_DEVICE(0x13D3, 0x3335)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3336)}, /* 11n mode disable */ - /* ASUS/Media BOX */ - {USB_DEVICE(0x13D3, 0x3309)}, - /* Belkin */ - {USB_DEVICE(0x050D, 0x815F)}, - /* D-Link */ - {USB_DEVICE(0x07D1, 0x3302)}, - {USB_DEVICE(0x07D1, 0x3300)}, - {USB_DEVICE(0x07D1, 0x3303)}, - /* Edimax */ - {USB_DEVICE(0x7392, 0x7612)}, - /* EnGenius */ - {USB_DEVICE(0x1740, 0x9605)}, - /* Guillemot */ - {USB_DEVICE(0x06F8, 0xE031)}, - /* Hawking */ - {USB_DEVICE(0x0E66, 0x0015)}, - /* Mediao */ - {USB_DEVICE(0x13D3, 0x3306)}, - /* PCI */ - {USB_DEVICE(0x2019, 0xED18)}, - {USB_DEVICE(0x2019, 0x4901)}, - /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x0058)}, - {USB_DEVICE(0x0DF6, 0x0049)}, - {USB_DEVICE(0x0DF6, 0x004C)}, - {USB_DEVICE(0x0DF6, 0x006C)}, - {USB_DEVICE(0x0DF6, 0x0064)}, - /* Skyworth */ - {USB_DEVICE(0x14b2, 0x3300)}, - {USB_DEVICE(0x14b2, 0x3301)}, - {USB_DEVICE(0x14B2, 0x3302)}, - /* - */ - {USB_DEVICE(0x04F2, 0xAFF2)}, - {USB_DEVICE(0x04F2, 0xAFF5)}, - {USB_DEVICE(0x04F2, 0xAFF6)}, - {USB_DEVICE(0x13D3, 0x3339)}, - {USB_DEVICE(0x13D3, 0x3340)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3341)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3310)}, - {USB_DEVICE(0x13D3, 0x3325)}, - -/* RTL8192SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8174)}, - /* Belkin */ - {USB_DEVICE(0x050D, 0x845A)}, - /* Corega */ - {USB_DEVICE(0x07AA, 0x0051)}, - /* Edimax */ - {USB_DEVICE(0x7392, 0x7622)}, - /* NEC */ - {USB_DEVICE(0x0409, 0x02B6)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, rtl871x_usb_id_tbl); - -static struct specific_device_id specific_device_id_tbl[] = { - {.idVendor = 0x0b05, .idProduct = 0x1791, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x0df6, .idProduct = 0x0059, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3306, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13D3, .idProduct = 0x3311, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3335, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3336, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3340, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3341, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {} -}; - -struct drv_priv { - struct usb_driver r871xu_drv; - int drv_registered; -}; - -#ifdef CONFIG_PM -static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state) -{ - struct net_device *pnetdev = usb_get_intfdata(pusb_intf); - struct _adapter *padapter = netdev_priv(pnetdev); - - netdev_info(pnetdev, "Suspending...\n"); - padapter->suspended = true; - rtl871x_intf_stop(padapter); - if (pnetdev->netdev_ops->ndo_stop) - pnetdev->netdev_ops->ndo_stop(pnetdev); - mdelay(10); - netif_device_detach(pnetdev); - return 0; -} - -static void rtl871x_intf_resume(struct _adapter *padapter) -{ - if (padapter->dvobjpriv.inirp_init) - padapter->dvobjpriv.inirp_init(padapter); -} - -static int r871x_resume(struct usb_interface *pusb_intf) -{ - struct net_device *pnetdev = usb_get_intfdata(pusb_intf); - struct _adapter *padapter = netdev_priv(pnetdev); - - netdev_info(pnetdev, "Resuming...\n"); - netif_device_attach(pnetdev); - if (pnetdev->netdev_ops->ndo_open) - pnetdev->netdev_ops->ndo_open(pnetdev); - padapter->suspended = false; - rtl871x_intf_resume(padapter); - return 0; -} -#endif - -static struct drv_priv drvpriv = { - .r871xu_drv.name = "r8712u", - .r871xu_drv.id_table = rtl871x_usb_id_tbl, - .r871xu_drv.probe = r871xu_drv_init, - .r871xu_drv.disconnect = r871xu_dev_remove, -#ifdef CONFIG_PM - .r871xu_drv.suspend = r871x_suspend, - .r871xu_drv.resume = r871x_resume, -#endif -}; - -static uint r8712_usb_dvobj_init(struct _adapter *padapter) -{ - uint status = _SUCCESS; - struct usb_host_interface *phost_iface; - struct usb_interface_descriptor *piface_desc; - struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; - struct usb_device *pusbd = pdvobjpriv->pusbdev; - - pdvobjpriv->padapter = padapter; - padapter->eeprom_address_size = 6; - phost_iface = pintf->cur_altsetting; - piface_desc = &phost_iface->desc; - pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; - if (pusbd->speed == USB_SPEED_HIGH) { - pdvobjpriv->ishighspeed = true; - dev_info(&pusbd->dev, "r8712u: USB_SPEED_HIGH with %d endpoints\n", - pdvobjpriv->nr_endpoint); - } else { - pdvobjpriv->ishighspeed = false; - dev_info(&pusbd->dev, "r8712u: USB_SPEED_LOW with %d endpoints\n", - pdvobjpriv->nr_endpoint); - } - if ((r8712_alloc_io_queue(padapter)) == _FAIL) - status = _FAIL; - return status; -} - -static void r8712_usb_dvobj_deinit(struct _adapter *padapter) -{ - r8712_free_io_queue(padapter); -} - -void rtl871x_intf_stop(struct _adapter *padapter) -{ - /*disable_hw_interrupt*/ - if (!padapter->surprise_removed) { - /*device still exists, so driver can do i/o operation - * TODO: - */ - } - - /* cancel in irp */ - if (padapter->dvobjpriv.inirp_deinit) - padapter->dvobjpriv.inirp_deinit(padapter); - /* cancel out irp */ - r8712_usb_write_port_cancel(padapter); - /* TODO:cancel other irps */ -} - -void r871x_dev_unload(struct _adapter *padapter) -{ - if (padapter->bup) { - /*s1.*/ - padapter->driver_stopped = true; - - /*s3.*/ - rtl871x_intf_stop(padapter); - - /*s4.*/ - r8712_stop_drv_threads(padapter); - - /*s5.*/ - if (!padapter->surprise_removed) { - padapter->hw_init_completed = false; - rtl8712_hal_deinit(padapter); - } - - padapter->bup = false; - } -} - -static void disable_ht_for_spec_devid(const struct usb_device_id *pdid, - struct _adapter *padapter) -{ - u16 vid, pid; - u32 flags; - int i; - int num = ARRAY_SIZE(specific_device_id_tbl); - - for (i = 0; i < num; i++) { - vid = specific_device_id_tbl[i].idVendor; - pid = specific_device_id_tbl[i].idProduct; - flags = specific_device_id_tbl[i].flags; - - if ((pdid->idVendor == vid) && (pdid->idProduct == pid) && - (flags & SPEC_DEV_ID_DISABLE_HT)) { - padapter->registrypriv.ht_enable = 0; - padapter->registrypriv.cbw40_enable = 0; - padapter->registrypriv.ampdu_enable = 0; - } - } -} - -static const struct device_type wlan_type = { - .name = "wlan", -}; - -/* - * drv_init() - a device potentially for us - * - * notes: drv_init() is called when the bus driver has located a card for us - * to support. We accept the new device by returning 0. - */ -static int r871xu_drv_init(struct usb_interface *pusb_intf, - const struct usb_device_id *pdid) -{ - uint status; - struct _adapter *padapter = NULL; - struct dvobj_priv *pdvobjpriv; - struct net_device *pnetdev; - struct usb_device *udev; - - /* In this probe function, O.S. will provide the usb interface pointer - * to driver. We have to increase the reference count of the usb device - * structure by using the usb_get_dev function. - */ - udev = interface_to_usbdev(pusb_intf); - usb_get_dev(udev); - pintf = pusb_intf; - /* step 1. */ - pnetdev = r8712_init_netdev(); - if (!pnetdev) - goto put_dev; - padapter = netdev_priv(pnetdev); - disable_ht_for_spec_devid(pdid, padapter); - pdvobjpriv = &padapter->dvobjpriv; - pdvobjpriv->padapter = padapter; - padapter->dvobjpriv.pusbdev = udev; - padapter->pusb_intf = pusb_intf; - usb_set_intfdata(pusb_intf, pnetdev); - SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); - pnetdev->dev.type = &wlan_type; - /* step 2. */ - padapter->dvobj_init = r8712_usb_dvobj_init; - padapter->dvobj_deinit = r8712_usb_dvobj_deinit; - padapter->halpriv.hal_bus_init = r8712_usb_hal_bus_init; - padapter->dvobjpriv.inirp_init = r8712_usb_inirp_init; - padapter->dvobjpriv.inirp_deinit = r8712_usb_inirp_deinit; - /* step 3. - * initialize the dvobj_priv - */ - - status = padapter->dvobj_init(padapter); - if (status != _SUCCESS) - goto free_netdev; - - /* step 4. */ - status = r8712_init_drv_sw(padapter); - if (status) - goto dvobj_deinit; - /* step 5. read efuse/eeprom data and get mac_addr */ - { - int i, offset; - u8 mac[6]; - u8 tmpU1b, AutoloadFail, eeprom_CustomerID; - u8 *pdata = padapter->eeprompriv.efuse_eeprom_data; - - tmpU1b = r8712_read8(padapter, EE_9346CR);/*CR9346*/ - - /* To check system boot selection.*/ - dev_info(&udev->dev, "r8712u: Boot from %s: Autoload %s\n", - (tmpU1b & _9356SEL) ? "EEPROM" : "EFUSE", - (tmpU1b & _EEPROM_EN) ? "OK" : "Failed"); - - /* To check autoload success or not.*/ - if (tmpU1b & _EEPROM_EN) { - AutoloadFail = true; - /* The following operations prevent Efuse leakage by - * turning on 2.5V. - */ - tmpU1b = r8712_read8(padapter, EFUSE_TEST + 3); - r8712_write8(padapter, EFUSE_TEST + 3, tmpU1b | 0x80); - msleep(20); - r8712_write8(padapter, EFUSE_TEST + 3, - (tmpU1b & (~BIT(7)))); - - /* Retrieve Chip version. - * Recognize IC version by Reg0x4 BIT15. - */ - tmpU1b = (u8)((r8712_read32(padapter, PMC_FSM) >> 15) & - 0x1F); - if (tmpU1b == 0x3) - padapter->registrypriv.chip_version = - RTL8712_3rdCUT; - else - padapter->registrypriv.chip_version = - (tmpU1b >> 1) + 1; - switch (padapter->registrypriv.chip_version) { - case RTL8712_1stCUT: - case RTL8712_2ndCUT: - case RTL8712_3rdCUT: - break; - default: - padapter->registrypriv.chip_version = - RTL8712_2ndCUT; - break; - } - - for (i = 0, offset = 0; i < 128; i += 8, offset++) - r8712_efuse_pg_packet_read(padapter, offset, - &pdata[i]); - - if (!r8712_initmac || !mac_pton(r8712_initmac, mac)) { - /* Use the mac address stored in the Efuse - * offset = 0x12 for usb in efuse - */ - ether_addr_copy(mac, &pdata[0x12]); - } - eeprom_CustomerID = pdata[0x52]; - switch (eeprom_CustomerID) { - case EEPROM_CID_ALPHA: - padapter->eeprompriv.CustomerID = - RT_CID_819x_ALPHA; - break; - case EEPROM_CID_CAMEO: - padapter->eeprompriv.CustomerID = - RT_CID_819x_CAMEO; - break; - case EEPROM_CID_SITECOM: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Sitecom; - break; - case EEPROM_CID_COREGA: - padapter->eeprompriv.CustomerID = - RT_CID_COREGA; - break; - case EEPROM_CID_Senao: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Senao; - break; - case EEPROM_CID_EDIMAX_BELKIN: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Edimax_Belkin; - break; - case EEPROM_CID_SERCOMM_BELKIN: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Sercomm_Belkin; - break; - case EEPROM_CID_WNC_COREGA: - padapter->eeprompriv.CustomerID = - RT_CID_819x_WNC_COREGA; - break; - case EEPROM_CID_WHQL: - break; - case EEPROM_CID_NetCore: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Netcore; - break; - case EEPROM_CID_CAMEO1: - padapter->eeprompriv.CustomerID = - RT_CID_819x_CAMEO1; - break; - case EEPROM_CID_CLEVO: - padapter->eeprompriv.CustomerID = - RT_CID_819x_CLEVO; - break; - default: - padapter->eeprompriv.CustomerID = - RT_CID_DEFAULT; - break; - } - dev_info(&udev->dev, "r8712u: CustomerID = 0x%.4x\n", - padapter->eeprompriv.CustomerID); - /* Led mode */ - switch (padapter->eeprompriv.CustomerID) { - case RT_CID_DEFAULT: - case RT_CID_819x_ALPHA: - case RT_CID_819x_CAMEO: - padapter->ledpriv.LedStrategy = SW_LED_MODE1; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_Sitecom: - padapter->ledpriv.LedStrategy = SW_LED_MODE2; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_COREGA: - case RT_CID_819x_Senao: - padapter->ledpriv.LedStrategy = SW_LED_MODE3; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_Edimax_Belkin: - padapter->ledpriv.LedStrategy = SW_LED_MODE4; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_Sercomm_Belkin: - padapter->ledpriv.LedStrategy = SW_LED_MODE5; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_WNC_COREGA: - padapter->ledpriv.LedStrategy = SW_LED_MODE6; - padapter->ledpriv.bRegUseLed = true; - break; - default: - padapter->ledpriv.LedStrategy = SW_LED_MODE0; - padapter->ledpriv.bRegUseLed = false; - break; - } - } else { - AutoloadFail = false; - } - if ((!AutoloadFail) || - ((mac[0] == 0xff) && (mac[1] == 0xff) && - (mac[2] == 0xff) && (mac[3] == 0xff) && - (mac[4] == 0xff) && (mac[5] == 0xff)) || - ((mac[0] == 0x00) && (mac[1] == 0x00) && - (mac[2] == 0x00) && (mac[3] == 0x00) && - (mac[4] == 0x00) && (mac[5] == 0x00))) { - mac[0] = 0x00; - mac[1] = 0xe0; - mac[2] = 0x4c; - mac[3] = 0x87; - mac[4] = 0x00; - mac[5] = 0x00; - } - if (r8712_initmac) { - /* Make sure the user did not select a multicast - * address by setting bit 1 of first octet. - */ - mac[0] &= 0xFE; - dev_info(&udev->dev, - "r8712u: MAC Address from user = %pM\n", mac); - } else { - dev_info(&udev->dev, - "r8712u: MAC Address from efuse = %pM\n", mac); - } - eth_hw_addr_set(pnetdev, mac); - } - /* step 6. Load the firmware asynchronously */ - if (rtl871x_load_fw(padapter)) - goto deinit_drv_sw; - init_completion(&padapter->rx_filter_ready); - return 0; - -deinit_drv_sw: - r8712_free_drv_sw(padapter); -dvobj_deinit: - padapter->dvobj_deinit(padapter); -free_netdev: - free_netdev(pnetdev); -put_dev: - usb_put_dev(udev); - usb_set_intfdata(pusb_intf, NULL); - return -ENODEV; -} - -/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() - * => how to recognize both - */ -static void r871xu_dev_remove(struct usb_interface *pusb_intf) -{ - struct net_device *pnetdev = usb_get_intfdata(pusb_intf); - struct usb_device *udev = interface_to_usbdev(pusb_intf); - struct _adapter *padapter = netdev_priv(pnetdev); - - /* never exit with a firmware callback pending */ - wait_for_completion(&padapter->rtl8712_fw_ready); - if (pnetdev->reg_state != NETREG_UNINITIALIZED) - unregister_netdev(pnetdev); /* will call netdev_close() */ - usb_set_intfdata(pusb_intf, NULL); - release_firmware(padapter->fw); - if (drvpriv.drv_registered) - padapter->surprise_removed = true; - r8712_flush_rwctrl_works(padapter); - r8712_flush_led_works(padapter); - udelay(1); - /* Stop driver mlme relation timer */ - r8712_stop_drv_timers(padapter); - r871x_dev_unload(padapter); - if (padapter->dvobj_deinit) - padapter->dvobj_deinit(padapter); - r8712_free_drv_sw(padapter); - free_netdev(pnetdev); - - /* decrease the reference count of the usb device structure - * when disconnect - */ - usb_put_dev(udev); - - /* If we didn't unplug usb dongle and remove/insert module, driver - * fails on sitesurvey for the first time when device is up. - * Reset usb port for sitesurvey fail issue. - */ - if (udev->state != USB_STATE_NOTATTACHED) - usb_reset_device(udev); -} - -static int __init r8712u_drv_entry(void) -{ - drvpriv.drv_registered = true; - return usb_register(&drvpriv.r871xu_drv); -} - -static void __exit r8712u_drv_halt(void) -{ - drvpriv.drv_registered = false; - usb_deregister(&drvpriv.r871xu_drv); -} - -module_init(r8712u_drv_entry); -module_exit(r8712u_drv_halt); diff --git a/drivers/staging/rtl8712/usb_ops.c b/drivers/staging/rtl8712/usb_ops.c deleted file mode 100644 index af9966d03979c6f0221e11b5469cddf838081b2a..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/usb_ops.c +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_ops.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_OPS_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" -#include "usb_ops.h" -#include "recv_osdep.h" - -static u8 usb_read8(struct intf_hdl *intfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - int status; - __le32 data = 0; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x01; /* read_in */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 1; - status = r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, - &data, len, requesttype); - if (status < 0) - return 0; - return (u8)(le32_to_cpu(data) & 0x0ff); -} - -static u16 usb_read16(struct intf_hdl *intfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - int status; - __le32 data = 0; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x01; /* read_in */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 2; - status = r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, - &data, len, requesttype); - if (status < 0) - return 0; - return (u16)(le32_to_cpu(data) & 0xffff); -} - -static u32 usb_read32(struct intf_hdl *intfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - int status; - __le32 data = 0; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x01; /* read_in */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 4; - status = r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, - &data, len, requesttype); - if (status < 0) - return 0; - return le32_to_cpu(data); -} - -static void usb_write8(struct intf_hdl *intfhdl, u32 addr, u8 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - __le32 data; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x00; /* write_out */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 1; - data = cpu_to_le32((u32)val & 0x000000ff); - r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, &data, len, - requesttype); -} - -static void usb_write16(struct intf_hdl *intfhdl, u32 addr, u16 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - __le32 data; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x00; /* write_out */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 2; - data = cpu_to_le32((u32)val & 0x0000ffff); - r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, &data, len, - requesttype); -} - -static void usb_write32(struct intf_hdl *intfhdl, u32 addr, u32 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - __le32 data; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x00; /* write_out */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 4; - data = cpu_to_le32(val); - r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, &data, len, - requesttype); -} - -void r8712_usb_set_intf_option(u32 *option) -{ - *option = ((*option) | _INTF_ASYNC_); -} - -static void usb_intf_hdl_init(u8 *priv) -{ -} - -static void usb_intf_hdl_unload(u8 *priv) -{ -} - -static void usb_intf_hdl_open(u8 *priv) -{ -} - -static void usb_intf_hdl_close(u8 *priv) -{ -} - -void r8712_usb_set_intf_funs(struct intf_hdl *intfhdl) -{ - intfhdl->intf_hdl_init = usb_intf_hdl_init; - intfhdl->intf_hdl_unload = usb_intf_hdl_unload; - intfhdl->intf_hdl_open = usb_intf_hdl_open; - intfhdl->intf_hdl_close = usb_intf_hdl_close; -} - -void r8712_usb_set_intf_ops(struct _io_ops *ops) -{ - memset((u8 *)ops, 0, sizeof(struct _io_ops)); - ops->_read8 = usb_read8; - ops->_read16 = usb_read16; - ops->_read32 = usb_read32; - ops->_read_port = r8712_usb_read_port; - ops->_write8 = usb_write8; - ops->_write16 = usb_write16; - ops->_write32 = usb_write32; - ops->_write_mem = r8712_usb_write_mem; - ops->_write_port = r8712_usb_write_port; -} diff --git a/drivers/staging/rtl8712/usb_ops.h b/drivers/staging/rtl8712/usb_ops.h deleted file mode 100644 index 7a6b619b73fabe6bb2f1f966ed620ed91fdb2e71..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/usb_ops.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __USB_OPS_H_ -#define __USB_OPS_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" - -void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, - u32 cnt, u8 *wmem); -u32 r8712_usb_write_port(struct intf_hdl *pintfhdl, u32 addr, - u32 cnt, u8 *wmem); -u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, - u32 cnt, u8 *rmem); -void r8712_usb_set_intf_option(u32 *poption); -void r8712_usb_set_intf_funs(struct intf_hdl *pintf_hdl); -uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv); -void r8712_usb_unload_intf_priv(struct intf_priv *pintfpriv); -void r8712_usb_set_intf_ops(struct _io_ops *pops); -void r8712_usb_read_port_cancel(struct _adapter *padapter); -void r8712_usb_write_port_cancel(struct _adapter *padapter); -int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, - u16 index, void *pdata, u16 len, u8 requesttype); - -#endif - diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c deleted file mode 100644 index 4a34824830e39de1d7a298ccc5846f316adc2a22..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ /dev/null @@ -1,508 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_ops_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_OPS_OS_C_ - -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -#define RTL871X_VENQT_READ 0xc0 -#define RTL871X_VENQT_WRITE 0x40 - -uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv) -{ - pintfpriv->piorw_urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!pintfpriv->piorw_urb) - return _FAIL; - init_completion(&pintfpriv->io_retevt_comp); - return _SUCCESS; -} - -void r8712_usb_unload_intf_priv(struct intf_priv *pintfpriv) -{ - if (pintfpriv->piorw_urb) { - usb_kill_urb(pintfpriv->piorw_urb); - usb_free_urb(pintfpriv->piorw_urb); - } -} - -static unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr) -{ - unsigned int pipe = 0; - struct usb_device *pusbd = pdvobj->pusbdev; - - if (pdvobj->nr_endpoint == 11) { - switch (addr) { - case RTL8712_DMA_BKQ: - pipe = usb_sndbulkpipe(pusbd, 0x07); - break; - case RTL8712_DMA_BEQ: - pipe = usb_sndbulkpipe(pusbd, 0x06); - break; - case RTL8712_DMA_VIQ: - pipe = usb_sndbulkpipe(pusbd, 0x05); - break; - case RTL8712_DMA_VOQ: - pipe = usb_sndbulkpipe(pusbd, 0x04); - break; - case RTL8712_DMA_BCNQ: - pipe = usb_sndbulkpipe(pusbd, 0x0a); - break; - case RTL8712_DMA_BMCQ: /* HI Queue */ - pipe = usb_sndbulkpipe(pusbd, 0x0b); - break; - case RTL8712_DMA_MGTQ: - pipe = usb_sndbulkpipe(pusbd, 0x0c); - break; - case RTL8712_DMA_RX0FF: - pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ - break; - case RTL8712_DMA_C2HCMD: - pipe = usb_rcvbulkpipe(pusbd, 0x09); /* in */ - break; - case RTL8712_DMA_H2CCMD: - pipe = usb_sndbulkpipe(pusbd, 0x0d); - break; - } - } else if (pdvobj->nr_endpoint == 6) { - switch (addr) { - case RTL8712_DMA_BKQ: - pipe = usb_sndbulkpipe(pusbd, 0x07); - break; - case RTL8712_DMA_BEQ: - pipe = usb_sndbulkpipe(pusbd, 0x06); - break; - case RTL8712_DMA_VIQ: - pipe = usb_sndbulkpipe(pusbd, 0x05); - break; - case RTL8712_DMA_VOQ: - pipe = usb_sndbulkpipe(pusbd, 0x04); - break; - case RTL8712_DMA_RX0FF: - case RTL8712_DMA_C2HCMD: - pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ - break; - case RTL8712_DMA_H2CCMD: - case RTL8712_DMA_BCNQ: - case RTL8712_DMA_BMCQ: - case RTL8712_DMA_MGTQ: - pipe = usb_sndbulkpipe(pusbd, 0x0d); - break; - } - } else if (pdvobj->nr_endpoint == 4) { - switch (addr) { - case RTL8712_DMA_BEQ: - pipe = usb_sndbulkpipe(pusbd, 0x06); - break; - case RTL8712_DMA_VOQ: - pipe = usb_sndbulkpipe(pusbd, 0x04); - break; - case RTL8712_DMA_RX0FF: - case RTL8712_DMA_C2HCMD: - pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ - break; - case RTL8712_DMA_H2CCMD: - case RTL8712_DMA_BCNQ: - case RTL8712_DMA_BMCQ: - case RTL8712_DMA_MGTQ: - pipe = usb_sndbulkpipe(pusbd, 0x0d); - break; - } - } else { - pipe = 0; - } - return pipe; -} - -static void usb_write_mem_complete(struct urb *purb) -{ - struct io_queue *pio_q = (struct io_queue *)purb->context; - struct intf_hdl *pintf = &(pio_q->intf); - struct intf_priv *pintfpriv = pintf->pintfpriv; - struct _adapter *padapter = (struct _adapter *)pintf->adapter; - - if (purb->status != 0) { - if (purb->status == (-ESHUTDOWN)) - padapter->driver_stopped = true; - else - padapter->surprise_removed = true; - } - complete(&pintfpriv->io_retevt_comp); -} - -void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) -{ - unsigned int pipe; - struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; - struct intf_priv *pintfpriv = pintfhdl->pintfpriv; - struct io_queue *pio_queue = padapter->pio_queue; - struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev; - struct usb_device *pusbd = pdvobj->pusbdev; - struct urb *piorw_urb = pintfpriv->piorw_urb; - - if ((padapter->driver_stopped) || (padapter->surprise_removed) || - (padapter->pwrctrlpriv.pnp_bstop_trx)) - return; - /* translate DMA FIFO addr to pipehandle */ - pipe = ffaddr2pipehdl(pdvobj, addr); - if (pipe == 0) - return; - usb_fill_bulk_urb(piorw_urb, pusbd, pipe, - wmem, cnt, usb_write_mem_complete, - pio_queue); - usb_submit_urb(piorw_urb, GFP_ATOMIC); - wait_for_completion_interruptible(&pintfpriv->io_retevt_comp); -} - -static void r8712_usb_read_port_complete(struct urb *purb) -{ - uint isevt; - __le32 *pbuf; - struct recv_buf *precvbuf = (struct recv_buf *)purb->context; - struct _adapter *padapter = (struct _adapter *)precvbuf->adapter; - struct recv_priv *precvpriv = &padapter->recvpriv; - - if (padapter->surprise_removed || padapter->driver_stopped) - return; - if (purb->status == 0) { /* SUCCESS */ - if ((purb->actual_length > (MAX_RECVBUF_SZ)) || - (purb->actual_length < RXDESC_SIZE)) { - r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, - (unsigned char *)precvbuf); - } else { - _pkt *pskb = precvbuf->pskb; - - precvbuf->transfer_len = purb->actual_length; - pbuf = (__le32 *)precvbuf->pbuf; - isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff; - if ((isevt & 0x1ff) == 0x1ff) { - r8712_rxcmd_event_hdl(padapter, pbuf); - skb_queue_tail(&precvpriv->rx_skb_queue, pskb); - r8712_read_port(padapter, precvpriv->ff_hwaddr, - 0, (unsigned char *)precvbuf); - } else { - skb_put(pskb, purb->actual_length); - skb_queue_tail(&precvpriv->rx_skb_queue, pskb); - tasklet_hi_schedule(&precvpriv->recv_tasklet); - r8712_read_port(padapter, precvpriv->ff_hwaddr, - 0, (unsigned char *)precvbuf); - } - } - } else { - switch (purb->status) { - case -EINVAL: - case -EPIPE: - case -ENODEV: - case -ESHUTDOWN: - padapter->driver_stopped = true; - break; - case -ENOENT: - if (!padapter->suspended) { - padapter->driver_stopped = true; - break; - } - fallthrough; - case -EPROTO: - r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, - (unsigned char *)precvbuf); - break; - case -EINPROGRESS: - netdev_err(padapter->pnetdev, "ERROR: URB IS IN PROGRESS!\n"); - break; - default: - break; - } - } -} - -u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) -{ - unsigned int pipe; - int err; - u32 tmpaddr = 0; - int alignment = 0; - u32 ret = _SUCCESS; - struct urb *purb = NULL; - struct recv_buf *precvbuf = (struct recv_buf *)rmem; - struct intf_priv *pintfpriv = pintfhdl->pintfpriv; - struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev; - struct _adapter *adapter = pdvobj->padapter; - struct recv_priv *precvpriv = &adapter->recvpriv; - struct usb_device *pusbd = pdvobj->pusbdev; - - if (adapter->driver_stopped || adapter->surprise_removed || - adapter->pwrctrlpriv.pnp_bstop_trx || !precvbuf) - return _FAIL; - r8712_init_recvbuf(adapter, precvbuf); - /* Try to use skb from the free queue */ - precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); - - if (!precvbuf->pskb) { - precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, - MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - if (!precvbuf->pskb) - return _FAIL; - tmpaddr = (addr_t)precvbuf->pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); - skb_reserve(precvbuf->pskb, - (RECVBUFF_ALIGN_SZ - alignment)); - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - } else { /* skb is reused */ - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - } - purb = precvbuf->purb; - /* translate DMA FIFO addr to pipehandle */ - pipe = ffaddr2pipehdl(pdvobj, addr); - usb_fill_bulk_urb(purb, pusbd, pipe, - precvbuf->pbuf, MAX_RECVBUF_SZ, - r8712_usb_read_port_complete, - precvbuf); - err = usb_submit_urb(purb, GFP_ATOMIC); - if ((err) && (err != (-EPERM))) - ret = _FAIL; - return ret; -} - -void r8712_usb_read_port_cancel(struct _adapter *padapter) -{ - int i; - struct recv_buf *precvbuf; - - precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - if (precvbuf->purb) - usb_kill_urb(precvbuf->purb); - precvbuf++; - } -} - -void r8712_xmit_bh(struct tasklet_struct *t) -{ - int ret = false; - struct _adapter *padapter = from_tasklet(padapter, t, - xmitpriv.xmit_tasklet); - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - if (padapter->driver_stopped || - padapter->surprise_removed) { - netdev_err(padapter->pnetdev, "xmit_bh => driver_stopped or surprise_removed\n"); - return; - } - ret = r8712_xmitframe_complete(padapter, pxmitpriv, NULL); - if (!ret) - return; - tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); -} - -static void usb_write_port_complete(struct urb *purb) -{ - int i; - struct xmit_frame *pxmitframe = (struct xmit_frame *)purb->context; - struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; - struct _adapter *padapter = pxmitframe->padapter; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - switch (pattrib->priority) { - case 1: - case 2: - pxmitpriv->bkq_cnt--; - break; - case 4: - case 5: - pxmitpriv->viq_cnt--; - break; - case 6: - case 7: - pxmitpriv->voq_cnt--; - break; - case 0: - case 3: - default: - pxmitpriv->beq_cnt--; - break; - } - pxmitpriv->txirp_cnt--; - for (i = 0; i < 8; i++) { - if (purb == pxmitframe->pxmit_urb[i]) { - pxmitframe->bpending[i] = false; - break; - } - } - if (padapter->surprise_removed) - return; - switch (purb->status) { - case 0: - break; - default: - netdev_warn(padapter->pnetdev, - "r8712u: pipe error: (%d)\n", purb->status); - break; - } - /* not to consider tx fragment */ - r8712_free_xmitframe_ex(pxmitpriv, pxmitframe); - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); -} - -u32 r8712_usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) -{ - unsigned long irqL; - int i, status; - unsigned int pipe; - u32 ret, bwritezero; - struct urb *purb = NULL; - struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct xmit_frame *pxmitframe = (struct xmit_frame *)wmem; - struct usb_device *pusbd = pdvobj->pusbdev; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - if ((padapter->driver_stopped) || (padapter->surprise_removed) || - (padapter->pwrctrlpriv.pnp_bstop_trx)) - return _FAIL; - for (i = 0; i < 8; i++) { - if (!pxmitframe->bpending[i]) { - spin_lock_irqsave(&pxmitpriv->lock, irqL); - pxmitpriv->txirp_cnt++; - pxmitframe->bpending[i] = true; - switch (pattrib->priority) { - case 1: - case 2: - pxmitpriv->bkq_cnt++; - break; - case 4: - case 5: - pxmitpriv->viq_cnt++; - break; - case 6: - case 7: - pxmitpriv->voq_cnt++; - break; - case 0: - case 3: - default: - pxmitpriv->beq_cnt++; - break; - } - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - pxmitframe->sz[i] = (u16)cnt; - purb = pxmitframe->pxmit_urb[i]; - break; - } - } - bwritezero = false; - if (pdvobj->ishighspeed) { - if (cnt > 0 && cnt % 512 == 0) - bwritezero = true; - } else { - if (cnt > 0 && cnt % 64 == 0) - bwritezero = true; - } - /* translate DMA FIFO addr to pipehandle */ - pipe = ffaddr2pipehdl(pdvobj, addr); - if (pxmitpriv->free_xmitbuf_cnt % NR_XMITBUFF == 0) - purb->transfer_flags &= (~URB_NO_INTERRUPT); - else - purb->transfer_flags |= URB_NO_INTERRUPT; - if (bwritezero) - cnt += 8; - usb_fill_bulk_urb(purb, pusbd, pipe, - pxmitframe->mem_addr, - cnt, usb_write_port_complete, - pxmitframe); /* context is xmit_frame */ - status = usb_submit_urb(purb, GFP_ATOMIC); - if (!status) - ret = _SUCCESS; - else - ret = _FAIL; - return ret; -} - -void r8712_usb_write_port_cancel(struct _adapter *padapter) -{ - int i, j; - struct xmit_buf *pxmitbuf = (struct xmit_buf *) - padapter->xmitpriv.pxmitbuf; - - for (i = 0; i < NR_XMITBUFF; i++) { - for (j = 0; j < 8; j++) { - if (pxmitbuf->pxmit_urb[j]) - usb_kill_urb(pxmitbuf->pxmit_urb[j]); - } - pxmitbuf++; - } -} - -int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, - u16 index, void *pdata, u16 len, u8 requesttype) -{ - unsigned int pipe; - int status; - u8 reqtype; - struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *) - pintfpriv->intf_dev; - struct usb_device *udev = pdvobjpriv->pusbdev; - /* For mstar platform, mstar suggests the address for USB IO - * should be 16 bytes alignment. Trying to fix it here. - */ - u8 *palloc_buf, *pIo_buf; - - palloc_buf = kmalloc((u32)len + 16, GFP_ATOMIC); - if (!palloc_buf) - return -ENOMEM; - pIo_buf = palloc_buf + 16 - ((addr_t)(palloc_buf) & 0x0f); - if (requesttype == 0x01) { - pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ - reqtype = RTL871X_VENQT_READ; - } else { - pipe = usb_sndctrlpipe(udev, 0); /* write_out */ - reqtype = RTL871X_VENQT_WRITE; - memcpy(pIo_buf, pdata, len); - } - status = usb_control_msg(udev, pipe, request, reqtype, value, index, - pIo_buf, len, 500); - if (status < 0) - goto free; - if (status != len) { - status = -EREMOTEIO; - goto free; - } - /* Success this control transfer. */ - if (requesttype == 0x01) { - /* For Control read transfer, we have to copy the read - * data from pIo_buf to pdata. - */ - memcpy(pdata, pIo_buf, status); - } - -free: - kfree(palloc_buf); - return status; -} diff --git a/drivers/staging/rtl8712/usb_osintf.h b/drivers/staging/rtl8712/usb_osintf.h deleted file mode 100644 index 2e512b4a564c2119e570ef3b4e2287640bf9e0ee..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/usb_osintf.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __USB_OSINTF_H -#define __USB_OSINTF_H - -#include "osdep_service.h" -#include "drv_types.h" - -extern char *r8712_initmac; - -unsigned int r8712_usb_inirp_init(struct _adapter *padapter); -unsigned int r8712_usb_inirp_deinit(struct _adapter *padapter); -uint rtl871x_hal_init(struct _adapter *padapter); -uint rtl8712_hal_deinit(struct _adapter *padapter); - -void rtl871x_intf_stop(struct _adapter *padapter); -void r871x_dev_unload(struct _adapter *padapter); -void r8712_stop_drv_threads(struct _adapter *padapter); -void r8712_stop_drv_timers(struct _adapter *padapter); -int r8712_init_drv_sw(struct _adapter *padapter); -void r8712_free_drv_sw(struct _adapter *padapter); -struct net_device *r8712_init_netdev(void); - -#endif diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h deleted file mode 100644 index 498e6dec7e67f6efbc78ea19b4b34bf9f3515d17..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/wifi.h +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _WIFI_H_ -#define _WIFI_H_ - -#include -#include - -#define WLAN_HDR_A3_LEN 24 -#define WLAN_HDR_A3_QOS_LEN 26 - -enum WIFI_FRAME_TYPE { - WIFI_QOS_DATA_TYPE = (BIT(7) | BIT(3)), /*!< QoS Data */ -}; - -#define SetToDs(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_TODS); \ -}) - -#define GetToDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0) - -#define ClearToDs(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_TODS)); \ -}) - -#define SetFrDs(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_FROMDS); \ -}) - -#define GetFrDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0) - -#define ClearFrDs(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_FROMDS)); \ -}) - -static inline unsigned char get_tofr_ds(unsigned char *pframe) -{ - return ((GetToDs(pframe) << 1) | GetFrDs(pframe)); -} - -#define SetMFrag(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); \ -}) - -#define GetMFrag(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0) - -#define ClearMFrag(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)); \ -}) - -#define SetRetry(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_RETRY); \ -}) - -#define GetRetry(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0) - -#define ClearRetry(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_RETRY)); \ -}) - -#define SetPwrMgt(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PM); \ -}) - -#define GetPwrMgt(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_PM)) != 0) - -#define ClearPwrMgt(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_PM)); \ -}) - -#define SetMData(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); \ -}) - -#define GetMData(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0) - -#define ClearMData(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_MOREDATA)); \ -}) - -#define SetPrivacy(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); \ -}) - -#define GetPrivacy(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0) - -#define GetOrder(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0) - -#define GetFrameType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \ - (BIT(3) | BIT(2))) - -#define SetFrameType(pbuf, type) \ - do { \ - *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(3) | \ - BIT(2))); \ - *(__le16 *)(pbuf) |= cpu_to_le16(type); \ - } while (0) - -#define GetFrameSubType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \ - (BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | \ - BIT(2))) - -#define SetFrameSubType(pbuf, type) \ - do { \ - *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | \ - BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ - *(__le16 *)(pbuf) |= cpu_to_le16(type); \ - } while (0) - -#define GetSequence(pbuf) (le16_to_cpu(*(__le16 *)\ - ((addr_t)(pbuf) + 22)) >> 4) - -#define GetFragNum(pbuf) (le16_to_cpu(*(__le16 *)((addr_t)\ - (pbuf) + 22)) & 0x0f) - -#define SetSeqNum(pbuf, num) ({ \ - *(__le16 *)((addr_t)(pbuf) + 22) = \ - cpu_to_le16((le16_to_cpu(*(__le16 *)((addr_t)(pbuf) + 22)) & \ - 0x000f) | (0xfff0 & (num << 4))); \ -}) - -#define SetPriority(pbuf, tid) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(tid & 0xf); \ -}) - -#define GetPriority(pbuf) ((le16_to_cpu(*(__le16 *)(pbuf))) & 0xf) - -#define SetAckpolicy(pbuf, ack) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16((ack & 3) << 5); \ -}) - -#define GetAckpolicy(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 5) & 0x3) - -#define GetAMsdu(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 7) & 0x1) - -#define GetAddr1Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 4)) - -#define GetAddr2Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 10)) - -#define GetAddr3Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 16)) - -#define GetAddr4Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 24)) - -static inline unsigned char *get_hdr_bssid(unsigned char *pframe) -{ - unsigned char *sa; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); - - switch (to_fr_ds) { - case 0x00: /* ToDs=0, FromDs=0 */ - sa = GetAddr3Ptr(pframe); - break; - case 0x01: /* ToDs=0, FromDs=1 */ - sa = GetAddr2Ptr(pframe); - break; - case 0x02: /* ToDs=1, FromDs=0 */ - sa = GetAddr1Ptr(pframe); - break; - default: /* ToDs=1, FromDs=1 */ - sa = NULL; - break; - } - return sa; -} - -/* --------------------------------------------------------------------------- - * Below is the fixed elements... - * --------------------------------------------------------------------------- - */ -#define _BEACON_ITERVAL_ 2 -#define _CAPABILITY_ 2 -#define _TIMESTAMP_ 8 - -/*----------------------------------------------------------------------------- - * Below is the definition for WMM - *------------------------------------------------------------------------------ - */ -#define _WMM_IE_Length_ 7 /* for WMM STA */ - -#endif /* _WIFI_H_ */ - diff --git a/drivers/staging/rtl8712/wlan_bssdef.h b/drivers/staging/rtl8712/wlan_bssdef.h deleted file mode 100644 index ec3749813728d9b6a8611a4e010e2f08abe098bc..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/wlan_bssdef.h +++ /dev/null @@ -1,223 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __WLAN_BSSDEF_H__ -#define __WLAN_BSSDEF_H__ - -#define MAX_IE_SZ 768 - -#define NDIS_802_11_LENGTH_SSID 32 -#define NDIS_802_11_LENGTH_RATES 8 -#define NDIS_802_11_LENGTH_RATES_EX 16 - -struct ndis_802_11_ssid { - u32 SsidLength; - u8 Ssid[32]; -}; - -enum NDIS_802_11_NETWORK_TYPE { - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11NetworkTypeMax /* not a real type, defined as an upper bound*/ -}; - -struct NDIS_802_11_CONFIGURATION_FH { - u32 Length; /* Length of structure */ - u32 HopPattern; /* As defined by 802.11, MSB set */ - u32 HopSet; /* to one if non-802.11 */ - u32 DwellTime; /* units are Kusec */ -}; - -/* - * FW will only save the channel number in DSConfig. - * ODI Handler will convert the channel number to freq. number. - */ -struct NDIS_802_11_CONFIGURATION { - u32 Length; /* Length of structure */ - u32 BeaconPeriod; /* units are Kusec */ - u32 ATIMWindow; /* units are Kusec */ - u32 DSConfig; /* Frequency, units are kHz */ - struct NDIS_802_11_CONFIGURATION_FH FHConfig; -}; - -enum NDIS_802_11_NETWORK_INFRASTRUCTURE { - Ndis802_11IBSS, - Ndis802_11Infrastructure, - Ndis802_11AutoUnknown, - Ndis802_11InfrastructureMax, /*Not a real value,defined as upper bound*/ - Ndis802_11APMode -}; - -struct NDIS_802_11_FIXED_IEs { - u8 Timestamp[8]; - u16 BeaconInterval; - u16 Capabilities; -}; - -struct wlan_bssid_ex { - u32 Length; - unsigned char MacAddress[6]; - u8 Reserved[2]; - struct ndis_802_11_ssid Ssid; - __le32 Privacy; - s32 Rssi; - enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; - struct NDIS_802_11_CONFIGURATION Configuration; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; - u8 rates[NDIS_802_11_LENGTH_RATES_EX]; - /* number of content bytes in EIs, which varies */ - u32 IELength; - /*(timestamp, beacon interval, and capability information) */ - u8 IEs[MAX_IE_SZ]; -}; - -enum NDIS_802_11_AUTHENTICATION_MODE { - Ndis802_11AuthModeOpen, - Ndis802_11AuthModeShared, - Ndis802_11AuthModeAutoSwitch, - Ndis802_11AuthModeWPA, - Ndis802_11AuthModeWPAPSK, - Ndis802_11AuthModeWPANone, - Ndis802_11AuthModeMax /* Not a real mode, defined as upper bound */ -}; - -enum { - Ndis802_11WEPEnabled, - Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, - Ndis802_11WEPDisabled, - Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, - Ndis802_11WEPKeyAbsent, - Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, - Ndis802_11WEPNotSupported, - Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, - Ndis802_11Encryption2Enabled, - Ndis802_11Encryption2KeyAbsent, - Ndis802_11Encryption3Enabled, - Ndis802_11Encryption3KeyAbsent -}; - -#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 -#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 -#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 - -#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 -#define NDIS_802_11_AI_RESFI_STATUSCODE 2 -#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 - -struct NDIS_802_11_AI_REQFI { - u16 Capabilities; - u16 ListenInterval; - unsigned char CurrentAPAddress[6]; -}; - -struct NDIS_802_11_AI_RESFI { - u16 Capabilities; - u16 StatusCode; - u16 AssociationId; -}; - -struct NDIS_802_11_ASSOCIATION_INFORMATION { - u32 Length; - u16 AvailableRequestFixedIEs; - struct NDIS_802_11_AI_REQFI RequestFixedIEs; - u32 RequestIELength; - u32 OffsetRequestIEs; - u16 AvailableResponseFixedIEs; - struct NDIS_802_11_AI_RESFI ResponseFixedIEs; - u32 ResponseIELength; - u32 OffsetResponseIEs; -}; - -/* Key mapping keys require a BSSID*/ -struct NDIS_802_11_KEY { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - u32 KeyLength; /* length of key in bytes */ - unsigned char BSSID[6]; - unsigned long long KeyRSC; - u8 KeyMaterial[32]; /* variable length */ -}; - -struct NDIS_802_11_REMOVE_KEY { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - unsigned char BSSID[6]; -}; - -struct NDIS_802_11_WEP { - u32 Length; /* Length of this structure */ - u32 KeyIndex; /* 0 is the per-client key, - * 1-N are the global keys - */ - u32 KeyLength; /* length of key in bytes */ - u8 KeyMaterial[16]; /* variable length depending on above field */ -}; - -/* mask for authentication/integrity fields */ -#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f -#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 -#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 -#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 -#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E - -/* MIC check time, 60 seconds. */ -#define MIC_CHECK_TIME 60000000 - -#ifndef Ndis802_11APMode -#define Ndis802_11APMode (Ndis802_11InfrastructureMax + 1) -#endif - -struct wlan_network { - struct list_head list; - int network_type; /*refer to ieee80211.h for WIRELESS_11A/B/G */ - int fixed; /* set to fixed when not to be removed asi - * site-surveying - */ - unsigned int last_scanned; /*timestamp for the network */ - int aid; /*will only be valid when a BSS is joined. */ - int join_res; - struct wlan_bssid_ex network; /*must be the last item */ -}; - -enum VRTL_CARRIER_SENSE { - DISABLE_VCS, - ENABLE_VCS, - AUTO_VCS -}; - -enum VCS_TYPE { - NONE_VCS, - RTS_CTS, - CTS_TO_SELF -}; - -#define PWR_CAM 0 -#define PWR_MINPS 1 -#define PWR_MAXPS 2 -#define PWR_UAPSD 3 -#define PWR_VOIP 4 - -enum UAPSD_MAX_SP { - NO_LIMIT, - TWO_MSDU, - FOUR_MSDU, - SIX_MSDU -}; - -#define NUM_PRE_AUTH_KEY 16 -#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY - -#endif /* #ifndef WLAN_BSSDEF_H_ */ - diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c deleted file mode 100644 index ceb6b590b310fdd59b33ffc2372a1348076bd2bf..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/xmit_linux.c +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * xmit_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _XMIT_OSDEP_C_ - -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" - -#include "wifi.h" -#include "mlme_osdep.h" -#include "xmit_osdep.h" -#include "osdep_intf.h" - -static uint remainder_len(struct pkt_file *pfile) -{ - return (uint)(pfile->buf_len - ((addr_t)(pfile->cur_addr) - - (addr_t)(pfile->buf_start))); -} - -void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile) -{ - pfile->pkt = pktptr; - pfile->cur_addr = pfile->buf_start = pktptr->data; - pfile->pkt_len = pfile->buf_len = pktptr->len; - pfile->cur_buffer = pfile->buf_start; -} - -uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) -{ - uint len; - - len = remainder_len(pfile); - len = (rlen > len) ? len : rlen; - if (rmem) - skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, - rmem, len); - pfile->cur_addr += len; - pfile->pkt_len -= len; - return len; -} - -sint r8712_endofpktfile(struct pkt_file *pfile) -{ - return (pfile->pkt_len == 0); -} - -void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) -{ - struct ethhdr etherhdr; - struct iphdr ip_hdr; - u16 user_priority = 0; - - _r8712_open_pktfile(ppktfile->pkt, ppktfile); - _r8712_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN); - - /* get user_priority from IP hdr*/ - if (pattrib->ether_type == 0x0800) { - _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); - /*user_priority = (ntohs(ip_hdr.tos) >> 5) & 0x3 ;*/ - user_priority = ip_hdr.tos >> 5; - } else { - /* "When priority processing of data frames is supported, - * a STA's SME should send EAPOL-Key frames at the highest - * priority." - */ - - if (pattrib->ether_type == 0x888e) - user_priority = 7; - } - pattrib->priority = user_priority; - pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; - pattrib->subtype = WIFI_QOS_DATA_TYPE; -} - -void r8712_SetFilter(struct work_struct *work) -{ - struct _adapter *adapter = container_of(work, struct _adapter, - wk_filter_rx_ff0); - u8 oldvalue = 0x00, newvalue = 0x00; - - oldvalue = r8712_read8(adapter, 0x117); - newvalue = oldvalue & 0xfe; - r8712_write8(adapter, 0x117, newvalue); - - wait_for_completion(&adapter->rx_filter_ready); - r8712_write8(adapter, 0x117, oldvalue); -} - -int r8712_xmit_resource_alloc(struct _adapter *padapter, - struct xmit_buf *pxmitbuf) -{ - int i; - - for (i = 0; i < 8; i++) { - pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!pxmitbuf->pxmit_urb[i]) { - int k; - - for (k = i - 1; k >= 0; k--) { - /* handle allocation errors part way through loop */ - usb_free_urb(pxmitbuf->pxmit_urb[k]); - } - netdev_err(padapter->pnetdev, "pxmitbuf->pxmit_urb[i] == NULL\n"); - return -ENOMEM; - } - kmemleak_not_leak(pxmitbuf->pxmit_urb[i]); - } - return 0; -} - -void r8712_xmit_resource_free(struct _adapter *padapter, - struct xmit_buf *pxmitbuf) -{ - int i; - - for (i = 0; i < 8; i++) { - if (pxmitbuf->pxmit_urb[i]) { - usb_kill_urb(pxmitbuf->pxmit_urb[i]); - usb_free_urb(pxmitbuf->pxmit_urb[i]); - } - } -} - -void r8712_xmit_complete(struct _adapter *padapter, struct xmit_frame *pxframe) -{ - if (pxframe->pkt) - dev_kfree_skb_any(pxframe->pkt); - pxframe->pkt = NULL; -} - -netdev_tx_t r8712_xmit_entry(_pkt *pkt, struct net_device *netdev) -{ - struct xmit_frame *xmitframe = NULL; - struct _adapter *adapter = netdev_priv(netdev); - struct xmit_priv *xmitpriv = &(adapter->xmitpriv); - - if (!r8712_if_up(adapter)) - goto _xmit_entry_drop; - - xmitframe = r8712_alloc_xmitframe(xmitpriv); - if (!xmitframe) - goto _xmit_entry_drop; - - if (r8712_update_attrib(adapter, pkt, &xmitframe->attrib)) - goto _xmit_entry_drop; - - adapter->ledpriv.LedControlHandler(adapter, LED_CTL_TX); - xmitframe->pkt = pkt; - if (r8712_pre_xmit(adapter, xmitframe)) { - /*dump xmitframe directly or drop xframe*/ - dev_kfree_skb_any(pkt); - xmitframe->pkt = NULL; - } - xmitpriv->tx_pkts++; - xmitpriv->tx_bytes += xmitframe->attrib.last_txcmdsz; - return NETDEV_TX_OK; -_xmit_entry_drop: - if (xmitframe) - r8712_free_xmitframe(xmitpriv, xmitframe); - xmitpriv->tx_drop++; - dev_kfree_skb_any(pkt); - return NETDEV_TX_OK; -} diff --git a/drivers/staging/rtl8712/xmit_osdep.h b/drivers/staging/rtl8712/xmit_osdep.h deleted file mode 100644 index 1ad42658c8831c7126b1b8b4d973e79304a994c7..0000000000000000000000000000000000000000 --- a/drivers/staging/rtl8712/xmit_osdep.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __XMIT_OSDEP_H_ -#define __XMIT_OSDEP_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -struct pkt_file { - _pkt *pkt; - u32 pkt_len; /*the remainder length of the open_file*/ - _buffer *cur_buffer; - u8 *buf_start; - u8 *cur_addr; - u32 buf_len; -}; - -#define NR_XMITFRAME 256 - -struct xmit_priv; -struct pkt_attrib; -struct sta_xmit_priv; -struct xmit_frame; -struct xmit_buf; - -netdev_tx_t r8712_xmit_entry(_pkt *pkt, struct net_device *pnetdev); -void r8712_SetFilter(struct work_struct *work); -int r8712_xmit_resource_alloc(struct _adapter *padapter, - struct xmit_buf *pxmitbuf); -void r8712_xmit_resource_free(struct _adapter *padapter, - struct xmit_buf *pxmitbuf); - -void r8712_set_qos(struct pkt_file *ppktfile, - struct pkt_attrib *pattrib); -void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile); -uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen); -sint r8712_endofpktfile(struct pkt_file *pfile); -void r8712_xmit_complete(struct _adapter *padapter, - struct xmit_frame *pxframe); - -#endif diff --git a/drivers/staging/rtl8723bs/TODO b/drivers/staging/rtl8723bs/TODO index 4c413f9d3df00fde36ee377fbb79d3712b88da6c..050dcd0bffab59d80760d8c7820515211844f01c 100644 --- a/drivers/staging/rtl8723bs/TODO +++ b/drivers/staging/rtl8723bs/TODO @@ -6,6 +6,3 @@ TODO: of them will require refactoring - merge Realtek's bugfixes and new features into the driver - switch to use MAC80211 - -Please send any patches to Greg Kroah-Hartman , -Hans de Goede and Larry Finger . diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index 84ce7307d8f3dfe1a1733d1ff65e8f523171a4e4..64ce33c6fba17210c6932ec225b838b33e6c9737 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -382,7 +382,7 @@ int rtw_cmd_thread(void *context) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; struct drvextra_cmd_parm *extra_parm = NULL; - thread_enter("RTW_CMD_THREAD"); + allow_signal(SIGTERM); pcmdbuf = pcmdpriv->cmd_buf; @@ -1258,8 +1258,7 @@ static void dynamic_chk_wk_hdl(struct adapter *padapter) /* always call rtw_ps_processor() at last one. */ - if (is_primary_adapter(padapter)) - rtw_ps_processor(padapter); + rtw_ps_processor(padapter); } void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type); @@ -1465,6 +1464,7 @@ u8 rtw_ps_cmd(struct adapter *padapter) struct drvextra_cmd_parm *pdrvextra_cmd_parm; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; + ppscmd = rtw_zmalloc(sizeof(struct cmd_obj)); if (!ppscmd) { res = _FAIL; diff --git a/drivers/staging/rtl8723bs/core/rtw_efuse.c b/drivers/staging/rtl8723bs/core/rtw_efuse.c index 8b671f8a79659f106fd13faf1b3e5a44b9c37cb7..7a74b011dedc2afaee67b278cfe864e3d61d8bd9 100644 --- a/drivers/staging/rtl8723bs/core/rtw_efuse.c +++ b/drivers/staging/rtl8723bs/core/rtw_efuse.c @@ -77,33 +77,7 @@ struct adapter *padapter, u8 bWrite, u8 PwrState) { - padapter->HalFunc.EfusePowerSwitch(padapter, bWrite, PwrState); -} - -/*----------------------------------------------------------------------------- - * Function: Efuse_GetCurrentSize - * - * Overview: Get current efuse size!!! - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 11/16/2008 MHC Create Version 0. - * - *---------------------------------------------------------------------------*/ -u16 -Efuse_GetCurrentSize( - struct adapter *padapter, - u8 efuseType, - bool bPseudoTest) -{ - return padapter->HalFunc.EfuseGetCurrentSize(padapter, efuseType, - bPseudoTest); + Hal_EfusePowerSwitch(padapter, bWrite, PwrState); } /* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */ @@ -159,7 +133,7 @@ efuse_ReadEFuse( bool bPseudoTest ) { - Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); + Hal_ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); } void @@ -171,7 +145,7 @@ EFUSE_GetEfuseDefinition( bool bPseudoTest ) { - padapter->HalFunc.EFUSEGetEfuseDefinition(padapter, efuseType, type, pOut, bPseudoTest); + Hal_GetEfuseDefinition(padapter, efuseType, type, pOut, bPseudoTest); } /*----------------------------------------------------------------------------- @@ -312,68 +286,6 @@ u8 efuse_OneByteWrite(struct adapter *padapter, u16 addr, u8 data, bool bPseudoT return bResult; } -int -Efuse_PgPacketRead(struct adapter *padapter, - u8 offset, - u8 *data, - bool bPseudoTest) -{ - return padapter->HalFunc.Efuse_PgPacketRead(padapter, offset, data, - bPseudoTest); -} - -int -Efuse_PgPacketWrite(struct adapter *padapter, - u8 offset, - u8 word_en, - u8 *data, - bool bPseudoTest) -{ - return padapter->HalFunc.Efuse_PgPacketWrite(padapter, offset, word_en, - data, bPseudoTest); -} - -/*----------------------------------------------------------------------------- - * Function: efuse_WordEnableDataRead - * - * Overview: Read allowed word in current efuse section data. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 11/16/2008 MHC Create Version 0. - * 11/21/2008 MHC Fix Write bug when we only enable late word. - * - *---------------------------------------------------------------------------*/ -void -efuse_WordEnableDataRead(u8 word_en, - u8 *sourdata, - u8 *targetdata) -{ - if (!(word_en & BIT(0))) { - targetdata[0] = sourdata[0]; - targetdata[1] = sourdata[1]; - } - if (!(word_en & BIT(1))) { - targetdata[2] = sourdata[2]; - targetdata[3] = sourdata[3]; - } - if (!(word_en & BIT(2))) { - targetdata[4] = sourdata[4]; - targetdata[5] = sourdata[5]; - } - if (!(word_en & BIT(3))) { - targetdata[6] = sourdata[6]; - targetdata[7] = sourdata[7]; - } -} - - u8 Efuse_WordEnableDataWrite(struct adapter *padapter, u16 efuse_addr, diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index cbdb134278d37bfd0bc45f25e295edcfef58b8c1..5ded183aa08c49e80c7966444217ab47e3cee847 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -911,8 +911,7 @@ inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) { rtw_os_indicate_scan_done(padapter, aborted); - if (is_primary_adapter(padapter) && - (!adapter_to_pwrctl(padapter)->bInSuspend) && + if ((!adapter_to_pwrctl(padapter)->bInSuspend) && (!check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE|WIFI_UNDER_LINKING))) { rtw_set_ips_deny(padapter, 0); @@ -1589,8 +1588,7 @@ void rtw_dynamic_check_timer_handler(struct adapter *adapter) } } else { - if (is_primary_adapter(adapter)) - rtw_dynamic_chk_wk_cmd(adapter); + rtw_dynamic_chk_wk_cmd(adapter); } /* auto site survey */ diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 4d4bec47d1874cd125fc8fdb034c664f7c4efa16..317f3db193971c8202939d8aa88717b600aa695d 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -1870,10 +1870,10 @@ unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv if (0) { int pp; - printk("pattrib->pktlen = %d =>", pattrib->pkt_len); + netdev_dbg(padapter->pnetdev, "pattrib->pktlen = %d =>", pattrib->pkt_len); for (pp = 0; pp < pattrib->pkt_len; pp++) - printk(" %02x ", pframe[pp]); - printk("\n"); + pr_cont(" %02x ", pframe[pp]); + pr_cont("\n"); } return _SUCCESS; @@ -4872,8 +4872,7 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) /* set_link_timer(pmlmeext, DISCONNECT_TO); */ } - if (get_iface_type(padapter) == IFACE_PORT0) - rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); } /* currently only adhoc mode will go here */ @@ -5638,7 +5637,7 @@ u8 setkey_hdl(struct adapter *padapter, u8 *pbuf) rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)true); /* allow multicast packets to driver */ - padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr); + SetHwReg8723BS(padapter, HW_VAR_ON_RCR_AM, null_addr); return H2C_SUCCESS; } diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c index dbfcbac3d85554b43940e17c35b4def3f530202b..c60e179bb2e196fcde02903cb9dd03e59d3d2826 100644 --- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c @@ -73,9 +73,6 @@ int ips_leave(struct adapter *padapter) struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); int ret; - if (!is_primary_adapter(padapter)) - return _SUCCESS; - mutex_lock(&pwrpriv->lock); ret = _ips_leave(padapter); mutex_unlock(&pwrpriv->lock); @@ -455,10 +452,6 @@ void LPS_Enter(struct adapter *padapter, const char *msg) if (n_assoc_iface != 1) return; - /* Skip lps enter request for adapter not port0 */ - if (get_iface_type(padapter) != IFACE_PORT0) - return; - if (!PS_RDY_CHECK(dvobj->padapters)) return; diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index f37fec1efaf91c840d0290e9c40457ccedfa0a9e..73c70b016f00972209ca8d638195b53b8d7acf5e 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -290,21 +290,11 @@ inline void rtw_set_oper_ch(struct adapter *adapter, u8 ch) dvobj->oper_channel = ch; } -inline u8 rtw_get_oper_bw(struct adapter *adapter) -{ - return adapter_to_dvobj(adapter)->oper_bwmode; -} - inline void rtw_set_oper_bw(struct adapter *adapter, u8 bw) { adapter_to_dvobj(adapter)->oper_bwmode = bw; } -inline u8 rtw_get_oper_choffset(struct adapter *adapter) -{ - return adapter_to_dvobj(adapter)->oper_ch_offset; -} - inline void rtw_set_oper_choffset(struct adapter *adapter, u8 offset) { adapter_to_dvobj(adapter)->oper_ch_offset = offset; @@ -445,34 +435,6 @@ void invalidate_cam_all(struct adapter *padapter) spin_unlock_bh(&cam_ctl->lock); } -static u32 _ReadCAM(struct adapter *padapter, u32 addr) -{ - u32 count = 0, cmd; - - cmd = CAM_POLLINIG | addr; - rtw_write32(padapter, RWCAM, cmd); - - do { - if (0 == (rtw_read32(padapter, REG_CAMCMD) & CAM_POLLINIG)) - break; - } while (count++ < 100); - - return rtw_read32(padapter, REG_CAMREAD); -} - -void read_cam(struct adapter *padapter, u8 entry, u8 *get_key) -{ - u32 j, addr, cmd; - - addr = entry << 3; - - for (j = 0; j < 6; j++) { - cmd = _ReadCAM(padapter, addr+j); - if (j > 1) /* get key from cam */ - memcpy(get_key+(j-2)*4, &cmd, 4); - } -} - void _write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key) { unsigned int i, val, addr; @@ -1613,9 +1575,9 @@ void update_wireless_mode(struct adapter *padapter) SIFS_Timer = 0x0a0a0808; /* 0x0808 -> for CCK, 0x0a0a -> for OFDM */ /* change this value if having IOT issues. */ - padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer); + SetHwReg8723BS(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer); - padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_WIRELESS_MODE, (u8 *)&(pmlmeext->cur_wireless_mode)); + SetHwReg8723BS(padapter, HW_VAR_WIRELESS_MODE, (u8 *)&(pmlmeext->cur_wireless_mode)); if (pmlmeext->cur_wireless_mode & WIRELESS_11B) update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); @@ -1822,29 +1784,3 @@ void rtw_release_macid(struct adapter *padapter, struct sta_info *psta) } spin_unlock_bh(&pdvobj->lock); } - -/* For 8188E RA */ -u8 rtw_search_max_mac_id(struct adapter *padapter) -{ - u8 max_mac_id = 0; - struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); - int i; - - spin_lock_bh(&pdvobj->lock); - for (i = (NUM_STA-1); i >= 0 ; i--) { - if (pdvobj->macid[i] == true) - break; - } - max_mac_id = i; - spin_unlock_bh(&pdvobj->lock); - - return max_mac_id; -} - -struct adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj) -{ - if (get_iface_type(dvobj->padapters[i]) != IFACE_PORT0) - return NULL; - - return dvobj->padapters; -} diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 3e88f14e3bf78a2a67c3e61b965cd37845398454..699cff7b0ac9559607f6fb07cc028f3063534225 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -2489,7 +2489,7 @@ int rtw_xmit_thread(void *context) err = _SUCCESS; padapter = context; - thread_enter("RTW_XMIT_THREAD"); + allow_signal(SIGTERM); do { err = rtw_hal_xmit_thread_handler(padapter); diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c index 719dd116d8076a7cb6cf8d64167f52af10c4bb51..95fb38283c582a3af51a8aafd320cf18ca9110d7 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com.c +++ b/drivers/staging/rtl8723bs/hal/hal_com.c @@ -13,23 +13,20 @@ u8 rtw_hal_data_init(struct adapter *padapter) { - if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */ - padapter->hal_data_sz = sizeof(struct hal_com_data); - padapter->HalData = vzalloc(padapter->hal_data_sz); - if (!padapter->HalData) - return _FAIL; - } + padapter->hal_data_sz = sizeof(struct hal_com_data); + padapter->HalData = vzalloc(padapter->hal_data_sz); + if (!padapter->HalData) + return _FAIL; + return _SUCCESS; } void rtw_hal_data_deinit(struct adapter *padapter) { - if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */ - if (padapter->HalData) { - vfree(padapter->HalData); - padapter->HalData = NULL; - padapter->hal_data_sz = 0; - } + if (padapter->HalData) { + vfree(padapter->HalData); + padapter->HalData = NULL; + padapter->hal_data_sz = 0; } } @@ -796,19 +793,6 @@ u8 GetHalDefVar( return bResult; } -void GetHalODMVar( - struct adapter *Adapter, - enum hal_odm_variable eVariable, - void *pValue1, - void *pValue2 -) -{ - switch (eVariable) { - default: - break; - } -} - void SetHalODMVar( struct adapter *Adapter, enum hal_odm_variable eVariable, @@ -883,7 +867,6 @@ void rtw_hal_check_rxfifo_full(struct adapter *adapter) int save_cnt = false; /* switch counter to RX fifo */ - /* printk("8723b or 8192e , MAC_667 set 0xf0\n"); */ rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0); save_cnt = true; /* todo: other chips */ @@ -910,10 +893,9 @@ void rtw_dump_raw_rssi_info(struct adapter *padapter) for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { if (!isCCKrate) { - printk(", rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n", - psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]); - } else { - printk("\n"); + netdev_dbg(padapter->pnetdev, ", rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n", + psample_pkt_rssi->ofdm_pwr[rf_path], + psample_pkt_rssi->ofdm_snr[rf_path]); } } } diff --git a/drivers/staging/rtl8723bs/hal/hal_intf.c b/drivers/staging/rtl8723bs/hal/hal_intf.c index 0a3900548fd2ca05d52ccf4acc73f266f2517ebd..0db8f623b8059ad63046f3516b24895ec520e0c4 100644 --- a/drivers/staging/rtl8723bs/hal/hal_intf.c +++ b/drivers/staging/rtl8723bs/hal/hal_intf.c @@ -9,52 +9,37 @@ void rtw_hal_chip_configure(struct adapter *padapter) { - if (padapter->HalFunc.intf_chip_configure) - padapter->HalFunc.intf_chip_configure(padapter); + rtl8723bs_interface_configure(padapter); } void rtw_hal_read_chip_info(struct adapter *padapter) { - if (padapter->HalFunc.read_adapter_info) - padapter->HalFunc.read_adapter_info(padapter); + ReadAdapterInfo8723BS(padapter); } void rtw_hal_read_chip_version(struct adapter *padapter) { - if (padapter->HalFunc.read_chip_version) - padapter->HalFunc.read_chip_version(padapter); + rtl8723b_read_chip_version(padapter); } void rtw_hal_def_value_init(struct adapter *padapter) { - if (is_primary_adapter(padapter)) - if (padapter->HalFunc.init_default_value) - padapter->HalFunc.init_default_value(padapter); + rtl8723bs_init_default_value(padapter); } void rtw_hal_free_data(struct adapter *padapter) { /* free HAL Data */ rtw_hal_data_deinit(padapter); - - if (is_primary_adapter(padapter)) - if (padapter->HalFunc.free_hal_data) - padapter->HalFunc.free_hal_data(padapter); } void rtw_hal_dm_init(struct adapter *padapter) { - if (is_primary_adapter(padapter)) - if (padapter->HalFunc.dm_init) - padapter->HalFunc.dm_init(padapter); + rtl8723b_init_dm_priv(padapter); } void rtw_hal_dm_deinit(struct adapter *padapter) { - /* cancel dm timer */ - if (is_primary_adapter(padapter)) - if (padapter->HalFunc.dm_deinit) - padapter->HalFunc.dm_deinit(padapter); } static void rtw_hal_init_opmode(struct adapter *padapter) @@ -82,7 +67,7 @@ uint rtw_hal_init(struct adapter *padapter) uint status; struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - status = padapter->HalFunc.hal_init(padapter); + status = rtl8723bs_hal_init(padapter); if (status == _SUCCESS) { rtw_hal_init_opmode(padapter); @@ -111,7 +96,7 @@ uint rtw_hal_deinit(struct adapter *padapter) uint status = _SUCCESS; struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - status = padapter->HalFunc.hal_deinit(padapter); + status = rtl8723bs_hal_deinit(padapter); if (status == _SUCCESS) { padapter = dvobj->padapters; @@ -123,34 +108,27 @@ uint rtw_hal_deinit(struct adapter *padapter) void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val) { - if (padapter->HalFunc.SetHwRegHandler) - padapter->HalFunc.SetHwRegHandler(padapter, variable, val); + SetHwReg8723BS(padapter, variable, val); } void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val) { - if (padapter->HalFunc.GetHwRegHandler) - padapter->HalFunc.GetHwRegHandler(padapter, variable, val); + GetHwReg8723BS(padapter, variable, val); } void rtw_hal_set_hwreg_with_buf(struct adapter *padapter, u8 variable, u8 *pbuf, int len) { - if (padapter->HalFunc.SetHwRegHandlerWithBuf) - padapter->HalFunc.SetHwRegHandlerWithBuf(padapter, variable, pbuf, len); + SetHwRegWithBuf8723B(padapter, variable, pbuf, len); } u8 rtw_hal_set_def_var(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue) { - if (padapter->HalFunc.SetHalDefVarHandler) - return padapter->HalFunc.SetHalDefVarHandler(padapter, eVariable, pValue); - return _FAIL; + return SetHalDefVar8723BSDIO(padapter, eVariable, pValue); } u8 rtw_hal_get_def_var(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue) { - if (padapter->HalFunc.GetHalDefVarHandler) - return padapter->HalFunc.GetHalDefVarHandler(padapter, eVariable, pValue); - return _FAIL; + return GetHalDefVar8723BSDIO(padapter, eVariable, pValue); } void rtw_hal_set_odm_var(struct adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) @@ -161,40 +139,27 @@ void rtw_hal_set_odm_var(struct adapter *padapter, enum hal_odm_variable eVariab void rtw_hal_enable_interrupt(struct adapter *padapter) { - if (padapter->HalFunc.enable_interrupt) - padapter->HalFunc.enable_interrupt(padapter); + EnableInterrupt8723BSdio(padapter); } void rtw_hal_disable_interrupt(struct adapter *padapter) { - if (padapter->HalFunc.disable_interrupt) - padapter->HalFunc.disable_interrupt(padapter); + DisableInterrupt8723BSdio(padapter); } u8 rtw_hal_check_ips_status(struct adapter *padapter) { - u8 val = false; - - if (padapter->HalFunc.check_ips_status) - val = padapter->HalFunc.check_ips_status(padapter); - - return val; + return CheckIPSStatus(padapter); } s32 rtw_hal_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe) { - if (padapter->HalFunc.hal_xmitframe_enqueue) - return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe); - - return false; + return rtl8723bs_hal_xmitframe_enqueue(padapter, pxmitframe); } s32 rtw_hal_xmit(struct adapter *padapter, struct xmit_frame *pxmitframe) { - if (padapter->HalFunc.hal_xmit) - return padapter->HalFunc.hal_xmit(padapter, pxmitframe); - - return false; + return rtl8723bs_hal_xmit(padapter, pxmitframe); } /* @@ -202,8 +167,6 @@ s32 rtw_hal_xmit(struct adapter *padapter, struct xmit_frame *pxmitframe) */ s32 rtw_hal_mgnt_xmit(struct adapter *padapter, struct xmit_frame *pmgntframe) { - s32 ret = _FAIL; - update_mgntframe_attrib_addr(padapter, pmgntframe); /* pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; */ /* pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; */ @@ -220,36 +183,27 @@ s32 rtw_hal_mgnt_xmit(struct adapter *padapter, struct xmit_frame *pmgntframe) rtw_mgmt_xmitframe_coalesce(padapter, pmgntframe->pkt, pmgntframe); } - if (padapter->HalFunc.mgnt_xmit) - ret = padapter->HalFunc.mgnt_xmit(padapter, pmgntframe); - return ret; + return rtl8723bs_mgnt_xmit(padapter, pmgntframe); } s32 rtw_hal_init_xmit_priv(struct adapter *padapter) { - if (padapter->HalFunc.init_xmit_priv) - return padapter->HalFunc.init_xmit_priv(padapter); - return _FAIL; + return rtl8723bs_init_xmit_priv(padapter); } void rtw_hal_free_xmit_priv(struct adapter *padapter) { - if (padapter->HalFunc.free_xmit_priv) - padapter->HalFunc.free_xmit_priv(padapter); + rtl8723bs_free_xmit_priv(padapter); } s32 rtw_hal_init_recv_priv(struct adapter *padapter) { - if (padapter->HalFunc.init_recv_priv) - return padapter->HalFunc.init_recv_priv(padapter); - - return _FAIL; + return rtl8723bs_init_recv_priv(padapter); } void rtw_hal_free_recv_priv(struct adapter *padapter) { - if (padapter->HalFunc.free_recv_priv) - padapter->HalFunc.free_recv_priv(padapter); + rtl8723bs_free_recv_priv(padapter); } void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level) @@ -267,91 +221,70 @@ void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level) if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) add_RATid(padapter, psta, rssi_level); else { - if (padapter->HalFunc.UpdateRAMaskHandler) - padapter->HalFunc.UpdateRAMaskHandler(padapter, psta->mac_id, rssi_level); + UpdateHalRAMask8723B(padapter, psta->mac_id, rssi_level); } } void rtw_hal_add_ra_tid(struct adapter *padapter, u32 bitmap, u8 *arg, u8 rssi_level) { - if (padapter->HalFunc.Add_RateATid) - padapter->HalFunc.Add_RateATid(padapter, bitmap, arg, rssi_level); + rtl8723b_Add_RateATid(padapter, bitmap, arg, rssi_level); } /*Start specifical interface thread */ void rtw_hal_start_thread(struct adapter *padapter) { - if (padapter->HalFunc.run_thread) - padapter->HalFunc.run_thread(padapter); + rtl8723b_start_thread(padapter); } /*Start specifical interface thread */ void rtw_hal_stop_thread(struct adapter *padapter) { - if (padapter->HalFunc.cancel_thread) - padapter->HalFunc.cancel_thread(padapter); + rtl8723b_stop_thread(padapter); } u32 rtw_hal_read_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask) { - u32 data = 0; - - if (padapter->HalFunc.read_bbreg) - data = padapter->HalFunc.read_bbreg(padapter, RegAddr, BitMask); - return data; + return PHY_QueryBBReg_8723B(padapter, RegAddr, BitMask); } void rtw_hal_write_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data) { - if (padapter->HalFunc.write_bbreg) - padapter->HalFunc.write_bbreg(padapter, RegAddr, BitMask, Data); + PHY_SetBBReg_8723B(padapter, RegAddr, BitMask, Data); } u32 rtw_hal_read_rfreg(struct adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask) { - u32 data = 0; - - if (padapter->HalFunc.read_rfreg) - data = padapter->HalFunc.read_rfreg(padapter, eRFPath, RegAddr, BitMask); - return data; + return PHY_QueryRFReg_8723B(padapter, eRFPath, RegAddr, BitMask); } void rtw_hal_write_rfreg(struct adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data) { - if (padapter->HalFunc.write_rfreg) - padapter->HalFunc.write_rfreg(padapter, eRFPath, RegAddr, BitMask, Data); + PHY_SetRFReg_8723B(padapter, eRFPath, RegAddr, BitMask, Data); } void rtw_hal_set_chan(struct adapter *padapter, u8 channel) { - if (padapter->HalFunc.set_channel_handler) - padapter->HalFunc.set_channel_handler(padapter, channel); + PHY_SwChnl8723B(padapter, channel); } void rtw_hal_set_chnl_bw(struct adapter *padapter, u8 channel, enum channel_width Bandwidth, u8 Offset40, u8 Offset80) { - if (padapter->HalFunc.set_chnl_bw_handler) - padapter->HalFunc.set_chnl_bw_handler(padapter, channel, - Bandwidth, Offset40, - Offset80); + PHY_SetSwChnlBWMode8723B(padapter, channel, Bandwidth, Offset40, Offset80); } void rtw_hal_dm_watchdog(struct adapter *padapter) { - if (padapter->HalFunc.hal_dm_watchdog) - padapter->HalFunc.hal_dm_watchdog(padapter); + rtl8723b_HalDmWatchDog(padapter); } void rtw_hal_dm_watchdog_in_lps(struct adapter *padapter) { if (adapter_to_pwrctl(padapter)->fw_current_in_ps_mode) { - if (padapter->HalFunc.hal_dm_watchdog_in_lps) - padapter->HalFunc.hal_dm_watchdog_in_lps(padapter); /* this function caller is in interrupt context */ + rtl8723b_HalDmWatchDog_in_LPS(padapter); /* this function caller is in interrupt context */ } } void beacon_timing_control(struct adapter *padapter) { - if (padapter->HalFunc.SetBeaconRelatedRegistersHandler) - padapter->HalFunc.SetBeaconRelatedRegistersHandler(padapter); + rtl8723b_SetBeaconRelatedRegisters(padapter); } diff --git a/drivers/staging/rtl8723bs/hal/odm.c b/drivers/staging/rtl8723bs/hal/odm.c index ea3b4cd3236035c2086b733a826d93600e7fc693..8d6131f0ad47d9eacda674d15136bbbee8d9c59c 100644 --- a/drivers/staging/rtl8723bs/hal/odm.c +++ b/drivers/staging/rtl8723bs/hal/odm.c @@ -417,13 +417,11 @@ static void odm_RefreshRateAdaptiveMaskCE(struct dm_odm_t *pDM_Odm) u8 i; struct adapter *padapter = pDM_Odm->Adapter; - if (padapter->bDriverStopped) { + if (padapter->bDriverStopped) return; - } - if (!pDM_Odm->bUseRAMask) { + if (!pDM_Odm->bUseRAMask) return; - } for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { PSTA_INFO_T pstat = pDM_Odm->pODM_StaInfo[i]; @@ -433,7 +431,6 @@ static void odm_RefreshRateAdaptiveMaskCE(struct dm_odm_t *pDM_Odm) continue; if (true == ODM_RAStateCheck(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level)) { - /* printk("RSSI:%d, RSSI_LEVEL:%d\n", pstat->rssi_stat.UndecoratedSmoothedPWDB, pstat->rssi_level); */ rtw_hal_update_ra_mask(pstat, pstat->rssi_level); } @@ -461,9 +458,9 @@ static void odm_RefreshRateAdaptiveMaskCE(struct dm_odm_t *pDM_Odm) static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm) { - if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) { + if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) return; - } + odm_RefreshRateAdaptiveMaskCE(pDM_Odm); } @@ -512,7 +509,6 @@ bool ODM_RAStateCheck( RATRState = DM_RATR_STA_MIDDLE; else RATRState = DM_RATR_STA_LOW; - /* printk("==>%s, RATRState:0x%02x , RSSI:%d\n", __func__, RATRState, RSSI); */ if (*pRATRState != RATRState || bForceUpdate) { *pRATRState = RATRState; @@ -593,8 +589,6 @@ static void odm_RSSIMonitorCheckCE(struct dm_odm_t *pDM_Odm) } } - /* printk("%s ==> sta_cnt(%d)\n", __func__, sta_cnt); */ - for (i = 0; i < sta_cnt; i++) { if (PWDB_rssi[i] != (0)) { if (pHalData->fw_ractrl == true)/* Report every sta's RSSI to FW */ diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c index 37ebbbf408ecfddbcc4b08bdaa864b399ba10173..e15ec6452fd0619b5e13a7f32f077436f1667003 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c @@ -53,8 +53,6 @@ static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize) u8 *bufferPtr = buffer; u32 i = 0, offset = 0; -/* printk("====>%s %d\n", __func__, __LINE__); */ - /* 3 Phase #1 */ blockCount_p1 = buffSize / blockSize_p1; remainSize_p1 = buffSize % blockSize_p1; @@ -62,7 +60,8 @@ static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize) for (i = 0; i < blockCount_p1; i++) { ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), *((u32 *)(bufferPtr + i * blockSize_p1))); if (ret == _FAIL) { - printk("====>%s %d i:%d\n", __func__, __LINE__, i); + netdev_dbg(padapter->pnetdev, "write failed at %s %d, block:%d\n", + __func__, __LINE__, i); goto exit; } } @@ -85,7 +84,8 @@ static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize) ret = rtw_write8(padapter, (FW_8723B_START_ADDRESS + offset + i), *(bufferPtr + offset + i)); if (ret == _FAIL) { - printk("====>%s %d i:%d\n", __func__, __LINE__, i); + netdev_dbg(padapter->pnetdev, "write failed at %s %d, block:%d\n", + __func__, __LINE__, i); goto exit; } } @@ -127,7 +127,8 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size) ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE); if (ret == _FAIL) { - printk("====>%s %d\n", __func__, __LINE__); + netdev_dbg(padapter->pnetdev, "page write failed at %s %d\n", + __func__, __LINE__); goto exit; } } @@ -138,7 +139,8 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size) ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize); if (ret == _FAIL) { - printk("====>%s %d\n", __func__, __LINE__); + netdev_dbg(padapter->pnetdev, "remaining page write failed at %s %d\n", + __func__, __LINE__); goto exit; } } @@ -439,10 +441,6 @@ void rtl8723b_InitializeFirmwareVars(struct adapter *padapter) /* pHalData->H2CStopInsertQueue = false; */ } -static void rtl8723b_free_hal_data(struct adapter *padapter) -{ -} - /* */ /* Efuse related code */ /* */ @@ -492,7 +490,7 @@ static u8 hal_EfuseSwitchToBank( return bRet; } -static void Hal_GetEfuseDefinition( +void Hal_GetEfuseDefinition( struct adapter *padapter, u8 efuseType, u8 type, @@ -604,46 +602,7 @@ static void Hal_GetEfuseDefinition( #define EFUSE_ACCESS_ON_8723 0x69 /* For RTL8723 only. */ #define REG_EFUSE_ACCESS_8723 0x00CF /* Efuse access protection for RTL8723 */ -/* */ -static void Hal_BT_EfusePowerSwitch( - struct adapter *padapter, u8 bWrite, u8 PwrState -) -{ - u8 tempval; - if (PwrState) { - /* enable BT power cut */ - /* 0x6A[14] = 1 */ - tempval = rtw_read8(padapter, 0x6B); - tempval |= BIT(6); - rtw_write8(padapter, 0x6B, tempval); - - /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */ - /* So don't write 0x6A[14]= 1 and 0x6A[15]= 0 together! */ - msleep(1); - /* disable BT output isolation */ - /* 0x6A[15] = 0 */ - tempval = rtw_read8(padapter, 0x6B); - tempval &= ~BIT(7); - rtw_write8(padapter, 0x6B, tempval); - } else { - /* enable BT output isolation */ - /* 0x6A[15] = 1 */ - tempval = rtw_read8(padapter, 0x6B); - tempval |= BIT(7); - rtw_write8(padapter, 0x6B, tempval); - - /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */ - /* So don't write 0x6A[14]= 1 and 0x6A[15]= 0 together! */ - - /* disable BT power cut */ - /* 0x6A[14] = 1 */ - tempval = rtw_read8(padapter, 0x6B); - tempval &= ~BIT(6); - rtw_write8(padapter, 0x6B, tempval); - } - -} -static void Hal_EfusePowerSwitch( +void Hal_EfusePowerSwitch( struct adapter *padapter, u8 bWrite, u8 PwrState ) { @@ -928,7 +887,7 @@ exit: kfree(efuseTbl); } -static void Hal_ReadEFuse( +void Hal_ReadEFuse( struct adapter *padapter, u8 efuseType, u16 _offset, @@ -1069,7 +1028,6 @@ static u16 hal_EfuseGetCurrentSize_BT(struct adapter *padapter, u8 bPseudoTest) /* only when bank is switched we have to reset the efuse_addr. */ if (bank != startBank) efuse_addr = 0; -#if 1 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { if (efuse_OneByteRead(padapter, efuse_addr, @@ -1098,33 +1056,6 @@ static u16 hal_EfuseGetCurrentSize_BT(struct adapter *padapter, u8 bPseudoTest) /* read next header */ efuse_addr += (word_cnts*2)+1; } -#else - while ( - bContinual && - efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) && - AVAILABLE_EFUSE_ADDR(efuse_addr) - ) { - if (efuse_data != 0xFF) { - if ((efuse_data&0x1F) == 0x0F) { /* extended header */ - efuse_addr++; - efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest); - if ((efuse_data & 0x0F) == 0x0F) { - efuse_addr++; - continue; - } else { - hworden = efuse_data & 0x0F; - } - } else { - hworden = efuse_data & 0x0F; - } - word_cnts = Efuse_CalculateWordCnts(hworden); - /* read next header */ - efuse_addr = efuse_addr + (word_cnts*2)+1; - } else - bContinual = false; - } -#endif - /* Check if we need to check next bank efuse */ if (efuse_addr < retU2) @@ -1141,7 +1072,7 @@ static u16 hal_EfuseGetCurrentSize_BT(struct adapter *padapter, u8 bPseudoTest) return retU2; } -static u16 Hal_EfuseGetCurrentSize( +u16 Hal_EfuseGetCurrentSize( struct adapter *padapter, u8 efuseType, bool bPseudoTest ) { @@ -1220,403 +1151,6 @@ static u8 Hal_EfuseWordEnableDataWrite( return badworden; } -static s32 Hal_EfusePgPacketRead( - struct adapter *padapter, - u8 offset, - u8 *data, - bool bPseudoTest -) -{ - u8 efuse_data, word_cnts = 0; - u16 efuse_addr = 0; - u8 hoffset = 0, hworden = 0; - u8 i; - u8 max_section = 0; - s32 ret; - - - if (!data) - return false; - - EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest); - if (offset > max_section) - return false; - - memset(data, 0xFF, PGPKT_DATA_SIZE); - ret = true; - - /* */ - /* Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */ - /* Skip dummy parts to prevent unexpected data read from Efuse. */ - /* By pass right now. 2009.02.19. */ - /* */ - while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { - if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == false) { - ret = false; - break; - } - - if (efuse_data == 0xFF) - break; - - if (EXT_HEADER(efuse_data)) { - hoffset = GET_HDR_OFFSET_2_0(efuse_data); - efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest); - if (ALL_WORDS_DISABLED(efuse_data)) - continue; - - hoffset |= ((efuse_data & 0xF0) >> 1); - hworden = efuse_data & 0x0F; - } else { - hoffset = (efuse_data>>4) & 0x0F; - hworden = efuse_data & 0x0F; - } - - if (hoffset == offset) { - for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { - /* Check word enable condition in the section */ - if (!(hworden & (0x01<= max_available) - return false; - - return true; -} - -static void hal_EfuseConstructPGPkt( - u8 offset, - u8 word_en, - u8 *pData, - struct pgpkt_struct *pTargetPkt -) -{ - memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE); - pTargetPkt->offset = offset; - pTargetPkt->word_en = word_en; - efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data); - pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); -} - -static u8 hal_EfusePartialWriteCheck( - struct adapter *padapter, - u8 efuseType, - u16 *pAddr, - struct pgpkt_struct *pTargetPkt, - u8 bPseudoTest -) -{ - struct hal_com_data *pHalData = GET_HAL_DATA(padapter); - struct efuse_hal *pEfuseHal = &pHalData->EfuseHal; - u8 bRet = false; - u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0; - u8 efuse_data = 0; - - EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest); - EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest); - - if (efuseType == EFUSE_WIFI) { - if (bPseudoTest) { -#ifdef HAL_EFUSE_MEMORY - startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes; -#else - startAddr = (u16)fakeEfuseUsedBytes; -#endif - } else - rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr); - } else { - if (bPseudoTest) { -#ifdef HAL_EFUSE_MEMORY - startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes; -#else - startAddr = (u16)fakeBTEfuseUsedBytes; -#endif - } else - rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&startAddr); - } - startAddr %= efuse_max; - - while (1) { - if (startAddr >= efuse_max_available_len) { - bRet = false; - break; - } - - if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) { -#if 1 - bRet = false; - break; -#else - if (EXT_HEADER(efuse_data)) { - cur_header = efuse_data; - startAddr++; - efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest); - if (ALL_WORDS_DISABLED(efuse_data)) { - bRet = false; - break; - } else { - curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); - curPkt.word_en = efuse_data & 0x0F; - } - } else { - cur_header = efuse_data; - curPkt.offset = (cur_header>>4) & 0x0F; - curPkt.word_en = cur_header & 0x0F; - } - - curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en); - /* if same header is found but no data followed */ - /* write some part of data followed by the header. */ - if ( - (curPkt.offset == pTargetPkt->offset) && - (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == false) && - wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == true - ) { - /* Here to write partial data */ - badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest); - if (badworden != 0x0F) { - u32 PgWriteSuccess = 0; - /* if write fail on some words, write these bad words again */ - if (efuseType == EFUSE_WIFI) - PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); - else - PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); - - if (!PgWriteSuccess) { - bRet = false; /* write fail, return */ - break; - } - } - /* partial write ok, update the target packet for later use */ - for (i = 0; i < 4; i++) { - if ((matched_wden & (0x1<word_en |= (0x1<word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); - } - /* read from next header */ - startAddr = startAddr + (curPkt.word_cnts*2) + 1; -#endif - } else { - /* not used header, 0xff */ - *pAddr = startAddr; - bRet = true; - break; - } - } - - return bRet; -} - -static u8 hal_EfusePgPacketWrite1ByteHeader( - struct adapter *padapter, - u8 efuseType, - u16 *pAddr, - struct pgpkt_struct *pTargetPkt, - u8 bPseudoTest -) -{ - u8 pg_header = 0, tmp_header = 0; - u16 efuse_addr = *pAddr; - u8 repeatcnt = 0; - - pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en; - - do { - efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest); - efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest); - if (tmp_header != 0xFF) - break; - if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) - return false; - - } while (1); - - if (tmp_header != pg_header) - return false; - - *pAddr = efuse_addr; - - return true; -} - -static u8 hal_EfusePgPacketWrite2ByteHeader( - struct adapter *padapter, - u8 efuseType, - u16 *pAddr, - struct pgpkt_struct *pTargetPkt, - u8 bPseudoTest -) -{ - u16 efuse_addr, efuse_max_available_len = 0; - u8 pg_header = 0, tmp_header = 0; - u8 repeatcnt = 0; - - EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest); - - efuse_addr = *pAddr; - if (efuse_addr >= efuse_max_available_len) - return false; - - pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F; - - do { - efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest); - efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest); - if (tmp_header != 0xFF) - break; - if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) - return false; - - } while (1); - - if (tmp_header != pg_header) - return false; - - /* to write ext_header */ - efuse_addr++; - pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en; - - do { - efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest); - efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest); - if (tmp_header != 0xFF) - break; - if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) - return false; - - } while (1); - - if (tmp_header != pg_header) /* offset PG fail */ - return false; - - *pAddr = efuse_addr; - - return true; -} - -static u8 hal_EfusePgPacketWriteHeader( - struct adapter *padapter, - u8 efuseType, - u16 *pAddr, - struct pgpkt_struct *pTargetPkt, - u8 bPseudoTest -) -{ - u8 bRet = false; - - if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE) - bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest); - else - bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest); - - return bRet; -} - -static u8 hal_EfusePgPacketWriteData( - struct adapter *padapter, - u8 efuseType, - u16 *pAddr, - struct pgpkt_struct *pTargetPkt, - u8 bPseudoTest -) -{ - u16 efuse_addr; - u8 badworden; - - - efuse_addr = *pAddr; - badworden = Efuse_WordEnableDataWrite(padapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest); - if (badworden != 0x0F) - return false; - - return true; -} - -static s32 Hal_EfusePgPacketWrite( - struct adapter *padapter, - u8 offset, - u8 word_en, - u8 *pData, - bool bPseudoTest -) -{ - struct pgpkt_struct targetPkt; - u16 startAddr = 0; - u8 efuseType = EFUSE_WIFI; - - if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest)) - return false; - - hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); - - if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) - return false; - - if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) - return false; - - if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) - return false; - - return true; -} - -static bool Hal_EfusePgPacketWrite_BT( - struct adapter *padapter, - u8 offset, - u8 word_en, - u8 *pData, - bool bPseudoTest -) -{ - struct pgpkt_struct targetPkt; - u16 startAddr = 0; - u8 efuseType = EFUSE_BT; - - if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest)) - return false; - - hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); - - if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) - return false; - - if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) - return false; - - if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) - return false; - - return true; -} - static struct hal_version ReadChipVersion8723B(struct adapter *padapter) { u32 value32; @@ -1645,15 +1179,15 @@ static struct hal_version ReadChipVersion8723B(struct adapter *padapter) pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0); pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0); pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT); -#if 1 + dump_chip_info(ChipVersion); -#endif + pHalData->VersionID = ChipVersion; return ChipVersion; } -static void rtl8723b_read_chip_version(struct adapter *padapter) +void rtl8723b_read_chip_version(struct adapter *padapter) { ReadChipVersion8723B(padapter); } @@ -1747,7 +1281,7 @@ static void _BeaconFunctionEnable(struct adapter *padapter, u8 Enable, u8 Linked rtw_write8(padapter, REG_RD_CTRL+1, 0x6F); } -static void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter) +void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter) { u8 val8; u32 value32; @@ -1808,16 +1342,6 @@ static void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter) rtw_write8(padapter, bcn_ctrl_reg, val8); } -static void rtl8723b_GetHalODMVar( - struct adapter *Adapter, - enum hal_odm_variable eVariable, - void *pValue1, - void *pValue2 -) -{ - GetHalODMVar(Adapter, eVariable, pValue1, pValue2); -} - static void rtl8723b_SetHalODMVar( struct adapter *Adapter, enum hal_odm_variable eVariable, @@ -1836,7 +1360,7 @@ static void hal_notch_filter_8723b(struct adapter *adapter, bool enable) rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1); } -static void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level) +void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level) { u32 mask, rate_bitmap; u8 shortGIrate = false; @@ -1876,49 +1400,9 @@ static void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_l void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc) { - pHalFunc->free_hal_data = &rtl8723b_free_hal_data; - - pHalFunc->dm_init = &rtl8723b_init_dm_priv; - - pHalFunc->read_chip_version = &rtl8723b_read_chip_version; - - pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8723B; - - pHalFunc->set_bwmode_handler = &PHY_SetBWMode8723B; - pHalFunc->set_channel_handler = &PHY_SwChnl8723B; - pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8723B; - - pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8723B; - pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8723B; - - pHalFunc->hal_dm_watchdog = &rtl8723b_HalDmWatchDog; - pHalFunc->hal_dm_watchdog_in_lps = &rtl8723b_HalDmWatchDog_in_LPS; - - - pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723b_SetBeaconRelatedRegisters; - - pHalFunc->Add_RateATid = &rtl8723b_Add_RateATid; - - pHalFunc->run_thread = &rtl8723b_start_thread; - pHalFunc->cancel_thread = &rtl8723b_stop_thread; - - pHalFunc->read_bbreg = &PHY_QueryBBReg_8723B; - pHalFunc->write_bbreg = &PHY_SetBBReg_8723B; - pHalFunc->read_rfreg = &PHY_QueryRFReg_8723B; - pHalFunc->write_rfreg = &PHY_SetRFReg_8723B; - /* Efuse related function */ - pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch; - pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch; - pHalFunc->ReadEFuse = &Hal_ReadEFuse; - pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition; - pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize; - pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead; - pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite; pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite; - pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT; - pHalFunc->GetHalODMVarHandler = &rtl8723b_GetHalODMVar; pHalFunc->SetHalODMVarHandler = &rtl8723b_SetHalODMVar; pHalFunc->xmit_thread_handler = &hal_xmit_handler; diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c index 4ff092b7c9c99a5e69d538c4a23473462297fd2f..d8709d40cb33fe95319dcc3ee838e9acf2f55f2c 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c @@ -575,10 +575,6 @@ void PHY_SetTxPowerLevel8723B(struct adapter *Adapter, u8 Channel) PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath); } -void PHY_GetTxPowerLevel8723B(struct adapter *Adapter, s32 *powerlevel) -{ -} - static void phy_SetRegBW_8723B( struct adapter *Adapter, enum channel_width CurrentBW ) @@ -764,17 +760,6 @@ static void PHY_HandleSwChnlAndSetBW8723B( } } -void PHY_SetBWMode8723B( - struct adapter *Adapter, - enum channel_width Bandwidth, /* 20M or 40M */ - unsigned char Offset /* Upper, Lower, or Don't care */ -) -{ - struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); - - PHY_HandleSwChnlAndSetBW8723B(Adapter, false, true, pHalData->CurrentChannel, Bandwidth, Offset, Offset, pHalData->CurrentChannel); -} - /* Call after initialization */ void PHY_SwChnl8723B(struct adapter *Adapter, u8 channel) { diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c index 78298e63edce6e51ddcfaf867e5d7593f1ddbc6b..5dc1c12fe03e5727c325b779b159d616871e1f02 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c @@ -411,14 +411,12 @@ int rtl8723bs_xmit_thread(void *context) s32 ret; struct adapter *padapter; struct xmit_priv *pxmitpriv; - u8 thread_name[20]; ret = _SUCCESS; padapter = context; pxmitpriv = &padapter->xmitpriv; - rtw_sprintf(thread_name, 20, "RTWHALXT-%s", ADPT_ARG(padapter)); - thread_enter(thread_name); + allow_signal(SIGTERM); do { ret = rtl8723bs_xmit_handler(padapter); diff --git a/drivers/staging/rtl8723bs/hal/sdio_halinit.c b/drivers/staging/rtl8723bs/hal/sdio_halinit.c index d3aae413fc0f929d1c3c3c86be1bb8b60ee41512..af9a2b068796a74d9e328da8322a875b6cbbc366 100644 --- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c +++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c @@ -583,7 +583,7 @@ static bool HalDetectPwrDownMode(struct adapter *Adapter) return pHalData->pwrdown; } /* HalDetectPwrDownMode */ -static u32 rtl8723bs_hal_init(struct adapter *padapter) +u32 rtl8723bs_hal_init(struct adapter *padapter) { s32 ret; struct hal_com_data *pHalData; @@ -884,7 +884,7 @@ static void CardDisableRTL8723BSdio(struct adapter *padapter) HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8723B_card_disable_flow); } -static u32 rtl8723bs_hal_deinit(struct adapter *padapter) +u32 rtl8723bs_hal_deinit(struct adapter *padapter) { struct dvobj_priv *psdpriv = padapter->dvobj; struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; @@ -937,17 +937,7 @@ static u32 rtl8723bs_hal_deinit(struct adapter *padapter) return _SUCCESS; } -static u32 rtl8723bs_inirp_init(struct adapter *padapter) -{ - return _SUCCESS; -} - -static u32 rtl8723bs_inirp_deinit(struct adapter *padapter) -{ - return _SUCCESS; -} - -static void rtl8723bs_init_default_value(struct adapter *padapter) +void rtl8723bs_init_default_value(struct adapter *padapter) { struct hal_com_data *pHalData; @@ -960,7 +950,7 @@ static void rtl8723bs_init_default_value(struct adapter *padapter) pHalData->SdioRxFIFOCnt = 0; } -static void rtl8723bs_interface_configure(struct adapter *padapter) +void rtl8723bs_interface_configure(struct adapter *padapter) { struct hal_com_data *pHalData = GET_HAL_DATA(padapter); struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); @@ -1142,7 +1132,7 @@ static s32 _ReadAdapterInfo8723BS(struct adapter *padapter) return _SUCCESS; } -static void ReadAdapterInfo8723BS(struct adapter *padapter) +void ReadAdapterInfo8723BS(struct adapter *padapter) { /* Read EEPROM size before call any EEPROM function */ padapter->EepromAddressSize = GetEEPROMSize8723B(padapter); @@ -1154,7 +1144,7 @@ static void ReadAdapterInfo8723BS(struct adapter *padapter) * If variable not handled here, * some variables will be processed in SetHwReg8723B() */ -static void SetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val) +void SetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val) { u8 val8; @@ -1195,7 +1185,7 @@ static void SetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val) * If variable not handled here, * some variables will be processed in GetHwReg8723B() */ -static void GetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val) +void GetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val) { switch (variable) { case HW_VAR_CPWM: @@ -1214,7 +1204,7 @@ static void GetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val) } } -static void SetHwRegWithBuf8723B(struct adapter *padapter, u8 variable, u8 *pbuf, int len) +void SetHwRegWithBuf8723B(struct adapter *padapter, u8 variable, u8 *pbuf, int len) { switch (variable) { case HW_VAR_C2H_HANDLE: @@ -1229,7 +1219,7 @@ static void SetHwRegWithBuf8723B(struct adapter *padapter, u8 variable, u8 *pbuf /* Description: */ /* Query setting of specified variable. */ /* */ -static u8 GetHalDefVar8723BSDIO( +u8 GetHalDefVar8723BSDIO( struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue ) { @@ -1257,8 +1247,7 @@ static u8 GetHalDefVar8723BSDIO( /* Description: */ /* Change default setting of specified variable. */ /* */ -static u8 SetHalDefVar8723BSDIO(struct adapter *Adapter, - enum hal_def_variable eVariable, void *pValue) +u8 SetHalDefVar8723BSDIO(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue) { return SetHalDefVar8723B(Adapter, eVariable, pValue); } @@ -1269,32 +1258,4 @@ void rtl8723bs_set_hal_ops(struct adapter *padapter) rtl8723b_set_hal_ops(pHalFunc); - pHalFunc->hal_init = &rtl8723bs_hal_init; - pHalFunc->hal_deinit = &rtl8723bs_hal_deinit; - - pHalFunc->inirp_init = &rtl8723bs_inirp_init; - pHalFunc->inirp_deinit = &rtl8723bs_inirp_deinit; - - pHalFunc->init_xmit_priv = &rtl8723bs_init_xmit_priv; - pHalFunc->free_xmit_priv = &rtl8723bs_free_xmit_priv; - - pHalFunc->init_recv_priv = &rtl8723bs_init_recv_priv; - pHalFunc->free_recv_priv = &rtl8723bs_free_recv_priv; - - pHalFunc->init_default_value = &rtl8723bs_init_default_value; - pHalFunc->intf_chip_configure = &rtl8723bs_interface_configure; - pHalFunc->read_adapter_info = &ReadAdapterInfo8723BS; - - pHalFunc->enable_interrupt = &EnableInterrupt8723BSdio; - pHalFunc->disable_interrupt = &DisableInterrupt8723BSdio; - pHalFunc->check_ips_status = &CheckIPSStatus; - pHalFunc->SetHwRegHandler = &SetHwReg8723BS; - pHalFunc->GetHwRegHandler = &GetHwReg8723BS; - pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8723B; - pHalFunc->GetHalDefVarHandler = &GetHalDefVar8723BSDIO; - pHalFunc->SetHalDefVarHandler = &SetHalDefVar8723BSDIO; - - pHalFunc->hal_xmit = &rtl8723bs_hal_xmit; - pHalFunc->mgnt_xmit = &rtl8723bs_mgnt_xmit; - pHalFunc->hal_xmitframe_enqueue = &rtl8723bs_hal_xmitframe_enqueue; } diff --git a/drivers/staging/rtl8723bs/include/drv_types.h b/drivers/staging/rtl8723bs/include/drv_types.h index 0b35c97843cc7bc027d626df1ce8d9fe5f6d1bdb..7b0e824e05a9a1727be5f7195841416ccdf753f6 100644 --- a/drivers/staging/rtl8723bs/include/drv_types.h +++ b/drivers/staging/rtl8723bs/include/drv_types.h @@ -182,8 +182,6 @@ struct registry_priv { #include -#define is_primary_adapter(adapter) (1) -#define get_iface_type(adapter) (IFACE_PORT0) #define GET_PRIMARY_ADAPTER(padapter) (((struct adapter *)padapter)->dvobj->if1) #define GET_IFACE_NUMS(padapter) (((struct adapter *)padapter)->dvobj->iface_nums) #define GET_ADAPTER(padapter, iface_id) (((struct adapter *)padapter)->dvobj->padapters[iface_id]) @@ -320,14 +318,6 @@ static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj) return &dvobj->intf_data.func->dev; } -struct adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj); - -enum { - IFACE_PORT0, /* mapping to port0 for C/D series chips */ - IFACE_PORT1, /* mapping to port1 for C/D series chip */ - MAX_IFACE_PORT, -}; - enum { DRIVER_NORMAL = 0, DRIVER_DISAPPEAR = 1, diff --git a/drivers/staging/rtl8723bs/include/hal_com.h b/drivers/staging/rtl8723bs/include/hal_com.h index 17d5cfb66a365fd292eaa64648e94eaf0c504420..4db93484725f0973430c38c7fdbfcc8caf604137 100644 --- a/drivers/staging/rtl8723bs/include/hal_com.h +++ b/drivers/staging/rtl8723bs/include/hal_com.h @@ -158,10 +158,6 @@ void rtw_dump_raw_rssi_info(struct adapter *padapter); void rtw_bb_rf_gain_offset(struct adapter *padapter); -void GetHalODMVar(struct adapter *Adapter, - enum hal_odm_variable eVariable, - void *pValue1, - void *pValue2); void SetHalODMVar( struct adapter *Adapter, enum hal_odm_variable eVariable, diff --git a/drivers/staging/rtl8723bs/include/hal_intf.h b/drivers/staging/rtl8723bs/include/hal_intf.h index efdd1f912b5d9e3ad5de6d3b1b8088b5cb4f9d8f..282e141616b0a22fb6b81d9959aeb479332252bd 100644 --- a/drivers/staging/rtl8723bs/include/hal_intf.h +++ b/drivers/staging/rtl8723bs/include/hal_intf.h @@ -162,91 +162,9 @@ enum hal_intf_ps_func { typedef s32 (*c2h_id_filter)(u8 *c2h_evt); struct hal_ops { - u32 (*hal_power_on)(struct adapter *padapter); - void (*hal_power_off)(struct adapter *padapter); - u32 (*hal_init)(struct adapter *padapter); - u32 (*hal_deinit)(struct adapter *padapter); - - void (*free_hal_data)(struct adapter *padapter); - - u32 (*inirp_init)(struct adapter *padapter); - u32 (*inirp_deinit)(struct adapter *padapter); - void (*irp_reset)(struct adapter *padapter); - - s32 (*init_xmit_priv)(struct adapter *padapter); - void (*free_xmit_priv)(struct adapter *padapter); - - s32 (*init_recv_priv)(struct adapter *padapter); - void (*free_recv_priv)(struct adapter *padapter); - - void (*dm_init)(struct adapter *padapter); - void (*dm_deinit)(struct adapter *padapter); - void (*read_chip_version)(struct adapter *padapter); - - void (*init_default_value)(struct adapter *padapter); - - void (*intf_chip_configure)(struct adapter *padapter); - - void (*read_adapter_info)(struct adapter *padapter); - - void (*enable_interrupt)(struct adapter *padapter); - void (*disable_interrupt)(struct adapter *padapter); - u8 (*check_ips_status)(struct adapter *padapter); - s32 (*interrupt_handler)(struct adapter *padapter); - void (*clear_interrupt)(struct adapter *padapter); - void (*set_bwmode_handler)(struct adapter *padapter, enum channel_width Bandwidth, u8 Offset); - void (*set_channel_handler)(struct adapter *padapter, u8 channel); - void (*set_chnl_bw_handler)(struct adapter *padapter, u8 channel, enum channel_width Bandwidth, u8 Offset40, u8 Offset80); - - void (*set_tx_power_level_handler)(struct adapter *padapter, u8 channel); - void (*get_tx_power_level_handler)(struct adapter *padapter, s32 *powerlevel); - - void (*hal_dm_watchdog)(struct adapter *padapter); - void (*hal_dm_watchdog_in_lps)(struct adapter *padapter); - - - void (*SetHwRegHandler)(struct adapter *padapter, u8 variable, u8 *val); - void (*GetHwRegHandler)(struct adapter *padapter, u8 variable, u8 *val); - - void (*SetHwRegHandlerWithBuf)(struct adapter *padapter, u8 variable, u8 *pbuf, int len); - - u8 (*GetHalDefVarHandler)(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue); - u8 (*SetHalDefVarHandler)(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue); - - void (*GetHalODMVarHandler)(struct adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, void *pValue2); void (*SetHalODMVarHandler)(struct adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet); - void (*UpdateRAMaskHandler)(struct adapter *padapter, u32 mac_id, u8 rssi_level); - void (*SetBeaconRelatedRegistersHandler)(struct adapter *padapter); - - void (*Add_RateATid)(struct adapter *padapter, u32 bitmap, u8 *arg, u8 rssi_level); - - void (*run_thread)(struct adapter *padapter); - void (*cancel_thread)(struct adapter *padapter); - - u8 (*interface_ps_func)(struct adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val); - - s32 (*hal_xmit)(struct adapter *padapter, struct xmit_frame *pxmitframe); - /* - * mgnt_xmit should be implemented to run in interrupt context - */ - s32 (*mgnt_xmit)(struct adapter *padapter, struct xmit_frame *pmgntframe); - s32 (*hal_xmitframe_enqueue)(struct adapter *padapter, struct xmit_frame *pxmitframe); - - u32 (*read_bbreg)(struct adapter *padapter, u32 RegAddr, u32 BitMask); - void (*write_bbreg)(struct adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data); - u32 (*read_rfreg)(struct adapter *padapter, u8 eRFPath, u32 RegAddr, u32 BitMask); - void (*write_rfreg)(struct adapter *padapter, u8 eRFPath, u32 RegAddr, u32 BitMask, u32 Data); - - void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite, u8 PwrState); - void (*BTEfusePowerSwitch)(struct adapter *padapter, u8 bWrite, u8 PwrState); - void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest); - void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest); - u16 (*EfuseGetCurrentSize)(struct adapter *padapter, u8 efuseType, bool bPseudoTest); - int (*Efuse_PgPacketRead)(struct adapter *padapter, u8 offset, u8 *data, bool bPseudoTest); - int (*Efuse_PgPacketWrite)(struct adapter *padapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest); u8 (*Efuse_WordEnableDataWrite)(struct adapter *padapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest); - bool (*Efuse_PgPacketWrite_BT)(struct adapter *padapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest); s32 (*xmit_thread_handler)(struct adapter *padapter); void (*hal_notch_filter)(struct adapter *adapter, bool enable); @@ -357,4 +275,17 @@ s32 rtw_hal_macid_wakeup(struct adapter *padapter, u32 macid); s32 rtw_hal_fill_h2c_cmd(struct adapter *, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +void SetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val); +void GetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val); +void SetHwRegWithBuf8723B(struct adapter *padapter, u8 variable, u8 *pbuf, int len); +u8 GetHalDefVar8723BSDIO(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue); +u8 SetHalDefVar8723BSDIO(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue); +void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level); +void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter); +void Hal_EfusePowerSwitch(struct adapter *padapter, u8 bWrite, u8 PwrState); +void Hal_ReadEFuse(struct adapter *padapter, u8 efuseType, u16 _offset, + u16 _size_byte, u8 *pbuf, bool bPseudoTest); +void Hal_GetEfuseDefinition(struct adapter *padapter, u8 efuseType, u8 type, + void *pOut, bool bPseudoTest); +u16 Hal_EfuseGetCurrentSize(struct adapter *padapter, u8 efuseType, bool bPseudoTest); #endif /* __HAL_INTF_H__ */ diff --git a/drivers/staging/rtl8723bs/include/hal_phy_cfg.h b/drivers/staging/rtl8723bs/include/hal_phy_cfg.h index ea494bcf830b81e5e62053eca557b94478abec0c..07bf0a8d019aa9a1beb4888d6d3cf3b8dbe10390 100644 --- a/drivers/staging/rtl8723bs/include/hal_phy_cfg.h +++ b/drivers/staging/rtl8723bs/include/hal_phy_cfg.h @@ -49,13 +49,8 @@ void PHY_SetTxPowerIndex(struct adapter *Adapter, u32 PowerIndex, u8 PHY_GetTxPowerIndex(struct adapter *padapter, u8 RFPath, u8 Rate, enum channel_width BandWidth, u8 Channel); -void PHY_GetTxPowerLevel8723B(struct adapter *Adapter, s32 *powerlevel); - void PHY_SetTxPowerLevel8723B(struct adapter *Adapter, u8 channel); -void PHY_SetBWMode8723B(struct adapter *Adapter, enum channel_width Bandwidth, - unsigned char Offset); - /* Call after initialization */ void PHY_SwChnl8723B(struct adapter *Adapter, u8 channel); diff --git a/drivers/staging/rtl8723bs/include/osdep_intf.h b/drivers/staging/rtl8723bs/include/osdep_intf.h index 111e0179712ac6e0b8846c65e30f5dd3716618d0..215ece612f71570ebb4f46383b6f4c216fae7f9d 100644 --- a/drivers/staging/rtl8723bs/include/osdep_intf.h +++ b/drivers/staging/rtl8723bs/include/osdep_intf.h @@ -55,9 +55,6 @@ void rtw_unregister_netdevs(struct dvobj_priv *dvobj); u16 rtw_recv_select_queue(struct sk_buff *skb); -int rtw_ndev_notifier_register(void); -void rtw_ndev_notifier_unregister(void); - void rtw_ips_dev_unload(struct adapter *padapter); int rtw_ips_pwr_up(struct adapter *padapter); diff --git a/drivers/staging/rtl8723bs/include/osdep_service.h b/drivers/staging/rtl8723bs/include/osdep_service.h index b21267d7ef7209f4e6c7e3bfd21cb24ef9b41c0b..8b1634f4091ec15971bdc6f5209a2c3a46d1b4db 100644 --- a/drivers/staging/rtl8723bs/include/osdep_service.h +++ b/drivers/staging/rtl8723bs/include/osdep_service.h @@ -73,11 +73,6 @@ int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb); extern void _rtw_init_queue(struct __queue *pqueue); -static inline void thread_enter(char *name) -{ - allow_signal(SIGTERM); -} - static inline void flush_signals_thread(void) { if (signal_pending(current)) diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_recv.h b/drivers/staging/rtl8723bs/include/rtl8723b_recv.h index a108ce89bce43298d6a154c403737f6b714c457c..783f64de0aec2325c23166dd00969b2d2e7b6852 100644 --- a/drivers/staging/rtl8723bs/include/rtl8723b_recv.h +++ b/drivers/staging/rtl8723bs/include/rtl8723b_recv.h @@ -87,4 +87,9 @@ void rtl8723bs_free_recv_priv(struct adapter *padapter); void rtl8723b_query_rx_phy_status(union recv_frame *prframe, struct phy_stat *pphy_stat); void rtl8723b_process_phy_info(struct adapter *padapter, void *prframe); +void rtl8723b_read_chip_version(struct adapter *padapter); +void rtl8723bs_init_default_value(struct adapter *padapter); +void rtl8723bs_interface_configure(struct adapter *padapter); +void ReadAdapterInfo8723BS(struct adapter *padapter); + #endif diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h b/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h index ad2542d0cabe26ac7fc52137cc961e9f94706937..ac4ca7e05b9bf5fbb8b876c6f00c22953239359f 100644 --- a/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h +++ b/drivers/staging/rtl8723bs/include/rtl8723b_xmit.h @@ -405,6 +405,8 @@ struct txdesc_8723b { void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); void rtl8723b_fill_fake_txdesc(struct adapter *padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); +u32 rtl8723bs_hal_init(struct adapter *padapter); +u32 rtl8723bs_hal_deinit(struct adapter *padapter); s32 rtl8723bs_init_xmit_priv(struct adapter *padapter); void rtl8723bs_free_xmit_priv(struct adapter *padapter); s32 rtl8723bs_hal_xmit(struct adapter *padapter, struct xmit_frame *pxmitframe); diff --git a/drivers/staging/rtl8723bs/include/rtw_efuse.h b/drivers/staging/rtl8723bs/include/rtw_efuse.h index 0cb8c6f6d34dba0f70f74d4225eb4c8cfda76e5d..d6ea8a4a856f13e103b148d1685037c2875ca101 100644 --- a/drivers/staging/rtl8723bs/include/rtw_efuse.h +++ b/drivers/staging/rtl8723bs/include/rtw_efuse.h @@ -90,16 +90,12 @@ extern u8 fakeBTEfuseInitMap[]; extern u8 fakeBTEfuseModifiedMap[]; /*------------------------Export global variable----------------------------*/ -u16 Efuse_GetCurrentSize(struct adapter *padapter, u8 efuseType, bool bPseudoTest); u8 Efuse_CalculateWordCnts(u8 word_en); void EFUSE_GetEfuseDefinition(struct adapter *padapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest); u8 efuse_OneByteRead(struct adapter *padapter, u16 addr, u8 *data, bool bPseudoTest); u8 efuse_OneByteWrite(struct adapter *padapter, u16 addr, u8 data, bool bPseudoTest); void Efuse_PowerSwitch(struct adapter *padapter, u8 bWrite, u8 PwrState); -int Efuse_PgPacketRead(struct adapter *padapter, u8 offset, u8 *data, bool bPseudoTest); -int Efuse_PgPacketWrite(struct adapter *padapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest); -void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata); u8 Efuse_WordEnableDataWrite(struct adapter *padapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest); u8 EFUSE_Read1Byte(struct adapter *padapter, u16 Address); diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h index 8315399b64fdb56c02d6503fc7127935d2b3a826..2080408743ef72f81ebe76afc31ba149c2caa9cc 100644 --- a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h @@ -447,9 +447,7 @@ void Set_MSR(struct adapter *padapter, u8 type); u8 rtw_get_oper_ch(struct adapter *adapter); void rtw_set_oper_ch(struct adapter *adapter, u8 ch); -u8 rtw_get_oper_bw(struct adapter *adapter); void rtw_set_oper_bw(struct adapter *adapter, u8 bw); -u8 rtw_get_oper_choffset(struct adapter *adapter); void rtw_set_oper_choffset(struct adapter *adapter, u8 offset); u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset); unsigned long rtw_get_on_cur_ch_time(struct adapter *adapter); @@ -459,8 +457,6 @@ void r8723bs_select_channel(struct adapter *padapter, unsigned char channel); unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); -void read_cam(struct adapter *padapter, u8 entry, u8 *get_key); - /* modify HW only */ void _write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key); void _clear_cam_entry(struct adapter *padapter, u8 entry); @@ -528,7 +524,6 @@ void rtw_camid_free(struct adapter *adapter, u8 cam_id); extern void rtw_alloc_macid(struct adapter *padapter, struct sta_info *psta); extern void rtw_release_macid(struct adapter *padapter, struct sta_info *psta); -extern u8 rtw_search_max_mac_id(struct adapter *padapter); void report_join_res(struct adapter *padapter, int res); void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame); diff --git a/drivers/staging/rtl8723bs/include/rtw_mp.h b/drivers/staging/rtl8723bs/include/rtw_mp.h index f94bb18479da5da433738fe9b4e07432660e73a2..5a1cbd2ed8515df19c64a0f1296e4bed61215af7 100644 --- a/drivers/staging/rtl8723bs/include/rtw_mp.h +++ b/drivers/staging/rtl8723bs/include/rtw_mp.h @@ -276,10 +276,6 @@ void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u3 u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz); void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz); -u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask); -void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val); -u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr); -void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val); void SetChannel(struct adapter *padapter); void SetBandwidth(struct adapter *padapter); diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index b63a74e669bcf24bad9b2c273f11b9622f2aa451..c053ee9c1361c48901edcd0c7d5939d12778c3d7 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -581,7 +581,6 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); - /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ /* set mic key */ memcpy(txkey, &(param->u.crypt.key[16]), 8); memcpy(rxkey, &(param->u.crypt.key[24]), 8); @@ -626,7 +625,6 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { psta->dot118021XPrivacy = _TKIP_; - /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ /* set mic key */ memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); @@ -657,7 +655,6 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); - /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ /* set mic key */ memcpy(txkey, &(param->u.crypt.key[16]), 8); memcpy(rxkey, &(param->u.crypt.key[24]), 8); @@ -785,7 +782,6 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ - /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */ memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); @@ -806,10 +802,6 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param } else if (strcmp(param->u.crypt.alg, "BIP") == 0) { /* save the IGTK key, length 16 bytes */ memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); - /* - for (no = 0;no<16;no++) - printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); - */ padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; padapter->securitypriv.binstallBIPkey = true; } @@ -817,9 +809,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param } pbcmc_sta = rtw_get_bcmc_stainfo(padapter); - if (!pbcmc_sta) { - /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */ - } else { + if (pbcmc_sta) { /* Jeff: don't disable ieee8021x_blocked while clearing key */ if (strcmp(param->u.crypt.alg, "none") != 0) pbcmc_sta->ieee8021x_blocked = false; diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c index a9e481e182ad6c6ad8fd5ce7bdbee1cfb3069ab4..793b051536f324a65f43d3c16e828078f472bd5c 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c @@ -138,9 +138,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */ psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); - if (!psta) { - /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */ - } else { + if (psta) { /* Jeff: don't disable ieee8021x_blocked while clearing key */ if (strcmp(param->u.crypt.alg, "none") != 0) psta->ieee8021x_blocked = false; @@ -154,7 +152,6 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ - /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */ memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8); memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8); @@ -177,13 +174,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, true); } else if (strcmp(param->u.crypt.alg, "BIP") == 0) { - /* printk("BIP key_len =%d , index =%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */ /* save the IGTK key, length 16 bytes */ memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); - /*printk("IGTK key below:\n"); - for (no = 0;no<16;no++) - printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); - printk("\n");*/ padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; padapter->securitypriv.binstallBIPkey = true; } @@ -191,9 +183,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, } pbcmc_sta = rtw_get_bcmc_stainfo(padapter); - if (!pbcmc_sta) { - /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */ - } else { + if (pbcmc_sta) { /* Jeff: don't disable ieee8021x_blocked while clearing key */ if (strcmp(param->u.crypt.alg, "none") != 0) pbcmc_sta->ieee8021x_blocked = false; @@ -629,7 +619,6 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); - /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ /* set mic key */ memcpy(txkey, ¶m->u.crypt.key[16], 8); memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8); @@ -674,7 +663,6 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { psta->dot118021XPrivacy = _TKIP_; - /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ /* set mic key */ memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8); memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8); @@ -703,7 +691,6 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); - /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ /* set mic key */ memcpy(txkey, ¶m->u.crypt.key[16], 8); memcpy(rxkey, ¶m->u.crypt.key[24], 8); diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index fc9b9c5efb50e183f239cdb2e50a83c0bd5bb9b2..4e1917c054029157b07c6d3c6e2e311c52b0aa7a 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -381,34 +381,6 @@ u16 rtw_recv_select_queue(struct sk_buff *skb) return rtw_1d_to_queue[priority]; } -static int rtw_ndev_notifier_call(struct notifier_block *nb, unsigned long state, void *ptr) -{ - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - - if (dev->netdev_ops->ndo_do_ioctl != rtw_ioctl) - return NOTIFY_DONE; - - netdev_dbg(dev, FUNC_NDEV_FMT " state:%lu\n", FUNC_NDEV_ARG(dev), - state); - - return NOTIFY_DONE; -} - -static struct notifier_block rtw_ndev_notifier = { - .notifier_call = rtw_ndev_notifier_call, -}; - -int rtw_ndev_notifier_register(void) -{ - return register_netdevice_notifier(&rtw_ndev_notifier); -} - -void rtw_ndev_notifier_unregister(void) -{ - unregister_netdevice_notifier(&rtw_ndev_notifier); -} - - static int rtw_ndev_init(struct net_device *dev) { struct adapter *adapter = rtw_netdev_priv(dev); @@ -633,8 +605,7 @@ void rtw_reset_drv_sw(struct adapter *padapter) struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); /* hal_priv */ - if (is_primary_adapter(padapter)) - rtw_hal_def_value_init(padapter); + rtw_hal_def_value_init(padapter); RTW_ENABLE_FUNC(padapter, DF_RX_BIT); RTW_ENABLE_FUNC(padapter, DF_TX_BIT); diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c index d18fde4e5d6ceaf0c3e8e26a6c605ba2fa883f53..5a7238e661ffbea6b0f0236a730f762a2e7abca2 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -72,7 +72,7 @@ static int sdio_alloc_irq(struct dvobj_priv *dvobj) err = sdio_claim_irq(func, &sd_sync_int_hdl); if (err) { dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++; - printk(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err); + netdev_crit(dvobj->if1->pnetdev, "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err); } else { dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++; dvobj->irq_alloc = 1; @@ -382,7 +382,6 @@ static int rtw_drv_init( if (sdio_alloc_irq(dvobj) != _SUCCESS) goto free_if1; - rtw_ndev_notifier_register(); status = _SUCCESS; free_if1: @@ -484,22 +483,12 @@ static int rtw_sdio_resume(struct device *dev) static int __init rtw_drv_entry(void) { - int ret; - - ret = sdio_register_driver(&rtl8723bs_sdio_driver); - if (ret != 0) - rtw_ndev_notifier_unregister(); - - return ret; + return sdio_register_driver(&rtl8723bs_sdio_driver); } +module_init(rtw_drv_entry); static void __exit rtw_drv_halt(void) { sdio_unregister_driver(&rtl8723bs_sdio_driver); - - rtw_ndev_notifier_unregister(); } - - -module_init(rtw_drv_entry); module_exit(rtw_drv_halt); diff --git a/drivers/staging/rts5208/Kconfig b/drivers/staging/rts5208/Kconfig deleted file mode 100644 index b864023d3ccb5847c54bab0f93afaf86fdd99ba5..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config RTS5208 - tristate "Realtek PCI-E Card Reader RTS5208/5288 support" - depends on PCI && SCSI - help - Say Y here to include driver code to support the Realtek - PCI-E card reader rts5208/rts5288. - - If this driver is compiled as a module, it will be named rts5208. diff --git a/drivers/staging/rts5208/Makefile b/drivers/staging/rts5208/Makefile deleted file mode 100644 index 3c9e9797d3d936a5f5d14ad8aa24abb4a36fc9b1..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_RTS5208) := rts5208.o - -rts5208-y := rtsx.o rtsx_chip.o rtsx_transport.o rtsx_scsi.o \ - rtsx_card.o general.o sd.o xd.o ms.o spi.o diff --git a/drivers/staging/rts5208/TODO b/drivers/staging/rts5208/TODO deleted file mode 100644 index 9cec0d8dd0b6cad6d8890d9bae1357629a25f6b2..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: -- use kernel coding style -- checkpatch.pl fixes -- We will use the stack in drivers/mmc to implement - rts5208/5288 in the future - -Micky Ching diff --git a/drivers/staging/rts5208/general.c b/drivers/staging/rts5208/general.c deleted file mode 100644 index 0f912b011064f195203223306d04f1bf7e9a474a..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/general.c +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include "general.h" - -int bit1cnt_long(u32 data) -{ - int i, cnt = 0; - - for (i = 0; i < 32; i++) { - if (data & 0x01) - cnt++; - data >>= 1; - } - return cnt; -} - diff --git a/drivers/staging/rts5208/general.h b/drivers/staging/rts5208/general.h deleted file mode 100644 index 53e2dbabf04b7b57db85bfe576e0158a042ef049..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/general.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __RTSX_GENERAL_H -#define __RTSX_GENERAL_H - -#include "rtsx.h" - -int bit1cnt_long(u32 data); - -#endif /* __RTSX_GENERAL_H */ diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c deleted file mode 100644 index bfeb5873bf3baafb791f38f597b91545e90a5400..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/ms.c +++ /dev/null @@ -1,4311 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include -#include - -#include "rtsx.h" -#include "ms.h" - -static inline void ms_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct ms_info *ms_card = &chip->ms_card; - - ms_card->err_code = err_code; -} - -static inline int ms_check_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct ms_info *ms_card = &chip->ms_card; - - return (ms_card->err_code == err_code); -} - -static int ms_parse_err_code(struct rtsx_chip *chip) -{ - return STATUS_FAIL; -} - -static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode, - u8 tpc, u8 cnt, u8 cfg) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 *ptr; - - dev_dbg(rtsx_dev(chip), "%s: tpc = 0x%x\n", __func__, tpc); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, - 0xFF, MS_TRANSFER_START | trans_mode); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - rtsx_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - if (!(tpc & 0x08)) { /* Read Packet */ - if (*ptr & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - return ms_parse_err_code(chip); - } - } else { /* Write Packet */ - if (CHK_MSPRO(ms_card) && !(*ptr & 0x80)) { - if (*ptr & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - return ms_parse_err_code(chip); - } - } - } - - if (*ptr & MS_RDY_TIMEOUT) { - rtsx_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - return STATUS_SUCCESS; -} - -static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, - u8 tpc, u16 sec_cnt, u8 cfg, bool mode_2k, - int use_sg, void *buf, int buf_len) -{ - int retval; - u8 val, err_code = 0; - enum dma_data_direction dir; - - if (!buf || !buf_len) - return STATUS_FAIL; - - if (trans_mode == MS_TM_AUTO_READ) { - dir = DMA_FROM_DEVICE; - err_code = MS_FLASH_READ_ERROR; - } else if (trans_mode == MS_TM_AUTO_WRITE) { - dir = DMA_TO_DEVICE; - err_code = MS_FLASH_WRITE_ERROR; - } else { - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - - if (mode_2k) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_CFG, MS_2K_SECTOR_MODE, MS_2K_SECTOR_MODE); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0); - } - - trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); - rtsx_add_cmd(chip, CHECK_REG_CMD, - MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, MS_CARD, buf, buf_len, - use_sg, dir, chip->mspro_timeout); - if (retval < 0) { - ms_set_err_code(chip, err_code); - if (retval == -ETIMEDOUT) - retval = STATUS_TIMEDOUT; - else - retval = STATUS_FAIL; - - return retval; - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval) - return retval; - - if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_write_bytes(struct rtsx_chip *chip, - u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - - if (!data || data_len < cnt) - return STATUS_ERROR; - - rtsx_init_cmd(chip); - - for (i = 0; i < cnt; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, data[i]); - } - if (cnt % 2) - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); - rtsx_add_cmd(chip, CHECK_REG_CMD, - MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - u8 val = 0; - - rtsx_read_register(chip, MS_TRANS_CFG, &val); - dev_dbg(rtsx_dev(chip), "MS_TRANS_CFG: 0x%02x\n", val); - - rtsx_clear_ms_error(chip); - - if (!(tpc & 0x08)) { - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - return ms_parse_err_code(chip); - } - } else { - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - return ms_parse_err_code(chip); - } - } - } - - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - return STATUS_SUCCESS; -} - -static int ms_read_bytes(struct rtsx_chip *chip, - u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 *ptr; - - if (!data) - return STATUS_ERROR; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_READ_BYTES); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - for (i = 0; i < data_len - 1; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); - - if (data_len % 2) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0); - else - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, - 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - u8 val = 0; - - rtsx_read_register(chip, MS_TRANS_CFG, &val); - rtsx_clear_ms_error(chip); - - if (!(tpc & 0x08)) { - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - return ms_parse_err_code(chip); - } - } else { - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - return ms_parse_err_code(chip); - } - } - } - - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - for (i = 0; i < data_len; i++) - data[i] = ptr[i]; - - if (tpc == PRO_READ_SHORT_DATA && data_len == 8) { - dev_dbg(rtsx_dev(chip), "Read format progress:\n"); - print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, ptr, - cnt); - } - - return STATUS_SUCCESS; -} - -static int ms_set_rw_reg_addr(struct rtsx_chip *chip, u8 read_start, - u8 read_cnt, u8 write_start, u8 write_cnt) -{ - int retval, i; - u8 data[4]; - - data[0] = read_start; - data[1] = read_cnt; - data[2] = write_start; - data[3] = write_cnt; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, SET_RW_REG_ADRS, 4, - NO_WAIT_INT, data, 4); - if (retval == STATUS_SUCCESS) - return STATUS_SUCCESS; - rtsx_clear_ms_error(chip); - } - - return STATUS_FAIL; -} - -static int ms_send_cmd(struct rtsx_chip *chip, u8 cmd, u8 cfg) -{ - u8 data[2]; - - data[0] = cmd; - data[1] = 0; - - return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1); -} - -static int ms_set_init_para(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (CHK_HG8BIT(ms_card)) { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_hg_clk; - else - ms_card->ms_clock = chip->fpga_ms_hg_clk; - - } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_4bit_clk; - else - ms_card->ms_clock = chip->fpga_ms_4bit_clk; - - } else { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_1bit_clk; - else - ms_card->ms_clock = chip->fpga_ms_1bit_clk; - } - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_switch_clock(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_pull_ctl_disable(struct rtsx_chip *chip) -{ - int retval; - - if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF, - MS_D1_PD | MS_D2_PD | MS_CLK_PD | - MS_D6_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, - MS_D3_PD | MS_D0_PD | MS_BS_PD | - XD_D4_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF, - MS_D7_PD | XD_CE_PD | XD_CLE_PD | - XD_CD_PU); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | - XD_ALE_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | - SD_CMD_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - if (retval) - return retval; - - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, - 0xFF, 0x55); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL2, - 0xFF, 0x55); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL3, - 0xFF, 0x4B); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL4, - 0xFF, 0x69); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -static int ms_pull_ctl_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - MS_D1_PD | MS_D2_PD | MS_CLK_NP | MS_D6_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - MS_D3_PD | MS_D0_PD | MS_BS_NP | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL2, 0xFF, 0x45); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL3, 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL4, 0xFF, 0x29); - } - } - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_prepare_reset(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 oc_mask = 0; - - ms_card->ms_type = 0; - ms_card->check_ms_flow = 0; - ms_card->switch_8bit_fail = 0; - ms_card->delay_write.delay_write_flag = 0; - - ms_card->pro_under_formatting = 0; - - retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) - wait_timeout(250); - - retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->asic_code) { - retval = ms_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_MS_PULL_CTL_BIT | 0x20, 0); - if (retval) - return retval; - } - - if (!chip->ft2_fast_mode) { - retval = card_power_on(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(150); - -#ifdef SUPPORT_OCP - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - oc_mask = MS_OC_NOW | MS_OC_EVER; - else - oc_mask = SD_OC_NOW | SD_OC_EVER; - - if (chip->ocp_stat & oc_mask) { - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - return STATUS_FAIL; - } -#endif - } - - retval = rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, - MS_OUTPUT_EN); - if (retval) - return retval; - - if (chip->asic_code) { - retval = rtsx_write_register(chip, MS_CFG, 0xFF, - SAMPLE_TIME_RISING | - PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | - MS_BUS_WIDTH_1); - if (retval) - return retval; - - } else { - retval = rtsx_write_register(chip, MS_CFG, 0xFF, - SAMPLE_TIME_FALLING | - PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | - MS_BUS_WIDTH_1); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, MS_TRANS_CFG, 0xFF, - NO_WAIT_INT | NO_AUTO_READ_INT_REG); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, - MS_STOP | MS_CLR_ERR); - if (retval) - return retval; - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val; - - retval = ms_set_rw_reg_addr(chip, PRO_STATUS_REG, 6, SYSTEM_PARAM, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, - 6, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 2, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "Type register: 0x%x\n", val); - if (val != 0x01) { - if (val != 0x02) - ms_card->check_ms_flow = 1; - - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 4, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "Category register: 0x%x\n", val); - if (val != 0) { - ms_card->check_ms_flow = 1; - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 5, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "Class register: 0x%x\n", val); - if (val == 0) { - retval = rtsx_read_register(chip, PPBUF_BASE2, &val); - if (retval) - return retval; - - if (val & WRT_PRTCT) - chip->card_wp |= MS_CARD; - else - chip->card_wp &= ~MS_CARD; - - } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) { - chip->card_wp |= MS_CARD; - } else { - ms_card->check_ms_flow = 1; - return STATUS_FAIL; - } - - ms_card->ms_type |= TYPE_MSPRO; - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 3, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "IF Mode register: 0x%x\n", val); - if (val == 0) { - ms_card->ms_type &= 0x0F; - } else if (val == 7) { - if (switch_8bit_bus) - ms_card->ms_type |= MS_HG; - else - ms_card->ms_type &= 0x0F; - - } else { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_confirm_cpu_startup(struct rtsx_chip *chip) -{ - int retval, i, k; - u8 val; - - /* Confirm CPU StartUp */ - k = 0; - do { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_read_bytes(chip, GET_INT, 1, - NO_WAIT_INT, &val, 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (k > 100) - return STATUS_FAIL; - - k++; - wait_timeout(100); - } while (!(val & INT_REG_CED)); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (val & INT_REG_ERR) { - if (val & INT_REG_CMDNK) - chip->card_wp |= (MS_CARD); - else - return STATUS_FAIL; - } - /* -- end confirm CPU startup */ - - return STATUS_SUCCESS; -} - -static int ms_switch_parallel_bus(struct rtsx_chip *chip) -{ - int retval, i; - u8 data[2]; - - data[0] = PARALLEL_4BIT_IF; - data[1] = 0; - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, - data, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_switch_8bit_bus(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 data[2]; - - data[0] = PARALLEL_8BIT_IF; - data[1] = 0; - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 1, - NO_WAIT_INT, data, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, MS_CFG, 0x98, - MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); - if (retval) - return retval; - - ms_card->ms_type |= MS_8BIT; - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, - 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - - for (i = 0; i < 3; i++) { - retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_identify_media_type(chip, switch_8bit_bus); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_confirm_cpu_startup(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_switch_parallel_bus(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - continue; - } else { - break; - } - } - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Switch MS-PRO into Parallel mode */ - retval = rtsx_write_register(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); - if (retval) - return retval; - - retval = rtsx_write_register(chip, MS_CFG, PUSH_TIME_ODD, - PUSH_TIME_ODD); - if (retval) - return retval; - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* If MSPro HG Card, We shall try to switch to 8-bit bus */ - if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) { - retval = ms_switch_8bit_bus(chip); - if (retval != STATUS_SUCCESS) { - ms_card->switch_8bit_fail = 1; - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -#ifdef XC_POWERCLASS -static int msxc_change_power(struct rtsx_chip *chip, u8 mode) -{ - int retval; - u8 buf[6]; - - ms_cleanup_work(chip); - - retval = ms_set_rw_reg_addr(chip, 0, 0, PRO_DATA_COUNT1, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf[0] = 0; - buf[1] = mode; - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_REG, 6, NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, buf); - if (retval) - return retval; - - if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} -#endif - -static int ms_read_attribute_info(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val, *buf, class_code, device_type, sub_class, data[16]; - u16 total_blk = 0, blk_size = 0; -#ifdef SUPPORT_MSXC - u32 xc_total_blk = 0, xc_blk_size = 0; -#endif - u32 sys_info_addr = 0, sys_info_size; -#ifdef SUPPORT_PCGL_1P18 - u32 model_name_addr = 0, model_name_size; - int found_sys_info = 0, found_model_name = 0; -#endif - - retval = ms_set_rw_reg_addr(chip, PRO_INT_REG, 2, PRO_SYSTEM_PARAM, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS8BIT(ms_card)) - data[0] = PARALLEL_8BIT_IF; - else - data[0] = PARALLEL_4BIT_IF; - - data[1] = 0; - - data[2] = 0x40; - data[3] = 0; - data[4] = 0; - data[5] = 0; - data[6] = 0; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, - data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(64 * 512, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT); - if (retval != STATUS_SUCCESS) - continue; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - if (!(val & MS_INT_BREQ)) { - kfree(buf); - return STATUS_FAIL; - } - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, - PRO_READ_LONG_DATA, 0x40, WAIT_INT, - 0, 0, buf, 64 * 512); - if (retval == STATUS_SUCCESS) - break; - - rtsx_clear_ms_error(chip); - } - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - i = 0; - do { - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - if ((val & MS_INT_CED) || !(val & MS_INT_BREQ)) - break; - - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, - PRO_READ_LONG_DATA, 0, WAIT_INT); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - i++; - } while (i < 1024); - - if (buf[0] != 0xa5 && buf[1] != 0xc3) { - /* Signature code is wrong */ - kfree(buf); - return STATUS_FAIL; - } - - if (buf[4] < 1 || buf[4] > 12) { - kfree(buf); - return STATUS_FAIL; - } - - for (i = 0; i < buf[4]; i++) { - int cur_addr_off = 16 + i * 12; - -#ifdef SUPPORT_MSXC - if (buf[cur_addr_off + 8] == 0x10 || - buf[cur_addr_off + 8] == 0x13) { -#else - if (buf[cur_addr_off + 8] == 0x10) { -#endif - sys_info_addr = ((u32)buf[cur_addr_off + 0] << 24) | - ((u32)buf[cur_addr_off + 1] << 16) | - ((u32)buf[cur_addr_off + 2] << 8) | - buf[cur_addr_off + 3]; - sys_info_size = ((u32)buf[cur_addr_off + 4] << 24) | - ((u32)buf[cur_addr_off + 5] << 16) | - ((u32)buf[cur_addr_off + 6] << 8) | - buf[cur_addr_off + 7]; - dev_dbg(rtsx_dev(chip), "sys_info_addr = 0x%x, sys_info_size = 0x%x\n", - sys_info_addr, sys_info_size); - if (sys_info_size != 96) { - kfree(buf); - return STATUS_FAIL; - } - if (sys_info_addr < 0x1A0) { - kfree(buf); - return STATUS_FAIL; - } - if ((sys_info_size + sys_info_addr) > 0x8000) { - kfree(buf); - return STATUS_FAIL; - } - -#ifdef SUPPORT_MSXC - if (buf[cur_addr_off + 8] == 0x13) - ms_card->ms_type |= MS_XC; -#endif -#ifdef SUPPORT_PCGL_1P18 - found_sys_info = 1; -#else - break; -#endif - } -#ifdef SUPPORT_PCGL_1P18 - if (buf[cur_addr_off + 8] == 0x15) { - model_name_addr = ((u32)buf[cur_addr_off + 0] << 24) | - ((u32)buf[cur_addr_off + 1] << 16) | - ((u32)buf[cur_addr_off + 2] << 8) | - buf[cur_addr_off + 3]; - model_name_size = ((u32)buf[cur_addr_off + 4] << 24) | - ((u32)buf[cur_addr_off + 5] << 16) | - ((u32)buf[cur_addr_off + 6] << 8) | - buf[cur_addr_off + 7]; - dev_dbg(rtsx_dev(chip), "model_name_addr = 0x%x, model_name_size = 0x%x\n", - model_name_addr, model_name_size); - if (model_name_size != 48) { - kfree(buf); - return STATUS_FAIL; - } - if (model_name_addr < 0x1A0) { - kfree(buf); - return STATUS_FAIL; - } - if ((model_name_size + model_name_addr) > 0x8000) { - kfree(buf); - return STATUS_FAIL; - } - - found_model_name = 1; - } - - if (found_sys_info && found_model_name) - break; -#endif - } - - if (i == buf[4]) { - kfree(buf); - return STATUS_FAIL; - } - - class_code = buf[sys_info_addr + 0]; - device_type = buf[sys_info_addr + 56]; - sub_class = buf[sys_info_addr + 46]; -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - xc_total_blk = ((u32)buf[sys_info_addr + 6] << 24) | - ((u32)buf[sys_info_addr + 7] << 16) | - ((u32)buf[sys_info_addr + 8] << 8) | - buf[sys_info_addr + 9]; - xc_blk_size = ((u32)buf[sys_info_addr + 32] << 24) | - ((u32)buf[sys_info_addr + 33] << 16) | - ((u32)buf[sys_info_addr + 34] << 8) | - buf[sys_info_addr + 35]; - dev_dbg(rtsx_dev(chip), "xc_total_blk = 0x%x, xc_blk_size = 0x%x\n", - xc_total_blk, xc_blk_size); - } else { - total_blk = ((u16)buf[sys_info_addr + 6] << 8) | - buf[sys_info_addr + 7]; - blk_size = ((u16)buf[sys_info_addr + 2] << 8) | - buf[sys_info_addr + 3]; - dev_dbg(rtsx_dev(chip), "total_blk = 0x%x, blk_size = 0x%x\n", - total_blk, blk_size); - } -#else - total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; - blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; - dev_dbg(rtsx_dev(chip), "total_blk = 0x%x, blk_size = 0x%x\n", - total_blk, blk_size); -#endif - - dev_dbg(rtsx_dev(chip), "class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n", - class_code, device_type, sub_class); - - memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96); -#ifdef SUPPORT_PCGL_1P18 - memcpy(ms_card->raw_model_name, buf + model_name_addr, 48); -#endif - - kfree(buf); - -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - if (class_code != 0x03) - return STATUS_FAIL; - } else { - if (class_code != 0x02) - return STATUS_FAIL; - } -#else - if (class_code != 0x02) - return STATUS_FAIL; -#endif - - if (device_type != 0x00) { - if (device_type == 0x01 || device_type == 0x02 || - device_type == 0x03) { - chip->card_wp |= MS_CARD; - } else { - return STATUS_FAIL; - } - } - - if (sub_class & 0xC0) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n", - class_code, device_type, sub_class); - -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - chip->capacity[chip->card2lun[MS_CARD]] = - ms_card->capacity = xc_total_blk * xc_blk_size; - } else { - chip->capacity[chip->card2lun[MS_CARD]] = - ms_card->capacity = total_blk * blk_size; - } -#else - ms_card->capacity = total_blk * blk_size; - chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; -#endif - - return STATUS_SUCCESS; -} - -#ifdef SUPPORT_MAGIC_GATE -static int mg_set_tpc_para_sub(struct rtsx_chip *chip, - int type, u8 mg_entry_num); -#endif - -static int reset_ms_pro(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; -#ifdef XC_POWERCLASS - u8 change_power_class; - - if (chip->ms_power_class_en & 0x02) - change_power_class = 2; - else if (chip->ms_power_class_en & 0x01) - change_power_class = 1; - else - change_power_class = 0; -#endif - -#ifdef XC_POWERCLASS -retry: -#endif - retval = ms_pro_reset_flow(chip, 1); - if (retval != STATUS_SUCCESS) { - if (ms_card->switch_8bit_fail) { - retval = ms_pro_reset_flow(chip, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - return STATUS_FAIL; - } - } - - retval = ms_read_attribute_info(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -#ifdef XC_POWERCLASS - if (CHK_HG8BIT(ms_card)) - change_power_class = 0; - - if (change_power_class && CHK_MSXC(ms_card)) { - u8 power_class_en = chip->ms_power_class_en; - - dev_dbg(rtsx_dev(chip), "power_class_en = 0x%x\n", - power_class_en); - dev_dbg(rtsx_dev(chip), "change_power_class = %d\n", - change_power_class); - - if (change_power_class) - power_class_en &= (1 << (change_power_class - 1)); - else - power_class_en = 0; - - if (power_class_en) { - u8 power_class_mode = - (ms_card->raw_sys_info[46] & 0x18) >> 3; - dev_dbg(rtsx_dev(chip), "power_class_mode = 0x%x", - power_class_mode); - if (change_power_class > power_class_mode) - change_power_class = power_class_mode; - if (change_power_class) { - retval = msxc_change_power(chip, - change_power_class); - if (retval != STATUS_SUCCESS) { - change_power_class--; - goto retry; - } - } - } - } -#endif - -#ifdef SUPPORT_MAGIC_GATE - retval = mg_set_tpc_para_sub(chip, 0, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; -#endif - - if (CHK_HG8BIT(ms_card)) - chip->card_bus_width[chip->card2lun[MS_CARD]] = 8; - else - chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - - return STATUS_SUCCESS; -} - -static int ms_read_status_reg(struct rtsx_chip *chip) -{ - int retval; - u8 val[2]; - - retval = ms_set_rw_reg_addr(chip, STATUS_REG0, 2, 0, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_read_extra_data(struct rtsx_chip *chip, - u16 block_addr, u8 page_num, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val, data[10]; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x40; - data[5] = page_num; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, - data, 6); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, - MS_EXTRA_SIZE, SYSTEM_PARAM, - 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } - - retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, - data, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (buf && buf_len) { - if (buf_len > MS_EXTRA_SIZE) - buf_len = MS_EXTRA_SIZE; - memcpy(buf, data, buf_len); - } - - return STATUS_SUCCESS; -} - -static int ms_write_extra_data(struct rtsx_chip *chip, u16 block_addr, - u8 page_num, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val, data[16]; - - if (!buf || buf_len < MS_EXTRA_SIZE) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6 + MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x40; - data[5] = page_num; - - for (i = 6; i < MS_EXTRA_SIZE + 6; i++) - data[i] = buf[i - 6]; - - retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), - NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 val, data[6]; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x20; - data[5] = page_num; - - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - - } else { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - } - } - - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, - 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 val, data[8], extra[MS_EXTRA_SIZE]; - - retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = extra[0] & 0x7F; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i = 0; - u8 val, data[6]; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0; - data[5] = 0; - - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -ERASE_RTY: - retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - if (i < 3) { - i++; - goto ERASE_RTY; - } - - ms_set_err_code(chip, MS_CMD_NK); - ms_set_bad_block(chip, phy_blk); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len) -{ - if (!extra || extra_len < MS_EXTRA_SIZE) - return; - - memset(extra, 0xFF, MS_EXTRA_SIZE); - - if (type == set_PS_NG) { - /* set page status as 1:NG,and block status keep 1:OK */ - extra[0] = 0xB8; - } else { - /* set page status as 0:Data Error,and block status keep 1:OK */ - extra[0] = 0x98; - } - - extra[2] = (u8)(log_blk >> 8); - extra[3] = (u8)log_blk; -} - -static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, - u8 start_page, u8 end_page) -{ - int retval; - u8 extra[MS_EXTRA_SIZE], i; - - memset(extra, 0xff, MS_EXTRA_SIZE); - - extra[0] = 0xf8; /* Block, page OK, data erased */ - extra[1] = 0xff; - extra[2] = (u8)(log_blk >> 8); - extra[3] = (u8)log_blk; - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_write_extra_data(chip, phy_blk, i, - extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page, u8 end_page) -{ - struct ms_info *ms_card = &chip->ms_card; - bool uncorrect_flag = false; - int retval, rty_cnt; - u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; - - dev_dbg(rtsx_dev(chip), "Copy page from 0x%x to 0x%x, logical block is 0x%x\n", - old_blk, new_blk, log_blk); - dev_dbg(rtsx_dev(chip), "start_page = %d, end_page = %d\n", - start_page, end_page); - - retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PPBUF_BASE2, &val); - if (retval) - return retval; - - if (val & BUF_FULL) { - retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_read_extra_data(chip, old_blk, i, extra, - MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, - MS_EXTRA_SIZE, SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x20; - data[5] = i; - - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, - data, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { - uncorrect_flag = true; - dev_dbg(rtsx_dev(chip), "Uncorrectable error\n"); - } else { - uncorrect_flag = false; - } - - retval = ms_transfer_tpc(chip, - MS_TM_NORMAL_READ, - READ_PAGE_DATA, - 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (uncorrect_flag) { - ms_set_page_status(log_blk, set_PS_NG, - extra, - MS_EXTRA_SIZE); - if (i == 0) - extra[0] &= 0xEF; - - ms_write_extra_data(chip, old_blk, i, - extra, - MS_EXTRA_SIZE); - dev_dbg(rtsx_dev(chip), "page %d : extra[0] = 0x%x\n", - i, extra[0]); - MS_SET_BAD_BLOCK_FLG(ms_card); - - ms_set_page_status(log_blk, - set_PS_error, extra, - MS_EXTRA_SIZE); - ms_write_extra_data(chip, new_blk, i, - extra, - MS_EXTRA_SIZE); - continue; - } - - for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; - rty_cnt++) { - retval = ms_transfer_tpc(chip, - MS_TM_NORMAL_WRITE, - WRITE_PAGE_DATA, - 0, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (rty_cnt == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - } - - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - } - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(new_blk >> 8); - data[3] = (u8)new_blk; - data[4] = 0x20; - data[5] = i; - - if ((extra[0] & 0x60) != 0x60) - data[6] = extra[0]; - else - data[6] = 0xF8; - - data[6 + 1] = 0xFF; - data[6 + 2] = (u8)(log_blk >> 8); - data[6 + 3] = (u8)log_blk; - - for (j = 4; j <= MS_EXTRA_SIZE; j++) - data[6 + j] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), - NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - if (i == 0) { - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, - MS_EXTRA_SIZE, SYSTEM_PARAM, - 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = 0xEF; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, - NO_WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, - NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, - MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - } - } - - return STATUS_SUCCESS; -} - -static int reset_ms(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u16 i, reg_addr, block_size; - u8 val, extra[MS_EXTRA_SIZE], j, *ptr; -#ifndef SUPPORT_MAGIC_GATE - u16 eblock_cnt; -#endif - - retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_card->ms_type |= TYPE_MS; - - retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PPBUF_BASE2, &val); - if (retval) - return retval; - - if (val & WRT_PRTCT) - chip->card_wp |= MS_CARD; - else - chip->card_wp &= ~MS_CARD; - - i = 0; - -RE_SEARCH: - /* Search Boot Block */ - while (i < (MAX_DEFECTIVE_BLOCK + 2)) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_read_extra_data(chip, i, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { - i++; - continue; - } - - if (extra[0] & BLOCK_OK) { - if (!(extra[1] & NOT_BOOT_BLOCK)) { - ms_card->boot_block = i; - break; - } - } - i++; - } - - if (i == (MAX_DEFECTIVE_BLOCK + 2)) { - dev_dbg(rtsx_dev(chip), "No boot block found!"); - return STATUS_FAIL; - } - - for (j = 0; j < 3; j++) { - retval = ms_read_page(chip, ms_card->boot_block, j); - if (retval != STATUS_SUCCESS) { - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { - i = ms_card->boot_block + 1; - ms_set_err_code(chip, MS_NO_ERROR); - goto RE_SEARCH; - } - } - } - - retval = ms_read_page(chip, ms_card->boot_block, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Read MS system information as sys_info */ - rtsx_init_cmd(chip); - - for (i = 0; i < 96; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip); - memcpy(ms_card->raw_sys_info, ptr, 96); - - /* Read useful block contents */ - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); - - for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - rtsx_add_cmd(chip, READ_REG_CMD, MS_device_type, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_support, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip); - - dev_dbg(rtsx_dev(chip), "Boot block data:\n"); - dev_dbg(rtsx_dev(chip), "%*ph\n", 16, ptr); - - /* Block ID error - * HEADER_ID0, HEADER_ID1 - */ - if (ptr[0] != 0x00 || ptr[1] != 0x01) { - i = ms_card->boot_block + 1; - goto RE_SEARCH; - } - - /* Page size error - * PAGE_SIZE_0, PAGE_SIZE_1 - */ - if (ptr[12] != 0x02 || ptr[13] != 0x00) { - i = ms_card->boot_block + 1; - goto RE_SEARCH; - } - - if (ptr[14] == 1 || ptr[14] == 3) - chip->card_wp |= MS_CARD; - - /* BLOCK_SIZE_0, BLOCK_SIZE_1 */ - block_size = ((u16)ptr[6] << 8) | ptr[7]; - if (block_size == 0x0010) { - /* Block size 16KB */ - ms_card->block_shift = 5; - ms_card->page_off = 0x1F; - } else if (block_size == 0x0008) { - /* Block size 8KB */ - ms_card->block_shift = 4; - ms_card->page_off = 0x0F; - } - - /* BLOCK_COUNT_0, BLOCK_COUNT_1 */ - ms_card->total_block = ((u16)ptr[8] << 8) | ptr[9]; - -#ifdef SUPPORT_MAGIC_GATE - j = ptr[10]; - - if (ms_card->block_shift == 4) { /* 4MB or 8MB */ - if (j < 2) { /* Effective block for 4MB: 0x1F0 */ - ms_card->capacity = 0x1EE0; - } else { /* Effective block for 8MB: 0x3E0 */ - ms_card->capacity = 0x3DE0; - } - } else { /* 16MB, 32MB, 64MB or 128MB */ - if (j < 5) { /* Effective block for 16MB: 0x3E0 */ - ms_card->capacity = 0x7BC0; - } else if (j < 0xA) { /* Effective block for 32MB: 0x7C0 */ - ms_card->capacity = 0xF7C0; - } else if (j < 0x11) { /* Effective block for 64MB: 0xF80 */ - ms_card->capacity = 0x1EF80; - } else { /* Effective block for 128MB: 0x1F00 */ - ms_card->capacity = 0x3DF00; - } - } -#else - /* EBLOCK_COUNT_0, EBLOCK_COUNT_1 */ - eblock_cnt = ((u16)ptr[10] << 8) | ptr[11]; - - ms_card->capacity = ((u32)eblock_cnt - 2) << ms_card->block_shift; -#endif - - chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; - - /* Switch I/F Mode */ - if (ptr[15]) { - retval = ms_set_rw_reg_addr(chip, 0, 0, SYSTEM_PARAM, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, PPBUF_BASE2, 0xFF, 0x88); - if (retval) - return retval; - - retval = rtsx_write_register(chip, PPBUF_BASE2 + 1, 0xFF, 0); - if (retval) - return retval; - - retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG, 1, - NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, MS_CFG, - 0x58 | MS_NO_CHECK_INT, - MS_BUS_WIDTH_4 | - PUSH_TIME_ODD | - MS_NO_CHECK_INT); - if (retval) - return retval; - - ms_card->ms_type |= MS_4BIT; - } - - if (CHK_MS4BIT(ms_card)) - chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - else - chip->card_bus_width[chip->card2lun[MS_CARD]] = 1; - - return STATUS_SUCCESS; -} - -static int ms_init_l2p_tbl(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int size, i, seg_no, retval; - u16 defect_block, reg_addr; - u8 val1, val2; - - ms_card->segment_cnt = ms_card->total_block >> 9; - dev_dbg(rtsx_dev(chip), "ms_card->segment_cnt = %d\n", - ms_card->segment_cnt); - - size = ms_card->segment_cnt * sizeof(struct zone_entry); - ms_card->segment = vzalloc(size); - if (!ms_card->segment) - return STATUS_FAIL; - - retval = ms_read_page(chip, ms_card->boot_block, 1); - if (retval != STATUS_SUCCESS) - goto INIT_FAIL; - - reg_addr = PPBUF_BASE2; - for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { - int block_no; - - retval = rtsx_read_register(chip, reg_addr++, &val1); - if (retval != STATUS_SUCCESS) - goto INIT_FAIL; - - retval = rtsx_read_register(chip, reg_addr++, &val2); - if (retval != STATUS_SUCCESS) - goto INIT_FAIL; - - defect_block = ((u16)val1 << 8) | val2; - if (defect_block == 0xFFFF) - break; - - seg_no = defect_block / 512; - - block_no = ms_card->segment[seg_no].disable_count++; - ms_card->segment[seg_no].defect_list[block_no] = defect_block; - } - - for (i = 0; i < ms_card->segment_cnt; i++) { - ms_card->segment[i].build_flag = 0; - ms_card->segment[i].l2p_table = NULL; - ms_card->segment[i].free_table = NULL; - ms_card->segment[i].get_index = 0; - ms_card->segment[i].set_index = 0; - ms_card->segment[i].unused_blk_cnt = 0; - - dev_dbg(rtsx_dev(chip), "defective block count of segment %d is %d\n", - i, ms_card->segment[i].disable_count); - } - - return STATUS_SUCCESS; - -INIT_FAIL: - vfree(ms_card->segment); - ms_card->segment = NULL; - - return STATUS_FAIL; -} - -static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - - if (!ms_card->segment) - return 0xFFFF; - - segment = &ms_card->segment[seg_no]; - - if (segment->l2p_table) - return segment->l2p_table[log_off]; - - return 0xFFFF; -} - -static void ms_set_l2p_tbl(struct rtsx_chip *chip, - int seg_no, u16 log_off, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - - if (!ms_card->segment) - return; - - segment = &ms_card->segment[seg_no]; - if (segment->l2p_table) - segment->l2p_table[log_off] = phy_blk; -} - -static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - int seg_no; - - seg_no = (int)phy_blk >> 9; - segment = &ms_card->segment[seg_no]; - - segment->free_table[segment->set_index++] = phy_blk; - if (segment->set_index >= MS_FREE_TABLE_CNT) - segment->set_index = 0; - - segment->unused_blk_cnt++; -} - -static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - u16 phy_blk; - - segment = &ms_card->segment[seg_no]; - - if (segment->unused_blk_cnt <= 0) - return 0xFFFF; - - phy_blk = segment->free_table[segment->get_index]; - segment->free_table[segment->get_index++] = 0xFFFF; - if (segment->get_index >= MS_FREE_TABLE_CNT) - segment->get_index = 0; - - segment->unused_blk_cnt--; - - return phy_blk; -} - -static const unsigned short ms_start_idx[] = {0, 494, 990, 1486, 1982, 2478, - 2974, 3470, 3966, 4462, 4958, - 5454, 5950, 6446, 6942, 7438, - 7934}; - -static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk, - u16 log_off, u8 us1, u8 us2) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - int seg_no; - u16 tmp_blk; - - seg_no = (int)phy_blk >> 9; - segment = &ms_card->segment[seg_no]; - tmp_blk = segment->l2p_table[log_off]; - - if (us1 != us2) { - if (us1 == 0) { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, tmp_blk); - - ms_set_unused_block(chip, tmp_blk); - segment->l2p_table[log_off] = phy_blk; - } else { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, phy_blk); - - ms_set_unused_block(chip, phy_blk); - } - } else { - if (phy_blk < tmp_blk) { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, phy_blk); - - ms_set_unused_block(chip, phy_blk); - } else { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, tmp_blk); - - ms_set_unused_block(chip, tmp_blk); - segment->l2p_table[log_off] = phy_blk; - } - } - - return STATUS_SUCCESS; -} - -static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - bool defect_flag; - int retval, table_size, disable_cnt, i; - u16 start, end, phy_blk, log_blk, tmp_blk, idx; - u8 extra[MS_EXTRA_SIZE], us1, us2; - - dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, seg_no); - - if (!ms_card->segment) { - retval = ms_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - return retval; - } - - if (ms_card->segment[seg_no].build_flag) { - dev_dbg(rtsx_dev(chip), "l2p table of segment %d has been built\n", - seg_no); - return STATUS_SUCCESS; - } - - if (seg_no == 0) - table_size = 494; - else - table_size = 496; - - segment = &ms_card->segment[seg_no]; - - if (!segment->l2p_table) { - segment->l2p_table = vmalloc(array_size(table_size, 2)); - if (!segment->l2p_table) - goto BUILD_FAIL; - } - memset((u8 *)(segment->l2p_table), 0xff, array_size(table_size, 2)); - - if (!segment->free_table) { - segment->free_table = vmalloc(array_size(MS_FREE_TABLE_CNT, 2)); - if (!segment->free_table) - goto BUILD_FAIL; - } - memset((u8 *)(segment->free_table), 0xff, array_size(MS_FREE_TABLE_CNT, 2)); - - start = (u16)seg_no << 9; - end = (u16)(seg_no + 1) << 9; - - disable_cnt = segment->disable_count; - - segment->get_index = 0; - segment->set_index = 0; - segment->unused_blk_cnt = 0; - - for (phy_blk = start; phy_blk < end; phy_blk++) { - if (disable_cnt) { - defect_flag = false; - for (i = 0; i < segment->disable_count; i++) { - if (phy_blk == segment->defect_list[i]) { - defect_flag = true; - break; - } - } - if (defect_flag) { - disable_cnt--; - continue; - } - } - - retval = ms_read_extra_data(chip, phy_blk, 0, - extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "read extra data fail\n"); - ms_set_bad_block(chip, phy_blk); - continue; - } - - if (seg_no == ms_card->segment_cnt - 1) { - if (!(extra[1] & NOT_TRANSLATION_TABLE)) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - extra[2] = 0xff; - extra[3] = 0xff; - } - } - } - - if (!(extra[0] & BLOCK_OK)) - continue; - if (!(extra[1] & NOT_BOOT_BLOCK)) - continue; - if ((extra[0] & PAGE_OK) != PAGE_OK) - continue; - - log_blk = ((u16)extra[2] << 8) | extra[3]; - - if (log_blk == 0xFFFF) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - } - ms_set_unused_block(chip, phy_blk); - continue; - } - - if (log_blk < ms_start_idx[seg_no] || - log_blk >= ms_start_idx[seg_no + 1]) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - } - ms_set_unused_block(chip, phy_blk); - continue; - } - - idx = log_blk - ms_start_idx[seg_no]; - - if (segment->l2p_table[idx] == 0xFFFF) { - segment->l2p_table[idx] = phy_blk; - continue; - } - - us1 = extra[0] & 0x10; - tmp_blk = segment->l2p_table[idx]; - retval = ms_read_extra_data(chip, tmp_blk, 0, - extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - continue; - us2 = extra[0] & 0x10; - - (void)ms_arbitrate_l2p(chip, phy_blk, - log_blk - ms_start_idx[seg_no], us1, us2); - } - - segment->build_flag = 1; - - dev_dbg(rtsx_dev(chip), "unused block count: %d\n", - segment->unused_blk_cnt); - - /* Logical Address Confirmation Process */ - if (seg_no == ms_card->segment_cnt - 1) { - if (segment->unused_blk_cnt < 2) - chip->card_wp |= MS_CARD; - } else { - if (segment->unused_blk_cnt < 1) - chip->card_wp |= MS_CARD; - } - - if (chip->card_wp & MS_CARD) - return STATUS_SUCCESS; - - for (log_blk = ms_start_idx[seg_no]; - log_blk < ms_start_idx[seg_no + 1]; log_blk++) { - idx = log_blk - ms_start_idx[seg_no]; - if (segment->l2p_table[idx] == 0xFFFF) { - phy_blk = ms_get_unused_block(chip, seg_no); - if (phy_blk == 0xFFFF) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - retval = ms_init_page(chip, phy_blk, log_blk, 0, 1); - if (retval != STATUS_SUCCESS) - goto BUILD_FAIL; - - segment->l2p_table[idx] = phy_blk; - if (seg_no == ms_card->segment_cnt - 1) { - if (segment->unused_blk_cnt < 2) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - } else { - if (segment->unused_blk_cnt < 1) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - } - } - } - - /* Make boot block be the first normal block */ - if (seg_no == 0) { - for (log_blk = 0; log_blk < 494; log_blk++) { - tmp_blk = segment->l2p_table[log_blk]; - if (tmp_blk < ms_card->boot_block) { - dev_dbg(rtsx_dev(chip), "Boot block is not the first normal block.\n"); - - if (chip->card_wp & MS_CARD) - break; - - phy_blk = ms_get_unused_block(chip, 0); - retval = ms_copy_page(chip, tmp_blk, phy_blk, - log_blk, 0, - ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - segment->l2p_table[log_blk] = phy_blk; - - retval = ms_set_bad_block(chip, tmp_blk); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } - } - - return STATUS_SUCCESS; - -BUILD_FAIL: - segment->build_flag = 0; - vfree(segment->l2p_table); - segment->l2p_table = NULL; - vfree(segment->free_table); - segment->free_table = NULL; - - return STATUS_FAIL; -} - -int reset_ms_card(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int seg_no = ms_card->total_block / 512 - 1; - int retval; - - memset(ms_card, 0, sizeof(struct ms_info)); - - retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_card->ms_type = 0; - - retval = reset_ms_pro(chip); - if (retval != STATUS_SUCCESS) { - if (ms_card->check_ms_flow) { - retval = reset_ms(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - return STATUS_FAIL; - } - } - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!CHK_MSPRO(ms_card)) { - /* Build table for the last segment, - * to check if L2P table block exists, erasing it - */ - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - dev_dbg(rtsx_dev(chip), "ms_card->ms_type = 0x%x\n", ms_card->ms_type); - - return STATUS_SUCCESS; -} - -static int mspro_set_rw_cmd(struct rtsx_chip *chip, - u32 start_sec, u16 sec_cnt, u8 cmd) -{ - int retval, i; - u8 data[8]; - - data[0] = cmd; - data[1] = (u8)(sec_cnt >> 8); - data[2] = (u8)sec_cnt; - data[3] = (u8)(start_sec >> 24); - data[4] = (u8)(start_sec >> 16); - data[5] = (u8)(start_sec >> 8); - data[6] = (u8)start_sec; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, - WAIT_INT, data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -void mspro_stop_seq_mode(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (ms_card->seq_mode) { - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return; - - ms_card->seq_mode = 0; - ms_card->total_sec_cnt = 0; - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - } -} - -static inline int ms_auto_tune_clock(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (chip->asic_code) { - if (ms_card->ms_clock > 30) - ms_card->ms_clock -= 20; - } else { - if (ms_card->ms_clock == CLK_80) - ms_card->ms_clock = CLK_60; - else if (ms_card->ms_clock == CLK_60) - ms_card->ms_clock = CLK_40; - } - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int mspro_rw_multi_sector(struct scsi_cmnd *srb, - struct rtsx_chip *chip, u32 start_sector, - u16 sector_cnt) -{ - struct ms_info *ms_card = &chip->ms_card; - bool mode_2k = false; - int retval; - u16 count; - u8 val, trans_mode, rw_tpc, rw_cmd; - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->cleanup_counter = 0; - - if (CHK_MSHG(ms_card)) { - if ((start_sector % 4) || (sector_cnt % 4)) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_LONG_DATA; - rw_cmd = PRO_READ_DATA; - } else { - rw_tpc = PRO_WRITE_LONG_DATA; - rw_cmd = PRO_WRITE_DATA; - } - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_QUAD_DATA; - rw_cmd = PRO_READ_2K_DATA; - } else { - rw_tpc = PRO_WRITE_QUAD_DATA; - rw_cmd = PRO_WRITE_2K_DATA; - } - mode_2k = true; - } - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_LONG_DATA; - rw_cmd = PRO_READ_DATA; - } else { - rw_tpc = PRO_WRITE_LONG_DATA; - rw_cmd = PRO_WRITE_DATA; - } - } - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (srb->sc_data_direction == DMA_FROM_DEVICE) - trans_mode = MS_TM_AUTO_READ; - else - trans_mode = MS_TM_AUTO_WRITE; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval) - return retval; - - if (ms_card->seq_mode) { - if (ms_card->pre_dir != srb->sc_data_direction || - ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != - start_sector) || - (mode_2k && (ms_card->seq_mode & MODE_512_SEQ)) || - (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ)) || - !(val & MS_INT_BREQ) || - ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) { - ms_card->seq_mode = 0; - ms_card->total_sec_cnt = 0; - if (val & MS_INT_BREQ) { - retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_write_register(chip, RBCTL, RB_FLUSH, - RB_FLUSH); - } - } - } - - if (!ms_card->seq_mode) { - ms_card->total_sec_cnt = 0; - if (sector_cnt >= SEQ_START_CRITERIA) { - if ((ms_card->capacity - start_sector) > 0xFE00) - count = 0xFE00; - else - count = (u16)(ms_card->capacity - start_sector); - - if (count > sector_cnt) { - if (mode_2k) - ms_card->seq_mode = MODE_2K_SEQ; - else - ms_card->seq_mode = MODE_512_SEQ; - } - } else { - count = sector_cnt; - } - retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd); - if (retval != STATUS_SUCCESS) { - ms_card->seq_mode = 0; - return STATUS_FAIL; - } - } - - retval = ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt, - WAIT_INT, mode_2k, scsi_sg_count(srb), - scsi_sglist(srb), scsi_bufflen(srb)); - if (retval != STATUS_SUCCESS) { - ms_card->seq_mode = 0; - rtsx_read_register(chip, MS_TRANS_CFG, &val); - rtsx_clear_ms_error(chip); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", - __func__); - return STATUS_FAIL; - } - - if (val & MS_INT_BREQ) - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - dev_dbg(rtsx_dev(chip), "MSPro CRC error, tune clock!\n"); - chip->rw_need_retry = 1; - ms_auto_tune_clock(chip); - } - - return retval; - } - - if (ms_card->seq_mode) { - ms_card->pre_sec_addr = start_sector; - ms_card->pre_sec_cnt = sector_cnt; - ms_card->pre_dir = srb->sc_data_direction; - ms_card->total_sec_cnt += sector_cnt; - } - - return STATUS_SUCCESS; -} - -static int mspro_read_format_progress(struct rtsx_chip *chip, - const int short_data_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u32 total_progress, cur_progress; - u8 cnt, tmp; - u8 data[8]; - - dev_dbg(rtsx_dev(chip), "%s, short_data_len = %d\n", __func__, - short_data_len); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (!(tmp & MS_INT_BREQ)) { - if ((tmp & (MS_INT_CED | MS_INT_BREQ | MS_INT_CMDNK | - MS_INT_ERR)) == MS_INT_CED) { - ms_card->format_status = FORMAT_SUCCESS; - return STATUS_SUCCESS; - } - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (short_data_len >= 256) - cnt = 0; - else - cnt = (u8)short_data_len; - - retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, - MS_NO_CHECK_INT); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, - data, 8); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - total_progress = (data[0] << 24) | (data[1] << 16) | - (data[2] << 8) | data[3]; - cur_progress = (data[4] << 24) | (data[5] << 16) | - (data[6] << 8) | data[7]; - - dev_dbg(rtsx_dev(chip), "total_progress = %d, cur_progress = %d\n", - total_progress, cur_progress); - - if (total_progress == 0) { - ms_card->progress = 0; - } else { - u64 ulltmp = (u64)cur_progress * (u64)65535; - - do_div(ulltmp, total_progress); - ms_card->progress = (u16)ulltmp; - } - dev_dbg(rtsx_dev(chip), "progress = %d\n", ms_card->progress); - - for (i = 0; i < 5000; i++) { - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - if (tmp & (MS_INT_CED | MS_INT_CMDNK | - MS_INT_BREQ | MS_INT_ERR)) - break; - - wait_timeout(1); - } - - retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, 0); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (i == 5000) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (tmp & MS_INT_CED) { - ms_card->format_status = FORMAT_SUCCESS; - ms_card->pro_under_formatting = 0; - } else if (tmp & MS_INT_BREQ) { - ms_card->format_status = FORMAT_IN_PROGRESS; - } else { - ms_card->format_status = FORMAT_FAIL; - ms_card->pro_under_formatting = 0; - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -void mspro_polling_format_status(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int i; - - if (ms_card->pro_under_formatting && - (rtsx_get_stat(chip) != RTSX_STAT_SS)) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - - for (i = 0; i < 65535; i++) { - mspro_read_format_progress(chip, MS_SHORT_DATA_LEN); - if (ms_card->format_status != FORMAT_IN_PROGRESS) - break; - } - } -} - -int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, - int short_data_len, bool quick_format) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 buf[8], tmp; - u16 para; - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, PRO_TPC_PARM, 0x01); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - memset(buf, 0, 2); - switch (short_data_len) { - case 32: - buf[0] = 0; - break; - case 64: - buf[0] = 1; - break; - case 128: - buf[0] = 2; - break; - case 256: - default: - buf[0] = 3; - break; - } - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_WRITE_REG, 1, - NO_WAIT_INT, buf, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (quick_format) - para = 0x0000; - else - para = 0x0001; - - retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval) - return retval; - - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) - return STATUS_FAIL; - - if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) { - ms_card->pro_under_formatting = 1; - ms_card->progress = 0; - ms_card->format_status = FORMAT_IN_PROGRESS; - return STATUS_SUCCESS; - } - - if (tmp & MS_INT_CED) { - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - ms_card->format_status = FORMAT_SUCCESS; - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); - return STATUS_SUCCESS; - } - - return STATUS_FAIL; -} - -static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, - u16 log_blk, u8 start_page, u8 end_page, - u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6]; - u8 *ptr; - - retval = ms_read_extra_data(chip, phy_blk, start_page, - extra, MS_EXTRA_SIZE); - if (retval == STATUS_SUCCESS) { - if ((extra[1] & 0x30) != 0x30) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - } - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0; - data[5] = start_page; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, - data, 6); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ptr = buf; - - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_ERR) { - if (val & INT_REG_BREQ) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { - if (!(chip->card_wp & MS_CARD)) { - reset_ms(chip); - ms_set_page_status - (log_blk, set_PS_NG, - extra, - MS_EXTRA_SIZE); - ms_write_extra_data - (chip, phy_blk, - page_addr, extra, - MS_EXTRA_SIZE); - } - ms_set_err_code(chip, - MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - } else { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - } else { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - } - - if (page_addr == (end_page - 1)) { - if (!(val & INT_REG_CED)) { - retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, - &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - - trans_cfg = NO_WAIT_INT; - } else { - trans_cfg = WAIT_INT; - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, - 0xFF, trans_cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, RING_BUFFER); - - trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_READ); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, - scsi_sg_count(chip->srb), - index, offset, - DMA_FROM_DEVICE, - chip->ms_timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - return STATUS_TIMEDOUT; - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - return STATUS_TIMEDOUT; - } - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - ms_set_err_code(chip, MS_CRC16_ERROR); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - } - - if (scsi_sg_count(chip->srb) == 0) - ptr += 512; - } - - return STATUS_SUCCESS; -} - -static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, - u16 new_blk, u16 log_blk, u8 start_page, - u8 end_page, u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 page_addr, val, data[16]; - u8 *ptr; - - if (!start_page) { - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = 0xEF; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, - data, 8); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, - NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(new_blk >> 8); - data[3] = (u8)new_blk; - if ((end_page - start_page) == 1) - data[4] = 0x20; - else - data[4] = 0; - - data[5] = start_page; - data[6] = 0xF8; - data[7] = 0xFF; - data[8] = (u8)(log_blk >> 8); - data[9] = (u8)log_blk; - - for (i = 0x0A; i < 0x10; i++) - data[i] = 0xFF; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, - NO_WAIT_INT, data, 16); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ptr = buf; - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - - udelay(30); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, - 0xFF, WRITE_PAGE_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, - 0xFF, WAIT_INT); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, RING_BUFFER); - - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, - scsi_sg_count(chip->srb), - index, offset, - DMA_TO_DEVICE, - chip->ms_timeout); - if (retval < 0) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - - if (retval == -ETIMEDOUT) - return STATUS_TIMEDOUT; - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if ((end_page - start_page) == 1) { - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } else { - if (page_addr == (end_page - 1)) { - if (!(val & INT_REG_CED)) { - retval = ms_send_cmd(chip, BLOCK_END, - WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, - NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (page_addr == (end_page - 1) || - page_addr == ms_card->page_off) { - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, - MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - } - - if (scsi_sg_count(chip->srb) == 0) - ptr += 512; - } - - return STATUS_SUCCESS; -} - -static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 page_off) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, seg_no; - - retval = ms_copy_page(chip, old_blk, new_blk, log_blk, - page_off, ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - seg_no = old_blk >> 9; - - if (MS_TST_BAD_BLOCK_FLG(ms_card)) { - MS_CLR_BAD_BLOCK_FLG(ms_card); - ms_set_bad_block(chip, old_blk); - } else { - retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) - ms_set_unused_block(chip, old_blk); - } - - ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); - - return STATUS_SUCCESS; -} - -static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page) -{ - int retval; - - if (start_page) { - retval = ms_copy_page(chip, old_blk, new_blk, log_blk, - 0, start_page); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -#ifdef MS_DELAY_WRITE -int ms_delay_write(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - struct ms_delay_write_tag *delay_write = &ms_card->delay_write; - int retval; - - if (delay_write->delay_write_flag) { - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - delay_write->delay_write_flag = 0; - retval = ms_finish_write(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->logblock, - delay_write->pageoff); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} -#endif - -static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); -} - -static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int retval, seg_no; - unsigned int index = 0, offset = 0; - u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt; - u8 start_page, end_page = 0, page_cnt; - u8 *ptr; -#ifdef MS_DELAY_WRITE - struct ms_delay_write_tag *delay_write = &ms_card->delay_write; -#endif - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->cleanup_counter = 0; - - ptr = (u8 *)scsi_sglist(srb); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - - log_blk = (u16)(start_sector >> ms_card->block_shift); - start_page = (u8)(start_sector & ms_card->page_off); - - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { - if (log_blk < ms_start_idx[seg_no + 1]) - break; - } - - if (ms_card->segment[seg_no].build_flag == 0) { - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { -#ifdef MS_DELAY_WRITE - if (delay_write->delay_write_flag && - delay_write->logblock == log_blk && - start_page > delay_write->pageoff) { - delay_write->delay_write_flag = 0; - retval = ms_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - log_blk, - delay_write->pageoff, start_page); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page == delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else { - retval = ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#endif - old_blk = ms_get_l2p_tbl - (chip, seg_no, - log_blk - ms_start_idx[seg_no]); - new_blk = ms_get_unused_block(chip, seg_no); - if (old_blk == 0xFFFF || new_blk == 0xFFFF) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - - retval = ms_prepare_write(chip, old_blk, new_blk, - log_blk, start_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != - STATUS_SUCCESS) { - set_sense_type - (chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#ifdef MS_DELAY_WRITE - } -#endif - } else { -#ifdef MS_DELAY_WRITE - retval = ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } -#endif - old_blk = ms_get_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } - } - - dev_dbg(rtsx_dev(chip), "seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", - seg_no, old_blk, new_blk); - - while (total_sec_cnt) { - if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) - end_page = ms_card->page_off + 1; - else - end_page = start_page + (u8)total_sec_cnt; - - page_cnt = end_page - start_page; - - dev_dbg(rtsx_dev(chip), "start_page = %d, end_page = %d, page_cnt = %d\n", - start_page, end_page, page_cnt); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - retval = ms_read_multiple_pages(chip, - old_blk, log_blk, - start_page, end_page, - ptr, &index, &offset); - } else { - retval = ms_write_multiple_pages(chip, old_blk, new_blk, - log_blk, start_page, - end_page, ptr, &index, - &offset); - } - - if (retval != STATUS_SUCCESS) { - toggle_gpio(chip, 1); - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (end_page == (ms_card->page_off + 1)) { - retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) - ms_set_unused_block(chip, old_blk); - - ms_set_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no], - new_blk); - } - } - - total_sec_cnt -= page_cnt; - if (scsi_sg_count(srb) == 0) - ptr += page_cnt * 512; - - if (total_sec_cnt == 0) - break; - - log_blk++; - - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; - seg_no++) { - if (log_blk < ms_start_idx[seg_no + 1]) - break; - } - - if (ms_card->segment[seg_no].build_flag == 0) { - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - old_blk = ms_get_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - new_blk = ms_get_unused_block(chip, seg_no); - if (new_blk == 0xFFFF) { - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - } - - dev_dbg(rtsx_dev(chip), "seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", - seg_no, old_blk, new_blk); - - start_page = 0; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (end_page < (ms_card->page_off + 1)) { -#ifdef MS_DELAY_WRITE - delay_write->delay_write_flag = 1; - delay_write->old_phyblock = old_blk; - delay_write->new_phyblock = new_blk; - delay_write->logblock = log_blk; - delay_write->pageoff = end_page; -#else - retval = ms_finish_write(chip, old_blk, new_blk, - log_blk, end_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != - STATUS_SUCCESS) { - set_sense_type - (chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } -#endif - } - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (CHK_MSPRO(ms_card)) - retval = mspro_rw_multi_sector(srb, chip, start_sector, - sector_cnt); - else - retval = ms_rw_multi_sector(srb, chip, start_sector, - sector_cnt); - - return retval; -} - -void ms_free_l2p_tbl(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int i = 0; - - if (ms_card->segment) { - for (i = 0; i < ms_card->segment_cnt; i++) { - vfree(ms_card->segment[i].l2p_table); - ms_card->segment[i].l2p_table = NULL; - vfree(ms_card->segment[i].free_table); - ms_card->segment[i].free_table = NULL; - } - vfree(ms_card->segment); - ms_card->segment = NULL; - } -} - -#ifdef SUPPORT_MAGIC_GATE - -#ifdef READ_BYTES_WAIT_INT -static int ms_poll_int(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - val = *rtsx_get_cmd_data(chip); - if (val & MS_INT_ERR) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} -#endif - -#ifdef MS_SAMPLE_INT_ERR -static int check_ms_err(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - retval = rtsx_read_register(chip, MS_TRANSFER, &val); - if (retval != STATUS_SUCCESS) - return 1; - if (val & MS_TRANSFER_ERR) - return 1; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) - return 1; - - if (val & (MS_INT_ERR | MS_INT_CMDNK)) - return 1; - - return 0; -} -#else -static int check_ms_err(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - retval = rtsx_read_register(chip, MS_TRANSFER, &val); - if (retval != STATUS_SUCCESS) - return 1; - if (val & MS_TRANSFER_ERR) - return 1; - - return 0; -} -#endif - -static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num) -{ - int retval, i; - u8 data[8]; - - data[0] = cmd; - data[1] = 0; - data[2] = 0; - data[3] = 0; - data[4] = 0; - data[5] = 0; - data[6] = entry_num; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, - data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, - u8 mg_entry_num) -{ - int retval; - u8 buf[6]; - - if (type == 0) - retval = ms_set_rw_reg_addr(chip, 0, 0, PRO_TPC_PARM, 1); - else - retval = ms_set_rw_reg_addr(chip, 0, 0, PRO_DATA_COUNT1, 6); - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf[0] = 0; - buf[1] = 0; - if (type == 1) { - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = mg_entry_num; - } - retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, - NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - int i; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[12]; - - if (scsi_bufflen(srb) < 12) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return STATUS_FAIL; - } - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - return STATUS_FAIL; - } - - memset(buf1, 0, 32); - rtsx_stor_get_xfer_buf(buf2, min_t(int, 12, scsi_bufflen(srb)), srb); - for (i = 0; i < 8; i++) - buf1[8 + i] = buf2[4 + i]; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, - buf1, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(1540, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - buf[0] = 0x04; - buf[1] = 0x1A; - buf[2] = 0x00; - buf[3] = 0x00; - - retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - goto free_buffer; - } - - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, - 3, WAIT_INT, 0, 0, buf + 4, 1536); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - goto free_buffer; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - retval = STATUS_FAIL; - goto free_buffer; - } - - bufflen = min_t(int, 1052, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, bufflen, srb); - -free_buffer: - kfree(buf); - return retval; -} - -int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; - int i; - unsigned int lun = SCSI_LUN(srb); - u8 buf[32]; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, - buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - memcpy(ms_card->magic_gate_id, buf, 16); - -#ifdef READ_BYTES_WAIT_INT - retval = ms_poll_int(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } -#endif - - retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - - bufflen = min_t(int, 12, scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - for (i = 0; i < 8; i++) - buf[i] = buf[4 + i]; - - for (i = 0; i < 24; i++) - buf[8 + i] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, - 32, WAIT_INT, buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - ms_card->mg_auth = 0; - - return STATUS_SUCCESS; -} - -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[36]; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, - buf1, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - buf2[0] = 0x00; - buf2[1] = 0x22; - buf2[2] = 0x00; - buf2[3] = 0x00; - - memcpy(buf2 + 4, ms_card->magic_gate_id, 16); - memcpy(buf2 + 20, buf1, 16); - - bufflen = min_t(int, 36, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf2, bufflen, srb); - -#ifdef READ_BYTES_WAIT_INT - retval = ms_poll_int(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } -#endif - - return STATUS_SUCCESS; -} - -int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int i; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 buf[32]; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - - bufflen = min_t(int, 12, scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - for (i = 0; i < 8; i++) - buf[i] = buf[4 + i]; - - for (i = 0; i < 24; i++) - buf[8 + i] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, - buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - ms_card->mg_auth = 1; - - return STATUS_SUCCESS; -} - -int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - buf[0] = 0x04; - buf[1] = 0x02; - buf[2] = 0x00; - buf[3] = 0x00; - - retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - goto free_buffer; - } - - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, - 2, WAIT_INT, 0, 0, buf + 4, 1024); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rtsx_clear_ms_error(chip); - goto free_buffer; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rtsx_clear_ms_error(chip); - retval = STATUS_FAIL; - goto free_buffer; - } - - bufflen = min_t(int, 1028, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, bufflen, srb); - -free_buffer: - kfree(buf); - return retval; -} - -int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; -#ifdef MG_SET_ICV_SLOW - int i; -#endif - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - bufflen = min_t(int, 1028, scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num); - if (retval != STATUS_SUCCESS) { - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type - (chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - goto set_ICV_finish; - } - -#ifdef MG_SET_ICV_SLOW - for (i = 0; i < 2; i++) { - udelay(50); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, - 0xFF, PRO_WRITE_LONG_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, RING_BUFFER); - - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i * 512, - 512, 0, DMA_TO_DEVICE, 3000); - if (retval < 0 || check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type - (chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } - retval = STATUS_FAIL; - goto set_ICV_finish; - } - } -#else - retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, - 2, WAIT_INT, 0, 0, buf + 4, 1024); - if (retval != STATUS_SUCCESS || check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type - (chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - goto set_ICV_finish; - } -#endif - -set_ICV_finish: - kfree(buf); - return retval; -} - -#endif /* SUPPORT_MAGIC_GATE */ - -void ms_cleanup_work(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - dev_dbg(rtsx_dev(chip), "MS Pro: stop transmission\n"); - mspro_stop_seq_mode(chip); - ms_card->cleanup_counter = 0; - } - if (CHK_MSHG(ms_card)) { - rtsx_write_register(chip, MS_CFG, - MS_2K_SECTOR_MODE, 0x00); - } - } -#ifdef MS_DELAY_WRITE - else if ((!CHK_MSPRO(ms_card)) && - ms_card->delay_write.delay_write_flag) { - dev_dbg(rtsx_dev(chip), "MS: delay write\n"); - ms_delay_write(chip); - ms_card->cleanup_counter = 0; - } -#endif -} - -int ms_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->asic_code) { - retval = ms_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_MS_PULL_CTL_BIT | 0x20, - FPGA_MS_PULL_CTL_BIT); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - if (retval) - return retval; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int release_ms_card(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - -#ifdef MS_DELAY_WRITE - ms_card->delay_write.delay_write_flag = 0; -#endif - ms_card->pro_under_formatting = 0; - - chip->card_ready &= ~MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->card_wp &= ~MS_CARD; - - ms_free_l2p_tbl(chip); - - memset(ms_card->raw_sys_info, 0, 96); -#ifdef SUPPORT_PCGL_1P18 - memset(ms_card->raw_model_name, 0, 48); -#endif - - retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/ms.h b/drivers/staging/rts5208/ms.h deleted file mode 100644 index 33bda9ce36b67c8300485adaebaadc489efb31e6..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/ms.h +++ /dev/null @@ -1,214 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_MS_H -#define __REALTEK_RTSX_MS_H - -#define MS_DELAY_WRITE - -#define MS_MAX_RETRY_COUNT 3 - -#define MS_EXTRA_SIZE 0x9 - -#define WRT_PRTCT 0x01 - -/* Error Code */ -#define MS_NO_ERROR 0x00 -#define MS_CRC16_ERROR 0x80 -#define MS_TO_ERROR 0x40 -#define MS_NO_CARD 0x20 -#define MS_NO_MEMORY 0x10 -#define MS_CMD_NK 0x08 -#define MS_FLASH_READ_ERROR 0x04 -#define MS_FLASH_WRITE_ERROR 0x02 -#define MS_BREQ_ERROR 0x01 -#define MS_NOT_FOUND 0x03 - -/* Transfer Protocol Command */ -#define READ_PAGE_DATA 0x02 -#define READ_REG 0x04 -#define GET_INT 0x07 -#define WRITE_PAGE_DATA 0x0D -#define WRITE_REG 0x0B -#define SET_RW_REG_ADRS 0x08 -#define SET_CMD 0x0E - -#define PRO_READ_LONG_DATA 0x02 -#define PRO_READ_SHORT_DATA 0x03 -#define PRO_READ_REG 0x04 -#define PRO_READ_QUAD_DATA 0x05 -#define PRO_GET_INT 0x07 -#define PRO_WRITE_LONG_DATA 0x0D -#define PRO_WRITE_SHORT_DATA 0x0C -#define PRO_WRITE_QUAD_DATA 0x0A -#define PRO_WRITE_REG 0x0B -#define PRO_SET_RW_REG_ADRS 0x08 -#define PRO_SET_CMD 0x0E -#define PRO_EX_SET_CMD 0x09 - -#ifdef SUPPORT_MAGIC_GATE - -#define MG_GET_ID 0x40 -#define MG_SET_LID 0x41 -#define MG_GET_LEKB 0x42 -#define MG_SET_RD 0x43 -#define MG_MAKE_RMS 0x44 -#define MG_MAKE_KSE 0x45 -#define MG_SET_IBD 0x46 -#define MG_GET_IBD 0x47 - -#endif - -#ifdef XC_POWERCLASS -#define XC_CHG_POWER 0x16 -#endif - -#define BLOCK_READ 0xAA -#define BLOCK_WRITE 0x55 -#define BLOCK_END 0x33 -#define BLOCK_ERASE 0x99 -#define FLASH_STOP 0xCC - -#define SLEEP 0x5A -#define CLEAR_BUF 0xC3 -#define MS_RESET 0x3C - -#define PRO_READ_DATA 0x20 -#define PRO_WRITE_DATA 0x21 -#define PRO_READ_ATRB 0x24 -#define PRO_STOP 0x25 -#define PRO_ERASE 0x26 -#define PRO_READ_2K_DATA 0x27 -#define PRO_WRITE_2K_DATA 0x28 - -#define PRO_FORMAT 0x10 -#define PRO_SLEEP 0x11 - -#define INT_REG 0x01 -#define STATUS_REG0 0x02 -#define STATUS_REG1 0x03 - -#define SYSTEM_PARAM 0x10 -#define BLOCK_ADRS 0x11 -#define CMD_PARM 0x14 -#define PAGE_ADRS 0x15 - -#define OVERWRITE_FLAG 0x16 -#define MANAGEMEN_FLAG 0x17 -#define LOGICAL_ADRS 0x18 -#define RESERVE_AREA 0x1A - -#define PRO_INT_REG 0x01 -#define PRO_STATUS_REG 0x02 -#define PRO_TYPE_REG 0x04 -#define PRO_IF_mode_REG 0x05 -#define PRO_CATEGORY_REG 0x06 -#define PRO_CLASS_REG 0x07 - -#define PRO_SYSTEM_PARAM 0x10 -#define PRO_DATA_COUNT1 0x11 -#define PRO_DATA_COUNT0 0x12 -#define PRO_DATA_ADDR3 0x13 -#define PRO_DATA_ADDR2 0x14 -#define PRO_DATA_ADDR1 0x15 -#define PRO_DATA_ADDR0 0x16 - -#define PRO_TPC_PARM 0x17 -#define PRO_CMD_PARM 0x18 - -#define INT_REG_CED 0x80 -#define INT_REG_ERR 0x40 -#define INT_REG_BREQ 0x20 -#define INT_REG_CMDNK 0x01 - -#define BLOCK_BOOT 0xC0 -#define BLOCK_OK 0x80 -#define PAGE_OK 0x60 -#define DATA_COMPL 0x10 - -#define NOT_BOOT_BLOCK 0x4 -#define NOT_TRANSLATION_TABLE 0x8 - -#define HEADER_ID0 PPBUF_BASE2 -#define HEADER_ID1 (PPBUF_BASE2 + 1) -#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4) -#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5) -#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6) -#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7) -#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2) -#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3) -#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4) -#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5) -#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6) -#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7) -#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8) -#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9) - -#define MS_device_type (PPBUF_BASE2 + 0x1D8) - -#define MS_4bit_support (PPBUF_BASE2 + 0x1D3) - -#define set_PS_NG 1 -#define set_PS_error 0 - -#define PARALLEL_8BIT_IF 0x40 -#define PARALLEL_4BIT_IF 0x00 -#define SERIAL_IF 0x80 - -#define BUF_FULL 0x10 -#define BUF_EMPTY 0x20 - -#define MEDIA_BUSY 0x80 -#define FLASH_BUSY 0x40 -#define DATA_ERROR 0x20 -#define STS_UCDT 0x10 -#define EXTRA_ERROR 0x08 -#define STS_UCEX 0x04 -#define FLAG_ERROR 0x02 -#define STS_UCFG 0x01 - -#define MS_SHORT_DATA_LEN 32 - -#define FORMAT_SUCCESS 0 -#define FORMAT_FAIL 1 -#define FORMAT_IN_PROGRESS 2 - -#define MS_SET_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag |= 0x80) -#define MS_CLR_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag &= 0x7F) -#define MS_TST_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag & 0x80) - -void mspro_polling_format_status(struct rtsx_chip *chip); - -void mspro_stop_seq_mode(struct rtsx_chip *chip); -int reset_ms_card(struct rtsx_chip *chip); -int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt); -int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, - int short_data_len, bool quick_format); -void ms_free_l2p_tbl(struct rtsx_chip *chip); -void ms_cleanup_work(struct rtsx_chip *chip); -int ms_power_off_card3v3(struct rtsx_chip *chip); -int release_ms_card(struct rtsx_chip *chip); -#ifdef MS_DELAY_WRITE -int ms_delay_write(struct rtsx_chip *chip); -#endif - -#ifdef SUPPORT_MAGIC_GATE -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_MS_H */ diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c deleted file mode 100644 index c4f54c311d0549247730a3cce94aad0c30470b12..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx.c +++ /dev/null @@ -1,987 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include -#include - -#include "rtsx.h" -#include "ms.h" -#include "sd.h" -#include "xd.h" - -MODULE_DESCRIPTION("Realtek PCI-Express card reader rts5208/rts5288 driver"); -MODULE_LICENSE("GPL"); - -static unsigned int delay_use = 1; -module_param(delay_use, uint, 0644); -MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); - -static int ss_en; -module_param(ss_en, int, 0644); -MODULE_PARM_DESC(ss_en, "enable selective suspend"); - -static int ss_interval = 50; -module_param(ss_interval, int, 0644); -MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds"); - -static int auto_delink_en; -module_param(auto_delink_en, int, 0644); -MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); - -static unsigned char aspm_l0s_l1_en; -module_param(aspm_l0s_l1_en, byte, 0644); -MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm"); - -static int msi_en; -module_param(msi_en, int, 0644); -MODULE_PARM_DESC(msi_en, "enable msi"); - -static irqreturn_t rtsx_interrupt(int irq, void *dev_id); - -/*********************************************************************** - * Host functions - ***********************************************************************/ - -static const char *host_info(struct Scsi_Host *host) -{ - return "SCSI emulation for PCI-Express Mass Storage devices"; -} - -static int slave_alloc(struct scsi_device *sdev) -{ - /* - * Set the INQUIRY transfer length to 36. We don't use any of - * the extra data and many devices choke if asked for more or - * less than 36 bytes. - */ - sdev->inquiry_len = 36; - return 0; -} - -static int slave_configure(struct scsi_device *sdev) -{ - /* Set the SCSI level to at least 2. We'll leave it at 3 if that's - * what is originally reported. We need this to avoid confusing - * the SCSI layer with devices that report 0 or 1, but need 10-byte - * commands (ala ATAPI devices behind certain bridges, or devices - * which simply have broken INQUIRY data). - * - * NOTE: This means /dev/sg programs (ala cdrecord) will get the - * actual information. This seems to be the preference for - * programs like that. - * - * NOTE: This also means that /proc/scsi/scsi and sysfs may report - * the actual value or the modified one, depending on where the - * data comes from. - */ - if (sdev->scsi_level < SCSI_2) { - sdev->scsi_level = SCSI_2; - sdev->sdev_target->scsi_level = SCSI_2; - } - - return 0; -} - -/*********************************************************************** - * /proc/scsi/ functions - ***********************************************************************/ - -/* we use this macro to help us write into the buffer */ -#undef SPRINTF -#define SPRINTF(args...) \ - do { \ - if (pos < buffer + length) \ - pos += sprintf(pos, ## args); \ - } while (0) - -/* queue a command */ -/* This is always called with spin_lock_irq(host->host_lock) held */ -static int queuecommand_lck(struct scsi_cmnd *srb) -{ - void (*done)(struct scsi_cmnd *) = scsi_done; - struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - struct rtsx_chip *chip = dev->chip; - - /* check for state-transition errors */ - if (chip->srb) { - dev_err(&dev->pci->dev, "Error: chip->srb = %p\n", - chip->srb); - return SCSI_MLQUEUE_HOST_BUSY; - } - - /* fail the command if we are disconnecting */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "Fail command during disconnect\n"); - srb->result = DID_NO_CONNECT << 16; - done(srb); - return 0; - } - - /* enqueue the command and wake up the control thread */ - chip->srb = srb; - complete(&dev->cmnd_ready); - - return 0; -} - -static DEF_SCSI_QCMD(queuecommand) - -/*********************************************************************** - * Error handling functions - ***********************************************************************/ - -/* Command timeout and abort */ -static int command_abort(struct scsi_cmnd *srb) -{ - struct Scsi_Host *host = srb->device->host; - struct rtsx_dev *dev = host_to_rtsx(host); - struct rtsx_chip *chip = dev->chip; - - spin_lock_irq(host->host_lock); - - /* Is this command still active? */ - if (chip->srb != srb) { - spin_unlock_irq(host->host_lock); - dev_info(&dev->pci->dev, "-- nothing to abort\n"); - return FAILED; - } - - rtsx_set_stat(chip, RTSX_STAT_ABORT); - - spin_unlock_irq(host->host_lock); - - /* Wait for the aborted command to finish */ - wait_for_completion(&dev->notify); - - return SUCCESS; -} - -/* - * This invokes the transport reset mechanism to reset the state of the - * device - */ -static int device_reset(struct scsi_cmnd *srb) -{ - return SUCCESS; -} - -/* - * this defines our host template, with which we'll allocate hosts - */ - -static const struct scsi_host_template rtsx_host_template = { - /* basic userland interface stuff */ - .name = CR_DRIVER_NAME, - .proc_name = CR_DRIVER_NAME, - .info = host_info, - - /* command interface -- queued only */ - .queuecommand = queuecommand, - - /* error and abort handlers */ - .eh_abort_handler = command_abort, - .eh_device_reset_handler = device_reset, - - /* queue commands only, only one command per LUN */ - .can_queue = 1, - - /* unknown initiator id */ - .this_id = -1, - - .slave_alloc = slave_alloc, - .slave_configure = slave_configure, - - /* lots of sg segments can be handled */ - .sg_tablesize = SG_ALL, - - /* limit the total size of a transfer to 120 KB */ - .max_sectors = 240, - - /* - * Scatter-gather buffers (all but the last) must have a length - * divisible by the bulk maxpacket size. Otherwise a data packet - * would end up being short, causing a premature end to the data - * transfer. Since high-speed bulk pipes have a maxpacket size - * of 512, we'll use that as the scsi device queue's DMA alignment - * mask. Guaranteeing proper alignment of the first buffer will - * have the desired effect because, except at the beginning and - * the end, scatter-gather buffers follow page boundaries. - */ - .dma_alignment = 511, - - /* emulated HBA */ - .emulated = 1, - - /* we do our own delay after a device or bus reset */ - .skip_settle_delay = 1, - - /* module management */ - .module = THIS_MODULE -}; - -static int rtsx_acquire_irq(struct rtsx_dev *dev) -{ - struct rtsx_chip *chip = dev->chip; - - dev_info(&dev->pci->dev, "%s: chip->msi_en = %d, pci->irq = %d\n", - __func__, chip->msi_en, dev->pci->irq); - - if (request_irq(dev->pci->irq, rtsx_interrupt, - chip->msi_en ? 0 : IRQF_SHARED, - CR_DRIVER_NAME, dev)) { - dev_err(&dev->pci->dev, - "rtsx: unable to grab IRQ %d, disabling device\n", - dev->pci->irq); - return -1; - } - - dev->irq = dev->pci->irq; - pci_intx(dev->pci, !chip->msi_en); - - return 0; -} - -/* - * power management - */ -static int __maybe_unused rtsx_suspend(struct device *dev_d) -{ - struct pci_dev *pci = to_pci_dev(dev_d); - struct rtsx_dev *dev = pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return 0; - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - chip = dev->chip; - - rtsx_do_before_power_down(chip, PM_S3); - - if (dev->irq >= 0) { - free_irq(dev->irq, (void *)dev); - dev->irq = -1; - } - - if (chip->msi_en) - pci_free_irq_vectors(pci); - - device_wakeup_enable(dev_d); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - - return 0; -} - -static int __maybe_unused rtsx_resume(struct device *dev_d) -{ - struct pci_dev *pci = to_pci_dev(dev_d); - struct rtsx_dev *dev = pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return 0; - - chip = dev->chip; - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - pci_set_master(pci); - - if (chip->msi_en) { - if (pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI) < 0) - chip->msi_en = 0; - } - - if (rtsx_acquire_irq(dev) < 0) { - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - return -EIO; - } - - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00); - rtsx_init_chip(chip); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - - return 0; -} - -static void rtsx_shutdown(struct pci_dev *pci) -{ - struct rtsx_dev *dev = pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return; - - chip = dev->chip; - - rtsx_do_before_power_down(chip, PM_S1); - - if (dev->irq >= 0) { - free_irq(dev->irq, (void *)dev); - dev->irq = -1; - } - - if (chip->msi_en) - pci_free_irq_vectors(pci); - - pci_disable_device(pci); -} - -static int rtsx_control_thread(void *__dev) -{ - struct rtsx_dev *dev = __dev; - struct rtsx_chip *chip = dev->chip; - struct Scsi_Host *host = rtsx_to_host(dev); - - for (;;) { - if (wait_for_completion_interruptible(&dev->cmnd_ready)) - break; - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - /* if the device has disconnected, we are free to exit */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "-- rtsx-control exiting\n"); - mutex_unlock(&dev->dev_mutex); - break; - } - - /* lock access to the state */ - spin_lock_irq(host->host_lock); - - /* has the command aborted ? */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - chip->srb->result = DID_ABORT << 16; - goto skip_for_abort; - } - - spin_unlock_irq(host->host_lock); - - /* reject the command if the direction indicator - * is UNKNOWN - */ - if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { - dev_err(&dev->pci->dev, "UNKNOWN data direction\n"); - chip->srb->result = DID_ERROR << 16; - } else if (chip->srb->device->id) { - /* reject if target != 0 or if LUN is higher than - * the maximum known LUN - */ - dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n", - chip->srb->device->id, - (u8)chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } else if (chip->srb->device->lun > chip->max_lun) { - dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n", - chip->srb->device->id, - (u8)chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } else { - /* we've got a command, let's do it! */ - scsi_show_command(chip); - rtsx_invoke_transport(chip->srb, chip); - } - - /* lock access to the state */ - spin_lock_irq(host->host_lock); - - /* did the command already complete because of a disconnect? */ - if (!chip->srb) - ; /* nothing to do */ - - /* indicate that the command is done */ - else if (chip->srb->result != DID_ABORT << 16) { - scsi_done(chip->srb); - } else { -skip_for_abort: - dev_err(&dev->pci->dev, "scsi command aborted\n"); - } - - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - complete(&dev->notify); - - rtsx_set_stat(chip, RTSX_STAT_IDLE); - } - - /* finished working on this command */ - chip->srb = NULL; - spin_unlock_irq(host->host_lock); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - } /* for (;;) */ - - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * kthread_complete_and_exit() goes even further than this -- - * it is safe in the case that the thread of the caller is going away - * (not just the structure) -- this is necessary for the module-remove - * case. This is important in preemption kernels, which transfer the - * flow of execution immediately upon a complete(). - */ - kthread_complete_and_exit(&dev->control_exit, 0); -} - -static int rtsx_polling_thread(void *__dev) -{ - struct rtsx_dev *dev = __dev; - struct rtsx_chip *chip = dev->chip; - struct sd_info *sd_card = &chip->sd_card; - struct xd_info *xd_card = &chip->xd_card; - struct ms_info *ms_card = &chip->ms_card; - - sd_card->cleanup_counter = 0; - xd_card->cleanup_counter = 0; - ms_card->cleanup_counter = 0; - - /* Wait until SCSI scan finished */ - wait_timeout((delay_use + 5) * 1000); - - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(POLLING_INTERVAL)); - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - /* if the device has disconnected, we are free to exit */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "-- rtsx-polling exiting\n"); - mutex_unlock(&dev->dev_mutex); - break; - } - - mutex_unlock(&dev->dev_mutex); - - mspro_polling_format_status(chip); - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - rtsx_polling_func(chip); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - } - - kthread_complete_and_exit(&dev->polling_exit, 0); -} - -/* - * interrupt handler - */ -static irqreturn_t rtsx_interrupt(int irq, void *dev_id) -{ - struct rtsx_dev *dev = dev_id; - struct rtsx_chip *chip; - int retval; - u32 status; - - if (dev) - chip = dev->chip; - else - return IRQ_NONE; - - if (!chip) - return IRQ_NONE; - - spin_lock(&dev->reg_lock); - - retval = rtsx_pre_handle_interrupt(chip); - if (retval == STATUS_FAIL) { - spin_unlock(&dev->reg_lock); - if (chip->int_reg == 0xFFFFFFFF) - return IRQ_HANDLED; - return IRQ_NONE; - } - - status = chip->int_reg; - - if (dev->check_card_cd) { - if (!(dev->check_card_cd & status)) { - /* card not exist, return TRANS_RESULT_FAIL */ - dev->trans_result = TRANS_RESULT_FAIL; - if (dev->done) - complete(dev->done); - goto exit; - } - } - - if (status & (NEED_COMPLETE_INT | DELINK_INT)) { - if (status & (TRANS_FAIL_INT | DELINK_INT)) { - if (status & DELINK_INT) - RTSX_SET_DELINK(chip); - dev->trans_result = TRANS_RESULT_FAIL; - if (dev->done) - complete(dev->done); - } else if (status & TRANS_OK_INT) { - dev->trans_result = TRANS_RESULT_OK; - if (dev->done) - complete(dev->done); - } else if (status & DATA_DONE_INT) { - dev->trans_result = TRANS_NOT_READY; - if (dev->done && dev->trans_state == STATE_TRANS_SG) - complete(dev->done); - } - } - -exit: - spin_unlock(&dev->reg_lock); - return IRQ_HANDLED; -} - -/* Release all our dynamic resources */ -static void rtsx_release_resources(struct rtsx_dev *dev) -{ - dev_info(&dev->pci->dev, "-- %s\n", __func__); - - /* Tell the control thread to exit. The SCSI host must - * already have been removed so it won't try to queue - * any more commands. - */ - dev_info(&dev->pci->dev, "-- sending exit command to thread\n"); - complete(&dev->cmnd_ready); - if (dev->ctl_thread) - wait_for_completion(&dev->control_exit); - if (dev->polling_thread) - wait_for_completion(&dev->polling_exit); - - wait_timeout(200); - - if (dev->rtsx_resv_buf) { - dev->chip->host_cmds_ptr = NULL; - dev->chip->host_sg_tbl_ptr = NULL; - } - - if (dev->irq > 0) - free_irq(dev->irq, (void *)dev); - if (dev->chip->msi_en) - pci_free_irq_vectors(dev->pci); - if (dev->remap_addr) - iounmap(dev->remap_addr); - - rtsx_release_chip(dev->chip); - kfree(dev->chip); -} - -/* - * First stage of disconnect processing: stop all commands and remove - * the host - */ -static void quiesce_and_remove_host(struct rtsx_dev *dev) -{ - struct Scsi_Host *host = rtsx_to_host(dev); - struct rtsx_chip *chip = dev->chip; - - /* - * Prevent new transfers, stop the current command, and - * interrupt a SCSI-scan or device-reset delay - */ - mutex_lock(&dev->dev_mutex); - spin_lock_irq(host->host_lock); - rtsx_set_stat(chip, RTSX_STAT_DISCONNECT); - spin_unlock_irq(host->host_lock); - mutex_unlock(&dev->dev_mutex); - wake_up(&dev->delay_wait); - wait_for_completion(&dev->scanning_done); - - /* Wait some time to let other threads exist */ - wait_timeout(100); - - /* - * queuecommand won't accept any new commands and the control - * thread won't execute a previously-queued command. If there - * is such a command pending, complete it with an error. - */ - mutex_lock(&dev->dev_mutex); - if (chip->srb) { - chip->srb->result = DID_NO_CONNECT << 16; - spin_lock_irq(host->host_lock); - scsi_done(dev->chip->srb); - chip->srb = NULL; - spin_unlock_irq(host->host_lock); - } - mutex_unlock(&dev->dev_mutex); - - /* Now we own no commands so it's safe to remove the SCSI host */ - scsi_remove_host(host); -} - -/* Second stage of disconnect processing: deallocate all resources */ -static void release_everything(struct rtsx_dev *dev) -{ - rtsx_release_resources(dev); - - /* - * Drop our reference to the host; the SCSI core will free it - * when the refcount becomes 0. - */ - scsi_host_put(rtsx_to_host(dev)); -} - -/* Thread to carry out delayed SCSI-device scanning */ -static int rtsx_scan_thread(void *__dev) -{ - struct rtsx_dev *dev = __dev; - struct rtsx_chip *chip = dev->chip; - - /* Wait for the timeout to expire or for a disconnect */ - if (delay_use > 0) { - dev_info(&dev->pci->dev, - "%s: waiting for device to settle before scanning\n", - CR_DRIVER_NAME); - wait_event_interruptible_timeout - (dev->delay_wait, - rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT), - delay_use * HZ); - } - - /* If the device is still connected, perform the scanning */ - if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - scsi_scan_host(rtsx_to_host(dev)); - dev_info(&dev->pci->dev, "%s: device scan complete\n", - CR_DRIVER_NAME); - - /* Should we unbind if no devices were detected? */ - } - - kthread_complete_and_exit(&dev->scanning_done, 0); -} - -static void rtsx_init_options(struct rtsx_chip *chip) -{ - chip->vendor_id = chip->rtsx->pci->vendor; - chip->product_id = chip->rtsx->pci->device; - chip->adma_mode = 1; - chip->lun_mc = 0; - chip->driver_first_load = 1; -#ifdef HW_AUTO_SWITCH_SD_BUS - chip->sdio_in_charge = 0; -#endif - - chip->mspro_formatter_enable = 1; - chip->ignore_sd = 0; - chip->use_hw_setting = 0; - chip->lun_mode = DEFAULT_SINGLE; - chip->auto_delink_en = auto_delink_en; - chip->ss_en = ss_en; - chip->ss_idle_period = ss_interval * 1000; - chip->remote_wakeup_en = 0; - chip->aspm_l0s_l1_en = aspm_l0s_l1_en; - chip->dynamic_aspm = 1; - chip->fpga_sd_sdr104_clk = CLK_200; - chip->fpga_sd_ddr50_clk = CLK_100; - chip->fpga_sd_sdr50_clk = CLK_100; - chip->fpga_sd_hs_clk = CLK_100; - chip->fpga_mmc_52m_clk = CLK_80; - chip->fpga_ms_hg_clk = CLK_80; - chip->fpga_ms_4bit_clk = CLK_80; - chip->fpga_ms_1bit_clk = CLK_40; - chip->asic_sd_sdr104_clk = 203; - chip->asic_sd_sdr50_clk = 98; - chip->asic_sd_ddr50_clk = 98; - chip->asic_sd_hs_clk = 98; - chip->asic_mmc_52m_clk = 98; - chip->asic_ms_hg_clk = 117; - chip->asic_ms_4bit_clk = 78; - chip->asic_ms_1bit_clk = 39; - chip->ssc_depth_sd_sdr104 = SSC_DEPTH_2M; - chip->ssc_depth_sd_sdr50 = SSC_DEPTH_2M; - chip->ssc_depth_sd_ddr50 = SSC_DEPTH_1M; - chip->ssc_depth_sd_hs = SSC_DEPTH_1M; - chip->ssc_depth_mmc_52m = SSC_DEPTH_1M; - chip->ssc_depth_ms_hg = SSC_DEPTH_1M; - chip->ssc_depth_ms_4bit = SSC_DEPTH_512K; - chip->ssc_depth_low_speed = SSC_DEPTH_512K; - chip->ssc_en = 1; - chip->sd_speed_prior = 0x01040203; - chip->sd_current_prior = 0x00010203; - chip->sd_ctl = SD_PUSH_POINT_AUTO | - SD_SAMPLE_POINT_AUTO | - SUPPORT_MMC_DDR_MODE; - chip->sd_ddr_tx_phase = 0; - chip->mmc_ddr_tx_phase = 1; - chip->sd_default_tx_phase = 15; - chip->sd_default_rx_phase = 15; - chip->pmos_pwr_on_interval = 200; - chip->sd_voltage_switch_delay = 1000; - chip->ms_power_class_en = 3; - - chip->sd_400mA_ocp_thd = 1; - chip->sd_800mA_ocp_thd = 5; - chip->ms_ocp_thd = 2; - - chip->card_drive_sel = 0x55; - chip->sd30_drive_sel_1v8 = 0x03; - chip->sd30_drive_sel_3v3 = 0x01; - - chip->do_delink_before_power_down = 1; - chip->auto_power_down = 1; - chip->polling_config = 0; - - chip->force_clkreq_0 = 1; - chip->ft2_fast_mode = 0; - - chip->sdio_retry_cnt = 1; - - chip->xd_timeout = 2000; - chip->sd_timeout = 10000; - chip->ms_timeout = 2000; - chip->mspro_timeout = 15000; - - chip->power_down_in_ss = 1; - - chip->sdr104_en = 1; - chip->sdr50_en = 1; - chip->ddr50_en = 1; - - chip->delink_stage1_step = 100; - chip->delink_stage2_step = 40; - chip->delink_stage3_step = 20; - - chip->auto_delink_in_L1 = 1; - chip->blink_led = 1; - chip->msi_en = msi_en; - chip->hp_watch_bios_hotplug = 0; - chip->max_payload = 0; - chip->phy_voltage = 0; - - chip->support_ms_8bit = 1; - chip->s3_pwr_off_delay = 1000; -} - -static int rtsx_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - struct Scsi_Host *host; - struct rtsx_dev *dev; - int err = 0; - struct task_struct *th; - - dev_dbg(&pci->dev, "Realtek PCI-E card reader detected\n"); - - err = pcim_enable_device(pci); - if (err < 0) { - dev_err(&pci->dev, "PCI enable device failed!\n"); - return err; - } - - err = pci_request_regions(pci, CR_DRIVER_NAME); - if (err < 0) { - dev_err(&pci->dev, "PCI request regions for %s failed!\n", - CR_DRIVER_NAME); - return err; - } - - /* - * Ask the SCSI layer to allocate a host structure, with extra - * space at the end for our private rtsx_dev structure. - */ - host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); - if (!host) { - dev_err(&pci->dev, "Unable to allocate the scsi host\n"); - err = -ENOMEM; - goto scsi_host_alloc_fail; - } - - dev = host_to_rtsx(host); - memset(dev, 0, sizeof(struct rtsx_dev)); - - dev->chip = kzalloc(sizeof(*dev->chip), GFP_KERNEL); - if (!dev->chip) { - err = -ENOMEM; - goto chip_alloc_fail; - } - - spin_lock_init(&dev->reg_lock); - mutex_init(&dev->dev_mutex); - init_completion(&dev->cmnd_ready); - init_completion(&dev->control_exit); - init_completion(&dev->polling_exit); - init_completion(&dev->notify); - init_completion(&dev->scanning_done); - init_waitqueue_head(&dev->delay_wait); - - dev->pci = pci; - dev->irq = -1; - - dev_info(&pci->dev, "Resource length: 0x%x\n", - (unsigned int)pci_resource_len(pci, 0)); - dev->addr = pci_resource_start(pci, 0); - dev->remap_addr = ioremap(dev->addr, pci_resource_len(pci, 0)); - if (!dev->remap_addr) { - dev_err(&pci->dev, "ioremap error\n"); - err = -ENXIO; - goto ioremap_fail; - } - - /* - * Using "unsigned long" cast here to eliminate gcc warning in - * 64-bit system - */ - dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n", - (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); - - dev->rtsx_resv_buf = dmam_alloc_coherent(&pci->dev, RTSX_RESV_BUF_LEN, - &dev->rtsx_resv_buf_addr, - GFP_KERNEL); - if (!dev->rtsx_resv_buf) { - dev_err(&pci->dev, "alloc dma buffer fail\n"); - err = -ENXIO; - goto dma_alloc_fail; - } - dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; - dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; - dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; - dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + - HOST_CMDS_BUF_LEN; - - dev->chip->rtsx = dev; - - rtsx_init_options(dev->chip); - - dev_info(&pci->dev, "pci->irq = %d\n", pci->irq); - - if (dev->chip->msi_en) { - if (pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI) < 0) - dev->chip->msi_en = 0; - } - - if (rtsx_acquire_irq(dev) < 0) { - err = -EBUSY; - goto irq_acquire_fail; - } - - pci_set_master(pci); - synchronize_irq(dev->irq); - - rtsx_init_chip(dev->chip); - - /* - * set the supported max_lun and max_id for the scsi host - * NOTE: the minimal value of max_id is 1 - */ - host->max_id = 1; - host->max_lun = dev->chip->max_lun; - - /* Start up our control thread */ - th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start control thread\n"); - err = PTR_ERR(th); - goto control_thread_fail; - } - dev->ctl_thread = th; - - err = scsi_add_host(host, &pci->dev); - if (err) { - dev_err(&pci->dev, "Unable to add the scsi host\n"); - goto scsi_add_host_fail; - } - - /* Start up the thread for delayed SCSI-device scanning */ - th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan"); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); - complete(&dev->scanning_done); - err = PTR_ERR(th); - goto scan_thread_fail; - } - - /* Start up the thread for polling thread */ - th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start the device-polling thread\n"); - err = PTR_ERR(th); - goto scan_thread_fail; - } - dev->polling_thread = th; - - pci_set_drvdata(pci, dev); - - return 0; - - /* We come here if there are any problems */ -scan_thread_fail: - quiesce_and_remove_host(dev); -scsi_add_host_fail: - complete(&dev->cmnd_ready); - wait_for_completion(&dev->control_exit); -control_thread_fail: - free_irq(dev->irq, (void *)dev); - rtsx_release_chip(dev->chip); -irq_acquire_fail: - dev->chip->host_cmds_ptr = NULL; - dev->chip->host_sg_tbl_ptr = NULL; - if (dev->chip->msi_en) - pci_free_irq_vectors(dev->pci); -dma_alloc_fail: - iounmap(dev->remap_addr); -ioremap_fail: - kfree(dev->chip); -chip_alloc_fail: - dev_err(&pci->dev, "%s failed\n", __func__); - scsi_host_put(host); -scsi_host_alloc_fail: - pci_release_regions(pci); - return err; -} - -static void rtsx_remove(struct pci_dev *pci) -{ - struct rtsx_dev *dev = pci_get_drvdata(pci); - - quiesce_and_remove_host(dev); - release_everything(dev); - pci_release_regions(pci); -} - -/* PCI IDs */ -static const struct pci_device_id rtsx_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5208), - PCI_CLASS_OTHERS << 16, 0xFF0000 }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5288), - PCI_CLASS_OTHERS << 16, 0xFF0000 }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, rtsx_ids); - -static SIMPLE_DEV_PM_OPS(rtsx_pm_ops, rtsx_suspend, rtsx_resume); - -/* pci_driver definition */ -static struct pci_driver rtsx_driver = { - .name = CR_DRIVER_NAME, - .id_table = rtsx_ids, - .probe = rtsx_probe, - .remove = rtsx_remove, - .driver.pm = &rtsx_pm_ops, - .shutdown = rtsx_shutdown, -}; - -module_pci_driver(rtsx_driver); diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h deleted file mode 100644 index ec6f5b07390b2c9d2cd83579c7019ab0efb4d594..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx.h +++ /dev/null @@ -1,164 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_H -#define __REALTEK_RTSX_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define CR_DRIVER_NAME "rts5208" - -/* - * macros for easy use - */ -#define wait_timeout_x(task_state, msecs) \ -do { \ - set_current_state((task_state)); \ - schedule_timeout((msecs) * HZ / 1000); \ -} while (0) -#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs)) - -#define STATE_TRANS_NONE 0 -#define STATE_TRANS_CMD 1 -#define STATE_TRANS_BUF 2 -#define STATE_TRANS_SG 3 - -#define TRANS_NOT_READY 0 -#define TRANS_RESULT_OK 1 -#define TRANS_RESULT_FAIL 2 - -#define SCSI_LUN(srb) ((srb)->device->lun) - -struct rtsx_chip; - -struct rtsx_dev { - struct pci_dev *pci; - - /* pci resources */ - unsigned long addr; - void __iomem *remap_addr; - int irq; - - /* locks */ - spinlock_t reg_lock; - - struct task_struct *ctl_thread; /* the control thread */ - struct task_struct *polling_thread; /* the polling thread */ - - /* mutual exclusion and synchronization structures */ - struct completion cmnd_ready; /* to sleep thread on */ - struct completion control_exit; /* control thread exit */ - struct completion polling_exit; /* polling thread exit */ - struct completion notify; /* thread begin/end */ - struct completion scanning_done; /* wait for scan thread */ - - wait_queue_head_t delay_wait; /* wait during scan, reset */ - struct mutex dev_mutex; - - /* host reserved buffer */ - void *rtsx_resv_buf; - dma_addr_t rtsx_resv_buf_addr; - - char trans_result; - char trans_state; - - struct completion *done; - /* Whether interrupt handler should care card cd info */ - u32 check_card_cd; - - struct rtsx_chip *chip; -}; - -/* Convert between rtsx_dev and the corresponding Scsi_Host */ -static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev) -{ - return container_of((void *)dev, struct Scsi_Host, hostdata); -} - -static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host) -{ - return (struct rtsx_dev *)host->hostdata; -} - -#define lock_state(chip) spin_lock_irq(&((chip)->rtsx->reg_lock)) -#define unlock_state(chip) spin_unlock_irq(&((chip)->rtsx->reg_lock)) - -/* struct scsi_cmnd transfer buffer access utilities */ -enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; - -#include "rtsx_chip.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "rtsx_sys.h" -#include "general.h" - -static inline void rtsx_writel(struct rtsx_chip *chip, u32 reg, u32 value) -{ - iowrite32(value, chip->rtsx->remap_addr + reg); -} - -static inline u32 rtsx_readl(struct rtsx_chip *chip, u32 reg) -{ - return ioread32(chip->rtsx->remap_addr + reg); -} - -static inline void rtsx_writew(struct rtsx_chip *chip, u32 reg, u16 value) -{ - iowrite16(value, chip->rtsx->remap_addr + reg); -} - -static inline u16 rtsx_readw(struct rtsx_chip *chip, u32 reg) -{ - return ioread16(chip->rtsx->remap_addr + reg); -} - -static inline void rtsx_writeb(struct rtsx_chip *chip, u32 reg, u8 value) -{ - iowrite8(value, chip->rtsx->remap_addr + reg); -} - -static inline u8 rtsx_readb(struct rtsx_chip *chip, u32 reg) -{ - return ioread8((chip)->rtsx->remap_addr + reg); -} - -static inline int rtsx_read_config_byte(struct rtsx_chip *chip, int where, u8 *val) -{ - return pci_read_config_byte(chip->rtsx->pci, where, val); -} - -static inline int rtsx_write_config_byte(struct rtsx_chip *chip, int where, u8 val) -{ - return pci_write_config_byte(chip->rtsx->pci, where, val); -} - -#endif /* __REALTEK_RTSX_H */ diff --git a/drivers/staging/rts5208/rtsx_card.c b/drivers/staging/rts5208/rtsx_card.c deleted file mode 100644 index 326b04756f62c71916f8bd44a324825b587c72ff..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_card.c +++ /dev/null @@ -1,1151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include -#include -#include - -#include "rtsx.h" -#include "sd.h" -#include "xd.h" -#include "ms.h" - -void do_remaining_work(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; -#ifdef XD_DELAY_WRITE - struct xd_info *xd_card = &chip->xd_card; -#endif - struct ms_info *ms_card = &chip->ms_card; - - if (chip->card_ready & SD_CARD) { - if (sd_card->seq_mode) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - sd_card->cleanup_counter++; - } else { - sd_card->cleanup_counter = 0; - } - } - -#ifdef XD_DELAY_WRITE - if (chip->card_ready & XD_CARD) { - if (xd_card->delay_write.delay_write_flag) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - xd_card->cleanup_counter++; - } else { - xd_card->cleanup_counter = 0; - } - } -#endif - - if (chip->card_ready & MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - ms_card->cleanup_counter++; - } else { - ms_card->cleanup_counter = 0; - } - } else { -#ifdef MS_DELAY_WRITE - if (ms_card->delay_write.delay_write_flag) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - ms_card->cleanup_counter++; - } else { - ms_card->cleanup_counter = 0; - } -#endif - } - } - - if (sd_card->cleanup_counter > POLLING_WAIT_CNT) - sd_cleanup_work(chip); - - if (xd_card->cleanup_counter > POLLING_WAIT_CNT) - xd_cleanup_work(chip); - - if (ms_card->cleanup_counter > POLLING_WAIT_CNT) - ms_cleanup_work(chip); -} - -void try_to_switch_sdio_ctrl(struct rtsx_chip *chip) -{ - u8 reg1 = 0, reg2 = 0; - - rtsx_read_register(chip, 0xFF34, ®1); - rtsx_read_register(chip, 0xFF38, ®2); - dev_dbg(rtsx_dev(chip), "reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", - reg1, reg2); - if ((reg1 & 0xC0) && (reg2 & 0xC0)) { - chip->sd_int = 1; - rtsx_write_register(chip, SDIO_CTRL, 0xFF, - SDIO_BUS_CTRL | SDIO_CD_CTRL); - rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_ON); - } -} - -#ifdef SUPPORT_SDIO_ASPM -void dynamic_configure_sdio_aspm(struct rtsx_chip *chip) -{ - u8 buf[12], reg; - int i; - - for (i = 0; i < 12; i++) - rtsx_read_register(chip, 0xFF08 + i, &buf[i]); - rtsx_read_register(chip, 0xFF25, ®); - if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) { - chip->sdio_counter = 0; - chip->sdio_idle = 0; - } else { - if (!chip->sdio_idle) { - chip->sdio_counter++; - if (chip->sdio_counter >= SDIO_IDLE_COUNT) { - chip->sdio_counter = 0; - chip->sdio_idle = 1; - } - } - } - memcpy(chip->sdio_raw_data, buf, 12); - - if (chip->sdio_idle) { - if (!chip->sdio_aspm) { - dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n"); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, - 0x30 | (chip->aspm_level[1] << 2)); - chip->sdio_aspm = 1; - } - } else { - if (chip->sdio_aspm) { - dev_dbg(rtsx_dev(chip), "SDIO exit ASPM!\n"); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30); - chip->sdio_aspm = 0; - } - } -} -#endif - -void do_reset_sd_card(struct rtsx_chip *chip) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, - chip->sd_reset_counter, chip->card2lun[SD_CARD]); - - if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(SD_NR, &chip->need_reset); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_sd_card(chip); - if (chip->need_release & SD_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(SD_NR, &chip->need_reset); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - chip->card_ready |= SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; - } else { - if (chip->sd_io || chip->sd_reset_counter >= MAX_RESET_CNT) { - clear_bit(SD_NR, &chip->need_reset); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - } else { - chip->sd_reset_counter++; - } - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->rw_card[chip->card2lun[SD_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, SD_CARD); - if (chip->sd_io) { - chip->sd_int = 0; - try_to_switch_sdio_ctrl(chip); - } else { - disable_card_clock(chip, SD_CARD); - } - } -} - -void do_reset_xd_card(struct rtsx_chip *chip) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, - chip->xd_reset_counter, chip->card2lun[XD_CARD]); - - if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(XD_NR, &chip->need_reset); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_xd_card(chip); - if (chip->need_release & XD_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(XD_NR, &chip->need_reset); - chip->xd_reset_counter = 0; - chip->card_ready |= XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; - } else { - if (chip->xd_reset_counter >= MAX_RESET_CNT) { - clear_bit(XD_NR, &chip->need_reset); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - } else { - chip->xd_reset_counter++; - } - chip->card_ready &= ~XD_CARD; - chip->card_fail |= XD_CARD; - chip->capacity[chip->card2lun[XD_CARD]] = 0; - chip->rw_card[chip->card2lun[XD_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, XD_CARD); - disable_card_clock(chip, XD_CARD); - } -} - -void do_reset_ms_card(struct rtsx_chip *chip) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, - chip->ms_reset_counter, chip->card2lun[MS_CARD]); - - if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(MS_NR, &chip->need_reset); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_ms_card(chip); - if (chip->need_release & MS_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(MS_NR, &chip->need_reset); - chip->ms_reset_counter = 0; - chip->card_ready |= MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; - } else { - if (chip->ms_reset_counter >= MAX_RESET_CNT) { - clear_bit(MS_NR, &chip->need_reset); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - } else { - chip->ms_reset_counter++; - } - chip->card_ready &= ~MS_CARD; - chip->card_fail |= MS_CARD; - chip->capacity[chip->card2lun[MS_CARD]] = 0; - chip->rw_card[chip->card2lun[MS_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, MS_CARD); - disable_card_clock(chip, MS_CARD); - } -} - -static void release_sdio(struct rtsx_chip *chip) -{ - if (chip->sd_io) { - rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - - if (chip->chip_insert_with_sdio) { - chip->chip_insert_with_sdio = 0; - - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, 0xFE5A, 0x08, 0x00); - else - rtsx_write_register(chip, 0xFE70, 0x80, 0x00); - } - - rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0); - chip->sd_io = 0; - } -} - -void rtsx_power_off_card(struct rtsx_chip *chip) -{ - if ((chip->card_ready & SD_CARD) || chip->sd_io) { - sd_cleanup_work(chip); - sd_power_off_card3v3(chip); - } - - if (chip->card_ready & XD_CARD) { - xd_cleanup_work(chip); - xd_power_off_card3v3(chip); - } - - if (chip->card_ready & MS_CARD) { - ms_cleanup_work(chip); - ms_power_off_card3v3(chip); - } -} - -void rtsx_release_cards(struct rtsx_chip *chip) -{ - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if ((chip->card_ready & SD_CARD) || chip->sd_io) { - if (chip->int_reg & SD_EXIST) - sd_cleanup_work(chip); - release_sd_card(chip); - } - - if (chip->card_ready & XD_CARD) { - if (chip->int_reg & XD_EXIST) - xd_cleanup_work(chip); - release_xd_card(chip); - } - - if (chip->card_ready & MS_CARD) { - if (chip->int_reg & MS_EXIST) - ms_cleanup_work(chip); - release_ms_card(chip); - } -} - -void rtsx_reset_cards(struct rtsx_chip *chip) -{ - if (!chip->need_reset) - return; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - - rtsx_disable_aspm(chip); - - if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio) - clear_bit(SD_NR, &chip->need_reset); - - if (chip->need_reset & XD_CARD) { - chip->card_exist |= XD_CARD; - - if (chip->xd_show_cnt >= MAX_SHOW_CNT) - do_reset_xd_card(chip); - else - chip->xd_show_cnt++; - } - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { - if (chip->card_exist & XD_CARD) { - clear_bit(SD_NR, &chip->need_reset); - clear_bit(MS_NR, &chip->need_reset); - } - } - if (chip->need_reset & SD_CARD) { - chip->card_exist |= SD_CARD; - - if (chip->sd_show_cnt >= MAX_SHOW_CNT) { - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - do_reset_sd_card(chip); - } else { - chip->sd_show_cnt++; - } - } - if (chip->need_reset & MS_CARD) { - chip->card_exist |= MS_CARD; - - if (chip->ms_show_cnt >= MAX_SHOW_CNT) - do_reset_ms_card(chip); - else - chip->ms_show_cnt++; - } -} - -void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip) -{ - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - - if (reset_chip) - rtsx_reset_chip(chip); - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) { - release_sdio(chip); - release_sd_card(chip); - - wait_timeout(100); - - chip->card_exist |= SD_CARD; - do_reset_sd_card(chip); - } - - if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) { - release_xd_card(chip); - - wait_timeout(100); - - chip->card_exist |= XD_CARD; - do_reset_xd_card(chip); - } - - if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) { - release_ms_card(chip); - - wait_timeout(100); - - chip->card_exist |= MS_CARD; - do_reset_ms_card(chip); - } - - chip->need_reinit = 0; -} - -#ifdef DISABLE_CARD_INT -void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, - unsigned long *need_release) -{ - u8 release_map = 0, reset_map = 0; - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->card_exist) { - if (chip->card_exist & XD_CARD) { - if (!(chip->int_reg & XD_EXIST)) - release_map |= XD_CARD; - } else if (chip->card_exist & SD_CARD) { - if (!(chip->int_reg & SD_EXIST)) - release_map |= SD_CARD; - } else if (chip->card_exist & MS_CARD) { - if (!(chip->int_reg & MS_EXIST)) - release_map |= MS_CARD; - } - } else { - if (chip->int_reg & XD_EXIST) - reset_map |= XD_CARD; - else if (chip->int_reg & SD_EXIST) - reset_map |= SD_CARD; - else if (chip->int_reg & MS_EXIST) - reset_map |= MS_CARD; - } - - if (reset_map) { - int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; - int i; - - for (i = 0; i < (DEBOUNCE_CNT); i++) { - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->int_reg & XD_EXIST) - xd_cnt++; - else - xd_cnt = 0; - - if (chip->int_reg & SD_EXIST) - sd_cnt++; - else - sd_cnt = 0; - - if (chip->int_reg & MS_EXIST) - ms_cnt++; - else - ms_cnt = 0; - - wait_timeout(30); - } - - reset_map = 0; - if (!(chip->card_exist & XD_CARD) && - (xd_cnt > (DEBOUNCE_CNT - 1))) - reset_map |= XD_CARD; - if (!(chip->card_exist & SD_CARD) && - (sd_cnt > (DEBOUNCE_CNT - 1))) - reset_map |= SD_CARD; - if (!(chip->card_exist & MS_CARD) && - (ms_cnt > (DEBOUNCE_CNT - 1))) - reset_map |= MS_CARD; - } - - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00); - - if (need_reset) - *need_reset = reset_map; - if (need_release) - *need_release = release_map; -} -#endif - -void rtsx_init_cards(struct rtsx_chip *chip) -{ - if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { - dev_dbg(rtsx_dev(chip), "Reset chip in polling thread!\n"); - rtsx_reset_chip(chip); - RTSX_CLR_DELINK(chip); - } - -#ifdef DISABLE_CARD_INT - card_cd_debounce(chip, &chip->need_reset, &chip->need_release); -#endif - - if (chip->need_release) { - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { - if (chip->int_reg & XD_EXIST) { - clear_bit(SD_NR, &chip->need_release); - clear_bit(MS_NR, &chip->need_release); - } - } - - if (!(chip->card_exist & SD_CARD) && !chip->sd_io) - clear_bit(SD_NR, &chip->need_release); - if (!(chip->card_exist & XD_CARD)) - clear_bit(XD_NR, &chip->need_release); - if (!(chip->card_exist & MS_CARD)) - clear_bit(MS_NR, &chip->need_release); - - dev_dbg(rtsx_dev(chip), "chip->need_release = 0x%x\n", - (unsigned int)(chip->need_release)); - -#ifdef SUPPORT_OCP - if (chip->need_release) { - if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER)) - rtsx_write_register(chip, OCPCLR, - CARD_OC_INT_CLR | - CARD_OC_CLR, - CARD_OC_INT_CLR | - CARD_OC_CLR); - chip->ocp_stat = 0; - } -#endif - if (chip->need_release) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - } - - if (chip->need_release & SD_CARD) { - clear_bit(SD_NR, &chip->need_release); - chip->card_exist &= ~SD_CARD; - chip->card_ejected &= ~SD_CARD; - chip->card_fail &= ~SD_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]); - chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - - release_sdio(chip); - release_sd_card(chip); - } - - if (chip->need_release & XD_CARD) { - clear_bit(XD_NR, &chip->need_release); - chip->card_exist &= ~XD_CARD; - chip->card_ejected &= ~XD_CARD; - chip->card_fail &= ~XD_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]); - chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; - - release_xd_card(chip); - - if (CHECK_PID(chip, 0x5288) && - CHECK_BARO_PKG(chip, QFN)) - rtsx_write_register(chip, HOST_SLEEP_STATE, - 0xC0, 0xC0); - } - - if (chip->need_release & MS_CARD) { - clear_bit(MS_NR, &chip->need_release); - chip->card_exist &= ~MS_CARD; - chip->card_ejected &= ~MS_CARD; - chip->card_fail &= ~MS_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]); - chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; - - release_ms_card(chip); - } - - dev_dbg(rtsx_dev(chip), "chip->card_exist = 0x%x\n", - chip->card_exist); - - if (!chip->card_exist) - turn_off_led(chip, LED_GPIO); - } - - if (chip->need_reset) { - dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x\n", - (unsigned int)(chip->need_reset)); - - rtsx_reset_cards(chip); - } - - if (chip->need_reinit) { - dev_dbg(rtsx_dev(chip), "chip->need_reinit = 0x%x\n", - (unsigned int)(chip->need_reinit)); - - rtsx_reinit_cards(chip, 0); - } -} - -int switch_ssc_clock(struct rtsx_chip *chip, int clk) -{ - int retval; - u8 n = (u8)(clk - 2), min_n, max_n; - u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; - int sd_vpclk_phase_reset = 0; - - if (chip->cur_clk == clk) - return STATUS_SUCCESS; - - min_n = 60; - max_n = 120; - max_div = CLK_DIV_4; - - dev_dbg(rtsx_dev(chip), "Switch SSC clock to %dMHz (cur_clk = %d)\n", - clk, chip->cur_clk); - - if (clk <= 2 || n > max_n) - return STATUS_FAIL; - - mcu_cnt = (u8)(125 / clk + 3); - if (mcu_cnt > 7) - mcu_cnt = 7; - - div = CLK_DIV_1; - while ((n < min_n) && (div < max_div)) { - n = (n + 2) * 2 - 2; - div++; - } - dev_dbg(rtsx_dev(chip), "n = %d, div = %d\n", n, div); - - if (chip->ssc_en) { - ssc_depth = 0x01; - n -= 2; - } else { - ssc_depth = 0; - } - - ssc_depth_mask = 0x03; - - dev_dbg(rtsx_dev(chip), "ssc_depth = %d\n", ssc_depth); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); - rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); - if (sd_vpclk_phase_reset) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - } - - retval = rtsx_send_cmd(chip, 0, WAIT_TIME); - if (retval < 0) - return STATUS_ERROR; - - udelay(10); - retval = rtsx_write_register(chip, CLK_CTL, CLK_LOW_FREQ, 0); - if (retval) - return retval; - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -int switch_normal_clock(struct rtsx_chip *chip, int clk) -{ - int retval; - u8 sel, div, mcu_cnt; - int sd_vpclk_phase_reset = 0; - - if (chip->cur_clk == clk) - return STATUS_SUCCESS; - - switch (clk) { - case CLK_20: - dev_dbg(rtsx_dev(chip), "Switch clock to 20MHz\n"); - sel = SSC_80; - div = CLK_DIV_4; - mcu_cnt = 7; - break; - - case CLK_30: - dev_dbg(rtsx_dev(chip), "Switch clock to 30MHz\n"); - sel = SSC_120; - div = CLK_DIV_4; - mcu_cnt = 7; - break; - - case CLK_40: - dev_dbg(rtsx_dev(chip), "Switch clock to 40MHz\n"); - sel = SSC_80; - div = CLK_DIV_2; - mcu_cnt = 7; - break; - - case CLK_50: - dev_dbg(rtsx_dev(chip), "Switch clock to 50MHz\n"); - sel = SSC_100; - div = CLK_DIV_2; - mcu_cnt = 6; - break; - - case CLK_60: - dev_dbg(rtsx_dev(chip), "Switch clock to 60MHz\n"); - sel = SSC_120; - div = CLK_DIV_2; - mcu_cnt = 6; - break; - - case CLK_80: - dev_dbg(rtsx_dev(chip), "Switch clock to 80MHz\n"); - sel = SSC_80; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_100: - dev_dbg(rtsx_dev(chip), "Switch clock to 100MHz\n"); - sel = SSC_100; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_120: - dev_dbg(rtsx_dev(chip), "Switch clock to 120MHz\n"); - sel = SSC_120; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_150: - dev_dbg(rtsx_dev(chip), "Switch clock to 150MHz\n"); - sel = SSC_150; - div = CLK_DIV_1; - mcu_cnt = 4; - break; - - case CLK_200: - dev_dbg(rtsx_dev(chip), "Switch clock to 200MHz\n"); - sel = SSC_200; - div = CLK_DIV_1; - mcu_cnt = 4; - break; - - default: - dev_dbg(rtsx_dev(chip), "Try to switch to an illegal clock (%d)\n", - clk); - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ); - if (retval) - return retval; - if (sd_vpclk_phase_reset) { - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK1_CTL, - PHASE_NOT_RESET, 0); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, CLK_DIV, 0xFF, - (div << 4) | mcu_cnt); - if (retval) - return retval; - retval = rtsx_write_register(chip, CLK_SEL, 0xFF, sel); - if (retval) - return retval; - - if (sd_vpclk_phase_reset) { - udelay(200); - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK1_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - if (retval) - return retval; - udelay(200); - } - retval = rtsx_write_register(chip, CLK_CTL, 0xFF, 0); - if (retval) - return retval; - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, - u32 byte_cnt, u8 pack_size) -{ - if (pack_size > DMA_1024) - pack_size = DMA_512; - - rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT); - - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt); - - if (dir == DMA_FROM_DEVICE) { - rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, - 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_FROM_CARD | DMA_EN | pack_size); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, - 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_TO_CARD | DMA_EN | pack_size); - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); -} - -int enable_card_clock(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, clk_en); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int disable_card_clock(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int card_power_on(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 mask, val1, val2; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && card == MS_CARD) { - mask = MS_POWER_MASK; - val1 = MS_PARTIAL_POWER_ON; - val2 = MS_POWER_ON; - } else { - mask = SD_POWER_MASK; - val1 = SD_PARTIAL_POWER_ON; - val2 = SD_POWER_ON; - } - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - udelay(chip->pmos_pwr_on_interval); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int card_power_off(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 mask, val; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && card == MS_CARD) { - mask = MS_POWER_MASK; - val = MS_POWER_OFF; - } else { - mask = SD_POWER_MASK; - val = SD_POWER_OFF; - } - - retval = rtsx_write_register(chip, CARD_PWR_CTL, mask, val); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 sec_addr, u16 sec_cnt) -{ - int retval; - unsigned int lun = SCSI_LUN(srb); - int i; - - if (!chip->rw_card[lun]) - return STATUS_FAIL; - - for (i = 0; i < 3; i++) { - chip->rw_need_retry = 0; - - retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); - if (retval != STATUS_SUCCESS) { - if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { - rtsx_release_chip(chip); - return STATUS_FAIL; - } - if (detect_card_cd(chip, chip->cur_card) != - STATUS_SUCCESS) { - return STATUS_FAIL; - } - - if (!chip->rw_need_retry) { - dev_dbg(rtsx_dev(chip), "RW fail, but no need to retry\n"); - break; - } - } else { - chip->rw_need_retry = 0; - break; - } - - dev_dbg(rtsx_dev(chip), "Retry RW, (i = %d)\n", i); - } - - return retval; -} - -int card_share_mode(struct rtsx_chip *chip, int card) -{ - int retval; - u8 mask, value; - - if (CHECK_PID(chip, 0x5208)) { - mask = CARD_SHARE_MASK; - if (card == SD_CARD) - value = CARD_SHARE_48_SD; - else if (card == MS_CARD) - value = CARD_SHARE_48_MS; - else if (card == XD_CARD) - value = CARD_SHARE_48_XD; - else - return STATUS_FAIL; - - } else if (CHECK_PID(chip, 0x5288)) { - mask = 0x03; - if (card == SD_CARD) - value = CARD_SHARE_BAROSSA_SD; - else if (card == MS_CARD) - value = CARD_SHARE_BAROSSA_MS; - else if (card == XD_CARD) - value = CARD_SHARE_BAROSSA_XD; - else - return STATUS_FAIL; - - } else { - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, CARD_SHARE_MODE, mask, value); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int select_card(struct rtsx_chip *chip, int card) -{ - int retval; - - if (chip->cur_card != card) { - u8 mod; - - if (card == SD_CARD) - mod = SD_MOD_SEL; - else if (card == MS_CARD) - mod = MS_MOD_SEL; - else if (card == XD_CARD) - mod = XD_MOD_SEL; - else if (card == SPI_CARD) - mod = SPI_MOD_SEL; - else - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_SELECT, 0x07, mod); - if (retval) - return retval; - chip->cur_card = card; - - retval = card_share_mode(chip, card); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -void toggle_gpio(struct rtsx_chip *chip, u8 gpio) -{ - u8 temp_reg; - - rtsx_read_register(chip, CARD_GPIO, &temp_reg); - temp_reg ^= (0x01 << gpio); - rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg); -} - -void turn_on_led(struct rtsx_chip *chip, u8 gpio) -{ - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), - (u8)(1 << gpio)); - else - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); -} - -void turn_off_led(struct rtsx_chip *chip, u8 gpio) -{ - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); - else - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), - (u8)(1 << gpio)); -} - -int detect_card_cd(struct rtsx_chip *chip, int card) -{ - u32 card_cd, status; - - if (card == SD_CARD) { - card_cd = SD_EXIST; - } else if (card == MS_CARD) { - card_cd = MS_EXIST; - } else if (card == XD_CARD) { - card_cd = XD_EXIST; - } else { - dev_dbg(rtsx_dev(chip), "Wrong card type: 0x%x\n", card); - return STATUS_FAIL; - } - - status = rtsx_readl(chip, RTSX_BIPR); - if (!(status & card_cd)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int check_card_exist(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_exist & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_ready(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_ready & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_wp(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_wp & chip->lun2card[lun]) - return 1; - - return 0; -} - -u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) -{ - if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) - return (u8)XD_CARD; - else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) - return (u8)SD_CARD; - else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) - return (u8)MS_CARD; - - return 0; -} - -void eject_card(struct rtsx_chip *chip, unsigned int lun) -{ - do_remaining_work(chip); - - if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { - release_sd_card(chip); - chip->card_ejected |= SD_CARD; - chip->card_ready &= ~SD_CARD; - chip->capacity[lun] = 0; - } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { - release_xd_card(chip); - chip->card_ejected |= XD_CARD; - chip->card_ready &= ~XD_CARD; - chip->capacity[lun] = 0; - } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { - release_ms_card(chip); - chip->card_ejected |= MS_CARD; - chip->card_ready &= ~MS_CARD; - chip->capacity[lun] = 0; - } -} diff --git a/drivers/staging/rts5208/rtsx_card.h b/drivers/staging/rts5208/rtsx_card.h deleted file mode 100644 index 39727371cd7adf4d8856760e6bf8cfc12dc34621..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_card.h +++ /dev/null @@ -1,1087 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_CARD_H -#define __REALTEK_RTSX_CARD_H - -#include "rtsx.h" -#include "rtsx_chip.h" -#include "rtsx_transport.h" -#include "sd.h" - -#define SSC_POWER_DOWN 0x01 -#define SD_OC_POWER_DOWN 0x02 -#define MS_OC_POWER_DOWN 0x04 -#define ALL_POWER_DOWN 0x07 -#define OC_POWER_DOWN 0x06 - -#define PMOS_STRG_MASK 0x10 -#define PMOS_STRG_800mA 0x10 -#define PMOS_STRG_400mA 0x00 - -#define POWER_OFF 0x03 -#define PARTIAL_POWER_ON 0x01 -#define POWER_ON 0x00 - -#define MS_POWER_OFF 0x0C -#define MS_PARTIAL_POWER_ON 0x04 -#define MS_POWER_ON 0x00 -#define MS_POWER_MASK 0x0C - -#define SD_POWER_OFF 0x03 -#define SD_PARTIAL_POWER_ON 0x01 -#define SD_POWER_ON 0x00 -#define SD_POWER_MASK 0x03 - -#define XD_OUTPUT_EN 0x02 -#define SD_OUTPUT_EN 0x04 -#define MS_OUTPUT_EN 0x08 -#define SPI_OUTPUT_EN 0x10 - -#define CLK_LOW_FREQ 0x01 - -#define CLK_DIV_1 0x01 -#define CLK_DIV_2 0x02 -#define CLK_DIV_4 0x03 -#define CLK_DIV_8 0x04 - -#define SSC_80 0 -#define SSC_100 1 -#define SSC_120 2 -#define SSC_150 3 -#define SSC_200 4 - -#define XD_CLK_EN 0x02 -#define SD_CLK_EN 0x04 -#define MS_CLK_EN 0x08 -#define SPI_CLK_EN 0x10 - -#define XD_MOD_SEL 1 -#define SD_MOD_SEL 2 -#define MS_MOD_SEL 3 -#define SPI_MOD_SEL 4 - -#define CHANGE_CLK 0x01 - -#define SD_CRC7_ERR 0x80 -#define SD_CRC16_ERR 0x40 -#define SD_CRC_WRITE_ERR 0x20 -#define SD_CRC_WRITE_ERR_MASK 0x1C -#define GET_CRC_TIME_OUT 0x02 -#define SD_TUNING_COMPARE_ERR 0x01 - -#define SD_RSP_80CLK_TIMEOUT 0x01 - -#define SD_CLK_TOGGLE_EN 0x80 -#define SD_CLK_FORCE_STOP 0x40 -#define SD_DAT3_STATUS 0x10 -#define SD_DAT2_STATUS 0x08 -#define SD_DAT1_STATUS 0x04 -#define SD_DAT0_STATUS 0x02 -#define SD_CMD_STATUS 0x01 - -#define SD_IO_USING_1V8 0x80 -#define SD_IO_USING_3V3 0x7F -#define TYPE_A_DRIVING 0x00 -#define TYPE_B_DRIVING 0x01 -#define TYPE_C_DRIVING 0x02 -#define TYPE_D_DRIVING 0x03 - -#define DDR_FIX_RX_DAT 0x00 -#define DDR_VAR_RX_DAT 0x80 -#define DDR_FIX_RX_DAT_EDGE 0x00 -#define DDR_FIX_RX_DAT_14_DELAY 0x40 -#define DDR_FIX_RX_CMD 0x00 -#define DDR_VAR_RX_CMD 0x20 -#define DDR_FIX_RX_CMD_POS_EDGE 0x00 -#define DDR_FIX_RX_CMD_14_DELAY 0x10 -#define SD20_RX_POS_EDGE 0x00 -#define SD20_RX_14_DELAY 0x08 -#define SD20_RX_SEL_MASK 0x08 - -#define DDR_FIX_TX_CMD_DAT 0x00 -#define DDR_VAR_TX_CMD_DAT 0x80 -#define DDR_FIX_TX_DAT_14_TSU 0x00 -#define DDR_FIX_TX_DAT_12_TSU 0x40 -#define DDR_FIX_TX_CMD_NEG_EDGE 0x00 -#define DDR_FIX_TX_CMD_14_AHEAD 0x20 -#define SD20_TX_NEG_EDGE 0x00 -#define SD20_TX_14_AHEAD 0x10 -#define SD20_TX_SEL_MASK 0x10 -#define DDR_VAR_SDCLK_POL_SWAP 0x01 - -#define SD_TRANSFER_START 0x80 -#define SD_TRANSFER_END 0x40 -#define SD_STAT_IDLE 0x20 -#define SD_TRANSFER_ERR 0x10 -#define SD_TM_NORMAL_WRITE 0x00 -#define SD_TM_AUTO_WRITE_3 0x01 -#define SD_TM_AUTO_WRITE_4 0x02 -#define SD_TM_AUTO_READ_3 0x05 -#define SD_TM_AUTO_READ_4 0x06 -#define SD_TM_CMD_RSP 0x08 -#define SD_TM_AUTO_WRITE_1 0x09 -#define SD_TM_AUTO_WRITE_2 0x0A -#define SD_TM_NORMAL_READ 0x0C -#define SD_TM_AUTO_READ_1 0x0D -#define SD_TM_AUTO_READ_2 0x0E -#define SD_TM_AUTO_TUNING 0x0F - -#define PHASE_CHANGE 0x80 -#define PHASE_NOT_RESET 0x40 - -#define DCMPS_CHANGE 0x80 -#define DCMPS_CHANGE_DONE 0x40 -#define DCMPS_ERROR 0x20 -#define DCMPS_CURRENT_PHASE 0x1F - -#define SD_CLK_DIVIDE_0 0x00 -#define SD_CLK_DIVIDE_256 0xC0 -#define SD_CLK_DIVIDE_128 0x80 -#define SD_BUS_WIDTH_1 0x00 -#define SD_BUS_WIDTH_4 0x01 -#define SD_BUS_WIDTH_8 0x02 -#define SD_ASYNC_FIFO_NOT_RST 0x10 -#define SD_20_MODE 0x00 -#define SD_DDR_MODE 0x04 -#define SD_30_MODE 0x08 - -#define SD_CLK_DIVIDE_MASK 0xC0 - -#define SD_CMD_IDLE 0x80 - -#define SD_DATA_IDLE 0x80 - -#define DCM_RESET 0x08 -#define DCM_LOCKED 0x04 -#define DCM_208M 0x00 -#define DCM_TX 0x01 -#define DCM_RX 0x02 - -#define DRP_START 0x80 -#define DRP_DONE 0x40 - -#define DRP_WRITE 0x80 -#define DRP_READ 0x00 -#define DCM_WRITE_ADDRESS_50 0x50 -#define DCM_WRITE_ADDRESS_51 0x51 -#define DCM_READ_ADDRESS_00 0x00 -#define DCM_READ_ADDRESS_51 0x51 - -#define SD_CALCULATE_CRC7 0x00 -#define SD_NO_CALCULATE_CRC7 0x80 -#define SD_CHECK_CRC16 0x00 -#define SD_NO_CHECK_CRC16 0x40 -#define SD_NO_CHECK_WAIT_CRC_TO 0x20 -#define SD_WAIT_BUSY_END 0x08 -#define SD_NO_WAIT_BUSY_END 0x00 -#define SD_CHECK_CRC7 0x00 -#define SD_NO_CHECK_CRC7 0x04 -#define SD_RSP_LEN_0 0x00 -#define SD_RSP_LEN_6 0x01 -#define SD_RSP_LEN_17 0x02 -#define SD_RSP_TYPE_R0 0x04 -#define SD_RSP_TYPE_R1 0x01 -#define SD_RSP_TYPE_R1b 0x09 -#define SD_RSP_TYPE_R2 0x02 -#define SD_RSP_TYPE_R3 0x05 -#define SD_RSP_TYPE_R4 0x05 -#define SD_RSP_TYPE_R5 0x01 -#define SD_RSP_TYPE_R6 0x01 -#define SD_RSP_TYPE_R7 0x01 - -#define SD_RSP_80CLK_TIMEOUT_EN 0x01 - -#define SAMPLE_TIME_RISING 0x00 -#define SAMPLE_TIME_FALLING 0x80 -#define PUSH_TIME_DEFAULT 0x00 -#define PUSH_TIME_ODD 0x40 -#define NO_EXTEND_TOGGLE 0x00 -#define EXTEND_TOGGLE_CHK 0x20 -#define MS_BUS_WIDTH_1 0x00 -#define MS_BUS_WIDTH_4 0x10 -#define MS_BUS_WIDTH_8 0x18 -#define MS_2K_SECTOR_MODE 0x04 -#define MS_512_SECTOR_MODE 0x00 -#define MS_TOGGLE_TIMEOUT_EN 0x00 -#define MS_TOGGLE_TIMEOUT_DISEN 0x01 -#define MS_NO_CHECK_INT 0x02 - -#define WAIT_INT 0x80 -#define NO_WAIT_INT 0x00 -#define NO_AUTO_READ_INT_REG 0x00 -#define AUTO_READ_INT_REG 0x40 -#define MS_CRC16_ERR 0x20 -#define MS_RDY_TIMEOUT 0x10 -#define MS_INT_CMDNK 0x08 -#define MS_INT_BREQ 0x04 -#define MS_INT_ERR 0x02 -#define MS_INT_CED 0x01 - -#define MS_TRANSFER_START 0x80 -#define MS_TRANSFER_END 0x40 -#define MS_TRANSFER_ERR 0x20 -#define MS_BS_STATE 0x10 -#define MS_TM_READ_BYTES 0x00 -#define MS_TM_NORMAL_READ 0x01 -#define MS_TM_WRITE_BYTES 0x04 -#define MS_TM_NORMAL_WRITE 0x05 -#define MS_TM_AUTO_READ 0x08 -#define MS_TM_AUTO_WRITE 0x0C - -#define CARD_SHARE_MASK 0x0F -#define CARD_SHARE_MULTI_LUN 0x00 -#define CARD_SHARE_NORMAL 0x00 -#define CARD_SHARE_48_XD 0x02 -#define CARD_SHARE_48_SD 0x04 -#define CARD_SHARE_48_MS 0x08 -#define CARD_SHARE_BAROSSA_XD 0x00 -#define CARD_SHARE_BAROSSA_SD 0x01 -#define CARD_SHARE_BAROSSA_MS 0x02 - -#define MS_DRIVE_8 0x00 -#define MS_DRIVE_4 0x40 -#define MS_DRIVE_12 0x80 -#define SD_DRIVE_8 0x00 -#define SD_DRIVE_4 0x10 -#define SD_DRIVE_12 0x20 -#define XD_DRIVE_8 0x00 -#define XD_DRIVE_4 0x04 -#define XD_DRIVE_12 0x08 - -#define SPI_STOP 0x01 -#define XD_STOP 0x02 -#define SD_STOP 0x04 -#define MS_STOP 0x08 -#define SPI_CLR_ERR 0x10 -#define XD_CLR_ERR 0x20 -#define SD_CLR_ERR 0x40 -#define MS_CLR_ERR 0x80 - -#define CRC_FIX_CLK (0x00 << 0) -#define CRC_VAR_CLK0 (0x01 << 0) -#define CRC_VAR_CLK1 (0x02 << 0) -#define SD30_FIX_CLK (0x00 << 2) -#define SD30_VAR_CLK0 (0x01 << 2) -#define SD30_VAR_CLK1 (0x02 << 2) -#define SAMPLE_FIX_CLK (0x00 << 4) -#define SAMPLE_VAR_CLK0 (0x01 << 4) -#define SAMPLE_VAR_CLK1 (0x02 << 4) - -#define SDIO_VER_20 0x80 -#define SDIO_VER_10 0x00 -#define SDIO_VER_CHG 0x40 -#define SDIO_BUS_AUTO_SWITCH 0x10 - -#define PINGPONG_BUFFER 0x01 -#define RING_BUFFER 0x00 - -#define RB_FLUSH 0x80 - -#define DMA_DONE_INT_EN 0x80 -#define SUSPEND_INT_EN 0x40 -#define LINK_RDY_INT_EN 0x20 -#define LINK_DOWN_INT_EN 0x10 - -#define DMA_DONE_INT 0x80 -#define SUSPEND_INT 0x40 -#define LINK_RDY_INT 0x20 -#define LINK_DOWN_INT 0x10 - -#define MRD_ERR_INT_EN 0x40 -#define MWR_ERR_INT_EN 0x20 -#define SCSI_CMD_INT_EN 0x10 -#define TLP_RCV_INT_EN 0x08 -#define TLP_TRSMT_INT_EN 0x04 -#define MRD_COMPLETE_INT_EN 0x02 -#define MWR_COMPLETE_INT_EN 0x01 - -#define MRD_ERR_INT 0x40 -#define MWR_ERR_INT 0x20 -#define SCSI_CMD_INT 0x10 -#define TLP_RX_INT 0x08 -#define TLP_TX_INT 0x04 -#define MRD_COMPLETE_INT 0x02 -#define MWR_COMPLETE_INT 0x01 - -#define MSG_RX_INT_EN 0x08 -#define MRD_RX_INT_EN 0x04 -#define MWR_RX_INT_EN 0x02 -#define CPLD_RX_INT_EN 0x01 - -#define MSG_RX_INT 0x08 -#define MRD_RX_INT 0x04 -#define MWR_RX_INT 0x02 -#define CPLD_RX_INT 0x01 - -#define MSG_TX_INT_EN 0x08 -#define MRD_TX_INT_EN 0x04 -#define MWR_TX_INT_EN 0x02 -#define CPLD_TX_INT_EN 0x01 - -#define MSG_TX_INT 0x08 -#define MRD_TX_INT 0x04 -#define MWR_TX_INT 0x02 -#define CPLD_TX_INT 0x01 - -#define DMA_RST 0x80 -#define DMA_BUSY 0x04 -#define DMA_DIR_TO_CARD 0x00 -#define DMA_DIR_FROM_CARD 0x02 -#define DMA_EN 0x01 -#define DMA_128 (0 << 4) -#define DMA_256 (1 << 4) -#define DMA_512 (2 << 4) -#define DMA_1024 (3 << 4) -#define DMA_PACK_SIZE_MASK 0x30 - -#define XD_PWR_OFF_DELAY0 0x00 -#define XD_PWR_OFF_DELAY1 0x02 -#define XD_PWR_OFF_DELAY2 0x04 -#define XD_PWR_OFF_DELAY3 0x06 -#define XD_AUTO_PWR_OFF_EN 0xF7 -#define XD_NO_AUTO_PWR_OFF 0x08 - -#define XD_TIME_RWN_1 0x00 -#define XD_TIME_RWN_STEP 0x20 -#define XD_TIME_RW_1 0x00 -#define XD_TIME_RW_STEP 0x04 -#define XD_TIME_SETUP_1 0x00 -#define XD_TIME_SETUP_STEP 0x01 - -#define XD_ECC2_UNCORRECTABLE 0x80 -#define XD_ECC2_ERROR 0x40 -#define XD_ECC1_UNCORRECTABLE 0x20 -#define XD_ECC1_ERROR 0x10 -#define XD_RDY 0x04 -#define XD_CE_EN 0xFD -#define XD_CE_DISEN 0x02 -#define XD_WP_EN 0xFE -#define XD_WP_DISEN 0x01 - -#define XD_TRANSFER_START 0x80 -#define XD_TRANSFER_END 0x40 -#define XD_PPB_EMPTY 0x20 -#define XD_RESET 0x00 -#define XD_ERASE 0x01 -#define XD_READ_STATUS 0x02 -#define XD_READ_ID 0x03 -#define XD_READ_REDUNDANT 0x04 -#define XD_READ_PAGES 0x05 -#define XD_SET_CMD 0x06 -#define XD_NORMAL_READ 0x07 -#define XD_WRITE_PAGES 0x08 -#define XD_NORMAL_WRITE 0x09 -#define XD_WRITE_REDUNDANT 0x0A -#define XD_SET_ADDR 0x0B - -#define XD_PPB_TO_SIE 0x80 -#define XD_TO_PPB_ONLY 0x00 -#define XD_BA_TRANSFORM 0x40 -#define XD_BA_NO_TRANSFORM 0x00 -#define XD_NO_CALC_ECC 0x20 -#define XD_CALC_ECC 0x00 -#define XD_IGNORE_ECC 0x10 -#define XD_CHECK_ECC 0x00 -#define XD_DIRECT_TO_RB 0x08 -#define XD_ADDR_LENGTH_0 0x00 -#define XD_ADDR_LENGTH_1 0x01 -#define XD_ADDR_LENGTH_2 0x02 -#define XD_ADDR_LENGTH_3 0x03 -#define XD_ADDR_LENGTH_4 0x04 - -#define XD_GPG 0xFF -#define XD_BPG 0x00 - -#define XD_GBLK 0xFF -#define XD_LATER_BBLK 0xF0 - -#define XD_ECC2_ALL1 0x80 -#define XD_ECC1_ALL1 0x40 -#define XD_BA2_ALL0 0x20 -#define XD_BA1_ALL0 0x10 -#define XD_BA1_BA2_EQL 0x04 -#define XD_BA2_VALID 0x02 -#define XD_BA1_VALID 0x01 - -#define XD_PGSTS_ZEROBIT_OVER4 0x00 -#define XD_PGSTS_NOT_FF 0x02 -#define XD_AUTO_CHK_DATA_STATUS 0x01 - -#define RSTB_MODE_DETECT 0x80 -#define MODE_OUT_VLD 0x40 -#define MODE_OUT_0_NONE 0x00 -#define MODE_OUT_10_NONE 0x04 -#define MODE_OUT_10_47 0x05 -#define MODE_OUT_10_180 0x06 -#define MODE_OUT_10_680 0x07 -#define MODE_OUT_16_NONE 0x08 -#define MODE_OUT_16_47 0x09 -#define MODE_OUT_16_180 0x0A -#define MODE_OUT_16_680 0x0B -#define MODE_OUT_NONE_NONE 0x0C -#define MODE_OUT_NONE_47 0x0D -#define MODE_OUT_NONE_180 0x0E -#define MODE_OUT_NONE_680 0x0F - -#define CARD_OC_INT_EN 0x20 -#define CARD_DETECT_EN 0x08 - -#define MS_DETECT_EN 0x80 -#define MS_OCP_INT_EN 0x40 -#define MS_OCP_INT_CLR 0x20 -#define MS_OC_CLR 0x10 -#define SD_DETECT_EN 0x08 -#define SD_OCP_INT_EN 0x04 -#define SD_OCP_INT_CLR 0x02 -#define SD_OC_CLR 0x01 - -#define CARD_OCP_DETECT 0x80 -#define CARD_OC_NOW 0x08 -#define CARD_OC_EVER 0x04 - -#define MS_OCP_DETECT 0x80 -#define MS_OC_NOW 0x40 -#define MS_OC_EVER 0x20 -#define SD_OCP_DETECT 0x08 -#define SD_OC_NOW 0x04 -#define SD_OC_EVER 0x02 - -#define CARD_OC_INT_CLR 0x08 -#define CARD_OC_CLR 0x02 - -#define SD_OCP_GLITCH_MASK 0x07 -#define SD_OCP_GLITCH_6_4 0x00 -#define SD_OCP_GLITCH_64 0x01 -#define SD_OCP_GLITCH_640 0x02 -#define SD_OCP_GLITCH_1000 0x03 -#define SD_OCP_GLITCH_2000 0x04 -#define SD_OCP_GLITCH_4000 0x05 -#define SD_OCP_GLITCH_8000 0x06 -#define SD_OCP_GLITCH_10000 0x07 - -#define MS_OCP_GLITCH_MASK 0x70 -#define MS_OCP_GLITCH_6_4 (0x00 << 4) -#define MS_OCP_GLITCH_64 (0x01 << 4) -#define MS_OCP_GLITCH_640 (0x02 << 4) -#define MS_OCP_GLITCH_1000 (0x03 << 4) -#define MS_OCP_GLITCH_2000 (0x04 << 4) -#define MS_OCP_GLITCH_4000 (0x05 << 4) -#define MS_OCP_GLITCH_8000 (0x06 << 4) -#define MS_OCP_GLITCH_10000 (0x07 << 4) - -#define OCP_TIME_60 0x00 -#define OCP_TIME_100 (0x01 << 3) -#define OCP_TIME_200 (0x02 << 3) -#define OCP_TIME_400 (0x03 << 3) -#define OCP_TIME_600 (0x04 << 3) -#define OCP_TIME_800 (0x05 << 3) -#define OCP_TIME_1100 (0x06 << 3) -#define OCP_TIME_MASK 0x38 - -#define MS_OCP_TIME_60 0x00 -#define MS_OCP_TIME_100 (0x01 << 4) -#define MS_OCP_TIME_200 (0x02 << 4) -#define MS_OCP_TIME_400 (0x03 << 4) -#define MS_OCP_TIME_600 (0x04 << 4) -#define MS_OCP_TIME_800 (0x05 << 4) -#define MS_OCP_TIME_1100 (0x06 << 4) -#define MS_OCP_TIME_MASK 0x70 - -#define SD_OCP_TIME_60 0x00 -#define SD_OCP_TIME_100 0x01 -#define SD_OCP_TIME_200 0x02 -#define SD_OCP_TIME_400 0x03 -#define SD_OCP_TIME_600 0x04 -#define SD_OCP_TIME_800 0x05 -#define SD_OCP_TIME_1100 0x06 -#define SD_OCP_TIME_MASK 0x07 - -#define OCP_THD_315_417 0x00 -#define OCP_THD_283_783 (0x01 << 6) -#define OCP_THD_244_946 (0x02 << 6) -#define OCP_THD_191_1080 (0x03 << 6) -#define OCP_THD_MASK 0xC0 - -#define MS_OCP_THD_450 0x00 -#define MS_OCP_THD_550 (0x01 << 4) -#define MS_OCP_THD_650 (0x02 << 4) -#define MS_OCP_THD_750 (0x03 << 4) -#define MS_OCP_THD_850 (0x04 << 4) -#define MS_OCP_THD_950 (0x05 << 4) -#define MS_OCP_THD_1050 (0x06 << 4) -#define MS_OCP_THD_1150 (0x07 << 4) -#define MS_OCP_THD_MASK 0x70 - -#define SD_OCP_THD_450 0x00 -#define SD_OCP_THD_550 0x01 -#define SD_OCP_THD_650 0x02 -#define SD_OCP_THD_750 0x03 -#define SD_OCP_THD_850 0x04 -#define SD_OCP_THD_950 0x05 -#define SD_OCP_THD_1050 0x06 -#define SD_OCP_THD_1150 0x07 -#define SD_OCP_THD_MASK 0x07 - -#define FPGA_MS_PULL_CTL_EN 0xEF -#define FPGA_SD_PULL_CTL_EN 0xF7 -#define FPGA_XD_PULL_CTL_EN1 0xFE -#define FPGA_XD_PULL_CTL_EN2 0xFD -#define FPGA_XD_PULL_CTL_EN3 0xFB - -#define FPGA_MS_PULL_CTL_BIT 0x10 -#define FPGA_SD_PULL_CTL_BIT 0x08 - -#define BLINK_EN 0x08 -#define LED_GPIO0 (0 << 4) -#define LED_GPIO1 (1 << 4) -#define LED_GPIO2 (2 << 4) - -#define SDIO_BUS_CTRL 0x01 -#define SDIO_CD_CTRL 0x02 - -#define SSC_RSTB 0x80 -#define SSC_8X_EN 0x40 -#define SSC_FIX_FRAC 0x20 -#define SSC_SEL_1M 0x00 -#define SSC_SEL_2M 0x08 -#define SSC_SEL_4M 0x10 -#define SSC_SEL_8M 0x18 - -#define SSC_DEPTH_MASK 0x07 -#define SSC_DEPTH_DISALBE 0x00 -#define SSC_DEPTH_4M 0x01 -#define SSC_DEPTH_2M 0x02 -#define SSC_DEPTH_1M 0x03 -#define SSC_DEPTH_512K 0x04 -#define SSC_DEPTH_256K 0x05 -#define SSC_DEPTH_128K 0x06 -#define SSC_DEPTH_64K 0x07 - -#define XD_D3_NP 0x00 -#define XD_D3_PD (0x01 << 6) -#define XD_D3_PU (0x02 << 6) -#define XD_D2_NP 0x00 -#define XD_D2_PD (0x01 << 4) -#define XD_D2_PU (0x02 << 4) -#define XD_D1_NP 0x00 -#define XD_D1_PD (0x01 << 2) -#define XD_D1_PU (0x02 << 2) -#define XD_D0_NP 0x00 -#define XD_D0_PD 0x01 -#define XD_D0_PU 0x02 - -#define SD_D7_NP 0x00 -#define SD_D7_PD (0x01 << 4) -#define SD_DAT7_PU (0x02 << 4) -#define SD_CLK_NP 0x00 -#define SD_CLK_PD (0x01 << 2) -#define SD_CLK_PU (0x02 << 2) -#define SD_D5_NP 0x00 -#define SD_D5_PD 0x01 -#define SD_D5_PU 0x02 - -#define MS_D1_NP 0x00 -#define MS_D1_PD (0x01 << 6) -#define MS_D1_PU (0x02 << 6) -#define MS_D2_NP 0x00 -#define MS_D2_PD (0x01 << 4) -#define MS_D2_PU (0x02 << 4) -#define MS_CLK_NP 0x00 -#define MS_CLK_PD (0x01 << 2) -#define MS_CLK_PU (0x02 << 2) -#define MS_D6_NP 0x00 -#define MS_D6_PD 0x01 -#define MS_D6_PU 0x02 - -#define XD_D7_NP 0x00 -#define XD_D7_PD (0x01 << 6) -#define XD_D7_PU (0x02 << 6) -#define XD_D6_NP 0x00 -#define XD_D6_PD (0x01 << 4) -#define XD_D6_PU (0x02 << 4) -#define XD_D5_NP 0x00 -#define XD_D5_PD (0x01 << 2) -#define XD_D5_PU (0x02 << 2) -#define XD_D4_NP 0x00 -#define XD_D4_PD 0x01 -#define XD_D4_PU 0x02 - -#define SD_D6_NP 0x00 -#define SD_D6_PD (0x01 << 6) -#define SD_D6_PU (0x02 << 6) -#define SD_D0_NP 0x00 -#define SD_D0_PD (0x01 << 4) -#define SD_D0_PU (0x02 << 4) -#define SD_D1_NP 0x00 -#define SD_D1_PD 0x01 -#define SD_D1_PU 0x02 - -#define MS_D3_NP 0x00 -#define MS_D3_PD (0x01 << 6) -#define MS_D3_PU (0x02 << 6) -#define MS_D0_NP 0x00 -#define MS_D0_PD (0x01 << 4) -#define MS_D0_PU (0x02 << 4) -#define MS_BS_NP 0x00 -#define MS_BS_PD (0x01 << 2) -#define MS_BS_PU (0x02 << 2) - -#define XD_WP_NP 0x00 -#define XD_WP_PD (0x01 << 6) -#define XD_WP_PU (0x02 << 6) -#define XD_CE_NP 0x00 -#define XD_CE_PD (0x01 << 3) -#define XD_CE_PU (0x02 << 3) -#define XD_CLE_NP 0x00 -#define XD_CLE_PD (0x01 << 1) -#define XD_CLE_PU (0x02 << 1) -#define XD_CD_PD 0x00 -#define XD_CD_PU 0x01 - -#define SD_D4_NP 0x00 -#define SD_D4_PD (0x01 << 6) -#define SD_D4_PU (0x02 << 6) - -#define MS_D7_NP 0x00 -#define MS_D7_PD (0x01 << 6) -#define MS_D7_PU (0x02 << 6) - -#define XD_RDY_NP 0x00 -#define XD_RDY_PD (0x01 << 6) -#define XD_RDY_PU (0x02 << 6) -#define XD_WE_NP 0x00 -#define XD_WE_PD (0x01 << 4) -#define XD_WE_PU (0x02 << 4) -#define XD_RE_NP 0x00 -#define XD_RE_PD (0x01 << 2) -#define XD_RE_PU (0x02 << 2) -#define XD_ALE_NP 0x00 -#define XD_ALE_PD 0x01 -#define XD_ALE_PU 0x02 - -#define SD_D3_NP 0x00 -#define SD_D3_PD (0x01 << 4) -#define SD_D3_PU (0x02 << 4) -#define SD_D2_NP 0x00 -#define SD_D2_PD (0x01 << 2) -#define SD_D2_PU (0x02 << 2) - -#define MS_INS_PD 0x00 -#define MS_INS_PU (0x01 << 7) -#define SD_WP_NP 0x00 -#define SD_WP_PD (0x01 << 5) -#define SD_WP_PU (0x02 << 5) -#define SD_CD_PD 0x00 -#define SD_CD_PU (0x01 << 4) -#define SD_CMD_NP 0x00 -#define SD_CMD_PD (0x01 << 2) -#define SD_CMD_PU (0x02 << 2) - -#define MS_D5_NP 0x00 -#define MS_D5_PD (0x01 << 2) -#define MS_D5_PU (0x02 << 2) -#define MS_D4_NP 0x00 -#define MS_D4_PD 0x01 -#define MS_D4_PU 0x02 - -#define FORCE_PM_CLOCK 0x10 -#define EN_CLOCK_PM 0x01 - -#define HOST_ENTER_S3 0x02 -#define HOST_ENTER_S1 0x01 - -#define AUX_PWR_DETECTED 0x01 - -#define PHY_DEBUG_MODE 0x01 - -#define SPI_COMMAND_BIT_8 0xE0 -#define SPI_ADDRESS_BIT_24 0x17 -#define SPI_ADDRESS_BIT_32 0x1F - -#define SPI_TRANSFER0_START 0x80 -#define SPI_TRANSFER0_END 0x40 -#define SPI_C_MODE0 0x00 -#define SPI_CA_MODE0 0x01 -#define SPI_CDO_MODE0 0x02 -#define SPI_CDI_MODE0 0x03 -#define SPI_CADO_MODE0 0x04 -#define SPI_CADI_MODE0 0x05 -#define SPI_POLLING_MODE0 0x06 - -#define SPI_TRANSFER1_START 0x80 -#define SPI_TRANSFER1_END 0x40 -#define SPI_DO_MODE1 0x00 -#define SPI_DI_MODE1 0x01 - -#define CS_POLARITY_HIGH 0x40 -#define CS_POLARITY_LOW 0x00 -#define DTO_MSB_FIRST 0x00 -#define DTO_LSB_FIRST 0x20 -#define SPI_MASTER 0x00 -#define SPI_SLAVE 0x10 -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x04 -#define SPI_MODE2 0x08 -#define SPI_MODE3 0x0C -#define SPI_MANUAL 0x00 -#define SPI_HALF_AUTO 0x01 -#define SPI_AUTO 0x02 -#define SPI_EEPROM_AUTO 0x03 - -#define EDO_TIMING_MASK 0x03 -#define SAMPLE_RISING 0x00 -#define SAMPLE_DELAY_HALF 0x01 -#define SAMPLE_DELAY_ONE 0x02 -#define SAPMLE_DELAY_ONE_HALF 0x03 -#define TCS_MASK 0x0C - -#define NOT_BYPASS_SD 0x02 -#define DISABLE_SDIO_FUNC 0x04 -#define SELECT_1LUN 0x08 - -#define PWR_GATE_EN 0x01 -#define LDO3318_PWR_MASK 0x06 -#define LDO_ON 0x00 -#define LDO_SUSPEND 0x04 -#define LDO_OFF 0x06 - -#define SD_CFG1 0xFDA0 -#define SD_CFG2 0xFDA1 -#define SD_CFG3 0xFDA2 -#define SD_STAT1 0xFDA3 -#define SD_STAT2 0xFDA4 -#define SD_BUS_STAT 0xFDA5 -#define SD_PAD_CTL 0xFDA6 -#define SD_SAMPLE_POINT_CTL 0xFDA7 -#define SD_PUSH_POINT_CTL 0xFDA8 -#define SD_CMD0 0xFDA9 -#define SD_CMD1 0xFDAA -#define SD_CMD2 0xFDAB -#define SD_CMD3 0xFDAC -#define SD_CMD4 0xFDAD -#define SD_CMD5 0xFDAE -#define SD_BYTE_CNT_L 0xFDAF -#define SD_BYTE_CNT_H 0xFDB0 -#define SD_BLOCK_CNT_L 0xFDB1 -#define SD_BLOCK_CNT_H 0xFDB2 -#define SD_TRANSFER 0xFDB3 -#define SD_CMD_STATE 0xFDB5 -#define SD_DATA_STATE 0xFDB6 - -#define DCM_DRP_CTL 0xFC23 -#define DCM_DRP_TRIG 0xFC24 -#define DCM_DRP_CFG 0xFC25 -#define DCM_DRP_WR_DATA_L 0xFC26 -#define DCM_DRP_WR_DATA_H 0xFC27 -#define DCM_DRP_RD_DATA_L 0xFC28 -#define DCM_DRP_RD_DATA_H 0xFC29 -#define SD_VPCLK0_CTL 0xFC2A -#define SD_VPCLK1_CTL 0xFC2B -#define SD_DCMPS0_CTL 0xFC2C -#define SD_DCMPS1_CTL 0xFC2D -#define SD_VPTX_CTL SD_VPCLK0_CTL -#define SD_VPRX_CTL SD_VPCLK1_CTL -#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL -#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL - -#define CARD_CLK_SOURCE 0xFC2E - -#define CARD_PWR_CTL 0xFD50 -#define CARD_CLK_SWITCH 0xFD51 -#define CARD_SHARE_MODE 0xFD52 -#define CARD_DRIVE_SEL 0xFD53 -#define CARD_STOP 0xFD54 -#define CARD_OE 0xFD55 -#define CARD_AUTO_BLINK 0xFD56 -#define CARD_GPIO_DIR 0xFD57 -#define CARD_GPIO 0xFD58 - -#define CARD_DATA_SOURCE 0xFD5B -#define CARD_SELECT 0xFD5C -#define SD30_DRIVE_SEL 0xFD5E - -#define CARD_CLK_EN 0xFD69 - -#define SDIO_CTRL 0xFD6B - -#define FPDCTL 0xFC00 -#define PDINFO 0xFC01 - -#define CLK_CTL 0xFC02 -#define CLK_DIV 0xFC03 -#define CLK_SEL 0xFC04 - -#define SSC_DIV_N_0 0xFC0F -#define SSC_DIV_N_1 0xFC10 - -#define RCCTL 0xFC14 - -#define FPGA_PULL_CTL 0xFC1D - -#define CARD_PULL_CTL1 0xFD60 -#define CARD_PULL_CTL2 0xFD61 -#define CARD_PULL_CTL3 0xFD62 -#define CARD_PULL_CTL4 0xFD63 -#define CARD_PULL_CTL5 0xFD64 -#define CARD_PULL_CTL6 0xFD65 - -#define IRQEN0 0xFE20 -#define IRQSTAT0 0xFE21 -#define IRQEN1 0xFE22 -#define IRQSTAT1 0xFE23 -#define TLPRIEN 0xFE24 -#define TLPRISTAT 0xFE25 -#define TLPTIEN 0xFE26 -#define TLPTISTAT 0xFE27 -#define DMATC0 0xFE28 -#define DMATC1 0xFE29 -#define DMATC2 0xFE2A -#define DMATC3 0xFE2B -#define DMACTL 0xFE2C -#define BCTL 0xFE2D -#define RBBC0 0xFE2E -#define RBBC1 0xFE2F -#define RBDAT 0xFE30 -#define RBCTL 0xFE34 -#define CFGADDR0 0xFE35 -#define CFGADDR1 0xFE36 -#define CFGDATA0 0xFE37 -#define CFGDATA1 0xFE38 -#define CFGDATA2 0xFE39 -#define CFGDATA3 0xFE3A -#define CFGRWCTL 0xFE3B -#define PHYRWCTL 0xFE3C -#define PHYDATA0 0xFE3D -#define PHYDATA1 0xFE3E -#define PHYADDR 0xFE3F -#define MSGRXDATA0 0xFE40 -#define MSGRXDATA1 0xFE41 -#define MSGRXDATA2 0xFE42 -#define MSGRXDATA3 0xFE43 -#define MSGTXDATA0 0xFE44 -#define MSGTXDATA1 0xFE45 -#define MSGTXDATA2 0xFE46 -#define MSGTXDATA3 0xFE47 -#define MSGTXCTL 0xFE48 -#define PETXCFG 0xFE49 - -#define CDRESUMECTL 0xFE52 -#define WAKE_SEL_CTL 0xFE54 -#define PME_FORCE_CTL 0xFE56 -#define ASPM_FORCE_CTL 0xFE57 -#define PM_CLK_FORCE_CTL 0xFE58 -#define PERST_GLITCH_WIDTH 0xFE5C -#define CHANGE_LINK_STATE 0xFE5B -#define RESET_LOAD_REG 0xFE5E -#define HOST_SLEEP_STATE 0xFE60 -#define MAIN_PWR_OFF_CTL 0xFE70 /* RTS5208 */ - -#define NFTS_TX_CTRL 0xFE72 - -#define PWR_GATE_CTRL 0xFE75 -#define PWD_SUSPEND_EN 0xFE76 - -#define EFUSE_CONTENT 0xFE5F - -#define XD_INIT 0xFD10 -#define XD_DTCTL 0xFD11 -#define XD_CTL 0xFD12 -#define XD_TRANSFER 0xFD13 -#define XD_CFG 0xFD14 -#define XD_ADDRESS0 0xFD15 -#define XD_ADDRESS1 0xFD16 -#define XD_ADDRESS2 0xFD17 -#define XD_ADDRESS3 0xFD18 -#define XD_ADDRESS4 0xFD19 -#define XD_DAT 0xFD1A -#define XD_PAGE_CNT 0xFD1B -#define XD_PAGE_STATUS 0xFD1C -#define XD_BLOCK_STATUS 0xFD1D -#define XD_BLOCK_ADDR1_L 0xFD1E -#define XD_BLOCK_ADDR1_H 0xFD1F -#define XD_BLOCK_ADDR2_L 0xFD20 -#define XD_BLOCK_ADDR2_H 0xFD21 -#define XD_BYTE_CNT_L 0xFD22 -#define XD_BYTE_CNT_H 0xFD23 -#define XD_PARITY 0xFD24 -#define XD_ECC_BIT1 0xFD25 -#define XD_ECC_BYTE1 0xFD26 -#define XD_ECC_BIT2 0xFD27 -#define XD_ECC_BYTE2 0xFD28 -#define XD_RESERVED0 0xFD29 -#define XD_RESERVED1 0xFD2A -#define XD_RESERVED2 0xFD2B -#define XD_RESERVED3 0xFD2C -#define XD_CHK_DATA_STATUS 0xFD2D -#define XD_CATCTL 0xFD2E - -#define MS_CFG 0xFD40 -#define MS_TPC 0xFD41 -#define MS_TRANS_CFG 0xFD42 -#define MS_TRANSFER 0xFD43 -#define MS_INT_REG 0xFD44 -#define MS_BYTE_CNT 0xFD45 -#define MS_SECTOR_CNT_L 0xFD46 -#define MS_SECTOR_CNT_H 0xFD47 -#define MS_DBUS_H 0xFD48 - -#define SSC_CTL1 0xFC11 -#define SSC_CTL2 0xFC12 - -#define OCPCTL 0xFC15 -#define OCPSTAT 0xFC16 -#define OCPCLR 0xFC17 /* 5208 */ -#define OCPPARA1 0xFC18 -#define OCPPARA2 0xFC19 - -#define EFUSE_OP 0xFC20 -#define EFUSE_CTRL 0xFC21 -#define EFUSE_DATA 0xFC22 - -#define SPI_COMMAND 0xFD80 -#define SPI_ADDR0 0xFD81 -#define SPI_ADDR1 0xFD82 -#define SPI_ADDR2 0xFD83 -#define SPI_ADDR3 0xFD84 -#define SPI_CA_NUMBER 0xFD85 -#define SPI_LENGTH0 0xFD86 -#define SPI_LENGTH1 0xFD87 -#define SPI_DATA 0xFD88 -#define SPI_DATA_NUMBER 0xFD89 -#define SPI_TRANSFER0 0xFD90 -#define SPI_TRANSFER1 0xFD91 -#define SPI_CONTROL 0xFD92 -#define SPI_SIG 0xFD93 -#define SPI_TCTL 0xFD94 -#define SPI_SLAVE_NUM 0xFD95 -#define SPI_CLK_DIVIDER0 0xFD96 -#define SPI_CLK_DIVIDER1 0xFD97 - -#define SRAM_BASE 0xE600 -#define RBUF_BASE 0xF400 -#define PPBUF_BASE1 0xF800 -#define PPBUF_BASE2 0xFA00 -#define IMAGE_FLAG_ADDR0 0xCE80 -#define IMAGE_FLAG_ADDR1 0xCE81 - -#define READ_OP 1 -#define WRITE_OP 2 - -#define LCTLR 0x80 - -#define POLLING_WAIT_CNT 1 -#define IDLE_MAX_COUNT 10 -#define SDIO_IDLE_COUNT 10 - -#define DEBOUNCE_CNT 5 - -void do_remaining_work(struct rtsx_chip *chip); -void try_to_switch_sdio_ctrl(struct rtsx_chip *chip); -void do_reset_sd_card(struct rtsx_chip *chip); -void do_reset_xd_card(struct rtsx_chip *chip); -void do_reset_ms_card(struct rtsx_chip *chip); -void rtsx_power_off_card(struct rtsx_chip *chip); -void rtsx_release_cards(struct rtsx_chip *chip); -void rtsx_reset_cards(struct rtsx_chip *chip); -void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip); -void rtsx_init_cards(struct rtsx_chip *chip); -int switch_ssc_clock(struct rtsx_chip *chip, int clk); -int switch_normal_clock(struct rtsx_chip *chip, int clk); -int enable_card_clock(struct rtsx_chip *chip, u8 card); -int disable_card_clock(struct rtsx_chip *chip, u8 card); -int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 sec_addr, u16 sec_cnt); -void trans_dma_enable(enum dma_data_direction dir, - struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size); -void toggle_gpio(struct rtsx_chip *chip, u8 gpio); -void turn_on_led(struct rtsx_chip *chip, u8 gpio); -void turn_off_led(struct rtsx_chip *chip, u8 gpio); - -int card_share_mode(struct rtsx_chip *chip, int card); -int select_card(struct rtsx_chip *chip, int card); -int detect_card_cd(struct rtsx_chip *chip, int card); -int check_card_exist(struct rtsx_chip *chip, unsigned int lun); -int check_card_ready(struct rtsx_chip *chip, unsigned int lun); -int check_card_wp(struct rtsx_chip *chip, unsigned int lun); -void eject_card(struct rtsx_chip *chip, unsigned int lun); -u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun); - -static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; - - if ((get_lun_card(chip, lun) == SD_CARD) && - (sd_card->sd_lock_status & SD_LOCKED)) - return 0; - - return chip->capacity[lun]; -#else - return chip->capacity[lun]; -#endif -} - -static inline int switch_clock(struct rtsx_chip *chip, int clk) -{ - int retval = 0; - - if (chip->asic_code) - retval = switch_ssc_clock(chip, clk); - else - retval = switch_normal_clock(chip, clk); - - return retval; -} - -int card_power_on(struct rtsx_chip *chip, u8 card); -int card_power_off(struct rtsx_chip *chip, u8 card); - -static inline int card_power_off_all(struct rtsx_chip *chip) -{ - int retval; - - retval = rtsx_write_register(chip, CARD_PWR_CTL, 0x0F, 0x0F); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static inline void rtsx_clear_xd_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, - XD_STOP | XD_CLR_ERR); -} - -static inline void rtsx_clear_sd_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); -} - -static inline void rtsx_clear_ms_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, - MS_STOP | MS_CLR_ERR); -} - -static inline void rtsx_clear_spi_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, SPI_STOP | SPI_CLR_ERR, - SPI_STOP | SPI_CLR_ERR); -} - -#ifdef SUPPORT_SDIO_ASPM -void dynamic_configure_sdio_aspm(struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_CARD_H */ diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c deleted file mode 100644 index 6375032918d4cf599d1c45e1d4c563c7b757abaa..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_chip.c +++ /dev/null @@ -1,2161 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include -#include -#include - -#include "rtsx.h" -#include "sd.h" -#include "xd.h" -#include "ms.h" - -static void rtsx_calibration(struct rtsx_chip *chip) -{ - rtsx_write_phy_register(chip, 0x1B, 0x135E); - wait_timeout(10); - rtsx_write_phy_register(chip, 0x00, 0x0280); - rtsx_write_phy_register(chip, 0x01, 0x7112); - rtsx_write_phy_register(chip, 0x01, 0x7110); - rtsx_write_phy_register(chip, 0x01, 0x7112); - rtsx_write_phy_register(chip, 0x01, 0x7113); - rtsx_write_phy_register(chip, 0x00, 0x0288); -} - -void rtsx_enable_card_int(struct rtsx_chip *chip) -{ - u32 reg = rtsx_readl(chip, RTSX_BIER); - int i; - - for (i = 0; i <= chip->max_lun; i++) { - if (chip->lun2card[i] & XD_CARD) - reg |= XD_INT_EN; - if (chip->lun2card[i] & SD_CARD) - reg |= SD_INT_EN; - if (chip->lun2card[i] & MS_CARD) - reg |= MS_INT_EN; - } - if (chip->hw_bypass_sd) - reg &= ~((u32)SD_INT_EN); - - rtsx_writel(chip, RTSX_BIER, reg); -} - -void rtsx_enable_bus_int(struct rtsx_chip *chip) -{ - u32 reg = 0; -#ifndef DISABLE_CARD_INT - int i; -#endif - - reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN; - -#ifndef DISABLE_CARD_INT - for (i = 0; i <= chip->max_lun; i++) { - dev_dbg(rtsx_dev(chip), "lun2card[%d] = 0x%02x\n", - i, chip->lun2card[i]); - - if (chip->lun2card[i] & XD_CARD) - reg |= XD_INT_EN; - if (chip->lun2card[i] & SD_CARD) - reg |= SD_INT_EN; - if (chip->lun2card[i] & MS_CARD) - reg |= MS_INT_EN; - } - if (chip->hw_bypass_sd) - reg &= ~((u32)SD_INT_EN); -#endif - - if (chip->ic_version >= IC_VER_C) - reg |= DELINK_INT_EN; -#ifdef SUPPORT_OCP - reg |= OC_INT_EN; -#endif - if (!chip->adma_mode) - reg |= DATA_DONE_INT_EN; - - /* Enable Bus Interrupt */ - rtsx_writel(chip, RTSX_BIER, reg); - - dev_dbg(rtsx_dev(chip), "RTSX_BIER: 0x%08x\n", reg); -} - -void rtsx_disable_bus_int(struct rtsx_chip *chip) -{ - rtsx_writel(chip, RTSX_BIER, 0); -} - -static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) -{ - int retval; - - if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) { - if (chip->asic_code) { - retval = rtsx_write_register(chip, CARD_PULL_CTL5, - 0xFF, - MS_INS_PU | SD_WP_PU | - SD_CD_PU | SD_CMD_PU); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - 0xFF, - FPGA_SD_PULL_CTL_EN); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, CARD_SHARE_MODE, 0xFF, - CARD_SHARE_48_SD); - if (retval) - return retval; - - /* Enable SDIO internal clock */ - retval = rtsx_write_register(chip, 0xFF2C, 0x01, 0x01); - if (retval) - return retval; - - retval = rtsx_write_register(chip, SDIO_CTRL, 0xFF, - SDIO_BUS_CTRL | SDIO_CD_CTRL); - if (retval) - return retval; - - chip->sd_int = 1; - chip->sd_io = 1; - } else { - chip->need_reset |= SD_CARD; - } - - return STATUS_SUCCESS; -} - -#ifdef HW_AUTO_SWITCH_SD_BUS -static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) -{ - u8 tmp; - bool sw_bypass_sd = false; - int retval; - - if (chip->driver_first_load) { - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_read_register(chip, 0xFE5A, &tmp); - if (retval) - return retval; - if (tmp & 0x08) - sw_bypass_sd = true; - } else if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_read_register(chip, 0xFE70, &tmp); - if (retval) - return retval; - if (tmp & 0x80) - sw_bypass_sd = true; - } - } else { - if (chip->sdio_in_charge) - sw_bypass_sd = true; - } - dev_dbg(rtsx_dev(chip), "chip->sdio_in_charge = %d\n", - chip->sdio_in_charge); - dev_dbg(rtsx_dev(chip), "chip->driver_first_load = %d\n", - chip->driver_first_load); - dev_dbg(rtsx_dev(chip), "sw_bypass_sd = %d\n", - sw_bypass_sd); - - if (sw_bypass_sd) { - u8 cd_toggle_mask = 0; - - retval = rtsx_read_register(chip, TLPTISTAT, &tmp); - if (retval) - return retval; - cd_toggle_mask = 0x08; - - if (tmp & cd_toggle_mask) { - /* Disable sdio_bus_auto_switch */ - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_register(chip, 0xFE5A, - 0x08, 0x00); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, 0xFE70, - 0x80, 0x00); - if (retval) - return retval; - } - - retval = rtsx_write_register(chip, TLPTISTAT, 0xFF, - tmp); - if (retval) - return retval; - - chip->need_reset |= SD_CARD; - } else { - dev_dbg(rtsx_dev(chip), "Chip inserted with SDIO!\n"); - - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register - (chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, - 0); - if (retval) - return retval; - } - retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Enable sdio_bus_auto_switch */ - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_register(chip, 0xFE5A, - 0x08, 0x08); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, 0xFE70, - 0x80, 0x80); - if (retval) - return retval; - } - - chip->chip_insert_with_sdio = 1; - chip->sd_io = 1; - } - } else { - retval = rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - if (retval) - return retval; - - chip->need_reset |= SD_CARD; - } - - return STATUS_SUCCESS; -} -#endif - -static int rtsx_reset_aspm(struct rtsx_chip *chip) -{ - int ret; - - if (chip->dynamic_aspm) { - if (!CHK_SDIO_EXIST(chip) || !CHECK_PID(chip, 0x5288)) - return STATUS_SUCCESS; - - ret = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, - chip->aspm_l0s_l1_en); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; - } - - if (CHECK_PID(chip, 0x5208)) { - ret = rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); - if (ret) - return ret; - } - ret = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->aspm_level[0] = chip->aspm_l0s_l1_en; - if (CHK_SDIO_EXIST(chip)) { - chip->aspm_level[1] = chip->aspm_l0s_l1_en; - ret = rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - } - - chip->aspm_enabled = 1; - - return STATUS_SUCCESS; -} - -static int rtsx_enable_pcie_intr(struct rtsx_chip *chip) -{ - int ret; - - if (!chip->asic_code || !CHECK_PID(chip, 0x5208)) { - rtsx_enable_bus_int(chip); - return STATUS_SUCCESS; - } - - if (chip->phy_debug_mode) { - ret = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); - if (ret) - return ret; - rtsx_disable_bus_int(chip); - } else { - rtsx_enable_bus_int(chip); - } - - if (chip->ic_version >= IC_VER_D) { - u16 reg; - - ret = rtsx_read_phy_register(chip, 0x00, ®); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - reg &= 0xFE7F; - reg |= 0x80; - ret = rtsx_write_phy_register(chip, 0x00, reg); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - ret = rtsx_read_phy_register(chip, 0x1C, ®); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - reg &= 0xFFF7; - ret = rtsx_write_phy_register(chip, 0x1C, reg); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (chip->driver_first_load && chip->ic_version < IC_VER_C) - rtsx_calibration(chip); - - return STATUS_SUCCESS; -} - -int rtsx_reset_chip(struct rtsx_chip *chip) -{ - int retval; - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - rtsx_disable_aspm(chip); - - retval = rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00); - if (retval) - return retval; - - /* Disable card clock */ - retval = rtsx_write_register(chip, CARD_CLK_EN, 0x1E, 0); - if (retval) - return retval; - -#ifdef SUPPORT_OCP - /* SSC power on, OCD power on */ - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN, 0); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN, - MS_OC_POWER_DOWN); - if (retval) - return retval; - } - - retval = rtsx_write_register(chip, OCPPARA1, OCP_TIME_MASK, - OCP_TIME_800); - if (retval) - return retval; - retval = rtsx_write_register(chip, OCPPARA2, OCP_THD_MASK, - OCP_THD_244_946); - if (retval) - return retval; - retval = rtsx_write_register(chip, OCPCTL, 0xFF, - CARD_OC_INT_EN | CARD_DETECT_EN); - if (retval) - return retval; -#else - /* OC power down */ - retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN, - OC_POWER_DOWN); - if (retval) - return retval; -#endif - - if (!CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0xFF, 0x03); - if (retval) - return retval; - } - - /* Turn off LED */ - retval = rtsx_write_register(chip, CARD_GPIO, 0xFF, 0x03); - if (retval) - return retval; - - /* Reset delink mode */ - retval = rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0); - if (retval) - return retval; - - /* Card driving select */ - retval = rtsx_write_register(chip, CARD_DRIVE_SEL, 0xFF, - chip->card_drive_sel); - if (retval) - return retval; - -#ifdef LED_AUTO_BLINK - retval = rtsx_write_register(chip, CARD_AUTO_BLINK, 0xFF, - LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); - if (retval) - return retval; -#endif - - if (chip->asic_code) { - /* Enable SSC Clock */ - retval = rtsx_write_register(chip, SSC_CTL1, 0xFF, - SSC_8X_EN | SSC_SEL_4M); - if (retval) - return retval; - retval = rtsx_write_register(chip, SSC_CTL2, 0xFF, 0x12); - if (retval) - return retval; - } - - /* - * Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0) - * 0xFE5B - * bit[1] u_cd_rst_core_en rst_value = 0 - * bit[2] u_force_rst_core_en rst_value = 0 - * bit[5] u_mac_phy_rst_n_dbg rst_value = 1 - * bit[4] u_non_sticky_rst_n_dbg rst_value = 0 - */ - retval = rtsx_write_register(chip, CHANGE_LINK_STATE, 0x16, 0x10); - if (retval) - return retval; - - /* Enable ASPM */ - if (chip->aspm_l0s_l1_en) { - retval = rtsx_reset_aspm(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_phy_register(chip, 0x07, 0x0129); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - retval = rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = rtsx_write_config_byte(chip, 0x81, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_SDIO_EXIST(chip)) { - retval = rtsx_write_cfg_dw(chip, - CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFF00, 0x0100); - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (CHECK_PID(chip, 0x5288) && !CHK_SDIO_EXIST(chip)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, - LINK_RDY_INT); - if (retval) - return retval; - - retval = rtsx_write_register(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); - if (retval) - return retval; - - retval = rtsx_enable_pcie_intr(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->need_reset = 0; - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->hw_bypass_sd) - goto nextcard; - dev_dbg(rtsx_dev(chip), "In %s, chip->int_reg = 0x%x\n", __func__, - chip->int_reg); - if (chip->int_reg & SD_EXIST) { -#ifdef HW_AUTO_SWITCH_SD_BUS - if (CHECK_PID(chip, 0x5208) && chip->ic_version < IC_VER_C) - retval = rtsx_pre_handle_sdio_old(chip); - else - retval = rtsx_pre_handle_sdio_new(chip); - - dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (%s)\n", - (unsigned int)(chip->need_reset), __func__); -#else /* HW_AUTO_SWITCH_SD_BUS */ - retval = rtsx_pre_handle_sdio_old(chip); -#endif /* HW_AUTO_SWITCH_SD_BUS */ - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - } else { - chip->sd_io = 0; - retval = rtsx_write_register(chip, SDIO_CTRL, - SDIO_BUS_CTRL | SDIO_CD_CTRL, 0); - if (retval) - return retval; - } - -nextcard: - if (chip->int_reg & XD_EXIST) - chip->need_reset |= XD_CARD; - if (chip->int_reg & MS_EXIST) - chip->need_reset |= MS_CARD; - if (chip->int_reg & CARD_EXIST) { - retval = rtsx_write_register(chip, SSC_CTL1, SSC_RSTB, - SSC_RSTB); - if (retval) - return retval; - } - - dev_dbg(rtsx_dev(chip), "In %s, chip->need_reset = 0x%x\n", __func__, - (unsigned int)(chip->need_reset)); - - retval = rtsx_write_register(chip, RCCTL, 0x01, 0x00); - if (retval) - return retval; - - if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { - /* Turn off main power when entering S3/S4 state */ - retval = rtsx_write_register(chip, MAIN_PWR_OFF_CTL, 0x03, - 0x03); - if (retval) - return retval; - } - - if (chip->remote_wakeup_en && !chip->auto_delink_en) { - retval = rtsx_write_register(chip, WAKE_SEL_CTL, 0x07, 0x07); - if (retval) - return retval; - if (chip->aux_pwr_exist) { - retval = rtsx_write_register(chip, PME_FORCE_CTL, - 0xFF, 0x33); - if (retval) - return retval; - } - } else { - retval = rtsx_write_register(chip, WAKE_SEL_CTL, 0x07, 0x04); - if (retval) - return retval; - retval = rtsx_write_register(chip, PME_FORCE_CTL, 0xFF, 0x30); - if (retval) - return retval; - } - - if (CHECK_PID(chip, 0x5208) && chip->ic_version >= IC_VER_D) { - retval = rtsx_write_register(chip, PETXCFG, 0x1C, 0x14); - if (retval) - return retval; - } - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { - retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (chip->ft2_fast_mode) { - retval = rtsx_write_register(chip, CARD_PWR_CTL, 0xFF, - MS_PARTIAL_POWER_ON | - SD_PARTIAL_POWER_ON); - if (retval) - return retval; - udelay(chip->pmos_pwr_on_interval); - retval = rtsx_write_register(chip, CARD_PWR_CTL, 0xFF, - MS_POWER_ON | SD_POWER_ON); - if (retval) - return retval; - - wait_timeout(200); - } - - /* Reset card */ - rtsx_reset_detected_cards(chip, 0); - - chip->driver_first_load = 0; - - return STATUS_SUCCESS; -} - -static inline int valid_sd_speed_prior(u32 sd_speed_prior) -{ - bool valid_para = true; - int i; - - for (i = 0; i < 4; i++) { - u8 tmp = (u8)(sd_speed_prior >> (i * 8)); - - if (tmp < 0x01 || tmp > 0x04) { - valid_para = false; - break; - } - } - - return valid_para; -} - -static inline int valid_sd_current_prior(u32 sd_current_prior) -{ - bool valid_para = true; - int i; - - for (i = 0; i < 4; i++) { - u8 tmp = (u8)(sd_current_prior >> (i * 8)); - - if (tmp > 0x03) { - valid_para = false; - break; - } - } - - return valid_para; -} - -static int rts5208_init(struct rtsx_chip *chip) -{ - int retval; - u16 reg = 0; - u8 val = 0; - - retval = rtsx_write_register(chip, CLK_SEL, 0x03, 0x03); - if (retval) - return retval; - retval = rtsx_read_register(chip, CLK_SEL, &val); - if (retval) - return retval; - chip->asic_code = val == 0 ? 1 : 0; - - if (chip->asic_code) { - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "Value of phy register 0x1C is 0x%x\n", - reg); - chip->ic_version = (reg >> 4) & 0x07; - chip->phy_debug_mode = reg & PHY_DEBUG_MODE ? 1 : 0; - - } else { - retval = rtsx_read_register(chip, 0xFE80, &val); - if (retval) - return retval; - chip->ic_version = val; - chip->phy_debug_mode = 0; - } - - retval = rtsx_read_register(chip, PDINFO, &val); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; - - retval = rtsx_read_register(chip, 0xFE50, &val); - if (retval) - return retval; - chip->hw_bypass_sd = val & 0x01 ? 1 : 0; - - rtsx_read_config_byte(chip, 0x0E, &val); - if (val & 0x80) - SET_SDIO_EXIST(chip); - else - CLR_SDIO_EXIST(chip); - - if (chip->use_hw_setting) { - retval = rtsx_read_register(chip, CHANGE_LINK_STATE, &val); - if (retval) - return retval; - chip->auto_delink_en = val & 0x80 ? 1 : 0; - } - - return STATUS_SUCCESS; -} - -static int rts5288_init(struct rtsx_chip *chip) -{ - int retval; - u8 val = 0, max_func; - u32 lval = 0; - - retval = rtsx_write_register(chip, CLK_SEL, 0x03, 0x03); - if (retval) - return retval; - retval = rtsx_read_register(chip, CLK_SEL, &val); - if (retval) - return retval; - chip->asic_code = val == 0 ? 1 : 0; - - chip->ic_version = 0; - chip->phy_debug_mode = 0; - - retval = rtsx_read_register(chip, PDINFO, &val); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; - - retval = rtsx_read_register(chip, CARD_SHARE_MODE, &val); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "CARD_SHARE_MODE: 0x%x\n", val); - chip->baro_pkg = val & 0x04 ? QFN : LQFP; - - retval = rtsx_read_register(chip, 0xFE5A, &val); - if (retval) - return retval; - chip->hw_bypass_sd = val & 0x10 ? 1 : 0; - - retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - max_func = (u8)((lval >> 29) & 0x07); - dev_dbg(rtsx_dev(chip), "Max function number: %d\n", max_func); - if (max_func == 0x02) - SET_SDIO_EXIST(chip); - else - CLR_SDIO_EXIST(chip); - - if (chip->use_hw_setting) { - retval = rtsx_read_register(chip, CHANGE_LINK_STATE, &val); - if (retval) - return retval; - chip->auto_delink_en = val & 0x80 ? 1 : 0; - - if (CHECK_BARO_PKG(chip, LQFP)) - chip->lun_mode = SD_MS_1LUN; - else - chip->lun_mode = DEFAULT_SINGLE; - } - - return STATUS_SUCCESS; -} - -int rtsx_init_chip(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - struct xd_info *xd_card = &chip->xd_card; - struct ms_info *ms_card = &chip->ms_card; - int retval; - unsigned int i; - - dev_dbg(rtsx_dev(chip), "Vendor ID: 0x%04x, Product ID: 0x%04x\n", - chip->vendor_id, chip->product_id); - - chip->ic_version = 0; - - memset(xd_card, 0, sizeof(struct xd_info)); - memset(sd_card, 0, sizeof(struct sd_info)); - memset(ms_card, 0, sizeof(struct ms_info)); - - chip->xd_reset_counter = 0; - chip->sd_reset_counter = 0; - chip->ms_reset_counter = 0; - - chip->xd_show_cnt = MAX_SHOW_CNT; - chip->sd_show_cnt = MAX_SHOW_CNT; - chip->ms_show_cnt = MAX_SHOW_CNT; - - chip->sd_io = 0; - chip->auto_delink_cnt = 0; - chip->auto_delink_allowed = 1; - rtsx_set_stat(chip, RTSX_STAT_INIT); - - chip->aspm_enabled = 0; - chip->chip_insert_with_sdio = 0; - chip->sdio_aspm = 0; - chip->sdio_idle = 0; - chip->sdio_counter = 0; - chip->cur_card = 0; - chip->phy_debug_mode = 0; - chip->sdio_func_exist = 0; - memset(chip->sdio_raw_data, 0, 12); - - for (i = 0; i < MAX_ALLOWED_LUN_CNT; i++) { - set_sense_type(chip, i, SENSE_TYPE_NO_SENSE); - chip->rw_fail_cnt[i] = 0; - } - - if (!valid_sd_speed_prior(chip->sd_speed_prior)) - chip->sd_speed_prior = 0x01040203; - - dev_dbg(rtsx_dev(chip), "sd_speed_prior = 0x%08x\n", - chip->sd_speed_prior); - - if (!valid_sd_current_prior(chip->sd_current_prior)) - chip->sd_current_prior = 0x00010203; - - dev_dbg(rtsx_dev(chip), "sd_current_prior = 0x%08x\n", - chip->sd_current_prior); - - if (chip->sd_ddr_tx_phase > 31 || chip->sd_ddr_tx_phase < 0) - chip->sd_ddr_tx_phase = 0; - - if (chip->mmc_ddr_tx_phase > 31 || chip->mmc_ddr_tx_phase < 0) - chip->mmc_ddr_tx_phase = 0; - - retval = rtsx_write_register(chip, FPDCTL, SSC_POWER_DOWN, 0); - if (retval) - return retval; - wait_timeout(200); - retval = rtsx_write_register(chip, CLK_DIV, 0x07, 0x07); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "chip->use_hw_setting = %d\n", - chip->use_hw_setting); - - if (CHECK_PID(chip, 0x5208)) { - retval = rts5208_init(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - } else if (CHECK_PID(chip, 0x5288)) { - retval = rts5288_init(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (chip->ss_en == 2) - chip->ss_en = 0; - - dev_dbg(rtsx_dev(chip), "chip->asic_code = %d\n", chip->asic_code); - dev_dbg(rtsx_dev(chip), "chip->ic_version = 0x%x\n", chip->ic_version); - dev_dbg(rtsx_dev(chip), "chip->phy_debug_mode = %d\n", - chip->phy_debug_mode); - dev_dbg(rtsx_dev(chip), "chip->aux_pwr_exist = %d\n", - chip->aux_pwr_exist); - dev_dbg(rtsx_dev(chip), "chip->sdio_func_exist = %d\n", - chip->sdio_func_exist); - dev_dbg(rtsx_dev(chip), "chip->hw_bypass_sd = %d\n", - chip->hw_bypass_sd); - dev_dbg(rtsx_dev(chip), "chip->aspm_l0s_l1_en = %d\n", - chip->aspm_l0s_l1_en); - dev_dbg(rtsx_dev(chip), "chip->lun_mode = %d\n", chip->lun_mode); - dev_dbg(rtsx_dev(chip), "chip->auto_delink_en = %d\n", - chip->auto_delink_en); - dev_dbg(rtsx_dev(chip), "chip->ss_en = %d\n", chip->ss_en); - dev_dbg(rtsx_dev(chip), "chip->baro_pkg = %d\n", chip->baro_pkg); - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 1; - chip->card2lun[XD_CARD] = 0xFF; - chip->lun2card[0] = SD_CARD; - chip->lun2card[1] = MS_CARD; - chip->max_lun = 1; - SET_SDIO_IGNORED(chip); - } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 0; - chip->card2lun[XD_CARD] = 0xFF; - chip->lun2card[0] = SD_CARD | MS_CARD; - chip->max_lun = 0; - } else { - chip->card2lun[XD_CARD] = 0; - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 0; - chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; - chip->max_lun = 0; - } - - retval = rtsx_reset_chip(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -void rtsx_release_chip(struct rtsx_chip *chip) -{ - xd_free_l2p_tbl(chip); - ms_free_l2p_tbl(chip); - chip->card_exist = 0; - chip->card_ready = 0; -} - -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) -static inline void rtsx_blink_led(struct rtsx_chip *chip) -{ - if (chip->card_exist && chip->blink_led) { - if (chip->led_toggle_counter < LED_TOGGLE_INTERVAL) { - chip->led_toggle_counter++; - } else { - chip->led_toggle_counter = 0; - toggle_gpio(chip, LED_GPIO); - } - } -} -#endif - -static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) -{ - bool reg_changed, maybe_support_aspm; - u32 tmp = 0; - u8 reg0 = 0, reg1 = 0; - - maybe_support_aspm = false; - reg_changed = false; - rtsx_read_config_byte(chip, LCTLR, ®0); - if (chip->aspm_level[0] != reg0) { - reg_changed = true; - chip->aspm_level[0] = reg0; - } - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { - rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp); - reg1 = (u8)tmp; - if (chip->aspm_level[1] != reg1) { - reg_changed = true; - chip->aspm_level[1] = reg1; - } - - if ((reg0 & 0x03) && (reg1 & 0x03)) - maybe_support_aspm = true; - - } else { - if (reg0 & 0x03) - maybe_support_aspm = true; - } - - if (reg_changed) { - if (maybe_support_aspm) - chip->aspm_l0s_l1_en = 0x03; - - dev_dbg(rtsx_dev(chip), - "aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n", - chip->aspm_level[0], chip->aspm_level[1]); - - if (chip->aspm_l0s_l1_en) { - chip->aspm_enabled = 1; - } else { - chip->aspm_enabled = 0; - chip->sdio_aspm = 0; - } - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, - 0x30 | chip->aspm_level[0] | - (chip->aspm_level[1] << 2)); - } -} - -static void rtsx_manage_ocp(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_OCP - if (!chip->ocp_int) - return; - - rtsx_read_register(chip, OCPSTAT, &chip->ocp_stat); - - if (chip->card_exist & SD_CARD) - sd_power_off_card3v3(chip); - else if (chip->card_exist & MS_CARD) - ms_power_off_card3v3(chip); - else if (chip->card_exist & XD_CARD) - xd_power_off_card3v3(chip); - - chip->ocp_int = 0; -#endif -} - -static void rtsx_manage_sd_lock(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; - u8 val; - - if (!sd_card->sd_erase_status) - return; - - if (chip->card_exist & SD_CARD) { - rtsx_read_register(chip, 0xFD30, &val); - if (val & 0x02) { - sd_card->sd_erase_status = SD_NOT_ERASE; - sd_card->sd_lock_notify = 1; - chip->need_reinit |= SD_CARD; - } - } else { - sd_card->sd_erase_status = SD_NOT_ERASE; - } -#endif -} - -static bool rtsx_is_ss_allowed(struct rtsx_chip *chip) -{ - u32 val; - - if (!chip->ss_en || CHECK_PID(chip, 0x5288)) - return false; - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { - rtsx_read_cfg_dw(chip, 1, 0x04, &val); - if (val & 0x07) - return false; - } - - return true; -} - -static void rtsx_manage_ss(struct rtsx_chip *chip) -{ - if (!rtsx_is_ss_allowed(chip) || chip->sd_io) - return; - - if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { - chip->ss_counter = 0; - return; - } - - if (chip->ss_counter < (chip->ss_idle_period / POLLING_INTERVAL)) - chip->ss_counter++; - else - rtsx_exclusive_enter_ss(chip); -} - -static void rtsx_manage_aspm(struct rtsx_chip *chip) -{ - u8 data; - - if (!CHECK_PID(chip, 0x5208)) - return; - - rtsx_monitor_aspm_config(chip); - -#ifdef SUPPORT_SDIO_ASPM - if (!CHK_SDIO_EXIST(chip) || CHK_SDIO_IGNORED(chip) || - !chip->aspm_l0s_l1_en || !chip->dynamic_aspm) - return; - - if (chip->sd_io) { - dynamic_configure_sdio_aspm(chip); - return; - } - - if (chip->sdio_aspm) - return; - - dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n"); - data = 0x30 | (chip->aspm_level[1] << 2); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, data); - chip->sdio_aspm = 1; -#endif -} - -static void rtsx_manage_idle(struct rtsx_chip *chip) -{ - if (chip->idle_counter < IDLE_MAX_COUNT) { - chip->idle_counter++; - return; - } - - if (rtsx_get_stat(chip) == RTSX_STAT_IDLE) - return; - - dev_dbg(rtsx_dev(chip), "Idle state!\n"); - rtsx_set_stat(chip, RTSX_STAT_IDLE); - -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) - chip->led_toggle_counter = 0; -#endif - rtsx_force_power_on(chip, SSC_PDCTL); - - turn_off_led(chip, LED_GPIO); - - if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); -} - -static void rtsx_manage_2lun_mode(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_OCP - u8 sd_oc, ms_oc; - - sd_oc = chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER); - ms_oc = chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER); - - if (sd_oc || ms_oc) - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - - if (sd_oc && (chip->card_exist & SD_CARD)) { - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - card_power_off(chip, SD_CARD); - chip->card_fail |= SD_CARD; - } - - if (ms_oc && (chip->card_exist & MS_CARD)) { - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - card_power_off(chip, MS_CARD); - chip->card_fail |= MS_CARD; - } -#endif -} - -static void rtsx_manage_1lun_mode(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_OCP - if (!(chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER))) - return; - - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - - if (chip->card_exist & SD_CARD) { - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - chip->card_fail |= SD_CARD; - } else if (chip->card_exist & MS_CARD) { - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - chip->card_fail |= MS_CARD; - } else if (chip->card_exist & XD_CARD) { - rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - chip->card_fail |= XD_CARD; - } - card_power_off(chip, SD_CARD); -#endif -} - -static void rtsx_delink_stage1(struct rtsx_chip *chip, int enter_L1, - int stage3_cnt) -{ - u8 val; - - rtsx_set_stat(chip, RTSX_STAT_DELINK); - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_set_phy_reg_bit(chip, 0x1C, 2); - - if (chip->card_exist) - dev_dbg(rtsx_dev(chip), "False card inserted, do force delink\n"); - else - dev_dbg(rtsx_dev(chip), "No card inserted, do delink\n"); - - if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); - - if (chip->card_exist) - val = 0x02; - else - val = 0x0A; - - rtsx_write_register(chip, CHANGE_LINK_STATE, val, val); - - if (enter_L1) - rtsx_enter_L1(chip); - - if (chip->card_exist) - chip->auto_delink_cnt = stage3_cnt + 1; -} - -static void rtsx_delink_stage(struct rtsx_chip *chip) -{ - int delink_stage1_cnt, delink_stage2_cnt, delink_stage3_cnt; - int enter_L1; - - if (!chip->auto_delink_en || !chip->auto_delink_allowed || - chip->card_ready || chip->card_ejected || chip->sd_io) { - chip->auto_delink_cnt = 0; - return; - } - - enter_L1 = chip->auto_delink_in_L1 && - (chip->aspm_l0s_l1_en || chip->ss_en); - - delink_stage1_cnt = chip->delink_stage1_step; - delink_stage2_cnt = delink_stage1_cnt + chip->delink_stage2_step; - delink_stage3_cnt = delink_stage2_cnt + chip->delink_stage3_step; - - if (chip->auto_delink_cnt > delink_stage3_cnt) - return; - - if (chip->auto_delink_cnt == delink_stage1_cnt) - rtsx_delink_stage1(chip, enter_L1, delink_stage3_cnt); - - if (chip->auto_delink_cnt == delink_stage2_cnt) { - dev_dbg(rtsx_dev(chip), "Try to do force delink\n"); - - if (enter_L1) - rtsx_exit_L1(chip); - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_set_phy_reg_bit(chip, 0x1C, 2); - - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); - } - - chip->auto_delink_cnt++; -} - -void rtsx_polling_func(struct rtsx_chip *chip) -{ - if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND)) - return; - - if (rtsx_chk_stat(chip, RTSX_STAT_DELINK)) - goto delink_stage; - - if (chip->polling_config) { - u8 val; - - rtsx_read_config_byte(chip, 0, &val); - } - - if (rtsx_chk_stat(chip, RTSX_STAT_SS)) - return; - - rtsx_manage_ocp(chip); - - rtsx_manage_sd_lock(chip); - - rtsx_init_cards(chip); - - rtsx_manage_ss(chip); - - rtsx_manage_aspm(chip); - - rtsx_manage_idle(chip); - - switch (rtsx_get_stat(chip)) { - case RTSX_STAT_RUN: -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) - rtsx_blink_led(chip); -#endif - do_remaining_work(chip); - break; - - case RTSX_STAT_IDLE: - if (chip->sd_io && !chip->sd_int) - try_to_switch_sdio_ctrl(chip); - - rtsx_enable_aspm(chip); - break; - - default: - break; - } - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_manage_2lun_mode(chip); - else - rtsx_manage_1lun_mode(chip); - -delink_stage: - rtsx_delink_stage(chip); -} - -/** - * rtsx_stop_cmd - stop command transfer and DMA transfer - * @chip: Realtek's card reader chip - * @card: flash card type - * - * Stop command transfer and DMA transfer. - * This function is called in error handler. - */ -void rtsx_stop_cmd(struct rtsx_chip *chip, int card) -{ - int i; - - for (i = 0; i <= 8; i++) { - int addr = RTSX_HCBAR + i * 4; - u32 reg; - - reg = rtsx_readl(chip, addr); - dev_dbg(rtsx_dev(chip), "BAR (0x%02x): 0x%08x\n", addr, reg); - } - rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD); - rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA); - - for (i = 0; i < 16; i++) { - u16 addr = 0xFE20 + (u16)i; - u8 val; - - rtsx_read_register(chip, addr, &val); - dev_dbg(rtsx_dev(chip), "0x%04X: 0x%02x\n", addr, val); - } - - rtsx_write_register(chip, DMACTL, 0x80, 0x80); - rtsx_write_register(chip, RBCTL, 0x80, 0x80); -} - -#define MAX_RW_REG_CNT 1024 - -int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data) -{ - int i; - u32 val = 3 << 30; - - val |= (u32)(addr & 0x3FFF) << 16; - val |= (u32)mask << 8; - val |= (u32)data; - - rtsx_writel(chip, RTSX_HAIMR, val); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - val = rtsx_readl(chip, RTSX_HAIMR); - if ((val & BIT(31)) == 0) { - if (data != (u8)val) - return STATUS_FAIL; - - return STATUS_SUCCESS; - } - } - - return STATUS_TIMEDOUT; -} - -int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) -{ - u32 val = 2 << 30; - int i; - - if (data) - *data = 0; - - val |= (u32)(addr & 0x3FFF) << 16; - - rtsx_writel(chip, RTSX_HAIMR, val); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - val = rtsx_readl(chip, RTSX_HAIMR); - if ((val & BIT(31)) == 0) - break; - } - - if (i >= MAX_RW_REG_CNT) - return STATUS_TIMEDOUT; - - if (data) - *data = (u8)(val & 0xFF); - - return STATUS_SUCCESS; -} - -int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, - u32 val) -{ - int retval; - u8 mode = 0, tmp; - int i; - - for (i = 0; i < 4; i++) { - if (mask & 0xFF) { - retval = rtsx_write_register(chip, CFGDATA0 + i, - 0xFF, - (u8)(val & mask & 0xFF)); - if (retval) - return retval; - mode |= (1 << i); - } - mask >>= 8; - val >>= 8; - } - - if (mode) { - retval = rtsx_write_register(chip, CFGADDR0, 0xFF, (u8)addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, CFGADDR1, 0xFF, - (u8)(addr >> 8)); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CFGRWCTL, 0xFF, - 0x80 | mode | - ((func_no & 0x03) << 4)); - if (retval) - return retval; - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - retval = rtsx_read_register(chip, CFGRWCTL, &tmp); - if (retval) - return retval; - if ((tmp & 0x80) == 0) - break; - } - } - - return STATUS_SUCCESS; -} - -int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) -{ - int retval; - int i; - u8 tmp; - u32 data = 0; - - retval = rtsx_write_register(chip, CFGADDR0, 0xFF, (u8)addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); - if (retval) - return retval; - retval = rtsx_write_register(chip, CFGRWCTL, 0xFF, - 0x80 | ((func_no & 0x03) << 4)); - if (retval) - return retval; - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - retval = rtsx_read_register(chip, CFGRWCTL, &tmp); - if (retval) - return retval; - if ((tmp & 0x80) == 0) - break; - } - - for (i = 0; i < 4; i++) { - retval = rtsx_read_register(chip, CFGDATA0 + i, &tmp); - if (retval) - return retval; - data |= (u32)tmp << (i * 8); - } - - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) -{ - u32 *data, *mask; - u16 offset = addr % 4; - u16 aligned_addr = addr - offset; - int dw_len, i, j; - int retval; - size_t size; - - if (!buf) - return STATUS_NOMEM; - - if ((len + offset) % 4) - dw_len = (len + offset) / 4 + 1; - else - dw_len = (len + offset) / 4; - - dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len); - - size = array_size(dw_len, 4); - data = vzalloc(size); - if (!data) - return STATUS_NOMEM; - - mask = vzalloc(size); - if (!mask) { - vfree(data); - return STATUS_NOMEM; - } - - j = 0; - for (i = 0; i < len; i++) { - mask[j] |= 0xFF << (offset * 8); - data[j] |= buf[i] << (offset * 8); - if (++offset == 4) { - j++; - offset = 0; - } - } - - print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, mask, size); - print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, data, size); - - for (i = 0; i < dw_len; i++) { - retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, - mask[i], data[i]); - if (retval != STATUS_SUCCESS) { - vfree(data); - vfree(mask); - return STATUS_FAIL; - } - } - - vfree(data); - vfree(mask); - - return STATUS_SUCCESS; -} - -int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) -{ - u32 *data; - u16 offset = addr % 4; - u16 aligned_addr = addr - offset; - int dw_len, i, j; - int retval; - - if ((len + offset) % 4) - dw_len = (len + offset) / 4 + 1; - else - dw_len = (len + offset) / 4; - - dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len); - - data = vmalloc(array_size(dw_len, 4)); - if (!data) - return STATUS_NOMEM; - - for (i = 0; i < dw_len; i++) { - retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, - data + i); - if (retval != STATUS_SUCCESS) { - vfree(data); - return STATUS_FAIL; - } - } - - if (buf) { - j = 0; - - for (i = 0; i < len; i++) { - buf[i] = (u8)(data[j] >> (offset * 8)); - if (++offset == 4) { - j++; - offset = 0; - } - } - } - - vfree(data); - - return STATUS_SUCCESS; -} - -int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) -{ - int retval; - bool finished = false; - int i; - u8 tmp; - - retval = rtsx_write_register(chip, PHYDATA0, 0xFF, (u8)val); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYDATA1, 0xFF, (u8)(val >> 8)); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYADDR, 0xFF, addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYRWCTL, 0xFF, 0x81); - if (retval) - return retval; - - for (i = 0; i < 100000; i++) { - retval = rtsx_read_register(chip, PHYRWCTL, &tmp); - if (retval) - return retval; - if (!(tmp & 0x80)) { - finished = true; - break; - } - } - - if (!finished) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) -{ - int retval; - bool finished = false; - int i; - u16 data = 0; - u8 tmp; - - retval = rtsx_write_register(chip, PHYADDR, 0xFF, addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYRWCTL, 0xFF, 0x80); - if (retval) - return retval; - - for (i = 0; i < 100000; i++) { - retval = rtsx_read_register(chip, PHYRWCTL, &tmp); - if (retval) - return retval; - if (!(tmp & 0x80)) { - finished = true; - break; - } - } - - if (!finished) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PHYDATA0, &tmp); - if (retval) - return retval; - data = tmp; - retval = rtsx_read_register(chip, PHYDATA1, &tmp); - if (retval) - return retval; - data |= (u16)tmp << 8; - - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val) -{ - int retval; - int i; - u8 data = 0; - - retval = rtsx_write_register(chip, EFUSE_CTRL, 0xFF, 0x80 | addr); - if (retval) - return retval; - - for (i = 0; i < 100; i++) { - retval = rtsx_read_register(chip, EFUSE_CTRL, &data); - if (retval) - return retval; - if (!(data & 0x80)) - break; - udelay(1); - } - - if (data & 0x80) - return STATUS_TIMEDOUT; - - retval = rtsx_read_register(chip, EFUSE_DATA, &data); - if (retval) - return retval; - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val) -{ - int retval; - int i, j; - u8 data = 0, tmp = 0xFF; - - for (i = 0; i < 8; i++) { - if (val & (u8)(1 << i)) - continue; - - tmp &= (~(u8)(1 << i)); - dev_dbg(rtsx_dev(chip), "Write 0x%x to 0x%x\n", tmp, addr); - - retval = rtsx_write_register(chip, EFUSE_DATA, 0xFF, tmp); - if (retval) - return retval; - retval = rtsx_write_register(chip, EFUSE_CTRL, 0xFF, - 0xA0 | addr); - if (retval) - return retval; - - for (j = 0; j < 100; j++) { - retval = rtsx_read_register(chip, EFUSE_CTRL, &data); - if (retval) - return retval; - if (!(data & 0x80)) - break; - wait_timeout(3); - } - - if (data & 0x80) - return STATUS_TIMEDOUT; - - wait_timeout(5); - } - - return STATUS_SUCCESS; -} - -int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) -{ - int retval; - u16 value; - - retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (value & (1 << bit)) { - value &= ~(1 << bit); - retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) -{ - int retval; - u16 value; - - retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if ((value & (1 << bit)) == 0) { - value |= (1 << bit); - retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate) -{ - u32 ultmp; - - dev_dbg(rtsx_dev(chip), "%04x set pm_dstate to %d\n", - chip->product_id, dstate); - - if (CHK_SDIO_EXIST(chip)) { - u8 func_no; - - if (CHECK_PID(chip, 0x5288)) - func_no = 2; - else - func_no = 1; - - rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp); - dev_dbg(rtsx_dev(chip), "pm_dstate of function %d: 0x%x\n", - (int)func_no, ultmp); - rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate); - } - - rtsx_write_config_byte(chip, 0x44, dstate); - rtsx_write_config_byte(chip, 0x45, 0); -} - -void rtsx_enter_L1(struct rtsx_chip *chip) -{ - rtsx_handle_pm_dstate(chip, 2); -} - -void rtsx_exit_L1(struct rtsx_chip *chip) -{ - rtsx_write_config_byte(chip, 0x44, 0); - rtsx_write_config_byte(chip, 0x45, 0); -} - -void rtsx_enter_ss(struct rtsx_chip *chip) -{ - dev_dbg(rtsx_dev(chip), "Enter Selective Suspend State!\n"); - - rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); - - if (chip->power_down_in_ss) { - rtsx_power_off_card(chip); - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - } - - if (CHK_SDIO_EXIST(chip)) - rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFF00, 0x0100); - - if (chip->auto_delink_en) { - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01); - } else { - if (!chip->phy_debug_mode) { - u32 tmp; - - tmp = rtsx_readl(chip, RTSX_BIER); - tmp |= CARD_INT; - rtsx_writel(chip, RTSX_BIER, tmp); - } - - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0); - } - - rtsx_enter_L1(chip); - - RTSX_CLR_DELINK(chip); - rtsx_set_stat(chip, RTSX_STAT_SS); -} - -void rtsx_exit_ss(struct rtsx_chip *chip) -{ - dev_dbg(rtsx_dev(chip), "Exit Selective Suspend State!\n"); - - rtsx_exit_L1(chip); - - if (chip->power_down_in_ss) { - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - udelay(1000); - } - - if (RTSX_TST_DELINK(chip)) { - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - RTSX_CLR_DELINK(chip); - } else if (chip->power_down_in_ss) { - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 0); - } -} - -int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) -{ - u32 status, int_enable; - bool exit_ss = false; -#ifdef SUPPORT_OCP - u32 ocp_int = 0; - - ocp_int = OC_INT; -#endif - - if (chip->ss_en) { - chip->ss_counter = 0; - if (rtsx_get_stat(chip) == RTSX_STAT_SS) { - exit_ss = true; - rtsx_exit_L1(chip); - rtsx_set_stat(chip, RTSX_STAT_RUN); - } - } - - int_enable = rtsx_readl(chip, RTSX_BIER); - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (((chip->int_reg & int_enable) == 0) || - chip->int_reg == 0xFFFFFFFF) - return STATUS_FAIL; - - status = chip->int_reg &= (int_enable | 0x7FFFFF); - - if (status & CARD_INT) { - chip->auto_delink_cnt = 0; - - if (status & SD_INT) { - if (status & SD_EXIST) { - set_bit(SD_NR, &chip->need_reset); - } else { - set_bit(SD_NR, &chip->need_release); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - clear_bit(SD_NR, &chip->need_reset); - } - } else { - /* - * If multi-luns, it's possible that - * when plugging/unplugging one card - * there is another card which still - * exists in the slot. In this case, - * all existed cards should be reset. - */ - if (exit_ss && (status & SD_EXIST)) - set_bit(SD_NR, &chip->need_reinit); - } - if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) { - if (status & XD_INT) { - if (status & XD_EXIST) { - set_bit(XD_NR, &chip->need_reset); - } else { - set_bit(XD_NR, &chip->need_release); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - clear_bit(XD_NR, &chip->need_reset); - } - } else { - if (exit_ss && (status & XD_EXIST)) - set_bit(XD_NR, &chip->need_reinit); - } - } - if (status & MS_INT) { - if (status & MS_EXIST) { - set_bit(MS_NR, &chip->need_reset); - } else { - set_bit(MS_NR, &chip->need_release); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - clear_bit(MS_NR, &chip->need_reset); - } - } else { - if (exit_ss && (status & MS_EXIST)) - set_bit(MS_NR, &chip->need_reinit); - } - } - -#ifdef SUPPORT_OCP - chip->ocp_int = ocp_int & status; -#endif - - if (chip->sd_io && (chip->int_reg & DATA_DONE_INT)) - chip->int_reg &= ~(u32)DATA_DONE_INT; - - return STATUS_SUCCESS; -} - -void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s, pm_stat = %d\n", __func__, pm_stat); - - rtsx_set_stat(chip, RTSX_STAT_SUSPEND); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) - return; - - rtsx_release_cards(chip); - rtsx_disable_bus_int(chip); - turn_off_led(chip, LED_GPIO); - -#ifdef HW_AUTO_SWITCH_SD_BUS - if (chip->sd_io) { - chip->sdio_in_charge = 1; - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - /* Enable sdio_bus_auto_switch */ - rtsx_write_register(chip, 0xFE70, 0x80, 0x80); - } else if (CHECK_PID(chip, 0x5288)) { - rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - /* Enable sdio_bus_auto_switch */ - rtsx_write_register(chip, 0xFE5A, 0x08, 0x08); - } - } -#endif - - if (CHECK_PID(chip, 0x5208) && chip->ic_version >= IC_VER_D) { - /* u_force_clkreq_0 */ - rtsx_write_register(chip, PETXCFG, 0x08, 0x08); - } - - if (pm_stat == PM_S1) { - dev_dbg(rtsx_dev(chip), "Host enter S1\n"); - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S1); - } else if (pm_stat == PM_S3) { - if (chip->s3_pwr_off_delay > 0) - wait_timeout(chip->s3_pwr_off_delay); - - dev_dbg(rtsx_dev(chip), "Host enter S3\n"); - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S3); - } - - if (chip->do_delink_before_power_down && chip->auto_delink_en) - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2); - - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - - chip->cur_clk = 0; - chip->cur_card = 0; - chip->card_exist = 0; -} - -void rtsx_enable_aspm(struct rtsx_chip *chip) -{ - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && !chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to enable ASPM\n"); - chip->aspm_enabled = 1; - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0); - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, - 0x30 | chip->aspm_level[0]); - } else { - rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - } - - if (CHK_SDIO_EXIST(chip)) { - u16 val = chip->aspm_l0s_l1_en | 0x0100; - - rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFFF, val); - } - } -} - -void rtsx_disable_aspm(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5208)) - rtsx_monitor_aspm_config(chip); - - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to disable ASPM\n"); - chip->aspm_enabled = 0; - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0x0129); - if (CHECK_PID(chip, 0x5208)) - rtsx_write_register(chip, ASPM_FORCE_CTL, - 0xF3, 0x30); - else - rtsx_write_config_byte(chip, LCTLR, 0x00); - - wait_timeout(1); - } -} - -int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) -{ - int retval; - int i, j; - u16 reg_addr; - u8 *ptr; - - if (!buf) - return STATUS_ERROR; - - ptr = buf; - reg_addr = PPBUF_BASE2; - for (i = 0; i < buf_len / 256; i++) { - rtsx_init_cmd(chip); - - for (j = 0; j < 256; j++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - - memcpy(ptr, rtsx_get_cmd_data(chip), 256); - ptr += 256; - } - - if (buf_len % 256) { - rtsx_init_cmd(chip); - - for (j = 0; j < buf_len % 256; j++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - } - - memcpy(ptr, rtsx_get_cmd_data(chip), buf_len % 256); - - return STATUS_SUCCESS; -} - -int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) -{ - int retval; - int i, j; - u16 reg_addr; - u8 *ptr; - - if (!buf) - return STATUS_ERROR; - - ptr = buf; - reg_addr = PPBUF_BASE2; - for (i = 0; i < buf_len / 256; i++) { - rtsx_init_cmd(chip); - - for (j = 0; j < 256; j++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); - ptr++; - } - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - } - - if (buf_len % 256) { - rtsx_init_cmd(chip); - - for (j = 0; j < buf_len % 256; j++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); - ptr++; - } - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int rtsx_check_chip_exist(struct rtsx_chip *chip) -{ - if (rtsx_readl(chip, 0) == 0xFFFFFFFF) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl) -{ - int retval; - u8 mask = 0; - - if (ctl & SSC_PDCTL) - mask |= SSC_POWER_DOWN; - -#ifdef SUPPORT_OCP - if (ctl & OC_PDCTL) { - mask |= SD_OC_POWER_DOWN; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - mask |= MS_OC_POWER_DOWN; - } -#endif - - if (mask) { - retval = rtsx_write_register(chip, FPDCTL, mask, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHECK_PID(chip, 0x5288)) - wait_timeout(200); - } - - return STATUS_SUCCESS; -} - -int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl) -{ - int retval; - u8 mask = 0, val = 0; - - if (ctl & SSC_PDCTL) - mask |= SSC_POWER_DOWN; - -#ifdef SUPPORT_OCP - if (ctl & OC_PDCTL) { - mask |= SD_OC_POWER_DOWN; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - mask |= MS_OC_POWER_DOWN; - } -#endif - - if (mask) { - val = mask; - retval = rtsx_write_register(chip, FPDCTL, mask, val); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h deleted file mode 100644 index bac65784d4a1983631a98e68e2810481ed9d1114..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_chip.h +++ /dev/null @@ -1,987 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_CHIP_H -#define __REALTEK_RTSX_CHIP_H - -#include "rtsx.h" - -#define SUPPORT_CPRM -#define SUPPORT_OCP -#define SUPPORT_SDIO_ASPM -#define SUPPORT_MAGIC_GATE -#define SUPPORT_MSXC -#define SUPPORT_SD_LOCK -/* Hardware switch bus_ctl and cd_ctl automatically */ -#define HW_AUTO_SWITCH_SD_BUS -/* Enable hardware interrupt write clear */ -#define HW_INT_WRITE_CLR -/* #define LED_AUTO_BLINK */ -/* #define DISABLE_CARD_INT */ - -#ifdef SUPPORT_MAGIC_GATE - /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICV */ - #define MG_SET_ICV_SLOW - /* HW may miss ERR/CMDNK signal when sampling INT status. */ - #define MS_SAMPLE_INT_ERR - /* - * HW DO NOT support Wait_INT function - * during READ_BYTES transfer mode - */ - #define READ_BYTES_WAIT_INT -#endif - -#ifdef SUPPORT_MSXC -#define XC_POWERCLASS -#define SUPPORT_PCGL_1P18 -#endif - -#ifndef LED_AUTO_BLINK -#define REGULAR_BLINK -#endif - -#define LED_BLINK_SPEED 5 -#define LED_TOGGLE_INTERVAL 6 -#define GPIO_TOGGLE_THRESHOLD 1024 -#define LED_GPIO 0 - -#define POLLING_INTERVAL 30 - -#define TRACE_ITEM_CNT 64 - -#ifndef STATUS_SUCCESS -#define STATUS_SUCCESS 0 -#endif -#ifndef STATUS_FAIL -#define STATUS_FAIL 1 -#endif -#ifndef STATUS_TIMEDOUT -#define STATUS_TIMEDOUT 2 -#endif -#ifndef STATUS_NOMEM -#define STATUS_NOMEM 3 -#endif -#ifndef STATUS_READ_FAIL -#define STATUS_READ_FAIL 4 -#endif -#ifndef STATUS_WRITE_FAIL -#define STATUS_WRITE_FAIL 5 -#endif -#ifndef STATUS_ERROR -#define STATUS_ERROR 10 -#endif - -#define PM_S1 1 -#define PM_S3 3 - -/* - * Transport return codes - */ - -#define TRANSPORT_GOOD 0 /* Transport good, command good */ -#define TRANSPORT_FAILED 1 /* Transport good, command failed */ -#define TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */ -#define TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */ - -/* - * Start-Stop-Unit - */ -#define STOP_MEDIUM 0x00 /* access disable */ -#define MAKE_MEDIUM_READY 0x01 /* access enable */ -#define UNLOAD_MEDIUM 0x02 /* unload */ -#define LOAD_MEDIUM 0x03 /* load */ - -/* - * STANDARD_INQUIRY - */ -#define QULIFIRE 0x00 -#define AENC_FNC 0x00 -#define TRML_IOP 0x00 -#define REL_ADR 0x00 -#define WBUS_32 0x00 -#define WBUS_16 0x00 -#define SYNC 0x00 -#define LINKED 0x00 -#define CMD_QUE 0x00 -#define SFT_RE 0x00 - -#define VEN_ID_LEN 8 /* Vendor ID Length */ -#define PRDCT_ID_LEN 16 /* Product ID Length */ -#define PRDCT_REV_LEN 4 /* Product LOT Length */ - -/* Dynamic flag definitions: used in set_bit() etc. */ -/* 0x00040000 transfer is active */ -#define RTSX_FLIDX_TRANS_ACTIVE 18 -/* 0x00100000 abort is in progress */ -#define RTSX_FLIDX_ABORTING 20 -/* 0x00200000 disconnect in progress */ -#define RTSX_FLIDX_DISCONNECTING 21 - -#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \ - (1UL << US_FLIDX_DISCONNECTING)) - -/* 0x00400000 device reset in progress */ -#define RTSX_FLIDX_RESETTING 22 -/* 0x00800000 SCSI midlayer timed out */ -#define RTSX_FLIDX_TIMED_OUT 23 -#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */ -#define RMB_DISC 0x80 /* The Device is Removable */ -#define ANSI_SCSI2 0x02 /* Based on ANSI-SCSI2 */ - -#define SCSI 0x00 /* Interface ID */ - -#define WRITE_PROTECTED_MEDIA 0x07 - -/*---- sense key ----*/ -#define ILI 0x20 /* ILI bit is on */ - -#define NO_SENSE 0x00 /* not exist sense key */ -#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ -#define NOT_READY 0x02 /* Logical unit is not ready */ -#define MEDIA_ERR 0x03 /* medium/data error */ -#define HARDWARE_ERR 0x04 /* hardware error */ -#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ -#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ -#define DAT_PRTCT 0x07 /* read/write is desable */ -#define BLNC_CHK 0x08 /* find blank/DOF in read */ - /* write to unblank area */ -#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illegal */ -#define ABRT_CMD 0x0b /* Target make the command in error */ -#define EQUAL 0x0c /* Search Data end with Equal */ -#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ -#define MISCMP 0x0e /* find inequality */ - -#define READ_ERR -1 -#define WRITE_ERR -2 - -#define FIRST_RESET 0x01 -#define USED_EXIST 0x02 - -/* - * SENSE_DATA - */ -/*---- valid ----*/ -#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ -#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ - -/*---- error code ----*/ -#define CUR_ERR 0x70 /* current error */ -#define DEF_ERR 0x71 /* specific command error */ - -/*---- sense key Information ----*/ -#define SNSKEYINFO_LEN 3 /* length of sense key information */ - -#define SKSV 0x80 -#define CDB_ILLEGAL 0x40 -#define DAT_ILLEGAL 0x00 -#define BPV 0x08 -#define BIT_ILLEGAL0 0 /* bit0 is illegal */ -#define BIT_ILLEGAL1 1 /* bit1 is illegal */ -#define BIT_ILLEGAL2 2 /* bit2 is illegal */ -#define BIT_ILLEGAL3 3 /* bit3 is illegal */ -#define BIT_ILLEGAL4 4 /* bit4 is illegal */ -#define BIT_ILLEGAL5 5 /* bit5 is illegal */ -#define BIT_ILLEGAL6 6 /* bit6 is illegal */ -#define BIT_ILLEGAL7 7 /* bit7 is illegal */ - -/*---- ASC ----*/ -#define ASC_NO_INFO 0x00 -#define ASC_MISCMP 0x1d -#define ASC_INVLD_CDB 0x24 -#define ASC_INVLD_PARA 0x26 -#define ASC_LU_NOT_READY 0x04 -#define ASC_WRITE_ERR 0x0c -#define ASC_READ_ERR 0x11 -#define ASC_LOAD_EJCT_ERR 0x53 -#define ASC_MEDIA_NOT_PRESENT 0x3A -#define ASC_MEDIA_CHANGED 0x28 -#define ASC_MEDIA_IN_PROCESS 0x04 -#define ASC_WRITE_PROTECT 0x27 -#define ASC_LUN_NOT_SUPPORTED 0x25 - -/*---- ASQC ----*/ -#define ASCQ_NO_INFO 0x00 -#define ASCQ_MEDIA_IN_PROCESS 0x01 -#define ASCQ_MISCMP 0x00 -#define ASCQ_INVLD_CDB 0x00 -#define ASCQ_INVLD_PARA 0x02 -#define ASCQ_LU_NOT_READY 0x02 -#define ASCQ_WRITE_ERR 0x02 -#define ASCQ_READ_ERR 0x00 -#define ASCQ_LOAD_EJCT_ERR 0x00 -#define ASCQ_WRITE_PROTECT 0x00 - -struct sense_data_t { - unsigned char err_code; /* error code */ - /* bit7 : valid */ - /* (1 : SCSI2) */ - /* (0 : Vendor * specific) */ - /* bit6-0 : error * code */ - /* (0x70 : current * error) */ - /* (0x71 : specific command error) */ - unsigned char seg_no; /* segment No. */ - unsigned char sense_key; /* byte5 : ILI */ - /* bit3-0 : sense key */ - unsigned char info[4]; /* information */ - unsigned char ad_sense_len; /* additional sense data length */ - unsigned char cmd_info[4]; /* command specific information */ - unsigned char asc; /* ASC */ - unsigned char ascq; /* ASCQ */ - unsigned char rfu; /* FRU */ - unsigned char sns_key_info[3];/* sense key specific information */ -}; - -/* PCI Operation Register Address */ -#define RTSX_HCBAR 0x00 -#define RTSX_HCBCTLR 0x04 -#define RTSX_HDBAR 0x08 -#define RTSX_HDBCTLR 0x0C -#define RTSX_HAIMR 0x10 -#define RTSX_BIPR 0x14 -#define RTSX_BIER 0x18 - -/* Host command buffer control register */ -#define STOP_CMD (0x01 << 28) - -/* Host data buffer control register */ -#define SDMA_MODE 0x00 -#define ADMA_MODE (0x02 << 26) -#define STOP_DMA (0x01 << 28) -#define TRIG_DMA (0x01 << 31) - -/* Bus interrupt pending register */ -#define CMD_DONE_INT BIT(31) -#define DATA_DONE_INT BIT(30) -#define TRANS_OK_INT BIT(29) -#define TRANS_FAIL_INT BIT(28) -#define XD_INT BIT(27) -#define MS_INT BIT(26) -#define SD_INT BIT(25) -#define GPIO0_INT BIT(24) -#define OC_INT BIT(23) -#define SD_WRITE_PROTECT BIT(19) -#define XD_EXIST BIT(18) -#define MS_EXIST BIT(17) -#define SD_EXIST BIT(16) -#define DELINK_INT GPIO0_INT -#define MS_OC_INT BIT(23) -#define SD_OC_INT BIT(22) - -#define CARD_INT (XD_INT | MS_INT | SD_INT) -#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT) -#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | CARD_INT | \ - GPIO0_INT | OC_INT) - -#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST) - -/* Bus interrupt enable register */ -#define CMD_DONE_INT_EN BIT(31) -#define DATA_DONE_INT_EN BIT(30) -#define TRANS_OK_INT_EN BIT(29) -#define TRANS_FAIL_INT_EN BIT(28) -#define XD_INT_EN BIT(27) -#define MS_INT_EN BIT(26) -#define SD_INT_EN BIT(25) -#define GPIO0_INT_EN BIT(24) -#define OC_INT_EN BIT(23) -#define DELINK_INT_EN GPIO0_INT_EN -#define MS_OC_INT_EN BIT(23) -#define SD_OC_INT_EN BIT(22) - -#define READ_REG_CMD 0 -#define WRITE_REG_CMD 1 -#define CHECK_REG_CMD 2 - -#define HOST_TO_DEVICE 0 -#define DEVICE_TO_HOST 1 - -#define RTSX_RESV_BUF_LEN 4096 -#define HOST_CMDS_BUF_LEN 1024 -#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN) - -#define SD_NR 2 -#define MS_NR 3 -#define XD_NR 4 -#define SPI_NR 7 -#define SD_CARD BIT(SD_NR) -#define MS_CARD BIT(MS_NR) -#define XD_CARD BIT(XD_NR) -#define SPI_CARD BIT(SPI_NR) - -#define MAX_ALLOWED_LUN_CNT 8 - -#define XD_FREE_TABLE_CNT 1200 -#define MS_FREE_TABLE_CNT 512 - -/* Bit Operation */ -#define SET_BIT(data, idx) ((data) |= 1 << (idx)) -#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx))) -#define CHK_BIT(data, idx) ((data) & (1 << (idx))) - -/* SG descriptor */ -#define RTSX_SG_INT 0x04 -#define RTSX_SG_END 0x02 -#define RTSX_SG_VALID 0x01 - -#define RTSX_SG_NO_OP 0x00 -#define RTSX_SG_TRANS_DATA (0x02 << 4) -#define RTSX_SG_LINK_DESC (0x03 << 4) - -struct rtsx_chip; - -typedef int (*card_rw_func)(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 sec_addr, u16 sec_cnt); - -/* Supported Clock */ -enum card_clock {CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, - CLK_80, CLK_100, CLK_120, CLK_150, CLK_200}; - -enum RTSX_STAT {RTSX_STAT_INIT, RTSX_STAT_IDLE, RTSX_STAT_RUN, RTSX_STAT_SS, - RTSX_STAT_DELINK, RTSX_STAT_SUSPEND, - RTSX_STAT_ABORT, RTSX_STAT_DISCONNECT}; -enum IC_VER {IC_VER_AB, IC_VER_C = 2, IC_VER_D = 3}; - -#define MAX_RESET_CNT 3 - -/* For MS Card */ -#define MAX_DEFECTIVE_BLOCK 10 - -struct zone_entry { - u16 *l2p_table; - u16 *free_table; - u16 defect_list[MAX_DEFECTIVE_BLOCK]; /* For MS card only */ - int set_index; - int get_index; - int unused_blk_cnt; - int disable_count; - /* To indicate whether the L2P table of this zone has been built. */ - int build_flag; -}; - -#define TYPE_SD 0x0000 -#define TYPE_MMC 0x0001 - -/* TYPE_SD */ -#define SD_HS 0x0100 -#define SD_SDR50 0x0200 -#define SD_DDR50 0x0400 -#define SD_SDR104 0x0800 -#define SD_HCXC 0x1000 - -/* TYPE_MMC */ -#define MMC_26M 0x0100 -#define MMC_52M 0x0200 -#define MMC_4BIT 0x0400 -#define MMC_8BIT 0x0800 -#define MMC_SECTOR_MODE 0x1000 -#define MMC_DDR52 0x2000 - -/* SD card */ -#define CHK_SD(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_SD) -#define CHK_SD_HS(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_HS)) -#define CHK_SD_SDR50(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_SDR50)) -#define CHK_SD_DDR50(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_DDR50)) -#define CHK_SD_SDR104(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_SDR104)) -#define CHK_SD_HCXC(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_HCXC)) -#define CHK_SD_HC(sd_card) (CHK_SD_HCXC(sd_card) && \ - ((sd_card)->capacity <= 0x4000000)) -#define CHK_SD_XC(sd_card) (CHK_SD_HCXC(sd_card) && \ - ((sd_card)->capacity > 0x4000000)) -#define CHK_SD30_SPEED(sd_card) (CHK_SD_SDR50(sd_card) || \ - CHK_SD_DDR50(sd_card) || \ - CHK_SD_SDR104(sd_card)) - -#define SET_SD(sd_card) ((sd_card)->sd_type = TYPE_SD) -#define SET_SD_HS(sd_card) ((sd_card)->sd_type |= SD_HS) -#define SET_SD_SDR50(sd_card) ((sd_card)->sd_type |= SD_SDR50) -#define SET_SD_DDR50(sd_card) ((sd_card)->sd_type |= SD_DDR50) -#define SET_SD_SDR104(sd_card) ((sd_card)->sd_type |= SD_SDR104) -#define SET_SD_HCXC(sd_card) ((sd_card)->sd_type |= SD_HCXC) - -#define CLR_SD_HS(sd_card) ((sd_card)->sd_type &= ~SD_HS) -#define CLR_SD_SDR50(sd_card) ((sd_card)->sd_type &= ~SD_SDR50) -#define CLR_SD_DDR50(sd_card) ((sd_card)->sd_type &= ~SD_DDR50) -#define CLR_SD_SDR104(sd_card) ((sd_card)->sd_type &= ~SD_SDR104) -#define CLR_SD_HCXC(sd_card) ((sd_card)->sd_type &= ~SD_HCXC) - -/* MMC card */ -#define CHK_MMC(sd_card) (((sd_card)->sd_type & 0xFF) == \ - TYPE_MMC) -#define CHK_MMC_26M(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_26M)) -#define CHK_MMC_52M(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_52M)) -#define CHK_MMC_4BIT(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_4BIT)) -#define CHK_MMC_8BIT(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_8BIT)) -#define CHK_MMC_SECTOR_MODE(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_SECTOR_MODE)) -#define CHK_MMC_DDR52(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_DDR52)) - -#define SET_MMC(sd_card) ((sd_card)->sd_type = TYPE_MMC) -#define SET_MMC_26M(sd_card) ((sd_card)->sd_type |= MMC_26M) -#define SET_MMC_52M(sd_card) ((sd_card)->sd_type |= MMC_52M) -#define SET_MMC_4BIT(sd_card) ((sd_card)->sd_type |= MMC_4BIT) -#define SET_MMC_8BIT(sd_card) ((sd_card)->sd_type |= MMC_8BIT) -#define SET_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type |= MMC_SECTOR_MODE) -#define SET_MMC_DDR52(sd_card) ((sd_card)->sd_type |= MMC_DDR52) - -#define CLR_MMC_26M(sd_card) ((sd_card)->sd_type &= ~MMC_26M) -#define CLR_MMC_52M(sd_card) ((sd_card)->sd_type &= ~MMC_52M) -#define CLR_MMC_4BIT(sd_card) ((sd_card)->sd_type &= ~MMC_4BIT) -#define CLR_MMC_8BIT(sd_card) ((sd_card)->sd_type &= ~MMC_8BIT) -#define CLR_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type &= ~MMC_SECTOR_MODE) -#define CLR_MMC_DDR52(sd_card) ((sd_card)->sd_type &= ~MMC_DDR52) - -#define CHK_MMC_HS(sd_card) (CHK_MMC_52M(sd_card) && \ - CHK_MMC_26M(sd_card)) -#define CLR_MMC_HS(sd_card) \ -do { \ - CLR_MMC_DDR52(sd_card); \ - CLR_MMC_52M(sd_card); \ - CLR_MMC_26M(sd_card); \ -} while (0) - -#define SD_SUPPORT_CLASS_TEN 0x01 -#define SD_SUPPORT_1V8 0x02 - -#define SD_SET_CLASS_TEN(sd_card) ((sd_card)->sd_setting |= \ - SD_SUPPORT_CLASS_TEN) -#define SD_CHK_CLASS_TEN(sd_card) ((sd_card)->sd_setting & \ - SD_SUPPORT_CLASS_TEN) -#define SD_CLR_CLASS_TEN(sd_card) ((sd_card)->sd_setting &= \ - ~SD_SUPPORT_CLASS_TEN) -#define SD_SET_1V8(sd_card) ((sd_card)->sd_setting |= \ - SD_SUPPORT_1V8) -#define SD_CHK_1V8(sd_card) ((sd_card)->sd_setting & \ - SD_SUPPORT_1V8) -#define SD_CLR_1V8(sd_card) ((sd_card)->sd_setting &= \ - ~SD_SUPPORT_1V8) - -struct sd_info { - u16 sd_type; - u8 err_code; - u8 sd_data_buf_ready; - u32 sd_addr; - u32 capacity; - - u8 raw_csd[16]; - u8 raw_scr[8]; - - /* Sequential RW */ - int seq_mode; - enum dma_data_direction pre_dir; - u32 pre_sec_addr; - u16 pre_sec_cnt; - - int cleanup_counter; - - int sd_clock; - - int mmc_dont_switch_bus; - -#ifdef SUPPORT_CPRM - int sd_pass_thru_en; - int pre_cmd_err; - u8 last_rsp_type; - u8 rsp[17]; -#endif - - u8 func_group1_mask; - u8 func_group2_mask; - u8 func_group3_mask; - u8 func_group4_mask; - - u8 sd_switch_fail; - u8 sd_read_phase; - -#ifdef SUPPORT_SD_LOCK - u8 sd_lock_status; - u8 sd_erase_status; - u8 sd_lock_notify; -#endif - int need_retune; -}; - -struct xd_delay_write_tag { - u32 old_phyblock; - u32 new_phyblock; - u32 logblock; - u8 pageoff; - u8 delay_write_flag; -}; - -struct xd_info { - u8 maker_code; - u8 device_code; - u8 block_shift; - u8 page_off; - u8 addr_cycle; - u16 cis_block; - u8 multi_flag; - u8 err_code; - u32 capacity; - - struct zone_entry *zone; - int zone_cnt; - - struct xd_delay_write_tag delay_write; - int cleanup_counter; - - int xd_clock; -}; - -#define MODE_512_SEQ 0x01 -#define MODE_2K_SEQ 0x02 - -#define TYPE_MS 0x0000 -#define TYPE_MSPRO 0x0001 - -#define MS_4BIT 0x0100 -#define MS_8BIT 0x0200 -#define MS_HG 0x0400 -#define MS_XC 0x0800 - -#define HG8BIT (MS_HG | MS_8BIT) - -#define CHK_MSPRO(ms_card) (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO) -#define CHK_HG8BIT(ms_card) (CHK_MSPRO(ms_card) && \ - (((ms_card)->ms_type & HG8BIT) == HG8BIT)) -#define CHK_MSXC(ms_card) (CHK_MSPRO(ms_card) && \ - ((ms_card)->ms_type & MS_XC)) -#define CHK_MSHG(ms_card) (CHK_MSPRO(ms_card) && \ - ((ms_card)->ms_type & MS_HG)) - -#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT)) -#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT)) - -struct ms_delay_write_tag { - u16 old_phyblock; - u16 new_phyblock; - u16 logblock; - u8 pageoff; - u8 delay_write_flag; -}; - -struct ms_info { - u16 ms_type; - u8 block_shift; - u8 page_off; - u16 total_block; - u16 boot_block; - u32 capacity; - - u8 check_ms_flow; - u8 switch_8bit_fail; - u8 err_code; - - struct zone_entry *segment; - int segment_cnt; - - int pro_under_formatting; - int format_status; - u16 progress; - u8 raw_sys_info[96]; -#ifdef SUPPORT_PCGL_1P18 - u8 raw_model_name[48]; -#endif - - u8 multi_flag; - - /* Sequential RW */ - u8 seq_mode; - enum dma_data_direction pre_dir; - u32 pre_sec_addr; - u16 pre_sec_cnt; - u32 total_sec_cnt; - - struct ms_delay_write_tag delay_write; - - int cleanup_counter; - - int ms_clock; - -#ifdef SUPPORT_MAGIC_GATE - u8 magic_gate_id[16]; - u8 mg_entry_num; - int mg_auth; /* flag to indicate authentication process */ -#endif -}; - -struct spi_info { - u8 use_clk; - u8 write_en; - u16 clk_div; - u8 err_code; - - int spi_clock; -}; - -/************/ -/* LUN mode */ -/************/ -/* Single LUN, support xD/SD/MS */ -#define DEFAULT_SINGLE 0 -/* 2 LUN mode, support SD/MS */ -#define SD_MS_2LUN 1 -/* Single LUN, but only support SD/MS, for Barossa LQFP */ -#define SD_MS_1LUN 2 - -#define LAST_LUN_MODE 2 - -/* Barossa package */ -#define QFN 0 -#define LQFP 1 - -/******************/ -/* sd_ctl bit map */ -/******************/ -/* SD push point control, bit 0, 1 */ -#define SD_PUSH_POINT_CTL_MASK 0x03 -#define SD_PUSH_POINT_DELAY 0x01 -#define SD_PUSH_POINT_AUTO 0x02 -/* SD sample point control, bit 2, 3 */ -#define SD_SAMPLE_POINT_CTL_MASK 0x0C -#define SD_SAMPLE_POINT_DELAY 0x04 -#define SD_SAMPLE_POINT_AUTO 0x08 -/* SD DDR Tx phase set by user, bit 4 */ -#define SD_DDR_TX_PHASE_SET_BY_USER 0x10 -/* MMC DDR Tx phase set by user, bit 5 */ -#define MMC_DDR_TX_PHASE_SET_BY_USER 0x20 -/* Support MMC DDR mode, bit 6 */ -#define SUPPORT_MMC_DDR_MODE 0x40 -/* Reset MMC at first */ -#define RESET_MMC_FIRST 0x80 - -#define SEQ_START_CRITERIA 0x20 - -/* MS Power Class En */ -#define POWER_CLASS_2_EN 0x02 -#define POWER_CLASS_1_EN 0x01 - -#define MAX_SHOW_CNT 10 -#define MAX_RESET_CNT 3 - -#define SDIO_EXIST 0x01 -#define SDIO_IGNORED 0x02 - -#define CHK_SDIO_EXIST(chip) ((chip)->sdio_func_exist & SDIO_EXIST) -#define SET_SDIO_EXIST(chip) ((chip)->sdio_func_exist |= SDIO_EXIST) -#define CLR_SDIO_EXIST(chip) ((chip)->sdio_func_exist &= ~SDIO_EXIST) - -#define CHK_SDIO_IGNORED(chip) ((chip)->sdio_func_exist & SDIO_IGNORED) -#define SET_SDIO_IGNORED(chip) ((chip)->sdio_func_exist |= \ - SDIO_IGNORED) -#define CLR_SDIO_IGNORED(chip) ((chip)->sdio_func_exist &= \ - ~SDIO_IGNORED) - -struct rtsx_chip { - struct rtsx_dev *rtsx; - - u32 int_reg; /* Bus interrupt pending register */ - char max_lun; - void *context; - - void *host_cmds_ptr; /* host commands buffer pointer */ - dma_addr_t host_cmds_addr; - int ci; /* Command Index */ - - void *host_sg_tbl_ptr; /* SG descriptor table */ - dma_addr_t host_sg_tbl_addr; - int sgi; /* SG entry index */ - - struct scsi_cmnd *srb; /* current srb */ - struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; - - int cur_clk; /* current card clock */ - - /* Current accessed card */ - int cur_card; - - unsigned long need_release; /* need release bit map */ - unsigned long need_reset; /* need reset bit map */ - /* - * Flag to indicate that this card is just resumed from SS state, - * and need released before being resetted - */ - unsigned long need_reinit; - - int rw_need_retry; - -#ifdef SUPPORT_OCP - u32 ocp_int; - u8 ocp_stat; -#endif - - u8 card_exist; /* card exist bit map (physical exist) */ - u8 card_ready; /* card ready bit map (reset successfully) */ - u8 card_fail; /* card reset fail bit map */ - u8 card_ejected; /* card ejected bit map */ - u8 card_wp; /* card write protected bit map */ - - u8 lun_mc; /* - * flag to indicate whether to answer - * MediaChange - */ - -#ifndef LED_AUTO_BLINK - int led_toggle_counter; -#endif - - int sd_reset_counter; - int xd_reset_counter; - int ms_reset_counter; - - /* card bus width */ - u8 card_bus_width[MAX_ALLOWED_LUN_CNT]; - /* card capacity */ - u32 capacity[MAX_ALLOWED_LUN_CNT]; - /* read/write card function pointer */ - card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; - /* read/write capacity, used for GPIO Toggle */ - u32 rw_cap[MAX_ALLOWED_LUN_CNT]; - /* card to lun mapping table */ - u8 card2lun[32]; - /* lun to card mapping table */ - u8 lun2card[MAX_ALLOWED_LUN_CNT]; - - int rw_fail_cnt[MAX_ALLOWED_LUN_CNT]; - - int sd_show_cnt; - int xd_show_cnt; - int ms_show_cnt; - - /* card information */ - struct sd_info sd_card; - struct xd_info xd_card; - struct ms_info ms_card; - - struct spi_info spi; - - int auto_delink_cnt; - int auto_delink_allowed; - - int aspm_enabled; - - int sdio_aspm; - int sdio_idle; - int sdio_counter; - u8 sdio_raw_data[12]; - - u8 sd_io; - u8 sd_int; - - u8 rtsx_flag; - - int ss_counter; - int idle_counter; - enum RTSX_STAT rtsx_stat; - - u16 vendor_id; - u16 product_id; - u8 ic_version; - - int driver_first_load; - -#ifdef HW_AUTO_SWITCH_SD_BUS - int sdio_in_charge; -#endif - - u8 aspm_level[2]; - - int chip_insert_with_sdio; - - /* Options */ - - int adma_mode; - - int auto_delink_en; - int ss_en; - u8 lun_mode; - u8 aspm_l0s_l1_en; - - int power_down_in_ss; - - int sdr104_en; - int ddr50_en; - int sdr50_en; - - int baro_pkg; - - int asic_code; - int phy_debug_mode; - int hw_bypass_sd; - int sdio_func_exist; - int aux_pwr_exist; - u8 ms_power_class_en; - - int mspro_formatter_enable; - - int remote_wakeup_en; - - int ignore_sd; - int use_hw_setting; - - int ss_idle_period; - - int dynamic_aspm; - - int fpga_sd_sdr104_clk; - int fpga_sd_ddr50_clk; - int fpga_sd_sdr50_clk; - int fpga_sd_hs_clk; - int fpga_mmc_52m_clk; - int fpga_ms_hg_clk; - int fpga_ms_4bit_clk; - int fpga_ms_1bit_clk; - - int asic_sd_sdr104_clk; - int asic_sd_ddr50_clk; - int asic_sd_sdr50_clk; - int asic_sd_hs_clk; - int asic_mmc_52m_clk; - int asic_ms_hg_clk; - int asic_ms_4bit_clk; - int asic_ms_1bit_clk; - - u8 ssc_depth_sd_sdr104; - u8 ssc_depth_sd_ddr50; - u8 ssc_depth_sd_sdr50; - u8 ssc_depth_sd_hs; - u8 ssc_depth_mmc_52m; - u8 ssc_depth_ms_hg; - u8 ssc_depth_ms_4bit; - u8 ssc_depth_low_speed; - - u8 card_drive_sel; - u8 sd30_drive_sel_1v8; - u8 sd30_drive_sel_3v3; - - u8 sd_400mA_ocp_thd; - u8 sd_800mA_ocp_thd; - u8 ms_ocp_thd; - - int ssc_en; - int msi_en; - - int xd_timeout; - int sd_timeout; - int ms_timeout; - int mspro_timeout; - - int auto_power_down; - - int sd_ddr_tx_phase; - int mmc_ddr_tx_phase; - int sd_default_tx_phase; - int sd_default_rx_phase; - - int pmos_pwr_on_interval; - int sd_voltage_switch_delay; - int s3_pwr_off_delay; - - int force_clkreq_0; - int ft2_fast_mode; - - int do_delink_before_power_down; - int polling_config; - int sdio_retry_cnt; - - int delink_stage1_step; - int delink_stage2_step; - int delink_stage3_step; - - int auto_delink_in_L1; - int hp_watch_bios_hotplug; - int support_ms_8bit; - - u8 blink_led; - u8 phy_voltage; - u8 max_payload; - - u32 sd_speed_prior; - u32 sd_current_prior; - u32 sd_ctl; -}; - -static inline struct device *rtsx_dev(const struct rtsx_chip *chip) -{ - return &chip->rtsx->pci->dev; -} - -#define rtsx_set_stat(chip, stat) \ -do { \ - if ((stat) != RTSX_STAT_IDLE) { \ - (chip)->idle_counter = 0; \ - } \ - (chip)->rtsx_stat = (enum RTSX_STAT)(stat); \ -} while (0) -#define rtsx_get_stat(chip) ((chip)->rtsx_stat) -#define rtsx_chk_stat(chip, stat) ((chip)->rtsx_stat == (stat)) - -#define RTSX_SET_DELINK(chip) ((chip)->rtsx_flag |= 0x01) -#define RTSX_CLR_DELINK(chip) ((chip)->rtsx_flag &= 0xFE) -#define RTSX_TST_DELINK(chip) ((chip)->rtsx_flag & 0x01) - -#define CHECK_PID(chip, pid) ((chip)->product_id == (pid)) -#define CHECK_BARO_PKG(chip, pkg) ((chip)->baro_pkg == (pkg)) -#define CHECK_LUN_MODE(chip, mode) ((chip)->lun_mode == (mode)) - -/* Power down control */ -#define SSC_PDCTL 0x01 -#define OC_PDCTL 0x02 - -int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl); -int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl); - -void rtsx_enable_card_int(struct rtsx_chip *chip); -void rtsx_enable_bus_int(struct rtsx_chip *chip); -void rtsx_disable_bus_int(struct rtsx_chip *chip); -int rtsx_reset_chip(struct rtsx_chip *chip); -int rtsx_init_chip(struct rtsx_chip *chip); -void rtsx_release_chip(struct rtsx_chip *chip); -void rtsx_polling_func(struct rtsx_chip *chip); -void rtsx_stop_cmd(struct rtsx_chip *chip, int card); -int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data); -int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data); -int rtsx_write_cfg_dw(struct rtsx_chip *chip, - u8 func_no, u16 addr, u32 mask, u32 val); -int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val); -int rtsx_write_cfg_seq(struct rtsx_chip *chip, - u8 func, u16 addr, u8 *buf, int len); -int rtsx_read_cfg_seq(struct rtsx_chip *chip, - u8 func, u16 addr, u8 *buf, int len); -int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val); -int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val); -int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val); -int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val); -int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); -int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); -void rtsx_enter_ss(struct rtsx_chip *chip); -void rtsx_exit_ss(struct rtsx_chip *chip); -int rtsx_pre_handle_interrupt(struct rtsx_chip *chip); -void rtsx_enter_L1(struct rtsx_chip *chip); -void rtsx_exit_L1(struct rtsx_chip *chip); -void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat); -void rtsx_enable_aspm(struct rtsx_chip *chip); -void rtsx_disable_aspm(struct rtsx_chip *chip); -int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); -int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); -int rtsx_check_chip_exist(struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_CHIP_H */ diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c deleted file mode 100644 index c27cffb9ad8f13ed26ccfd56036470307e7df757..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ /dev/null @@ -1,3279 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include -#include - -#include "rtsx.h" -#include "sd.h" -#include "ms.h" -#include "spi.h" - -void scsi_show_command(struct rtsx_chip *chip) -{ - struct scsi_cmnd *srb = chip->srb; - char *what = NULL; - bool unknown_cmd = false; - int len; - - switch (srb->cmnd[0]) { - case TEST_UNIT_READY: - what = "TEST_UNIT_READY"; - break; - case REZERO_UNIT: - what = "REZERO_UNIT"; - break; - case REQUEST_SENSE: - what = "REQUEST_SENSE"; - break; - case FORMAT_UNIT: - what = "FORMAT_UNIT"; - break; - case READ_BLOCK_LIMITS: - what = "READ_BLOCK_LIMITS"; - break; - case REASSIGN_BLOCKS: - what = "REASSIGN_BLOCKS"; - break; - case READ_6: - what = "READ_6"; - break; - case WRITE_6: - what = "WRITE_6"; - break; - case SEEK_6: - what = "SEEK_6"; - break; - case READ_REVERSE: - what = "READ_REVERSE"; - break; - case WRITE_FILEMARKS: - what = "WRITE_FILEMARKS"; - break; - case SPACE: - what = "SPACE"; - break; - case INQUIRY: - what = "INQUIRY"; - break; - case RECOVER_BUFFERED_DATA: - what = "RECOVER_BUFFERED_DATA"; - break; - case MODE_SELECT: - what = "MODE_SELECT"; - break; - case RESERVE: - what = "RESERVE"; - break; - case RELEASE: - what = "RELEASE"; - break; - case COPY: - what = "COPY"; - break; - case ERASE: - what = "ERASE"; - break; - case MODE_SENSE: - what = "MODE_SENSE"; - break; - case START_STOP: - what = "START_STOP"; - break; - case RECEIVE_DIAGNOSTIC: - what = "RECEIVE_DIAGNOSTIC"; - break; - case SEND_DIAGNOSTIC: - what = "SEND_DIAGNOSTIC"; - break; - case ALLOW_MEDIUM_REMOVAL: - what = "ALLOW_MEDIUM_REMOVAL"; - break; - case SET_WINDOW: - what = "SET_WINDOW"; - break; - case READ_CAPACITY: - what = "READ_CAPACITY"; - break; - case READ_10: - what = "READ_10"; - break; - case WRITE_10: - what = "WRITE_10"; - break; - case SEEK_10: - what = "SEEK_10"; - break; - case WRITE_VERIFY: - what = "WRITE_VERIFY"; - break; - case VERIFY: - what = "VERIFY"; - break; - case SEARCH_HIGH: - what = "SEARCH_HIGH"; - break; - case SEARCH_EQUAL: - what = "SEARCH_EQUAL"; - break; - case SEARCH_LOW: - what = "SEARCH_LOW"; - break; - case SET_LIMITS: - what = "SET_LIMITS"; - break; - case READ_POSITION: - what = "READ_POSITION"; - break; - case SYNCHRONIZE_CACHE: - what = "SYNCHRONIZE_CACHE"; - break; - case LOCK_UNLOCK_CACHE: - what = "LOCK_UNLOCK_CACHE"; - break; - case READ_DEFECT_DATA: - what = "READ_DEFECT_DATA"; - break; - case MEDIUM_SCAN: - what = "MEDIUM_SCAN"; - break; - case COMPARE: - what = "COMPARE"; - break; - case COPY_VERIFY: - what = "COPY_VERIFY"; - break; - case WRITE_BUFFER: - what = "WRITE_BUFFER"; - break; - case READ_BUFFER: - what = "READ_BUFFER"; - break; - case UPDATE_BLOCK: - what = "UPDATE_BLOCK"; - break; - case READ_LONG: - what = "READ_LONG"; - break; - case WRITE_LONG: - what = "WRITE_LONG"; - break; - case CHANGE_DEFINITION: - what = "CHANGE_DEFINITION"; - break; - case WRITE_SAME: - what = "WRITE_SAME"; - break; - case GPCMD_READ_SUBCHANNEL: - what = "READ SUBCHANNEL"; - break; - case READ_TOC: - what = "READ_TOC"; - break; - case GPCMD_READ_HEADER: - what = "READ HEADER"; - break; - case GPCMD_PLAY_AUDIO_10: - what = "PLAY AUDIO (10)"; - break; - case GPCMD_PLAY_AUDIO_MSF: - what = "PLAY AUDIO MSF"; - break; - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - what = "GET EVENT/STATUS NOTIFICATION"; - break; - case GPCMD_PAUSE_RESUME: - what = "PAUSE/RESUME"; - break; - case LOG_SELECT: - what = "LOG_SELECT"; - break; - case LOG_SENSE: - what = "LOG_SENSE"; - break; - case GPCMD_STOP_PLAY_SCAN: - what = "STOP PLAY/SCAN"; - break; - case GPCMD_READ_DISC_INFO: - what = "READ DISC INFORMATION"; - break; - case GPCMD_READ_TRACK_RZONE_INFO: - what = "READ TRACK INFORMATION"; - break; - case GPCMD_RESERVE_RZONE_TRACK: - what = "RESERVE TRACK"; - break; - case GPCMD_SEND_OPC: - what = "SEND OPC"; - break; - case MODE_SELECT_10: - what = "MODE_SELECT_10"; - break; - case GPCMD_REPAIR_RZONE_TRACK: - what = "REPAIR TRACK"; - break; - case 0x59: - what = "READ MASTER CUE"; - break; - case MODE_SENSE_10: - what = "MODE_SENSE_10"; - break; - case GPCMD_CLOSE_TRACK: - what = "CLOSE TRACK/SESSION"; - break; - case 0x5C: - what = "READ BUFFER CAPACITY"; - break; - case 0x5D: - what = "SEND CUE SHEET"; - break; - case GPCMD_BLANK: - what = "BLANK"; - break; - case REPORT_LUNS: - what = "REPORT LUNS"; - break; - case MOVE_MEDIUM: - what = "MOVE_MEDIUM or PLAY AUDIO (12)"; - break; - case READ_12: - what = "READ_12"; - break; - case WRITE_12: - what = "WRITE_12"; - break; - case WRITE_VERIFY_12: - what = "WRITE_VERIFY_12"; - break; - case SEARCH_HIGH_12: - what = "SEARCH_HIGH_12"; - break; - case SEARCH_EQUAL_12: - what = "SEARCH_EQUAL_12"; - break; - case SEARCH_LOW_12: - what = "SEARCH_LOW_12"; - break; - case SEND_VOLUME_TAG: - what = "SEND_VOLUME_TAG"; - break; - case READ_ELEMENT_STATUS: - what = "READ_ELEMENT_STATUS"; - break; - case GPCMD_READ_CD_MSF: - what = "READ CD MSF"; - break; - case GPCMD_SCAN: - what = "SCAN"; - break; - case GPCMD_SET_SPEED: - what = "SET CD SPEED"; - break; - case GPCMD_MECHANISM_STATUS: - what = "MECHANISM STATUS"; - break; - case GPCMD_READ_CD: - what = "READ CD"; - break; - case 0xE1: - what = "WRITE CONTINUE"; - break; - case WRITE_LONG_2: - what = "WRITE_LONG_2"; - break; - case VENDOR_CMND: - what = "Realtek's vendor command"; - break; - default: - what = "(unknown command)"; - unknown_cmd = true; - break; - } - - if (srb->cmnd[0] != TEST_UNIT_READY) - dev_dbg(rtsx_dev(chip), "Command %s (%d bytes)\n", - what, srb->cmd_len); - - if (unknown_cmd) { - len = min_t(unsigned short, srb->cmd_len, 16); - dev_dbg(rtsx_dev(chip), "%*ph\n", len, srb->cmnd); - } -} - -void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type) -{ - switch (sense_type) { - case SENSE_TYPE_MEDIA_CHANGE: - set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_NOT_PRESENT: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_PROTECT: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); - break; - - case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: - set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, - ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); - break; - - case SENSE_TYPE_FORMAT_IN_PROGRESS: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); - break; - - case SENSE_TYPE_FORMAT_CMD_FAILED: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); - break; - -#ifdef SUPPORT_MAGIC_GATE - case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); - break; - - case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); - break; -#endif - -#ifdef SUPPORT_SD_LOCK - case SENSE_TYPE_MEDIA_READ_FORBIDDEN: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); - break; -#endif - - case SENSE_TYPE_NO_SENSE: - default: - set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); - break; - } -} - -void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, - u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0, - u16 sns_key_info1) -{ - struct sense_data_t *sense = &chip->sense_buffer[lun]; - - sense->err_code = err_code; - sense->sense_key = sense_key; - sense->info[0] = (u8)(info >> 24); - sense->info[1] = (u8)(info >> 16); - sense->info[2] = (u8)(info >> 8); - sense->info[3] = (u8)info; - - sense->ad_sense_len = sizeof(struct sense_data_t) - 8; - sense->asc = asc; - sense->ascq = ascq; - if (sns_key_info0 != 0) { - sense->sns_key_info[0] = SKSV | sns_key_info0; - sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 4; - sense->sns_key_info[2] = sns_key_info1 & 0x0f; - } -} - -static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - -#ifdef SUPPORT_SD_LOCK - if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { - struct sd_info *sd_card = &chip->sd_card; - - if (sd_card->sd_lock_notify) { - sd_card->sd_lock_notify = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } else if (sd_card->sd_lock_status & SD_LOCKED) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - } -#endif - - return TRANSPORT_GOOD; -} - -static unsigned char formatter_inquiry_str[20] = { - 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', -#ifdef SUPPORT_MAGIC_GATE - '-', 'M', 'G', /* Byte[47:49] */ -#else - 0x20, 0x20, 0x20, /* Byte[47:49] */ -#endif - -#ifdef SUPPORT_MAGIC_GATE - 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ -#else - 0x09, /* Byte[50]: MS, MSPro, MSXC */ -#endif - 0x00, /* Byte[51]: Category Specific Commands */ - 0x00, /* Byte[52]: Access Control and feature */ - 0x20, 0x20, 0x20, /* Byte[53:55] */ -}; - -static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00"; - char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00"; - char *inquiry_sd = (char *)"Generic-SD/MMC 1.00"; - char *inquiry_ms = (char *)"Generic-MemoryStick 1.00"; - char *inquiry_string; - unsigned char sendbytes; - unsigned char *buf; - u8 card = get_lun_card(chip, lun); - bool pro_formatter_flag = false; - unsigned char inquiry_buf[] = { - QULIFIRE | DRCT_ACCESS_DEV, - RMB_DISC | 0x0D, - 0x00, - 0x01, - 0x1f, - 0x02, - 0, - REL_ADR | WBUS_32 | WBUS_16 | SYNC | LINKED | CMD_QUE | SFT_RE, - }; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - inquiry_string = inquiry_sd; - else - inquiry_string = inquiry_ms; - - } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { - inquiry_string = inquiry_sdms; - } else { - inquiry_string = inquiry_default; - } - - buf = vmalloc(scsi_bufflen(srb)); - if (!buf) - return TRANSPORT_ERROR; - -#ifdef SUPPORT_MAGIC_GATE - if (chip->mspro_formatter_enable && - (chip->lun2card[lun] & MS_CARD)) -#else - if (chip->mspro_formatter_enable) -#endif - if (!card || card == MS_CARD) - pro_formatter_flag = true; - - if (pro_formatter_flag) { - if (scsi_bufflen(srb) < 56) - sendbytes = (unsigned char)(scsi_bufflen(srb)); - else - sendbytes = 56; - - } else { - if (scsi_bufflen(srb) < 36) - sendbytes = (unsigned char)(scsi_bufflen(srb)); - else - sendbytes = 36; - } - - if (sendbytes > 8) { - memcpy(buf, inquiry_buf, 8); - memcpy(buf + 8, inquiry_string, min(sendbytes, 36) - 8); - if (pro_formatter_flag) { - /* Additional Length */ - buf[4] = 0x33; - } - } else { - memcpy(buf, inquiry_buf, sendbytes); - } - - if (pro_formatter_flag) { - if (sendbytes > 36) - memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); - } - - scsi_set_resid(srb, 0); - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - scsi_set_resid(srb, scsi_bufflen(srb)); - - if (srb->cmnd[1] == 1) - return TRANSPORT_GOOD; - - switch (srb->cmnd[0x4]) { - case STOP_MEDIUM: - /* Media disabled */ - return TRANSPORT_GOOD; - - case UNLOAD_MEDIUM: - /* Media shall be unload */ - if (check_card_ready(chip, lun)) - eject_card(chip, lun); - return TRANSPORT_GOOD; - - case MAKE_MEDIUM_READY: - case LOAD_MEDIUM: - if (check_card_ready(chip, lun)) - return TRANSPORT_GOOD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - - break; - } - - return TRANSPORT_ERROR; -} - -static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int prevent; - - prevent = srb->cmnd[4] & 0x1; - - scsi_set_resid(srb, 0); - - if (prevent) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sense_data_t *sense; - unsigned int lun = SCSI_LUN(srb); - struct ms_info *ms_card = &chip->ms_card; - unsigned char *tmp, *buf; - - sense = &chip->sense_buffer[lun]; - - if ((get_lun_card(chip, lun) == MS_CARD) && - ms_card->pro_under_formatting) { - if (ms_card->format_status == FORMAT_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } else if (ms_card->format_status == FORMAT_IN_PROGRESS) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16)(ms_card->progress)); - } else { - /* Format Command Failed */ - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } - - rtsx_set_stat(chip, RTSX_STAT_RUN); - } - - buf = vmalloc(scsi_bufflen(srb)); - if (!buf) - return TRANSPORT_ERROR; - - tmp = (unsigned char *)sense; - memcpy(buf, tmp, scsi_bufflen(srb)); - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - scsi_set_resid(srb, 0); - /* Reset Sense Data */ - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - return TRANSPORT_GOOD; -} - -static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, - int lun, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int sys_info_offset; - int data_size = buf_len; - bool support_format = false; - int i = 0; - - if (cmd == MODE_SENSE) { - sys_info_offset = 8; - if (data_size > 0x68) - data_size = 0x68; - - buf[i++] = 0x67; /* Mode Data Length */ - } else { - sys_info_offset = 12; - if (data_size > 0x6C) - data_size = 0x6C; - - buf[i++] = 0x00; /* Mode Data Length (MSB) */ - buf[i++] = 0x6A; /* Mode Data Length (LSB) */ - } - - /* Medium Type Code */ - if (check_card_ready(chip, lun)) { - if (CHK_MSXC(ms_card)) { - support_format = true; - buf[i++] = 0x40; - } else if (CHK_MSPRO(ms_card)) { - support_format = true; - buf[i++] = 0x20; - } else { - buf[i++] = 0x10; - } - - /* WP */ - if (check_card_wp(chip, lun)) - buf[i++] = 0x80; - else - buf[i++] = 0x00; - - } else { - buf[i++] = 0x00; /* MediaType */ - buf[i++] = 0x00; /* WP */ - } - - buf[i++] = 0x00; /* Reserved */ - - if (cmd == MODE_SENSE_10) { - buf[i++] = 0x00; /* Reserved */ - buf[i++] = 0x00; /* Block descriptor length(MSB) */ - buf[i++] = 0x00; /* Block descriptor length(LSB) */ - - /* The Following Data is the content of "Page 0x20" */ - if (data_size >= 9) - buf[i++] = 0x20; /* Page Code */ - if (data_size >= 10) - buf[i++] = 0x62; /* Page Length */ - if (data_size >= 11) - buf[i++] = 0x00; /* No Access Control */ - if (data_size >= 12) { - if (support_format) - buf[i++] = 0xC0; /* SF, SGM */ - else - buf[i++] = 0x00; - } - } else { - /* The Following Data is the content of "Page 0x20" */ - if (data_size >= 5) - buf[i++] = 0x20; /* Page Code */ - if (data_size >= 6) - buf[i++] = 0x62; /* Page Length */ - if (data_size >= 7) - buf[i++] = 0x00; /* No Access Control */ - if (data_size >= 8) { - if (support_format) - buf[i++] = 0xC0; /* SF, SGM */ - else - buf[i++] = 0x00; - } - } - - if (data_size > sys_info_offset) { - /* 96 Bytes Attribute Data */ - int len = data_size - sys_info_offset; - - len = (len < 96) ? len : 96; - - memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len); - } -} - -static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - unsigned int data_size; - int status; - bool pro_formatter_flag; - unsigned char page_code, *buf; - u8 card = get_lun_card(chip, lun); - -#ifndef SUPPORT_MAGIC_GATE - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - scsi_set_resid(srb, scsi_bufflen(srb)); - return TRANSPORT_FAILED; - } -#endif - - pro_formatter_flag = false; - data_size = 8; -#ifdef SUPPORT_MAGIC_GATE - if ((chip->lun2card[lun] & MS_CARD)) { - if (!card || card == MS_CARD) { - data_size = 108; - if (chip->mspro_formatter_enable) - pro_formatter_flag = true; - } - } -#else - if (card == MS_CARD) { - if (chip->mspro_formatter_enable) { - pro_formatter_flag = true; - data_size = 108; - } - } -#endif - - buf = kmalloc(data_size, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - page_code = srb->cmnd[2] & 0x3f; - - if (page_code == 0x3F || page_code == 0x1C || - page_code == 0x00 || - (pro_formatter_flag && page_code == 0x20)) { - if (srb->cmnd[0] == MODE_SENSE) { - if (page_code == 0x3F || page_code == 0x20) { - ms_mode_sense(chip, srb->cmnd[0], - lun, buf, data_size); - } else { - data_size = 4; - buf[0] = 0x03; - buf[1] = 0x00; - if (check_card_wp(chip, lun)) - buf[2] = 0x80; - else - buf[2] = 0x00; - - buf[3] = 0x00; - } - } else { - if (page_code == 0x3F || page_code == 0x20) { - ms_mode_sense(chip, srb->cmnd[0], - lun, buf, data_size); - } else { - data_size = 8; - buf[0] = 0x00; - buf[1] = 0x06; - buf[2] = 0x00; - if (check_card_wp(chip, lun)) - buf[3] = 0x80; - else - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x00; - buf[7] = 0x00; - } - } - status = TRANSPORT_GOOD; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - scsi_set_resid(srb, scsi_bufflen(srb)); - status = TRANSPORT_FAILED; - } - - if (status == TRANSPORT_GOOD) { - unsigned int len = min_t(unsigned int, scsi_bufflen(srb), - data_size); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - } - kfree(buf); - - return status; -} - -static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; -#endif - unsigned int lun = SCSI_LUN(srb); - int retval; - u32 start_sec; - u16 sec_cnt; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Accessing to any card is forbidden - * until the erase procedure of SD is completed - */ - dev_dbg(rtsx_dev(chip), "SD card being erased!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - - if (get_lun_card(chip, lun) == SD_CARD) { - if (sd_card->sd_lock_status & SD_LOCKED) { - dev_dbg(rtsx_dev(chip), "SD card locked!\n"); - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - } -#endif - - if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) { - start_sec = ((u32)srb->cmnd[2] << 24) | - ((u32)srb->cmnd[3] << 16) | - ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]); - sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { - start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) | - ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]); - sec_cnt = srb->cmnd[4]; - if (sec_cnt == 0) - sec_cnt = 256; - } else if ((srb->cmnd[0] == VENDOR_CMND) && - (srb->cmnd[1] == SCSI_APP_CMD) && - ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) { - start_sec = ((u32)srb->cmnd[4] << 24) | - ((u32)srb->cmnd[5] << 16) | - ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]); - sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10]; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - /* In some test, we will receive a start_sec like 0xFFFFFFFF. - * In this situation, start_sec + sec_cnt will overflow, so we - * need to judge start_sec at first - */ - if (start_sec > get_card_size(chip, lun) || - ((start_sec + sec_cnt) > get_card_size(chip, lun))) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); - return TRANSPORT_FAILED; - } - - if (sec_cnt == 0) { - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - if (chip->rw_fail_cnt[lun] == 3) { - dev_dbg(rtsx_dev(chip), "read/write fail three times in succession\n"); - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - return TRANSPORT_FAILED; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (check_card_wp(chip, lun)) { - dev_dbg(rtsx_dev(chip), "Write protected card!\n"); - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_PROTECT); - return TRANSPORT_FAILED; - } - } - - retval = card_rw(srb, chip, start_sec, sec_cnt); - if (retval != STATUS_SUCCESS) { - if (chip->need_release & chip->lun2card[lun]) { - chip->rw_fail_cnt[lun] = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } else { - chip->rw_fail_cnt[lun]++; - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type - (chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - } - retval = TRANSPORT_FAILED; - goto exit; - } else { - chip->rw_fail_cnt[lun] = 0; - retval = TRANSPORT_GOOD; - } - - scsi_set_resid(srb, 0); - -exit: - return retval; -} - -static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - unsigned int buf_len; - u8 card = get_lun_card(chip, lun); - u32 card_size; - int desc_cnt; - int i = 0; - - if (!check_card_ready(chip, lun)) { - if (!chip->mspro_formatter_enable) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - } - - buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - buf[i++] = 0; - buf[i++] = 0; - buf[i++] = 0; - - /* Capacity List Length */ - if (buf_len > 12 && chip->mspro_formatter_enable && - (chip->lun2card[lun] & MS_CARD) && - (!card || card == MS_CARD)) { - buf[i++] = 0x10; - desc_cnt = 2; - } else { - buf[i++] = 0x08; - desc_cnt = 1; - } - - while (desc_cnt) { - if (check_card_ready(chip, lun)) { - card_size = get_card_size(chip, lun); - buf[i++] = (unsigned char)(card_size >> 24); - buf[i++] = (unsigned char)(card_size >> 16); - buf[i++] = (unsigned char)(card_size >> 8); - buf[i++] = (unsigned char)card_size; - - if (desc_cnt == 2) - buf[i++] = 2; - else - buf[i++] = 0; - } else { - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - - if (desc_cnt == 2) - buf[i++] = 3; - else - buf[i++] = 0; - } - - buf[i++] = 0x00; - buf[i++] = 0x02; - buf[i++] = 0x00; - - desc_cnt--; - } - - buf_len = min_t(unsigned int, scsi_bufflen(srb), buf_len); - rtsx_stor_set_xfer_buf(buf, buf_len, srb); - kfree(buf); - - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - u32 card_size; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - buf = kmalloc(8, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - card_size = get_card_size(chip, lun); - buf[0] = (unsigned char)((card_size - 1) >> 24); - buf[1] = (unsigned char)((card_size - 1) >> 16); - buf[2] = (unsigned char)((card_size - 1) >> 8); - buf[3] = (unsigned char)(card_size - 1); - - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x02; - buf[7] = 0x00; - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - kfree(buf); - - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = spi_read_eeprom(chip, i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - if (len == 511) { - retval = spi_erase_eeprom_chip(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } else { - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), - len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - for (i = 0; i < len; i++) { - retval = spi_write_eeprom(chip, i, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xFC00) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = rtsx_read_register(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xFC00) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (get_lun_card(chip, lun) != SD_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -static int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 gpio = srb->cmnd[2]; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (gpio > 3) - gpio = 1; - toggle_gpio(chip, gpio); - - return TRANSPORT_GOOD; -} - -static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 addr, buf[4]; - u32 val; - unsigned int len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - - val = rtsx_readl(chip, addr); - dev_dbg(rtsx_dev(chip), "Host register (0x%x): 0x%x\n", addr, val); - - buf[0] = (u8)(val >> 24); - buf[1] = (u8)(val >> 16); - buf[2] = (u8)(val >> 8); - buf[3] = (u8)val; - - len = min_t(unsigned int, scsi_bufflen(srb), 4); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - return TRANSPORT_GOOD; -} - -static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 addr, buf[4]; - u32 val; - unsigned int len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - - len = min_t(unsigned int, scsi_bufflen(srb), 4); - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2] - << 8) | buf[3]; - - rtsx_writel(chip, addr, val); - - return TRANSPORT_GOOD; -} - -static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (srb->cmnd[3] == 1) { - /* Variable Clock */ - struct xd_info *xd_card = &chip->xd_card; - struct sd_info *sd_card = &chip->sd_card; - struct ms_info *ms_card = &chip->ms_card; - - switch (srb->cmnd[4]) { - case XD_CARD: - xd_card->xd_clock = srb->cmnd[5]; - break; - - case SD_CARD: - sd_card->sd_clock = srb->cmnd[5]; - break; - - case MS_CARD: - ms_card->ms_clock = srb->cmnd[5]; - break; - - default: - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - } else if (srb->cmnd[3] == 2) { - if (srb->cmnd[4]) { - chip->blink_led = 1; - } else { - int retval; - - chip->blink_led = 0; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && - (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - turn_off_led(chip, LED_GPIO); - } - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (srb->cmnd[3] == 1) { - struct xd_info *xd_card = &chip->xd_card; - struct sd_info *sd_card = &chip->sd_card; - struct ms_info *ms_card = &chip->ms_card; - u8 tmp; - - switch (srb->cmnd[4]) { - case XD_CARD: - tmp = (u8)(xd_card->xd_clock); - break; - - case SD_CARD: - tmp = (u8)(sd_card->sd_clock); - break; - - case MS_CARD: - tmp = (u8)(ms_card->ms_clock); - break; - - default: - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_stor_set_xfer_buf(&tmp, 1, srb); - } else if (srb->cmnd[3] == 2) { - u8 tmp = chip->blink_led; - - rtsx_stor_set_xfer_buf(&tmp, 1, srb); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - unsigned int lun = SCSI_LUN(srb); - u16 len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = min_t(u16, len, scsi_bufflen(srb)); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) - dev_dbg(rtsx_dev(chip), "Read from device\n"); - else - dev_dbg(rtsx_dev(chip), "Write to device\n"); - - retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len, - scsi_sg_count(srb), srb->sc_data_direction, - 1000); - if (retval < 0) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - - return TRANSPORT_FAILED; - } - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - struct ms_info *ms_card = &chip->ms_card; - int buf_len; - unsigned int lun = SCSI_LUN(srb); - u8 card = get_lun_card(chip, lun); - u8 status[32]; -#ifdef SUPPORT_OCP - u8 oc_now_mask = 0, oc_ever_mask = 0; -#endif - - memset(status, 0, 32); - - status[0] = (u8)(chip->product_id); - status[1] = chip->ic_version; - - if (chip->auto_delink_en) - status[2] = 0x10; - else - status[2] = 0x00; - - status[3] = 20; - status[4] = 10; - status[5] = 05; - status[6] = 21; - - if (chip->card_wp) - status[7] = 0x20; - else - status[7] = 0x00; - -#ifdef SUPPORT_OCP - status[8] = 0; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && - chip->lun2card[lun] == MS_CARD) { - oc_now_mask = MS_OC_NOW; - oc_ever_mask = MS_OC_EVER; - } else { - oc_now_mask = SD_OC_NOW; - oc_ever_mask = SD_OC_EVER; - } - - if (chip->ocp_stat & oc_now_mask) - status[8] |= 0x02; - - if (chip->ocp_stat & oc_ever_mask) - status[8] |= 0x01; -#endif - - if (card == SD_CARD) { - if (CHK_SD(sd_card)) { - if (CHK_SD_HCXC(sd_card)) { - if (sd_card->capacity > 0x4000000) - status[0x0E] = 0x02; - else - status[0x0E] = 0x01; - } else { - status[0x0E] = 0x00; - } - - if (CHK_SD_SDR104(sd_card)) - status[0x0F] = 0x03; - else if (CHK_SD_DDR50(sd_card)) - status[0x0F] = 0x04; - else if (CHK_SD_SDR50(sd_card)) - status[0x0F] = 0x02; - else if (CHK_SD_HS(sd_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } else { - if (CHK_MMC_SECTOR_MODE(sd_card)) - status[0x0E] = 0x01; - else - status[0x0E] = 0x00; - - if (CHK_MMC_DDR52(sd_card)) - status[0x0F] = 0x03; - else if (CHK_MMC_52M(sd_card)) - status[0x0F] = 0x02; - else if (CHK_MMC_26M(sd_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } - } else if (card == MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (CHK_MSXC(ms_card)) - status[0x0E] = 0x01; - else - status[0x0E] = 0x00; - - if (CHK_HG8BIT(ms_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } - } - -#ifdef SUPPORT_SD_LOCK - if (card == SD_CARD) { - status[0x17] = 0x80; - if (sd_card->sd_erase_status) - status[0x17] |= 0x01; - if (sd_card->sd_lock_status & SD_LOCKED) { - status[0x17] |= 0x02; - status[0x07] |= 0x40; - } - if (sd_card->sd_lock_status & SD_PWD_EXIST) - status[0x17] |= 0x04; - } else { - status[0x17] = 0x00; - } - - dev_dbg(rtsx_dev(chip), "status[0x17] = 0x%x\n", status[0x17]); -#endif - - status[0x18] = 0x8A; - status[0x1A] = 0x28; -#ifdef SUPPORT_SD_LOCK - status[0x1F] = 0x01; -#endif - - buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(status)); - rtsx_stor_set_xfer_buf(status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int phy_debug_mode; - int retval; - u16 reg; - - if (!CHECK_PID(chip, 0x5208)) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - phy_debug_mode = (int)(srb->cmnd[3]); - - if (phy_debug_mode) { - chip->phy_debug_mode = 1; - retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - rtsx_disable_bus_int(chip); - - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - reg |= 0x0001; - retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } else { - chip->phy_debug_mode = 0; - retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - rtsx_enable_bus_int(chip); - - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - reg &= 0xFFFE; - retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval = STATUS_SUCCESS; - unsigned int lun = SCSI_LUN(srb); - u8 cmd_type, mask, value, idx; - u16 addr; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - rtsx_init_cmd(chip); - break; - - case ADD_BATCHCMD: - cmd_type = srb->cmnd[4]; - if (cmd_type > 2) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; - mask = srb->cmnd[7]; - value = srb->cmnd[8]; - rtsx_add_cmd(chip, cmd_type, addr, mask, value); - break; - - case SEND_BATCHCMD: - retval = rtsx_send_cmd(chip, 0, 1000); - break; - - case GET_BATCHRSP: - idx = srb->cmnd[4]; - value = *(rtsx_get_cmd_data(chip) + idx); - if (scsi_bufflen(srb) < 1) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - rtsx_stor_set_xfer_buf(&value, 1, srb); - scsi_set_resid(srb, 0); - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - case ADD_BATCHCMD: - case SEND_BATCHCMD: - case GET_BATCHRSP: - return rw_mem_cmd_buf(srb, chip); - default: - return TRANSPORT_ERROR; - } -} - -static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - u16 val; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - if (len % 2) - len -= len % 2; - - if (len) { - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len / 2; i++) { - retval = rtsx_read_phy_register(chip, addr + i, &val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type - (chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - buf[2 * i] = (u8)(val >> 8); - buf[2 * i + 1] = (u8)val; - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), - len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - u16 val; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - if (len % 2) - len -= len % 2; - - if (len) { - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), - len); - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len / 2; i++) { - val = ((u16)buf[2 * i] << 8) | buf[2 * i + 1]; - retval = rtsx_write_phy_register(chip, addr + i, val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr; - int retval; - u8 mode; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - mode = srb->cmnd[3]; - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (mode == 0) { - retval = spi_erase_eeprom_chip(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } else if (mode == 1) { - retval = spi_erase_eeprom_byte(chip, addr); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } else { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = spi_read_eeprom(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = spi_write_eeprom(chip, addr + i, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 addr, len, i; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - len = srb->cmnd[5]; - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = rtsx_read_efuse(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (u8)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval, result = TRANSPORT_GOOD; - u16 val; - u8 addr, len, i; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - len = srb->cmnd[5]; - - len = (u8)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - if (chip->asic_code) { - retval = rtsx_read_phy_register(chip, 0x08, &val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_OFF); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - wait_timeout(600); - - retval = rtsx_write_phy_register(chip, 0x08, - 0x4C00 | chip->phy_voltage); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_ON); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - wait_timeout(600); - } - - retval = card_power_on(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - wait_timeout(50); - - for (i = 0; i < len; i++) { - retval = rtsx_write_efuse(chip, addr + i, buf[i]); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - result = TRANSPORT_FAILED; - goto exit; - } - } - -exit: - vfree(buf); - - retval = card_power_off(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - - if (chip->asic_code) { - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_OFF); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - - wait_timeout(600); - - retval = rtsx_write_phy_register(chip, 0x08, val); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_ON); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - } - - return result; -} - -static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - bool func_max; - u8 func; - u16 addr, len; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - func = srb->cmnd[3]; - addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; - - dev_dbg(rtsx_dev(chip), "%s: func = %d, addr = 0x%x, len = %d\n", - __func__, func, addr, len); - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = true; - else - func_max = false; - - if (func > func_max) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_read_cfg_seq(chip, func, addr, buf, len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - vfree(buf); - return TRANSPORT_FAILED; - } - - len = (u16)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - bool func_max; - u8 func; - u16 addr, len; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - func = srb->cmnd[3]; - addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; - - dev_dbg(rtsx_dev(chip), "%s: func = %d, addr = 0x%x\n", - __func__, func, addr); - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = true; - else - func_max = false; - - if (func > func_max) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_write_cfg_seq(chip, func, addr, buf, len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - vfree(buf); - return TRANSPORT_FAILED; - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - switch (srb->cmnd[2]) { - case PP_READ10: - case PP_WRITE10: - result = read_write(srb, chip); - break; - - case READ_HOST_REG: - result = read_host_reg(srb, chip); - break; - - case WRITE_HOST_REG: - result = write_host_reg(srb, chip); - break; - - case GET_VAR: - result = get_variable(srb, chip); - break; - - case SET_VAR: - result = set_variable(srb, chip); - break; - - case DMA_READ: - case DMA_WRITE: - result = dma_access_ring_buffer(srb, chip); - break; - - case READ_PHY: - result = read_phy_register(srb, chip); - break; - - case WRITE_PHY: - result = write_phy_register(srb, chip); - break; - - case ERASE_EEPROM2: - result = erase_eeprom2(srb, chip); - break; - - case READ_EEPROM2: - result = read_eeprom2(srb, chip); - break; - - case WRITE_EEPROM2: - result = write_eeprom2(srb, chip); - break; - - case READ_EFUSE: - result = read_efuse(srb, chip); - break; - - case WRITE_EFUSE: - result = write_efuse(srb, chip); - break; - - case READ_CFG: - result = read_cfg_byte(srb, chip); - break; - - case WRITE_CFG: - result = write_cfg_byte(srb, chip); - break; - - case SET_CHIP_MODE: - result = set_chip_mode(srb, chip); - break; - - case SUIT_CMD: - result = suit_cmd(srb, chip); - break; - - case GET_DEV_STATUS: - result = get_dev_status(srb, chip); - break; - - default: - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return result; -} - -static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 rtsx_status[16]; - int buf_len; - unsigned int lun = SCSI_LUN(srb); - - rtsx_status[0] = (u8)(chip->vendor_id >> 8); - rtsx_status[1] = (u8)(chip->vendor_id); - - rtsx_status[2] = (u8)(chip->product_id >> 8); - rtsx_status[3] = (u8)(chip->product_id); - - rtsx_status[4] = (u8)lun; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[5] = 2; - else - rtsx_status[5] = 3; - } else { - if (chip->card_exist) { - if (chip->card_exist & XD_CARD) - rtsx_status[5] = 4; - else if (chip->card_exist & SD_CARD) - rtsx_status[5] = 2; - else if (chip->card_exist & MS_CARD) - rtsx_status[5] = 3; - else - rtsx_status[5] = 7; - } else { - rtsx_status[5] = 7; - } - } - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_status[6] = 2; - else - rtsx_status[6] = 1; - - rtsx_status[7] = (u8)(chip->product_id); - rtsx_status[8] = chip->ic_version; - - if (check_card_exist(chip, lun)) - rtsx_status[9] = 1; - else - rtsx_status[9] = 0; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_status[10] = 0; - else - rtsx_status[10] = 1; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[11] = SD_CARD; - else - rtsx_status[11] = MS_CARD; - } else { - rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD; - } - - if (check_card_ready(chip, lun)) - rtsx_status[12] = 1; - else - rtsx_status[12] = 0; - - if (get_lun_card(chip, lun) == XD_CARD) { - rtsx_status[13] = 0x40; - } else if (get_lun_card(chip, lun) == SD_CARD) { - struct sd_info *sd_card = &chip->sd_card; - - rtsx_status[13] = 0x20; - if (CHK_SD(sd_card)) { - if (CHK_SD_HCXC(sd_card)) - rtsx_status[13] |= 0x04; - if (CHK_SD_HS(sd_card)) - rtsx_status[13] |= 0x02; - } else { - rtsx_status[13] |= 0x08; - if (CHK_MMC_52M(sd_card)) - rtsx_status[13] |= 0x02; - if (CHK_MMC_SECTOR_MODE(sd_card)) - rtsx_status[13] |= 0x04; - } - } else if (get_lun_card(chip, lun) == MS_CARD) { - struct ms_info *ms_card = &chip->ms_card; - - if (CHK_MSPRO(ms_card)) { - rtsx_status[13] = 0x38; - if (CHK_HG8BIT(ms_card)) - rtsx_status[13] |= 0x04; -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) - rtsx_status[13] |= 0x01; -#endif - } else { - rtsx_status[13] = 0x30; - } - } else { - if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) { -#ifdef SUPPORT_SDIO - if (chip->sd_io && chip->sd_int) - rtsx_status[13] = 0x60; - else - rtsx_status[13] = 0x70; -#else - rtsx_status[13] = 0x70; -#endif - } else { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[13] = 0x20; - else - rtsx_status[13] = 0x30; - } - } - - rtsx_status[14] = 0x78; - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - rtsx_status[15] = 0x83; - else - rtsx_status[15] = 0x82; - - buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(rtsx_status)); - rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - u8 card, bus_width; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - card = get_lun_card(chip, lun); - if (card == SD_CARD || card == MS_CARD) { - bus_width = chip->card_bus_width[lun]; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - unsigned int lun = SCSI_LUN(srb); - u8 gpio_dir; - - if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL); - - rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir); - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06); - - switch (srb->cmnd[2]) { - case SCSI_SPI_GETSTATUS: - result = spi_get_status(srb, chip); - break; - - case SCSI_SPI_SETPARAMETER: - result = spi_set_parameter(srb, chip); - break; - - case SCSI_SPI_READFALSHID: - result = spi_read_flash_id(srb, chip); - break; - - case SCSI_SPI_READFLASH: - result = spi_read_flash(srb, chip); - break; - - case SCSI_SPI_WRITEFLASH: - result = spi_write_flash(srb, chip); - break; - - case SCSI_SPI_WRITEFLASHSTATUS: - result = spi_write_flash_status(srb, chip); - break; - - case SCSI_SPI_ERASEFLASH: - result = spi_erase_flash(srb, chip); - break; - - default: - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); - - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); - - if (result != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - return TRANSPORT_GOOD; -} - -static int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - switch (srb->cmnd[1]) { - case READ_STATUS: - result = read_status(srb, chip); - break; - - case READ_MEM: - result = read_mem(srb, chip); - break; - - case WRITE_MEM: - result = write_mem(srb, chip); - break; - - case READ_EEPROM: - result = read_eeprom(srb, chip); - break; - - case WRITE_EEPROM: - result = write_eeprom(srb, chip); - break; - - case TOGGLE_GPIO: - result = toggle_gpio_cmd(srb, chip); - break; - - case GET_SD_CSD: - result = get_sd_csd(srb, chip); - break; - - case GET_BUS_WIDTH: - result = get_card_bus_width(srb, chip); - break; - - case SCSI_APP_CMD: - result = app_cmd(srb, chip); - break; - - case SPI_VENDOR_COMMAND: - result = spi_vendor_cmd(srb, chip); - break; - - default: - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return result; -} - -#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) -void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - u16 sec_cnt; - - if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) { - sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { - sec_cnt = srb->cmnd[4]; - if (sec_cnt == 0) - sec_cnt = 256; - } else { - return; - } - - if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { - toggle_gpio(chip, LED_GPIO); - chip->rw_cap[lun] = 0; - } else { - chip->rw_cap[lun] += sec_cnt; - } -} -#endif - -static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - bool quick_format; - int retval; - - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[3] != 0x4D || srb->cmnd[4] != 0x47 || - srb->cmnd[5] != 0x66 || srb->cmnd[6] != 0x6D || - srb->cmnd[7] != 0x74) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - - if (!check_card_ready(chip, lun) || - (get_card_size(chip, lun) == 0)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (srb->cmnd[8] & 0x01) - quick_format = false; - else - quick_format = true; - - if (!(chip->card_ready & MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (chip->card_wp & MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - return TRANSPORT_FAILED; - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -#ifdef SUPPORT_PCGL_1P18 -static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - u8 dev_info_id, data_len; - u8 *buf; - unsigned int buf_len; - int i; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[2] != 0xB0 || srb->cmnd[4] != 0x4D || - srb->cmnd[5] != 0x53 || srb->cmnd[6] != 0x49 || - srb->cmnd[7] != 0x44) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - dev_info_id = srb->cmnd[3]; - if ((CHK_MSXC(ms_card) && dev_info_id == 0x10) || - (!CHK_MSXC(ms_card) && dev_info_id == 0x13) || - !CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (dev_info_id == 0x15) { - buf_len = 0x3C; - data_len = 0x3A; - } else { - buf_len = 0x6C; - data_len = 0x6A; - } - - buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - i = 0; - /* GET Memory Stick Media Information Response Header */ - buf[i++] = 0x00; /* Data length MSB */ - buf[i++] = data_len; /* Data length LSB */ - /* Device Information Type Code */ - if (CHK_MSXC(ms_card)) - buf[i++] = 0x03; - else - buf[i++] = 0x02; - - /* SGM bit */ - buf[i++] = 0x01; - /* Reserved */ - buf[i++] = 0x00; - buf[i++] = 0x00; - buf[i++] = 0x00; - /* Number of Device Information */ - buf[i++] = 0x01; - - /* Device Information Body */ - - /* Device Information ID Number */ - buf[i++] = dev_info_id; - /* Device Information Length */ - if (dev_info_id == 0x15) - data_len = 0x31; - else - data_len = 0x61; - - buf[i++] = 0x00; /* Data length MSB */ - buf[i++] = data_len; /* Data length LSB */ - /* Valid Bit */ - buf[i++] = 0x80; - if (dev_info_id == 0x10 || dev_info_id == 0x13) { - /* System Information */ - memcpy(buf + i, ms_card->raw_sys_info, 96); - } else { - /* Model Name */ - memcpy(buf + i, ms_card->raw_model_name, 48); - } - - rtsx_stor_set_xfer_buf(buf, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - kfree(buf); - return STATUS_SUCCESS; -} -#endif - -static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval = TRANSPORT_ERROR; - - if (srb->cmnd[2] == MS_FORMAT) - retval = ms_format_cmnd(srb, chip); -#ifdef SUPPORT_PCGL_1P18 - else if (srb->cmnd[2] == GET_MS_INFORMATION) - retval = get_ms_information(srb, chip); -#endif - - return retval; -} - -#ifdef SUPPORT_CPRM -static int sd_extension_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - int result; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - sd_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != SD_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - switch (srb->cmnd[0]) { - case SD_PASS_THRU_MODE: - result = sd_pass_thru_mode(srb, chip); - break; - - case SD_EXECUTE_NO_DATA: - result = sd_execute_no_data(srb, chip); - break; - - case SD_EXECUTE_READ: - result = sd_execute_read_data(srb, chip); - break; - - case SD_EXECUTE_WRITE: - result = sd_execute_write_data(srb, chip); - break; - - case SD_GET_RSP: - result = sd_get_cmd_rsp(srb, chip); - break; - - case SD_HW_RST: - result = sd_hw_rst(srb, chip); - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return result; -} -#endif - -#ifdef SUPPORT_MAGIC_GATE -static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return TRANSPORT_FAILED; - } - - key_format = srb->cmnd[10] & 0x3F; - dev_dbg(rtsx_dev(chip), "key_format = 0x%x\n", key_format); - - switch (key_format) { - case KF_GET_LOC_EKB: - if ((scsi_bufflen(srb) == 0x41C) && - srb->cmnd[8] == 0x04 && - srb->cmnd[9] == 0x1C) { - retval = mg_get_local_EKB(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_RSP_CHG: - if ((scsi_bufflen(srb) == 0x24) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x24) { - retval = mg_get_rsp_chg(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_GET_ICV: - ms_card->mg_entry_num = srb->cmnd[5]; - if ((scsi_bufflen(srb) == 0x404) && - srb->cmnd[8] == 0x04 && - srb->cmnd[9] == 0x04 && - srb->cmnd[2] == 0x00 && - srb->cmnd[3] == 0x00 && - srb->cmnd[4] == 0x00 && - srb->cmnd[5] < 32) { - retval = mg_get_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (check_card_wp(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return TRANSPORT_FAILED; - } - - key_format = srb->cmnd[10] & 0x3F; - dev_dbg(rtsx_dev(chip), "key_format = 0x%x\n", key_format); - - switch (key_format) { - case KF_SET_LEAF_ID: - if ((scsi_bufflen(srb) == 0x0C) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x0C) { - retval = mg_set_leaf_id(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_CHG_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x0C) { - retval = mg_chg(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_RSP_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x0C) { - retval = mg_rsp(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_SET_ICV: - ms_card->mg_entry_num = srb->cmnd[5]; - if ((scsi_bufflen(srb) == 0x404) && - srb->cmnd[8] == 0x04 && - srb->cmnd[9] == 0x04 && - srb->cmnd[2] == 0x00 && - srb->cmnd[3] == 0x00 && - srb->cmnd[4] == 0x00 && - srb->cmnd[5] < 32) { - retval = mg_set_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; -#endif - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int result; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Block all SCSI command except for - * REQUEST_SENSE and rs_ppstatus - */ - if (!(srb->cmnd[0] == VENDOR_CMND && - srb->cmnd[1] == SCSI_APP_CMD && - srb->cmnd[2] == GET_DEV_STATUS) && - srb->cmnd[0] != REQUEST_SENSE) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, - 0x02, 0, 0x04, 0x04, 0, 0); - return TRANSPORT_FAILED; - } - } -#endif - - if ((get_lun_card(chip, lun) == MS_CARD) && - ms_card->format_status == FORMAT_IN_PROGRESS) { - if (srb->cmnd[0] != REQUEST_SENSE && - srb->cmnd[0] != INQUIRY) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16)(ms_card->progress)); - return TRANSPORT_FAILED; - } - } - - switch (srb->cmnd[0]) { - case READ_10: - case WRITE_10: - case READ_6: - case WRITE_6: - result = read_write(srb, chip); -#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) - led_shine(srb, chip); -#endif - break; - - case TEST_UNIT_READY: - result = test_unit_ready(srb, chip); - break; - - case INQUIRY: - result = inquiry(srb, chip); - break; - - case READ_CAPACITY: - result = read_capacity(srb, chip); - break; - - case START_STOP: - result = start_stop_unit(srb, chip); - break; - - case ALLOW_MEDIUM_REMOVAL: - result = allow_medium_removal(srb, chip); - break; - - case REQUEST_SENSE: - result = request_sense(srb, chip); - break; - - case MODE_SENSE: - case MODE_SENSE_10: - result = mode_sense(srb, chip); - break; - - case 0x23: - result = read_format_capacity(srb, chip); - break; - - case VENDOR_CMND: - result = vendor_cmnd(srb, chip); - break; - - case MS_SP_CMND: - result = ms_sp_cmnd(srb, chip); - break; - -#ifdef SUPPORT_CPRM - case SD_PASS_THRU_MODE: - case SD_EXECUTE_NO_DATA: - case SD_EXECUTE_READ: - case SD_EXECUTE_WRITE: - case SD_GET_RSP: - case SD_HW_RST: - result = sd_extension_cmnd(srb, chip); - break; -#endif - -#ifdef SUPPORT_MAGIC_GATE - case CMD_MSPRO_MG_RKEY: - result = mg_report_key(srb, chip); - break; - - case CMD_MSPRO_MG_SKEY: - result = mg_send_key(srb, chip); - break; -#endif - - case FORMAT_UNIT: - case MODE_SELECT: - case VERIFY: - result = TRANSPORT_GOOD; - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - result = TRANSPORT_FAILED; - } - - return result; -} diff --git a/drivers/staging/rts5208/rtsx_scsi.h b/drivers/staging/rts5208/rtsx_scsi.h deleted file mode 100644 index df6138c97aaad5e00677f7685464bc0201646a90..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_scsi.h +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_SCSI_H -#define __REALTEK_RTSX_SCSI_H - -#include "rtsx.h" -#include "rtsx_chip.h" - -#define MS_SP_CMND 0xFA -#define MS_FORMAT 0xA0 -#define GET_MS_INFORMATION 0xB0 - -#define VENDOR_CMND 0xF0 - -#define READ_STATUS 0x09 - -#define READ_EEPROM 0x04 -#define WRITE_EEPROM 0x05 -#define READ_MEM 0x0D -#define WRITE_MEM 0x0E -#define GET_BUS_WIDTH 0x13 -#define GET_SD_CSD 0x14 -#define TOGGLE_GPIO 0x15 -#define TRACE_MSG 0x18 - -#define SCSI_APP_CMD 0x10 - -#define PP_READ10 0x1A -#define PP_WRITE10 0x0A -#define READ_HOST_REG 0x1D -#define WRITE_HOST_REG 0x0D -#define SET_VAR 0x05 -#define GET_VAR 0x15 -#define DMA_READ 0x16 -#define DMA_WRITE 0x06 -#define GET_DEV_STATUS 0x10 -#define SET_CHIP_MODE 0x27 -#define SUIT_CMD 0xE0 -#define WRITE_PHY 0x07 -#define READ_PHY 0x17 -#define WRITE_EEPROM2 0x03 -#define READ_EEPROM2 0x13 -#define ERASE_EEPROM2 0x23 -#define WRITE_EFUSE 0x04 -#define READ_EFUSE 0x14 -#define WRITE_CFG 0x0E -#define READ_CFG 0x1E - -#define SPI_VENDOR_COMMAND 0x1C - -#define SCSI_SPI_GETSTATUS 0x00 -#define SCSI_SPI_SETPARAMETER 0x01 -#define SCSI_SPI_READFALSHID 0x02 -#define SCSI_SPI_READFLASH 0x03 -#define SCSI_SPI_WRITEFLASH 0x04 -#define SCSI_SPI_WRITEFLASHSTATUS 0x05 -#define SCSI_SPI_ERASEFLASH 0x06 - -#define INIT_BATCHCMD 0x41 -#define ADD_BATCHCMD 0x42 -#define SEND_BATCHCMD 0x43 -#define GET_BATCHRSP 0x44 - -#define CHIP_NORMALMODE 0x00 -#define CHIP_DEBUGMODE 0x01 - -/* SD Pass Through Command Extension */ -#define SD_PASS_THRU_MODE 0xD0 -#define SD_EXECUTE_NO_DATA 0xD1 -#define SD_EXECUTE_READ 0xD2 -#define SD_EXECUTE_WRITE 0xD3 -#define SD_GET_RSP 0xD4 -#define SD_HW_RST 0xD6 - -#ifdef SUPPORT_MAGIC_GATE -#define CMD_MSPRO_MG_RKEY 0xA4 /* Report Key Command */ -#define CMD_MSPRO_MG_SKEY 0xA3 /* Send Key Command */ - -/* CBWCB field: key class */ -#define KC_MG_R_PRO 0xBE /* MG-R PRO*/ - -/* CBWCB field: key format */ -#define KF_SET_LEAF_ID 0x31 /* Set Leaf ID */ -#define KF_GET_LOC_EKB 0x32 /* Get Local EKB */ -#define KF_CHG_HOST 0x33 /* Challenge (host) */ -#define KF_RSP_CHG 0x34 /* Response and Challenge (device) */ -#define KF_RSP_HOST 0x35 /* Response (host) */ -#define KF_GET_ICV 0x36 /* Get ICV */ -#define KF_SET_ICV 0x37 /* SSet ICV */ -#endif - -/* Sense type */ -#define SENSE_TYPE_NO_SENSE 0 -#define SENSE_TYPE_MEDIA_CHANGE 1 -#define SENSE_TYPE_MEDIA_NOT_PRESENT 2 -#define SENSE_TYPE_MEDIA_LBA_OVER_RANGE 3 -#define SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT 4 -#define SENSE_TYPE_MEDIA_WRITE_PROTECT 5 -#define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 -#define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 -#define SENSE_TYPE_MEDIA_WRITE_ERR 8 -#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 -#define SENSE_TYPE_FORMAT_CMD_FAILED 10 -#ifdef SUPPORT_MAGIC_GATE -#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b -#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c -#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d -#define SENSE_TYPE_MG_WRITE_ERR 0x0e -#endif -#ifdef SUPPORT_SD_LOCK -/* FOR Locked SD card*/ -#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 -#endif - -void scsi_show_command(struct rtsx_chip *chip); -void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type); -void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, - u8 sense_key, u32 info, u8 asc, u8 ascq, - u8 sns_key_info0, u16 sns_key_info1); -int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_SCSI_H */ diff --git a/drivers/staging/rts5208/rtsx_sys.h b/drivers/staging/rts5208/rtsx_sys.h deleted file mode 100644 index 77094809c814564d1b407cb967e0f2d63437db9d..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_sys.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __RTSX_SYS_H -#define __RTSX_SYS_H - -#include "rtsx.h" -#include "rtsx_chip.h" -#include "rtsx_card.h" - -static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip) -{ - struct rtsx_dev *dev = chip->rtsx; - - spin_lock(&dev->reg_lock); - rtsx_enter_ss(chip); - spin_unlock(&dev->reg_lock); -} - -static inline void rtsx_reset_detected_cards(struct rtsx_chip *chip, int flag) -{ - rtsx_reset_cards(chip); -} - -#define RTSX_MSG_IN_INT(x) - -#endif /* __RTSX_SYS_H */ - diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c deleted file mode 100644 index d5ad49de4c568544f96026574597f081d5564248..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_transport.c +++ /dev/null @@ -1,768 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include - -#include "rtsx.h" - -/*********************************************************************** - * Scatter-gather transfer buffer access routines - ***********************************************************************/ - -/* - * Copy a buffer of length buflen to/from the srb's transfer buffer. - * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer - * points to a list of s-g entries and we ignore srb->request_bufflen. - * For non-scatter-gather transfers, srb->request_buffer points to the - * transfer buffer itself and srb->request_bufflen is the buffer's length.) - * Update the *index and *offset variables so that the next copy will - * pick up from where this one left off. - */ - -unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, - struct scsi_cmnd *srb, - unsigned int *index, - unsigned int *offset, - enum xfer_buf_dir dir) -{ - unsigned int cnt; - - /* If not using scatter-gather, just transfer the data directly. */ - if (scsi_sg_count(srb) == 0) { - unsigned char *sgbuffer; - - if (*offset >= scsi_bufflen(srb)) - return 0; - cnt = min(buflen, scsi_bufflen(srb) - *offset); - - sgbuffer = (unsigned char *)scsi_sglist(srb) + *offset; - - if (dir == TO_XFER_BUF) - memcpy(sgbuffer, buffer, cnt); - else - memcpy(buffer, sgbuffer, cnt); - *offset += cnt; - - /* - * Using scatter-gather. We have to go through the list one entry - * at a time. Each s-g entry contains some number of pages which - * have to be copied one at a time. - */ - } else { - struct scatterlist *sg = - (struct scatterlist *)scsi_sglist(srb) - + *index; - - /* - * This loop handles a single s-g list entry, which may - * include multiple pages. Find the initial page structure - * and the starting offset within the page, and update - * the *offset and *index values for the next loop. - */ - cnt = 0; - while (cnt < buflen && *index < scsi_sg_count(srb)) { - struct page *page = sg_page(sg) + - ((sg->offset + *offset) >> PAGE_SHIFT); - unsigned int poff = (sg->offset + *offset) & - (PAGE_SIZE - 1); - unsigned int sglen = sg->length - *offset; - - if (sglen > buflen - cnt) { - /* Transfer ends within this s-g entry */ - sglen = buflen - cnt; - *offset += sglen; - } else { - /* Transfer continues to next s-g entry */ - *offset = 0; - ++*index; - ++sg; - } - - while (sglen > 0) { - unsigned int plen = min(sglen, (unsigned int) - PAGE_SIZE - poff); - - if (dir == TO_XFER_BUF) - memcpy_to_page(page, poff, buffer + cnt, plen); - else - memcpy_from_page(buffer + cnt, page, poff, plen); - - /* Start at the beginning of the next page */ - poff = 0; - ++page; - cnt += plen; - sglen -= plen; - } - } - } - - /* Return the amount actually transferred */ - return cnt; -} - -/* - * Store the contents of buffer into srb's transfer buffer and set the - * SCSI residue. - */ -void rtsx_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int index = 0, offset = 0; - - rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, - TO_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - -void rtsx_stor_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int index = 0, offset = 0; - - rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, - FROM_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - -/*********************************************************************** - * Transport routines - ***********************************************************************/ - -/* - * Invoke the transport and basic error-handling/recovery methods - * - * This is used to send the message to the device and receive the response. - */ -void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - result = rtsx_scsi_handler(srb, chip); - - /* - * if the command gets aborted by the higher layers, we need to - * short-circuit all other processing. - */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - dev_dbg(rtsx_dev(chip), "-- command was aborted\n"); - srb->result = DID_ABORT << 16; - goto handle_errors; - } - - /* if there is a transport error, reset and don't auto-sense */ - if (result == TRANSPORT_ERROR) { - dev_dbg(rtsx_dev(chip), "-- transport indicates error, resetting\n"); - srb->result = DID_ERROR << 16; - goto handle_errors; - } - - srb->result = SAM_STAT_GOOD; - - /* - * If we have a failure, we're going to do a REQUEST_SENSE - * automatically. Note that we differentiate between a command - * "failure" and an "error" in the transport mechanism. - */ - if (result == TRANSPORT_FAILED) { - /* set the result so the higher layers expect this data */ - srb->result = SAM_STAT_CHECK_CONDITION; - memcpy(srb->sense_buffer, - (unsigned char *)&chip->sense_buffer[SCSI_LUN(srb)], - sizeof(struct sense_data_t)); - } - - return; - -handle_errors: - return; -} - -void rtsx_add_cmd(struct rtsx_chip *chip, - u8 cmd_type, u16 reg_addr, u8 mask, u8 data) -{ - __le32 *cb = (__le32 *)(chip->host_cmds_ptr); - u32 val = 0; - - val |= (u32)(cmd_type & 0x03) << 30; - val |= (u32)(reg_addr & 0x3FFF) << 16; - val |= (u32)mask << 8; - val |= (u32)data; - - spin_lock_irq(&chip->rtsx->reg_lock); - if (chip->ci < (HOST_CMDS_BUF_LEN / 4)) - cb[(chip->ci)++] = cpu_to_le32(val); - - spin_unlock_irq(&chip->rtsx->reg_lock); -} - -void rtsx_send_cmd_no_wait(struct rtsx_chip *chip) -{ - u32 val = BIT(31); - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - val |= (u32)(chip->ci * 4) & 0x00FFFFFF; - /* Hardware Auto Response */ - val |= 0x40000000; - rtsx_writel(chip, RTSX_HCBCTLR, val); -} - -int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u32 val = BIT(31); - long timeleft; - int err = 0; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - rtsx->trans_result = TRANS_NOT_READY; - init_completion(&trans_done); - rtsx->trans_state = STATE_TRANS_CMD; - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - val |= (u32)(chip->ci * 4) & 0x00FFFFFF; - /* Hardware Auto Response */ - val |= 0x40000000; - rtsx_writel(chip, RTSX_HCBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto finish_send_cmd; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -finish_send_cmd: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static inline void rtsx_add_sg_tbl(struct rtsx_chip *chip, - u32 addr, u32 len, u8 option) -{ - __le64 *sgb = (__le64 *)(chip->host_sg_tbl_ptr); - u64 val = 0; - u32 temp_len = 0; - u8 temp_opt = 0; - - do { - if (len > 0x80000) { - temp_len = 0x80000; - temp_opt = option & (~RTSX_SG_END); - } else { - temp_len = len; - temp_opt = option; - } - val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt; - - if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8)) - sgb[(chip->sgi)++] = cpu_to_le64(val); - - len -= temp_len; - addr += temp_len; - } while (len); -} - -static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, - unsigned int *index, - unsigned int *offset, int size, - enum dma_data_direction dma_dir, - int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u8 dir; - int sg_cnt, i, resid; - int err = 0; - long timeleft; - struct scatterlist *sg_ptr; - u32 val = TRIG_DMA; - - if (!sg || num_sg <= 0 || !offset || !index) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - rtsx->trans_state = STATE_TRANS_SG; - rtsx->trans_result = TRANS_NOT_READY; - - spin_unlock_irq(&rtsx->reg_lock); - - sg_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - resid = size; - sg_ptr = sg; - chip->sgi = 0; - /* - * Usually the next entry will be @sg@ + 1, but if this sg element - * is part of a chained scatterlist, it could jump to the start of - * a new scatterlist array. So here we use sg_next to move to - * the proper sg. - */ - for (i = 0; i < *index; i++) - sg_ptr = sg_next(sg_ptr); - for (i = *index; i < sg_cnt; i++) { - dma_addr_t addr; - unsigned int len; - u8 option; - - addr = sg_dma_address(sg_ptr); - len = sg_dma_len(sg_ptr); - - dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n", - (unsigned int)addr, len); - dev_dbg(rtsx_dev(chip), "*index = %d, *offset = %d\n", - *index, *offset); - - addr += *offset; - - if ((len - *offset) > resid) { - *offset += resid; - len = resid; - resid = 0; - } else { - resid -= (len - *offset); - len -= *offset; - *offset = 0; - *index = *index + 1; - } - option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; - if ((i == sg_cnt - 1) || !resid) - option |= RTSX_SG_END; - - rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); - - if (!resid) - break; - - sg_ptr = sg_next(sg_ptr); - } - - dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi); - - val |= (u32)(dir & 0x01) << 29; - val |= ADMA_MODE; - - spin_lock_irq(&rtsx->reg_lock); - - init_completion(&trans_done); - - rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - spin_unlock_irq(&rtsx->reg_lock); - goto out; - } - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_NOT_READY) { - init_completion(&trans_done); - spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - } else { - spin_unlock_irq(&rtsx->reg_lock); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, - enum dma_data_direction dma_dir, - int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u8 dir; - int buf_cnt, i; - int err = 0; - long timeleft; - struct scatterlist *sg_ptr; - - if (!sg || num_sg <= 0) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - rtsx->trans_state = STATE_TRANS_SG; - rtsx->trans_result = TRANS_NOT_READY; - - spin_unlock_irq(&rtsx->reg_lock); - - buf_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - sg_ptr = sg; - - for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) { - u32 val = TRIG_DMA; - int sg_cnt, j; - - if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) - sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); - else - sg_cnt = HOST_SG_TBL_BUF_LEN / 8; - - chip->sgi = 0; - for (j = 0; j < sg_cnt; j++) { - dma_addr_t addr = sg_dma_address(sg_ptr); - unsigned int len = sg_dma_len(sg_ptr); - u8 option; - - dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n", - (unsigned int)addr, len); - - option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; - if (j == (sg_cnt - 1)) - option |= RTSX_SG_END; - - rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); - - sg_ptr = sg_next(sg_ptr); - } - - dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi); - - val |= (u32)(dir & 0x01) << 29; - val |= ADMA_MODE; - - spin_lock_irq(&rtsx->reg_lock); - - init_completion(&trans_done); - - rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - spin_unlock_irq(&rtsx->reg_lock); - goto out; - } - spin_unlock_irq(&rtsx->reg_lock); - - sg_ptr += sg_cnt; - } - - /* Wait for TRANS_OK_INT */ - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_NOT_READY) { - init_completion(&trans_done); - spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - } else { - spin_unlock_irq(&rtsx->reg_lock); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, - size_t len, enum dma_data_direction dma_dir, - int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - dma_addr_t addr; - u8 dir; - int err = 0; - u32 val = BIT(31); - long timeleft; - - if (!buf || len <= 0) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - addr = dma_map_single(&rtsx->pci->dev, buf, len, dma_dir); - if (dma_mapping_error(&rtsx->pci->dev, addr)) - return -ENOMEM; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - val |= (u32)(dir & 0x01) << 29; - val |= (u32)(len & 0x00FFFFFF); - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - init_completion(&trans_done); - - rtsx->trans_state = STATE_TRANS_BUF; - rtsx->trans_result = TRANS_NOT_READY; - - rtsx_writel(chip, RTSX_HDBAR, addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_single(&rtsx->pci->dev, addr, len, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, - void *buf, size_t len, int use_sg, - unsigned int *index, unsigned int *offset, - enum dma_data_direction dma_dir, int timeout) -{ - int err = 0; - - /* don't transfer data during abort processing */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) - return -EIO; - - if (use_sg) { - struct scatterlist *sg = buf; - - err = rtsx_transfer_sglist_adma_partial(chip, card, sg, use_sg, - index, offset, (int)len, - dma_dir, timeout); - } else { - err = rtsx_transfer_buf(chip, card, - buf, len, dma_dir, timeout); - } - if (err < 0) { - if (RTSX_TST_DELINK(chip)) { - RTSX_CLR_DELINK(chip); - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - } - } - - return err; -} - -int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, enum dma_data_direction dma_dir, int timeout) -{ - int err = 0; - - dev_dbg(rtsx_dev(chip), "use_sg = %d\n", use_sg); - - /* don't transfer data during abort processing */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) - return -EIO; - - if (use_sg) { - err = rtsx_transfer_sglist_adma(chip, card, buf, - use_sg, dma_dir, timeout); - } else { - err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); - } - - if (err < 0) { - if (RTSX_TST_DELINK(chip)) { - RTSX_CLR_DELINK(chip); - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - } - } - - return err; -} - diff --git a/drivers/staging/rts5208/rtsx_transport.h b/drivers/staging/rts5208/rtsx_transport.h deleted file mode 100644 index 097efed24b79857e42ca6bdbfbf670bd74243ac0..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/rtsx_transport.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_TRANSPORT_H -#define __REALTEK_RTSX_TRANSPORT_H - -#include "rtsx.h" -#include "rtsx_chip.h" - -#define WAIT_TIME 2000 - -unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, - struct scsi_cmnd *srb, - unsigned int *index, - unsigned int *offset, - enum xfer_buf_dir dir); -void rtsx_stor_set_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb); -void rtsx_stor_get_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb); -void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip); - -#define rtsx_init_cmd(chip) ((chip)->ci = 0) - -void rtsx_add_cmd(struct rtsx_chip *chip, u8 cmd_type, u16 reg_addr, u8 mask, - u8 data); -void rtsx_send_cmd_no_wait(struct rtsx_chip *chip); -int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout); - -static inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) -{ -#ifdef CMD_USING_SG - return (u8 *)(chip->host_sg_tbl_ptr); -#else - return (u8 *)(chip->host_cmds_ptr); -#endif -} - -int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, enum dma_data_direction dma_dir, - int timeout); - -int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, void *buf, - size_t len, int use_sg, unsigned int *index, - unsigned int *offset, - enum dma_data_direction dma_dir, int timeout); - -#endif /* __REALTEK_RTSX_TRANSPORT_H */ diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c deleted file mode 100644 index 74c4f476b3a4a12449b8283ffb7f8ac86947df64..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/sd.c +++ /dev/null @@ -1,4717 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include - -#include "rtsx.h" -#include "sd.h" - -#define SD_MAX_RETRY_COUNT 3 - -static u16 REG_SD_CFG1; -static u16 REG_SD_CFG2; -static u16 REG_SD_CFG3; -static u16 REG_SD_STAT1; -static u16 REG_SD_STAT2; -static u16 REG_SD_BUS_STAT; -static u16 REG_SD_PAD_CTL; -static u16 REG_SD_SAMPLE_POINT_CTL; -static u16 REG_SD_PUSH_POINT_CTL; -static u16 REG_SD_CMD0; -static u16 REG_SD_CMD1; -static u16 REG_SD_CMD2; -static u16 REG_SD_CMD3; -static u16 REG_SD_CMD4; -static u16 REG_SD_CMD5; -static u16 REG_SD_BYTE_CNT_L; -static u16 REG_SD_BYTE_CNT_H; -static u16 REG_SD_BLOCK_CNT_L; -static u16 REG_SD_BLOCK_CNT_H; -static u16 REG_SD_TRANSFER; -static u16 REG_SD_VPCLK0_CTL; -static u16 REG_SD_VPCLK1_CTL; -static u16 REG_SD_DCMPS0_CTL; -static u16 REG_SD_DCMPS1_CTL; - -static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &chip->sd_card; - - sd_card->err_code |= err_code; -} - -static inline void sd_clr_err_code(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - - sd_card->err_code = 0; -} - -static inline int sd_check_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &chip->sd_card; - - return sd_card->err_code & err_code; -} - -static void sd_init_reg_addr(struct rtsx_chip *chip) -{ - REG_SD_CFG1 = 0xFD31; - REG_SD_CFG2 = 0xFD33; - REG_SD_CFG3 = 0xFD3E; - REG_SD_STAT1 = 0xFD30; - REG_SD_STAT2 = 0; - REG_SD_BUS_STAT = 0; - REG_SD_PAD_CTL = 0; - REG_SD_SAMPLE_POINT_CTL = 0; - REG_SD_PUSH_POINT_CTL = 0; - REG_SD_CMD0 = 0xFD34; - REG_SD_CMD1 = 0xFD35; - REG_SD_CMD2 = 0xFD36; - REG_SD_CMD3 = 0xFD37; - REG_SD_CMD4 = 0xFD38; - REG_SD_CMD5 = 0xFD5A; - REG_SD_BYTE_CNT_L = 0xFD39; - REG_SD_BYTE_CNT_H = 0xFD3A; - REG_SD_BLOCK_CNT_L = 0xFD3B; - REG_SD_BLOCK_CNT_H = 0xFD3C; - REG_SD_TRANSFER = 0xFD32; - REG_SD_VPCLK0_CTL = 0; - REG_SD_VPCLK1_CTL = 0; - REG_SD_DCMPS0_CTL = 0; - REG_SD_DCMPS1_CTL = 0; -} - -static int sd_check_data0_status(struct rtsx_chip *chip) -{ - int retval; - u8 stat; - - retval = rtsx_read_register(chip, REG_SD_STAT1, &stat); - if (retval) - return retval; - - if (!(stat & SD_DAT0_STATUS)) { - sd_set_err_code(chip, SD_BUSY); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int timeout = 100; - u16 reg_addr; - u8 *ptr; - int stat_idx = 0; - int rty_cnt = 0; - - sd_clr_err_code(chip); - - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END | SD_STAT_IDLE, SD_TRANSFER_END | - SD_STAT_IDLE); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 16; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 5; - } - - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - u8 val; - - rtsx_read_register(chip, REG_SD_STAT1, &val); - dev_dbg(rtsx_dev(chip), "SD_STAT1: 0x%x\n", val); - - rtsx_read_register(chip, REG_SD_CFG3, &val); - dev_dbg(rtsx_dev(chip), "SD_CFG3: 0x%x\n", val); - - if (retval == -ETIMEDOUT) { - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return retval; - } - } else { - sd_set_err_code(chip, SD_TO_ERR); - } - retval = STATUS_TIMEDOUT; - } else { - retval = STATUS_FAIL; - } - rtsx_clear_sd_error(chip); - - return retval; - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - ptr = rtsx_get_cmd_data(chip) + 1; - - if ((ptr[0] & 0xC0) != 0) { - sd_set_err_code(chip, SD_STS_ERR); - return STATUS_FAIL; - } - - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (ptr[stat_idx] & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - if (rty_cnt < SD_MAX_RETRY_COUNT) { - wait_timeout(20); - rty_cnt++; - goto RTY_SEND_CMD; - } else { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - } - } - - if (rsp_type == SD_RSP_TYPE_R1 || rsp_type == SD_RSP_TYPE_R1b) { - if (cmd_idx != SEND_RELATIVE_ADDR && - cmd_idx != SEND_IF_COND) { - if (cmd_idx != STOP_TRANSMISSION) { - if (ptr[1] & 0x80) - return STATUS_FAIL; - } -#ifdef SUPPORT_SD_LOCK - if (ptr[1] & 0x7D) { -#else - if (ptr[1] & 0x7F) { -#endif - dev_dbg(rtsx_dev(chip), "ptr[1]: 0x%02x\n", - ptr[1]); - return STATUS_FAIL; - } - if (ptr[2] & 0xFF) { - dev_dbg(rtsx_dev(chip), "ptr[2]: 0x%02x\n", - ptr[2]); - return STATUS_FAIL; - } - if (ptr[3] & 0x80) { - dev_dbg(rtsx_dev(chip), "ptr[3]: 0x%02x\n", - ptr[3]); - return STATUS_FAIL; - } - if (ptr[3] & 0x01) - sd_card->sd_data_buf_ready = 1; - else - sd_card->sd_data_buf_ready = 0; - } - } - - if (rsp && rsp_len) - memcpy(rsp, ptr, rsp_len); - - return STATUS_SUCCESS; -} - -static int sd_read_data(struct rtsx_chip *chip, - u8 trans_mode, u8 *cmd, int cmd_len, u16 byte_cnt, - u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len, - int timeout) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - - sd_clr_err_code(chip); - - if (!buf) - buf_len = 0; - - if (buf_len > 512) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - if (cmd_len) { - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (min(cmd_len, 6)); i++) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i, - 0xFF, cmd[i]); - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - (u8)byte_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - (u8)blk_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - (u8)(blk_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - if (trans_mode != SD_TM_AUTO_TUNING) - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - trans_mode | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - return STATUS_FAIL; - } - - if (buf && buf_len) { - retval = rtsx_read_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode, - u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, - u8 bus_width, u8 *buf, int buf_len, int timeout) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - - sd_clr_err_code(chip); - - if (!buf) - buf_len = 0; - - if (buf_len > 512) { - /* This function can't write data more than one page */ - return STATUS_FAIL; - } - - if (buf && buf_len) { - retval = rtsx_write_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - if (cmd_len) { - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (min(cmd_len, 6)); i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - REG_SD_CMD0 + i, 0xFF, cmd[i]); - } - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - (u8)byte_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - (u8)blk_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - (u8)(blk_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - trans_mode | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_check_csd(struct rtsx_chip *chip, char check_wp) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - u8 csd_ver, trans_speed; - u8 rsp[16]; - - for (i = 0; i < 6; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr, - SD_RSP_TYPE_R2, rsp, 16); - if (retval == STATUS_SUCCESS) - break; - } - - if (i == 6) - return STATUS_FAIL; - - memcpy(sd_card->raw_csd, rsp + 1, 15); - - dev_dbg(rtsx_dev(chip), "CSD Response:\n"); - dev_dbg(rtsx_dev(chip), "%*ph\n", 16, sd_card->raw_csd); - - csd_ver = (rsp[1] & 0xc0) >> 6; - dev_dbg(rtsx_dev(chip), "csd_ver = %d\n", csd_ver); - - trans_speed = rsp[4]; - if ((trans_speed & 0x07) == 0x02) { - if ((trans_speed & 0xf8) >= 0x30) { - if (chip->asic_code) - sd_card->sd_clock = 47; - else - sd_card->sd_clock = CLK_50; - - } else if ((trans_speed & 0xf8) == 0x28) { - if (chip->asic_code) - sd_card->sd_clock = 39; - else - sd_card->sd_clock = CLK_40; - - } else if ((trans_speed & 0xf8) == 0x20) { - if (chip->asic_code) - sd_card->sd_clock = 29; - else - sd_card->sd_clock = CLK_30; - - } else if ((trans_speed & 0xf8) >= 0x10) { - if (chip->asic_code) - sd_card->sd_clock = 23; - else - sd_card->sd_clock = CLK_20; - - } else if ((trans_speed & 0x08) >= 0x08) { - if (chip->asic_code) - sd_card->sd_clock = 19; - else - sd_card->sd_clock = CLK_20; - } else { - return STATUS_FAIL; - } - } else { - return STATUS_FAIL; - } - - if (CHK_MMC_SECTOR_MODE(sd_card)) { - sd_card->capacity = 0; - } else { - if ((!CHK_SD_HCXC(sd_card)) || csd_ver == 0) { - u8 blk_size, c_size_mult; - u16 c_size; - - blk_size = rsp[6] & 0x0F; - c_size = ((u16)(rsp[7] & 0x03) << 10) - + ((u16)rsp[8] << 2) - + ((u16)(rsp[9] & 0xC0) >> 6); - c_size_mult = (u8)((rsp[10] & 0x03) << 1); - c_size_mult += (rsp[11] & 0x80) >> 7; - sd_card->capacity = (((u32)(c_size + 1)) * - (1 << (c_size_mult + 2))) - << (blk_size - 9); - } else { - u32 total_sector = 0; - - total_sector = (((u32)rsp[8] & 0x3f) << 16) | - ((u32)rsp[9] << 8) | (u32)rsp[10]; - sd_card->capacity = (total_sector + 1) << 10; - } - } - - if (check_wp) { - if (rsp[15] & 0x30) - chip->card_wp |= SD_CARD; - - dev_dbg(rtsx_dev(chip), "CSD WP Status: 0x%x\n", rsp[15]); - } - - return STATUS_SUCCESS; -} - -static int sd_set_sample_push_timing(struct rtsx_chip *chip) -{ - int retval; - struct sd_info *sd_card = &chip->sd_card; - u8 val = 0; - - if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) - val |= 0x10; - - if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { - if (chip->asic_code) { - if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - } else { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == - SD_SAMPLE_POINT_DELAY) { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x1C, val); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static void sd_choose_proper_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - - if (CHK_SD_SDR104(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_sdr104_clk; - else - sd_card->sd_clock = chip->fpga_sd_sdr104_clk; - - } else if (CHK_SD_DDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_ddr50_clk; - else - sd_card->sd_clock = chip->fpga_sd_ddr50_clk; - - } else if (CHK_SD_SDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_sdr50_clk; - else - sd_card->sd_clock = chip->fpga_sd_sdr50_clk; - - } else if (CHK_SD_HS(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_hs_clk; - else - sd_card->sd_clock = chip->fpga_sd_hs_clk; - - } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_mmc_52m_clk; - else - sd_card->sd_clock = chip->fpga_mmc_52m_clk; - - } else if (CHK_MMC_26M(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = 48; - else - sd_card->sd_clock = CLK_50; - } -} - -static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div) -{ - int retval; - u8 mask = 0, val = 0; - - mask = 0x60; - if (clk_div == SD_CLK_DIVIDE_0) - val = 0x00; - else if (clk_div == SD_CLK_DIVIDE_128) - val = 0x40; - else if (clk_div == SD_CLK_DIVIDE_256) - val = 0x20; - - retval = rtsx_write_register(chip, REG_SD_CFG1, mask, val); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_set_init_para(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - sd_choose_proper_clock(chip); - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int sd_select_card(struct rtsx_chip *chip, int select) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd_idx, cmd_type; - u32 addr; - - if (select) { - cmd_idx = SELECT_CARD; - cmd_type = SD_RSP_TYPE_R1; - addr = sd_card->sd_addr; - } else { - cmd_idx = DESELECT_CARD; - cmd_type = SD_RSP_TYPE_R0; - addr = 0; - } - - retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -#ifdef SUPPORT_SD_LOCK -static int sd_update_lock_status(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 rsp[5]; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (rsp[1] & 0x02) - sd_card->sd_lock_status |= SD_LOCKED; - else - sd_card->sd_lock_status &= ~SD_LOCKED; - - dev_dbg(rtsx_dev(chip), "sd_card->sd_lock_status = 0x%x\n", - sd_card->sd_lock_status); - - if (rsp[1] & 0x01) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} -#endif - -static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state, - u8 data_ready, int polling_cnt) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval, i; - u8 rsp[5]; - - for (i = 0; i < polling_cnt; i++) { - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, - rsp, 5); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (((rsp[3] & 0x1E) == state) && - ((rsp[3] & 0x01) == data_ready)) - return STATUS_SUCCESS; - } - - return STATUS_FAIL; -} - -static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage) -{ - int retval; - - if (voltage == SD_IO_3V3) { - if (chip->asic_code) { - retval = rtsx_write_phy_register(chip, 0x08, - 0x4FC0 | - chip->phy_voltage); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, SD_PAD_CTL, - SD_IO_USING_1V8, 0); - if (retval) - return retval; - } - } else if (voltage == SD_IO_1V8) { - if (chip->asic_code) { - retval = rtsx_write_phy_register(chip, 0x08, - 0x4C40 | - chip->phy_voltage); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, SD_PAD_CTL, - SD_IO_USING_1V8, - SD_IO_USING_1V8); - if (retval) - return retval; - } - } else { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_voltage_switch(struct rtsx_chip *chip) -{ - int retval; - u8 stat; - - retval = rtsx_write_register(chip, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, - SD_CLK_TOGGLE_EN); - if (retval) - return retval; - - retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - udelay(chip->sd_voltage_switch_delay); - - retval = rtsx_read_register(chip, SD_BUS_STAT, &stat); - if (retval) - return retval; - if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) { - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, SD_BUS_STAT, 0xFF, - SD_CLK_FORCE_STOP); - if (retval) - return retval; - retval = sd_change_bank_voltage(chip, SD_IO_1V8); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(50); - - retval = rtsx_write_register(chip, SD_BUS_STAT, 0xFF, - SD_CLK_TOGGLE_EN); - if (retval) - return retval; - wait_timeout(10); - - retval = rtsx_read_register(chip, SD_BUS_STAT, &stat); - if (retval) - return retval; - if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) != - (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) { - dev_dbg(rtsx_dev(chip), "SD_BUS_STAT: 0x%x\n", stat); - rtsx_write_register(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | - SD_CLK_FORCE_STOP, 0); - rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0); - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir) -{ - int retval; - - if (tune_dir == TUNE_RX) { - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, - DCM_RESET | DCM_RX); - if (retval) - return retval; - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, DCM_RX); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, - DCM_RESET | DCM_TX); - if (retval) - return retval; - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, DCM_TX); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) -{ - struct sd_info *sd_card = &chip->sd_card; - u16 SD_VP_CTL, SD_DCMPS_CTL; - u8 val; - int retval; - bool ddr_rx = false; - - dev_dbg(rtsx_dev(chip), "%s (sample_point = %d, tune_dir = %d)\n", - __func__, sample_point, tune_dir); - - if (tune_dir == TUNE_RX) { - SD_VP_CTL = SD_VPRX_CTL; - SD_DCMPS_CTL = SD_DCMPS_RX_CTL; - if (CHK_SD_DDR50(sd_card)) - ddr_rx = true; - } else { - SD_VP_CTL = SD_VPTX_CTL; - SD_DCMPS_CTL = SD_DCMPS_TX_CTL; - } - - if (chip->asic_code) { - retval = rtsx_write_register(chip, CLK_CTL, CHANGE_CLK, - CHANGE_CLK); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VP_CTL, 0x1F, - sample_point); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - if (retval) - return retval; - retval = rtsx_write_register(chip, CLK_CTL, CHANGE_CLK, 0); - if (retval) - return retval; - } else { - rtsx_read_register(chip, SD_VP_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val); - rtsx_read_register(chip, SD_DCMPS_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val); - - if (ddr_rx) { - retval = rtsx_write_register(chip, SD_VP_CTL, - PHASE_CHANGE, - PHASE_CHANGE); - if (retval) - return retval; - udelay(50); - retval = rtsx_write_register(chip, SD_VP_CTL, 0xFF, - PHASE_CHANGE | - PHASE_NOT_RESET | - sample_point); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, CLK_CTL, - CHANGE_CLK, CHANGE_CLK); - if (retval) - return retval; - udelay(50); - retval = rtsx_write_register(chip, SD_VP_CTL, 0xFF, - PHASE_NOT_RESET | - sample_point); - if (retval) - return retval; - } - udelay(100); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, - DCMPS_CHANGE); - rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, - DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) - goto fail; - - val = *rtsx_get_cmd_data(chip); - if (val & DCMPS_ERROR) - goto fail; - - if ((val & DCMPS_CURRENT_PHASE) != sample_point) - goto fail; - - retval = rtsx_write_register(chip, SD_DCMPS_CTL, - DCMPS_CHANGE, 0); - if (retval) - return retval; - if (ddr_rx) { - retval = rtsx_write_register(chip, SD_VP_CTL, - PHASE_CHANGE, 0); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, CLK_CTL, - CHANGE_CLK, 0); - if (retval) - return retval; - } - - udelay(50); - } - - retval = rtsx_write_register(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; - -fail: - rtsx_read_register(chip, SD_VP_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val); - rtsx_read_register(chip, SD_DCMPS_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val); - - rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); - rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0); - mdelay(10); - sd_reset_dcm(chip, tune_dir); - return STATUS_FAIL; -} - -static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], buf[8]; - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SEND_SCR; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width, - buf, 8, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - memcpy(sd_card->raw_scr, buf, 8); - - if ((buf[0] & 0x0F) == 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_query_switch_result(struct rtsx_chip *chip, u8 func_group, - u8 func_to_switch, u8 *buf, int buf_len) -{ - u8 support_mask = 0, query_switch = 0, switch_busy = 0; - int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0; - - if (func_group == SD_FUNC_GROUP_1) { - support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case HS_SUPPORT: - support_mask = HS_SUPPORT_MASK; - query_switch = HS_QUERY_SWITCH_OK; - switch_busy = HS_SWITCH_BUSY; - break; - - case SDR50_SUPPORT: - support_mask = SDR50_SUPPORT_MASK; - query_switch = SDR50_QUERY_SWITCH_OK; - switch_busy = SDR50_SWITCH_BUSY; - break; - - case SDR104_SUPPORT: - support_mask = SDR104_SUPPORT_MASK; - query_switch = SDR104_QUERY_SWITCH_OK; - switch_busy = SDR104_SWITCH_BUSY; - break; - - case DDR50_SUPPORT: - support_mask = DDR50_SUPPORT_MASK; - query_switch = DDR50_QUERY_SWITCH_OK; - switch_busy = DDR50_SWITCH_BUSY; - break; - - default: - return STATUS_FAIL; - } - } else if (func_group == SD_FUNC_GROUP_3) { - support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case DRIVING_TYPE_A: - support_mask = DRIVING_TYPE_A_MASK; - query_switch = TYPE_A_QUERY_SWITCH_OK; - switch_busy = TYPE_A_SWITCH_BUSY; - break; - - case DRIVING_TYPE_C: - support_mask = DRIVING_TYPE_C_MASK; - query_switch = TYPE_C_QUERY_SWITCH_OK; - switch_busy = TYPE_C_SWITCH_BUSY; - break; - - case DRIVING_TYPE_D: - support_mask = DRIVING_TYPE_D_MASK; - query_switch = TYPE_D_QUERY_SWITCH_OK; - switch_busy = TYPE_D_SWITCH_BUSY; - break; - - default: - return STATUS_FAIL; - } - } else if (func_group == SD_FUNC_GROUP_4) { - support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case CURRENT_LIMIT_400: - support_mask = CURRENT_LIMIT_400_MASK; - query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY; - break; - - case CURRENT_LIMIT_600: - support_mask = CURRENT_LIMIT_600_MASK; - query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY; - break; - - case CURRENT_LIMIT_800: - support_mask = CURRENT_LIMIT_800_MASK; - query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY; - break; - - default: - return STATUS_FAIL; - } - } else { - return STATUS_FAIL; - } - - if (func_group == SD_FUNC_GROUP_1) { - if (!(buf[support_offset] & support_mask) || - ((buf[query_switch_offset] & 0x0F) != query_switch)) { - return STATUS_FAIL; - } - } - - /* Check 'Busy Status' */ - if (buf[DATA_STRUCTURE_VER_OFFSET] == 0x01 && - ((buf[check_busy_offset] & switch_busy) == switch_busy)) { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, u8 func_group, - u8 func_to_switch, u8 bus_width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], buf[64]; - - dev_dbg(rtsx_dev(chip), "%s (mode = %d, func_group = %d, func_to_switch = %d)\n", - __func__, mode, func_group, func_to_switch); - - cmd[0] = 0x40 | SWITCH; - cmd[1] = mode; - - if (func_group == SD_FUNC_GROUP_1) { - cmd[2] = 0xFF; - cmd[3] = 0xFF; - cmd[4] = 0xF0 + func_to_switch; - } else if (func_group == SD_FUNC_GROUP_3) { - cmd[2] = 0xFF; - cmd[3] = 0xF0 + func_to_switch; - cmd[4] = 0xFF; - } else if (func_group == SD_FUNC_GROUP_4) { - cmd[2] = 0xFF; - cmd[3] = 0x0F + (func_to_switch << 4); - cmd[4] = 0xFF; - } else { - cmd[1] = SD_CHECK_MODE; - cmd[2] = 0xFF; - cmd[3] = 0xFF; - cmd[4] = 0xFF; - } - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width, - buf, 64, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - dev_dbg(rtsx_dev(chip), "%*ph\n", 64, buf); - - if (func_group == NO_ARGUMENT) { - sd_card->func_group1_mask = buf[0x0D]; - sd_card->func_group2_mask = buf[0x0B]; - sd_card->func_group3_mask = buf[0x09]; - sd_card->func_group4_mask = buf[0x07]; - - dev_dbg(rtsx_dev(chip), "func_group1_mask = 0x%02x\n", - buf[0x0D]); - dev_dbg(rtsx_dev(chip), "func_group2_mask = 0x%02x\n", - buf[0x0B]); - dev_dbg(rtsx_dev(chip), "func_group3_mask = 0x%02x\n", - buf[0x09]); - dev_dbg(rtsx_dev(chip), "func_group4_mask = 0x%02x\n", - buf[0x07]); - } else { - /* Maximum current consumption, check whether current is - * acceptable; bit[511:496] = 0x0000 means some error happened. - */ - u16 cc = ((u16)buf[0] << 8) | buf[1]; - - dev_dbg(rtsx_dev(chip), "Maximum current consumption: %dmA\n", - cc); - if (cc == 0 || cc > 800) - return STATUS_FAIL; - - retval = sd_query_switch_result(chip, func_group, - func_to_switch, buf, 64); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (cc > 400 || func_to_switch > CURRENT_LIMIT_400) { - retval = rtsx_write_register(chip, OCPPARA2, - SD_OCP_THD_MASK, - chip->sd_800mA_ocp_thd); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PWR_CTL, - PMOS_STRG_MASK, - PMOS_STRG_800mA); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch) -{ - if (func_group == SD_FUNC_GROUP_1) { - if (func_to_switch > HS_SUPPORT) - func_to_switch--; - - } else if (func_group == SD_FUNC_GROUP_4) { - if (func_to_switch > CURRENT_LIMIT_200) - func_to_switch--; - } - - return func_to_switch; -} - -static int sd_check_switch(struct rtsx_chip *chip, - u8 func_group, u8 func_to_switch, u8 bus_width) -{ - int retval; - int i; - bool switch_good = false; - - for (i = 0; i < 3; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group, - func_to_switch, bus_width); - if (retval == STATUS_SUCCESS) { - u8 stat; - - retval = sd_check_switch_mode(chip, SD_SWITCH_MODE, - func_group, - func_to_switch, - bus_width); - if (retval == STATUS_SUCCESS) { - switch_good = true; - break; - } - - retval = rtsx_read_register(chip, SD_STAT1, &stat); - if (retval) - return retval; - if (stat & SD_CRC16_ERR) { - dev_dbg(rtsx_dev(chip), "SD CRC16 error when switching mode\n"); - return STATUS_FAIL; - } - } - - func_to_switch = downgrade_switch_mode(func_group, - func_to_switch); - - wait_timeout(20); - } - - if (!switch_good) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - u8 func_to_switch = 0; - - /* Get supported functions */ - retval = sd_check_switch_mode(chip, SD_CHECK_MODE, NO_ARGUMENT, - NO_ARGUMENT, bus_width); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); - - /* Function Group 1: Access Mode */ - for (i = 0; i < 4; i++) { - switch ((u8)(chip->sd_speed_prior >> (i * 8))) { - case SDR104_SUPPORT: - if ((sd_card->func_group1_mask & SDR104_SUPPORT_MASK) && - chip->sdr104_en) { - func_to_switch = SDR104_SUPPORT; - } - break; - - case DDR50_SUPPORT: - if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK) && - chip->ddr50_en) { - func_to_switch = DDR50_SUPPORT; - } - break; - - case SDR50_SUPPORT: - if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK) && - chip->sdr50_en) { - func_to_switch = SDR50_SUPPORT; - } - break; - - case HS_SUPPORT: - if (sd_card->func_group1_mask & HS_SUPPORT_MASK) - func_to_switch = HS_SUPPORT; - - break; - - default: - continue; - } - - if (func_to_switch) - break; - } - dev_dbg(rtsx_dev(chip), "SD_FUNC_GROUP_1: func_to_switch = 0x%02x", - func_to_switch); - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_SDR_RST) && - func_to_switch == DDR50_SUPPORT && - (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { - func_to_switch = SDR50_SUPPORT; - dev_dbg(rtsx_dev(chip), "Using SDR50 instead of DDR50 for SD Lock\n"); - } -#endif - - if (func_to_switch) { - retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, - bus_width); - if (retval != STATUS_SUCCESS) { - if (func_to_switch == SDR104_SUPPORT) { - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK; - } else if (func_to_switch == DDR50_SUPPORT) { - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | - DDR50_SUPPORT_MASK; - } else if (func_to_switch == SDR50_SUPPORT) { - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | - DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; - } - return STATUS_FAIL; - } - - if (func_to_switch == SDR104_SUPPORT) - SET_SD_SDR104(sd_card); - else if (func_to_switch == DDR50_SUPPORT) - SET_SD_DDR50(sd_card); - else if (func_to_switch == SDR50_SUPPORT) - SET_SD_SDR50(sd_card); - else - SET_SD_HS(sd_card); - } - - if (CHK_SD_DDR50(sd_card)) { - retval = rtsx_write_register(chip, SD_PUSH_POINT_CTL, 0x06, - 0x04); - if (retval) - return retval; - retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (!func_to_switch || func_to_switch == HS_SUPPORT) { - /* Do not try to switch current limit if the card doesn't - * support UHS mode or we don't want it to support UHS mode - */ - return STATUS_SUCCESS; - } - - /* Function Group 4: Current Limit */ - func_to_switch = 0xFF; - - for (i = 0; i < 4; i++) { - switch ((u8)(chip->sd_current_prior >> (i * 8))) { - case CURRENT_LIMIT_800: - if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK) - func_to_switch = CURRENT_LIMIT_800; - - break; - - case CURRENT_LIMIT_600: - if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK) - func_to_switch = CURRENT_LIMIT_600; - - break; - - case CURRENT_LIMIT_400: - if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) - func_to_switch = CURRENT_LIMIT_400; - - break; - - case CURRENT_LIMIT_200: - if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK) - func_to_switch = CURRENT_LIMIT_200; - - break; - - default: - continue; - } - - if (func_to_switch != 0xFF) - break; - } - - dev_dbg(rtsx_dev(chip), "SD_FUNC_GROUP_4: func_to_switch = 0x%02x", - func_to_switch); - - if (func_to_switch <= CURRENT_LIMIT_800) { - retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, - bus_width); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - return STATUS_FAIL; - } - dev_dbg(rtsx_dev(chip), "Switch current limit finished! (%d)\n", - retval); - } - - if (CHK_SD_DDR50(sd_card)) { - retval = rtsx_write_register(chip, SD_PUSH_POINT_CTL, 0x06, 0); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -static int sd_wait_data_idle(struct rtsx_chip *chip) -{ - int retval = STATUS_TIMEDOUT; - int i; - u8 val = 0; - - for (i = 0; i < 100; i++) { - retval = rtsx_read_register(chip, SD_DATA_STATE, &val); - if (retval) - return retval; - if (val & SD_DATA_IDLE) { - retval = STATUS_SUCCESS; - break; - } - udelay(100); - } - dev_dbg(rtsx_dev(chip), "SD_DATA_STATE: 0x%02x\n", val); - - return retval; -} - -static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - int retval; - u8 cmd[5]; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SEND_TUNING_PATTERN; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_AUTO_TUNING, cmd, 5, 0x40, 1, - SD_BUS_WIDTH_4, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5]; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "sd ddr tuning rx\n"); - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SD_STATUS; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, - SD_BUS_WIDTH_4, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], bus_width; - - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "mmc ddr tuning rx\n"); - - cmd[0] = 0x40 | SEND_EXT_CSD; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 0x200, 1, - bus_width, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - if (retval) - return retval; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) { - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - } - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], bus_width; - - retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_SD(sd_card)) { - bus_width = SD_BUS_WIDTH_4; - } else { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - if (retval) - return retval; - - cmd[0] = 0x40 | PROGRAM_CSD; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2, cmd, 5, 16, 1, - bus_width, sd_card->raw_csd, 16, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - 0); - if (retval) - return retval; - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - - return STATUS_SUCCESS; -} - -static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, - u8 tune_dir) -{ - struct sd_info *sd_card = &chip->sd_card; - struct timing_phase_path path[MAX_PHASE + 1]; - int i, j, cont_path_cnt; - bool new_block; - int max_len, final_path_idx; - u8 final_phase = 0xFF; - - if (phase_map == 0xFFFFFFFF) { - if (tune_dir == TUNE_RX) - final_phase = (u8)chip->sd_default_rx_phase; - else - final_phase = (u8)chip->sd_default_tx_phase; - - goto search_finish; - } - - cont_path_cnt = 0; - new_block = true; - j = 0; - for (i = 0; i < MAX_PHASE + 1; i++) { - if (phase_map & (1 << i)) { - if (new_block) { - new_block = false; - j = cont_path_cnt++; - path[j].start = i; - path[j].end = i; - } else { - path[j].end = i; - } - } else { - new_block = true; - if (cont_path_cnt) { - int idx = cont_path_cnt - 1; - - path[idx].len = path[idx].end - - path[idx].start + 1; - path[idx].mid = path[idx].start + - path[idx].len / 2; - } - } - } - - if (cont_path_cnt == 0) { - dev_dbg(rtsx_dev(chip), "No continuous phase path\n"); - goto search_finish; - } else { - int idx = cont_path_cnt - 1; - - path[idx].len = path[idx].end - path[idx].start + 1; - path[idx].mid = path[idx].start + path[idx].len / 2; - } - - if (path[0].start == 0 && - path[cont_path_cnt - 1].end == MAX_PHASE) { - path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; - path[0].len += path[cont_path_cnt - 1].len; - path[0].mid = path[0].start + path[0].len / 2; - if (path[0].mid < 0) - path[0].mid += MAX_PHASE + 1; - - cont_path_cnt--; - } - - max_len = 0; - final_phase = 0; - final_path_idx = 0; - for (i = 0; i < cont_path_cnt; i++) { - if (path[i].len > max_len) { - max_len = path[i].len; - final_phase = (u8)path[i].mid; - final_path_idx = i; - } - - dev_dbg(rtsx_dev(chip), "path[%d].start = %d\n", - i, path[i].start); - dev_dbg(rtsx_dev(chip), "path[%d].end = %d\n", i, path[i].end); - dev_dbg(rtsx_dev(chip), "path[%d].len = %d\n", i, path[i].len); - dev_dbg(rtsx_dev(chip), "path[%d].mid = %d\n", i, path[i].mid); - dev_dbg(rtsx_dev(chip), "\n"); - } - - if (tune_dir == TUNE_TX) { - if (CHK_SD_SDR104(sd_card)) { - if (max_len > 15) { - int temp_mid = (max_len - 16) / 2; - int temp_final_phase = - path[final_path_idx].end - - (max_len - (6 + temp_mid)); - - if (temp_final_phase < 0) - final_phase = (u8)(temp_final_phase + - MAX_PHASE + 1); - else - final_phase = (u8)temp_final_phase; - } - } else if (CHK_SD_SDR50(sd_card)) { - if (max_len > 12) { - int temp_mid = (max_len - 13) / 2; - int temp_final_phase = - path[final_path_idx].end - - (max_len - (3 + temp_mid)); - - if (temp_final_phase < 0) - final_phase = (u8)(temp_final_phase + - MAX_PHASE + 1); - else - final_phase = (u8)temp_final_phase; - } - } - } - -search_finish: - dev_dbg(rtsx_dev(chip), "Final chosen phase: %d\n", final_phase); - return final_phase; -} - -static int sd_tuning_rx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i, j; - u32 raw_phase_map[3], phase_map; - u8 final_phase; - int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); - - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - tuning_cmd = sd_ddr_tuning_rx_cmd; - else - tuning_cmd = sd_sdr_tuning_rx_cmd; - - } else { - if (CHK_MMC_DDR52(sd_card)) - tuning_cmd = mmc_ddr_tuning_rx_cmd; - else - return STATUS_FAIL; - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - dev_dbg(rtsx_dev(chip), "RX raw_phase_map[%d] = 0x%08x\n", - i, raw_phase_map[i]); - - dev_dbg(rtsx_dev(chip), "RX phase_map = 0x%08x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); - if (final_phase == 0xFF) - return STATUS_FAIL; - - retval = sd_change_phase(chip, final_phase, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - u32 phase_map; - u8 final_phase; - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - if (retval) - return retval; - - phase_map = 0; - for (i = MAX_PHASE; i >= 0; i--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - - retval = sd_change_phase(chip, (u8)i, TUNE_TX); - if (retval != STATUS_SUCCESS) - continue; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval == STATUS_SUCCESS || - !sd_check_err_code(chip, SD_RSP_TIMEOUT)) - phase_map |= 1 << i; - } - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - 0); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase_map = 0x%08x\n", - phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) - return STATUS_FAIL; - - retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase: %d\n", - (int)final_phase); - - return STATUS_SUCCESS; -} - -static int sd_tuning_tx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i, j; - u32 raw_phase_map[3], phase_map; - u8 final_phase; - int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); - - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - tuning_cmd = sd_ddr_tuning_tx_cmd; - else - tuning_cmd = sd_sdr_tuning_tx_cmd; - - } else { - if (CHK_MMC_DDR52(sd_card)) - tuning_cmd = sd_ddr_tuning_tx_cmd; - else - return STATUS_FAIL; - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - - retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - dev_dbg(rtsx_dev(chip), "TX raw_phase_map[%d] = 0x%08x\n", - i, raw_phase_map[i]); - - dev_dbg(rtsx_dev(chip), "TX phase_map = 0x%08x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) - return STATUS_FAIL; - - retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning(struct rtsx_chip *chip) -{ - int retval; - - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning(struct rtsx_chip *chip) -{ - int retval; - - if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase, - TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tuning(struct rtsx_chip *chip) -{ - int retval; - - if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase, - TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int sd_switch_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int re_tuning = 0; - - retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (re_tuning) { - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - retval = sd_ddr_tuning(chip); - else - retval = sd_sdr_tuning(chip); - } else { - if (CHK_MMC_DDR52(sd_card)) - retval = mmc_ddr_tuning(chip); - } - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_prepare_reset(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - if (chip->asic_code) - sd_card->sd_clock = 29; - else - sd_card->sd_clock = CLK_30; - - sd_card->sd_type = 0; - sd_card->seq_mode = 0; - sd_card->sd_data_buf_ready = 0; - sd_card->capacity = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->sd_io = 0; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return retval; - - retval = rtsx_write_register(chip, REG_SD_CFG1, 0xFF, 0x40); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - if (retval) - return retval; - - retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_pull_ctl_disable(struct rtsx_chip *chip) -{ - int retval; - - if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | SD_D7_PD | SD_CLK_PD | - SD_D5_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, - SD_D6_PD | SD_D0_PD | SD_D1_PD | - XD_D5_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF, - SD_D4_PD | XD_CE_PD | XD_CLE_PD | - XD_CD_PU); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | - XD_ALE_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | - SD_CMD_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, - 0xFF, 0x4B); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, - 0xFF, 0x69); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -int sd_pull_ctl_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | SD_DAT7_PU | SD_CLK_NP | SD_D5_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - SD_D6_PU | SD_D0_PU | SD_D1_PU | XD_D5_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - SD_D4_PU | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PU | SD_D2_PU | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - 0xA8); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - 0x5A); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - 0x95); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - 0xAA); - } - } - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_init_power(struct rtsx_chip *chip) -{ - int retval; - - retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) - wait_timeout(250); - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, 0); - if (retval) - return retval; - } - - if (!chip->ft2_fast_mode) { - retval = card_power_on(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(260); - -#ifdef SUPPORT_OCP - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - return STATUS_FAIL; - } -#endif - } - - retval = rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, - SD_OUTPUT_EN); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_dummy_clock(struct rtsx_chip *chip) -{ - int retval; - - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x01, 0x01); - if (retval) - return retval; - wait_timeout(5); - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x01, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_read_lba0(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], bus_width; - - cmd[0] = 0x40 | READ_SINGLE_BLOCK; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - if (CHK_SD(sd_card)) { - bus_width = SD_BUS_WIDTH_4; - } else { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 512, 1, - bus_width, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_check_wp_state(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u32 val; - u16 sd_card_type; - u8 cmd[5], buf[64]; - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SD_STATUS; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, - SD_BUS_WIDTH_4, buf, 64, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - return STATUS_FAIL; - } - - dev_dbg(rtsx_dev(chip), "ACMD13:\n"); - dev_dbg(rtsx_dev(chip), "%*ph\n", 64, buf); - - sd_card_type = ((u16)buf[2] << 8) | buf[3]; - dev_dbg(rtsx_dev(chip), "sd_card_type = 0x%04x\n", sd_card_type); - if (sd_card_type == 0x0001 || sd_card_type == 0x0002) { - /* ROM card or OTP */ - chip->card_wp |= SD_CARD; - } - - /* Check SD Machanical Write-Protect Switch */ - val = rtsx_readl(chip, RTSX_BIPR); - if (val & SD_WRITE_PROTECT) - chip->card_wp |= SD_CARD; - - return STATUS_SUCCESS; -} - -static int reset_sd(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - bool hi_cap_flow = false; - int retval, i = 0, j = 0, k = 0; - bool sd_dont_switch = false; - bool support_1v8 = false; - bool try_sdio = true; - u8 rsp[16]; - u8 switch_bus_width; - u32 voltage = 0; - bool sd20_mode = false; - - SET_SD(sd_card); - -switch_fail: - - i = 0; - j = 0; - k = 0; - hi_cap_flow = false; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto SD_UNLOCK_ENTRY; -#endif - - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_dummy_clock(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) { - int rty_cnt = 0; - - for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - goto status_fail; - } - - retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0, - SD_RSP_TYPE_R4, rsp, 5); - if (retval == STATUS_SUCCESS) { - int func_num = (rsp[1] >> 4) & 0x07; - - if (func_num) { - dev_dbg(rtsx_dev(chip), "SD_IO card (Function number: %d)!\n", - func_num); - chip->sd_io = 1; - goto status_fail; - } - - break; - } - - sd_init_power(chip); - - sd_dummy_clock(chip); - } - - dev_dbg(rtsx_dev(chip), "Normal card!\n"); - } - - /* Start Initialization Process of SD Card */ -RTY_SD_RST: - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, - NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - wait_timeout(20); - - retval = sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA, - SD_RSP_TYPE_R7, rsp, 5); - if (retval == STATUS_SUCCESS) { - if (rsp[4] == 0xAA && ((rsp[3] & 0x0f) == 0x01)) { - hi_cap_flow = true; - voltage = SUPPORT_VOLTAGE | 0x40000000; - } - } - - if (!hi_cap_flow) { - voltage = SUPPORT_VOLTAGE; - - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, - SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - wait_timeout(20); - } - - do { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - goto status_fail; - } - - j++; - if (j < 3) - goto RTY_SD_RST; - else - goto status_fail; - } - - retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, - SD_RSP_TYPE_R3, rsp, 5); - if (retval != STATUS_SUCCESS) { - k++; - if (k < 3) - goto RTY_SD_RST; - else - goto status_fail; - } - - i++; - wait_timeout(20); - } while (!(rsp[1] & 0x80) && (i < 255)); - - if (i == 255) - goto status_fail; - - if (hi_cap_flow) { - if (rsp[1] & 0x40) - SET_SD_HCXC(sd_card); - else - CLR_SD_HCXC(sd_card); - - support_1v8 = false; - } else { - CLR_SD_HCXC(sd_card); - support_1v8 = false; - } - dev_dbg(rtsx_dev(chip), "support_1v8 = %d\n", support_1v8); - - if (support_1v8) { - retval = sd_voltage_switch(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - } - - retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, - NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - for (i = 0; i < 3; i++) { - retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, - SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) - goto status_fail; - - sd_card->sd_addr = (u32)rsp[1] << 24; - sd_card->sd_addr += (u32)rsp[2] << 16; - - if (sd_card->sd_addr) - break; - } - - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto status_fail; - -#ifdef SUPPORT_SD_LOCK -SD_UNLOCK_ENTRY: - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (sd_card->sd_lock_status & SD_LOCKED) { - sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); - return STATUS_SUCCESS; - } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - } -#endif - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (support_1v8) { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - switch_bus_width = SD_BUS_WIDTH_4; - } else { - switch_bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (!(sd_card->raw_csd[4] & 0x40)) - sd_dont_switch = true; - - if (!sd_dont_switch) { - if (sd20_mode) { - /* Set sd_switch_fail here, because we needn't - * switch to UHS mode - */ - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | - DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; - } - - /* Check the card whether follow SD1.1 spec or higher */ - retval = sd_check_spec(chip, switch_bus_width); - if (retval == STATUS_SUCCESS) { - retval = sd_switch_function(chip, switch_bus_width); - if (retval != STATUS_SUCCESS) { - sd_init_power(chip); - sd_dont_switch = true; - try_sdio = false; - - goto switch_fail; - } - } else { - if (support_1v8) { - sd_init_power(chip); - sd_dont_switch = true; - try_sdio = false; - - goto switch_fail; - } - } - } - - if (!support_1v8) { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - } - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - - if (!sd20_mode && CHK_SD30_SPEED(sd_card)) { - int read_lba0 = 1; - - retval = rtsx_write_register(chip, SD30_DRIVE_SEL, 0x07, - chip->sd30_drive_sel_1v8); - if (retval) - return retval; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (CHK_SD_DDR50(sd_card)) - retval = sd_ddr_tuning(chip); - else - retval = sd_sdr_tuning(chip); - - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - try_sdio = false; - sd20_mode = true; - goto switch_fail; - } - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - - if (CHK_SD_DDR50(sd_card)) { - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - read_lba0 = 0; - } - - if (read_lba0) { - retval = sd_read_lba0(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - try_sdio = false; - sd20_mode = true; - goto switch_fail; - } - } - } - - retval = sd_check_wp_state(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_H, 0xFF, - 0x02); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_L, 0xFF, - 0x00); - if (retval) - return retval; - } -#endif - - return STATUS_SUCCESS; - -status_fail: - return STATUS_FAIL; -} - -static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 buf[8] = {0}, bus_width, *ptr; - u16 byte_cnt; - int len; - - retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, - 0); - if (retval != STATUS_SUCCESS) - return SWITCH_FAIL; - - if (width == MMC_8BIT_BUS) { - buf[0] = 0x55; - buf[1] = 0xAA; - len = 8; - byte_cnt = 8; - bus_width = SD_BUS_WIDTH_8; - } else { - buf[0] = 0x5A; - len = 4; - byte_cnt = 4; - bus_width = SD_BUS_WIDTH_4; - } - - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02); - if (retval != STATUS_SUCCESS) - return SWITCH_ERR; - - retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, NULL, 0, byte_cnt, 1, - bus_width, buf, len, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); - return SWITCH_ERR; - } - - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); - if (retval != STATUS_SUCCESS) - return SWITCH_ERR; - - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", BUSTEST_R); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R); - - if (width == MMC_8BIT_BUS) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, - 0xFF, 0x08); - else - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, - 0xFF, 0x04); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, SD_CALCULATE_CRC7 | - SD_NO_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_NORMAL_READ | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); - if (width == MMC_8BIT_BUS) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval < 0) { - rtsx_clear_sd_error(chip); - return SWITCH_ERR; - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - if (width == MMC_8BIT_BUS) { - dev_dbg(rtsx_dev(chip), "BUSTEST_R [8bits]: 0x%02x 0x%02x\n", - ptr[0], ptr[1]); - if (ptr[0] == 0xAA && ptr[1] == 0x55) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70600; - else - arg = 0x03B70200; - - retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, - SD_RSP_TYPE_R1b, rsp, 5); - if (retval == STATUS_SUCCESS && - !(rsp[4] & MMC_SWITCH_ERR)) - return SWITCH_SUCCESS; - } - } else { - dev_dbg(rtsx_dev(chip), "BUSTEST_R [4bits]: 0x%02x\n", ptr[0]); - if (ptr[0] == 0xA5) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70500; - else - arg = 0x03B70100; - - retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, - SD_RSP_TYPE_R1b, rsp, 5); - if (retval == STATUS_SUCCESS && - !(rsp[4] & MMC_SWITCH_ERR)) - return SWITCH_SUCCESS; - } - } - - return SWITCH_FAIL; -} - -static int mmc_switch_timing_bus(struct rtsx_chip *chip, bool switch_ddr) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 *ptr, card_type, card_type_mask = 0; - - CLR_MMC_HS(sd_card); - - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", SEND_EXT_CSD); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, - 0x40 | SEND_EXT_CSD); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 2); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_NORMAL_READ | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 1000); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - rtsx_clear_sd_error(chip); - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - return STATUS_FAIL; - } - - ptr = rtsx_get_cmd_data(chip); - if (ptr[0] & SD_TRANSFER_ERR) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - return STATUS_FAIL; - } - - if (CHK_MMC_SECTOR_MODE(sd_card)) { - sd_card->capacity = ((u32)ptr[5] << 24) | ((u32)ptr[4] << 16) | - ((u32)ptr[3] << 8) | ((u32)ptr[2]); - } - - card_type_mask = 0x03; - card_type = ptr[1] & card_type_mask; - if (card_type) { - u8 rsp[5]; - - if (card_type & 0x04) { - if (switch_ddr) - SET_MMC_DDR52(sd_card); - else - SET_MMC_52M(sd_card); - } else if (card_type & 0x02) { - SET_MMC_52M(sd_card); - } else { - SET_MMC_26M(sd_card); - } - - retval = sd_send_cmd_get_rsp(chip, SWITCH, 0x03B90100, - SD_RSP_TYPE_R1b, rsp, 5); - if (retval != STATUS_SUCCESS || (rsp[4] & MMC_SWITCH_ERR)) - CLR_MMC_HS(sd_card); - } - - sd_choose_proper_clock(chip); - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Test Bus Procedure */ - retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS); - if (retval == SWITCH_SUCCESS) { - SET_MMC_8BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - } else if (retval == SWITCH_FAIL) { - retval = mmc_test_switch_bus(chip, MMC_4BIT_BUS); - if (retval == SWITCH_SUCCESS) { - SET_MMC_4BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - } else if (retval == SWITCH_FAIL) { - CLR_MMC_8BIT(sd_card); - CLR_MMC_4BIT(sd_card); - } else { - return STATUS_FAIL; - } - } else { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int reset_mmc(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval, i = 0, j = 0, k = 0; - bool switch_ddr = true; - u8 rsp[16]; - u8 spec_ver = 0; - u32 temp; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto MMC_UNLOCK_ENTRY; -#endif - -switch_fail: - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - return retval; - - SET_MMC(sd_card); - -RTY_MMC_RST: - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - do { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND, - (SUPPORT_VOLTAGE | 0x40000000), - SD_RSP_TYPE_R3, rsp, 5); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_BUSY) || - sd_check_err_code(chip, SD_TO_ERR)) { - k++; - if (k < 20) { - sd_clr_err_code(chip); - goto RTY_MMC_RST; - } else { - return STATUS_FAIL; - } - } else { - j++; - if (j < 100) { - sd_clr_err_code(chip); - goto RTY_MMC_RST; - } else { - return STATUS_FAIL; - } - } - } - - wait_timeout(20); - i++; - } while (!(rsp[1] & 0x80) && (i < 255)); - - if (i == 255) - return STATUS_FAIL; - - if ((rsp[1] & 0x60) == 0x40) - SET_MMC_SECTOR_MODE(sd_card); - else - CLR_MMC_SECTOR_MODE(sd_card); - - retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - sd_card->sd_addr = 0x00100000; - retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, - SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; - - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -#ifdef SUPPORT_SD_LOCK -MMC_UNLOCK_ENTRY: - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; -#endif - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; - - if (!sd_card->mmc_dont_switch_bus) { - if (spec_ver == 4) { - /* MMC 4.x Cards */ - retval = mmc_switch_timing_bus(chip, switch_ddr); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - sd_card->mmc_dont_switch_bus = 1; - goto switch_fail; - } - } - - if (CHK_MMC_SECTOR_MODE(sd_card) && sd_card->capacity == 0) - return STATUS_FAIL; - - if (switch_ddr && CHK_MMC_DDR52(sd_card)) { - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mmc_ddr_tuning(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - switch_ddr = false; - goto switch_fail; - } - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval == STATUS_SUCCESS) { - retval = sd_read_lba0(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - switch_ddr = false; - goto switch_fail; - } - } - } - } - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_H, 0xFF, - 0x02); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_L, 0xFF, - 0x00); - if (retval) - return retval; - } -#endif - - temp = rtsx_readl(chip, RTSX_BIPR); - if (temp & SD_WRITE_PROTECT) - chip->card_wp |= SD_CARD; - - return STATUS_SUCCESS; -} - -int reset_sd_card(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - sd_init_reg_addr(chip); - - memset(sd_card, 0, sizeof(struct sd_info)); - chip->capacity[chip->card2lun[SD_CARD]] = 0; - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->ignore_sd && CHK_SDIO_EXIST(chip) && - !CHK_SDIO_IGNORED(chip)) { - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | - 0x20, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->sd_io = 1; - return STATUS_FAIL; - } - - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->sd_ctl & RESET_MMC_FIRST) { - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - return STATUS_FAIL; - - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } else { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - return STATUS_FAIL; - - if (chip->sd_io) - return STATUS_FAIL; - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); - if (retval) - return retval; - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "sd_card->sd_type = 0x%x\n", sd_card->sd_type); - - return STATUS_SUCCESS; -} - -static int reset_mmc_only(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - sd_card->sd_type = 0; - sd_card->seq_mode = 0; - sd_card->sd_data_buf_ready = 0; - sd_card->capacity = 0; - sd_card->sd_switch_fail = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); - if (retval) - return retval; - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "In %s, sd_card->sd_type = 0x%x\n", - __func__, sd_card->sd_type); - - return STATUS_SUCCESS; -} - -#define WAIT_DATA_READY_RTY_CNT 255 - -static int wait_data_buf_ready(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int i, retval; - - for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - sd_card->sd_data_buf_ready = 0; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (sd_card->sd_data_buf_ready) { - return sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - } - } - - sd_set_err_code(chip, SD_TO_ERR); - - return STATUS_FAIL; -} - -void sd_stop_seq_mode(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - if (sd_card->seq_mode) { - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return; - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) - sd_set_err_code(chip, SD_STS_ERR); - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - sd_set_err_code(chip, SD_STS_ERR); - - sd_card->seq_mode = 0; - - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - } -} - -static inline int sd_auto_tune_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - if (chip->asic_code) { - if (sd_card->sd_clock > 30) - sd_card->sd_clock -= 20; - } else { - switch (sd_card->sd_clock) { - case CLK_200: - sd_card->sd_clock = CLK_150; - break; - - case CLK_150: - sd_card->sd_clock = CLK_120; - break; - - case CLK_120: - sd_card->sd_clock = CLK_100; - break; - - case CLK_100: - sd_card->sd_clock = CLK_80; - break; - - case CLK_80: - sd_card->sd_clock = CLK_60; - break; - - case CLK_60: - sd_card->sd_clock = CLK_50; - break; - - default: - break; - } - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, - u16 sector_cnt) -{ - struct sd_info *sd_card = &chip->sd_card; - u32 data_addr; - u8 cfg2; - int retval; - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - dev_dbg(rtsx_dev(chip), "%s: Read %d %s from 0x%x\n", __func__, - sector_cnt, (sector_cnt > 1) ? "sectors" : "sector", - start_sector); - } else { - dev_dbg(rtsx_dev(chip), "%s: Write %d %s to 0x%x\n", __func__, - sector_cnt, (sector_cnt > 1) ? "sectors" : "sector", - start_sector); - } - - sd_card->cleanup_counter = 0; - - if (!(chip->card_ready & SD_CARD)) { - sd_card->seq_mode = 0; - - retval = reset_sd_card(chip); - if (retval == STATUS_SUCCESS) { - chip->card_ready |= SD_CARD; - chip->card_fail &= ~SD_CARD; - } else { - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->rw_need_retry = 1; - return STATUS_FAIL; - } - } - - if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) - data_addr = start_sector << 9; - else - data_addr = start_sector; - - sd_clr_err_code(chip); - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_IO_ERR); - goto RW_FAIL; - } - - if (sd_card->seq_mode && - (sd_card->pre_dir != srb->sc_data_direction || - ((sd_card->pre_sec_addr + sd_card->pre_sec_cnt) != - start_sector))) { - if (sd_card->pre_sec_cnt < 0x80 && - sd_card->pre_dir == DMA_FROM_DEVICE && - !CHK_SD30_SPEED(sd_card) && - !CHK_SD_HS(sd_card) && - !CHK_MMC_HS(sd_card)) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_STS_ERR); - goto RW_FAIL; - } - - sd_card->seq_mode = 0; - - retval = rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_IO_ERR); - goto RW_FAIL; - } - - if (sd_card->pre_sec_cnt < 0x80 && - !CHK_SD30_SPEED(sd_card) && - !CHK_SD_HS(sd_card) && - !CHK_MMC_HS(sd_card)) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - (u8)sector_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - (u8)(sector_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - if (CHK_MMC_8BIT(sd_card)) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, - 0x03, SD_BUS_WIDTH_8); - else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, - 0x03, SD_BUS_WIDTH_4); - else - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, - 0x03, SD_BUS_WIDTH_1); - - if (sd_card->seq_mode) { - cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | - SD_RSP_LEN_0; - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, - DMA_512); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_3 | SD_TRANSFER_START); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - } - - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", - READ_MULTIPLE_BLOCK); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, - 0x40 | READ_MULTIPLE_BLOCK); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, - (u8)(data_addr >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, - (u8)(data_addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, - (u8)(data_addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, - (u8)data_addr); - - cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | - SD_RSP_LEN_6; - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, - sector_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } else { - retval = rtsx_send_cmd(chip, SD_CARD, 50); - if (retval < 0) { - rtsx_clear_sd_error(chip); - - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_TO_ERR); - goto RW_FAIL; - } - - retval = wait_data_buf_ready(chip); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_TO_ERR); - goto RW_FAIL; - } - - retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK, - data_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - goto RW_FAIL; - } - - rtsx_init_cmd(chip); - - cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | - SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, - sector_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } - - sd_card->seq_mode = 1; - } - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), - scsi_bufflen(srb), scsi_sg_count(srb), - srb->sc_data_direction, chip->sd_timeout); - if (retval < 0) { - u8 stat = 0; - int err; - - sd_card->seq_mode = 0; - - if (retval == -ETIMEDOUT) - err = STATUS_TIMEDOUT; - else - err = STATUS_FAIL; - - rtsx_read_register(chip, REG_SD_STAT1, &stat); - rtsx_clear_sd_error(chip); - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", - __func__); - return STATUS_FAIL; - } - - chip->rw_need_retry = 1; - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_STS_ERR); - goto RW_FAIL; - } - - if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) { - dev_dbg(rtsx_dev(chip), "SD CRC error, tune clock!\n"); - sd_set_err_code(chip, SD_CRC_ERR); - goto RW_FAIL; - } - - if (err == STATUS_TIMEDOUT) { - sd_set_err_code(chip, SD_TO_ERR); - goto RW_FAIL; - } - - return err; - } - - sd_card->pre_sec_addr = start_sector; - sd_card->pre_sec_cnt = sector_cnt; - sd_card->pre_dir = srb->sc_data_direction; - - return STATUS_SUCCESS; - -RW_FAIL: - sd_card->seq_mode = 0; - - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", __func__); - return STATUS_FAIL; - } - - if (sd_check_err_code(chip, SD_CRC_ERR)) { - if (CHK_MMC_4BIT(sd_card) || CHK_MMC_8BIT(sd_card)) { - sd_card->mmc_dont_switch_bus = 1; - reset_mmc_only(chip); - sd_card->mmc_dont_switch_bus = 0; - } else { - sd_card->need_retune = 1; - sd_auto_tune_clock(chip); - } - } else if (sd_check_err_code(chip, SD_TO_ERR | SD_STS_ERR)) { - retval = reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - } - } - - return STATUS_FAIL; -} - -#ifdef SUPPORT_CPRM -int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, u32 arg, - u8 rsp_type, u8 *rsp, int rsp_len, - bool special_check) -{ - int retval; - int timeout = 100; - u16 reg_addr; - u8 *ptr; - int stat_idx = 0; - int rty_cnt = 0; - - dev_dbg(rtsx_dev(chip), "EXT SD/MMC CMD %d\n", cmd_idx); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 17; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 6; - } - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0); - - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - rtsx_clear_sd_error(chip); - - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) - return retval; - } else { - sd_set_err_code(chip, SD_TO_ERR); - } - } - return STATUS_FAIL; - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - ptr = rtsx_get_cmd_data(chip) + 1; - - if ((ptr[0] & 0xC0) != 0) { - sd_set_err_code(chip, SD_STS_ERR); - return STATUS_FAIL; - } - - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (ptr[stat_idx] & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - if (rty_cnt < SD_MAX_RETRY_COUNT) { - wait_timeout(20); - rty_cnt++; - goto RTY_SEND_CMD; - } else { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - } - } - - if (cmd_idx == SELECT_CARD || cmd_idx == APP_CMD || - cmd_idx == SEND_STATUS || cmd_idx == STOP_TRANSMISSION) { - if (cmd_idx != STOP_TRANSMISSION && !special_check) { - if (ptr[1] & 0x80) - return STATUS_FAIL; - } -#ifdef SUPPORT_SD_LOCK - if (ptr[1] & 0x7D) { -#else - if (ptr[1] & 0x7F) { -#endif - return STATUS_FAIL; - } - if (ptr[2] & 0xF8) - return STATUS_FAIL; - - if (cmd_idx == SELECT_CARD) { - if (rsp_type == SD_RSP_TYPE_R2) { - if ((ptr[3] & 0x1E) != 0x04) - return STATUS_FAIL; - } - } - } - - if (rsp && rsp_len) - memcpy(rsp, ptr, rsp_len); - - return STATUS_SUCCESS; -} - -int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type) -{ - int retval, rsp_len; - u16 reg_addr; - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - - rsp_len = 17; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - - rsp_len = 6; - } - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (rsp) { - int min_len = (rsp_len < len) ? rsp_len : len; - - memcpy(rsp, rtsx_get_cmd_data(chip), min_len); - - dev_dbg(rtsx_dev(chip), "min_len = %d\n", min_len); - dev_dbg(rtsx_dev(chip), "Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n", - rsp[0], rsp[1], rsp[2], rsp[3]); - } - - return STATUS_SUCCESS; -} - -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int len; - u8 buf[18] = { - 0x00, - 0x00, - 0x00, - 0x0E, - 0x00, - 0x00, - 0x00, - 0x00, - 0x53, - 0x44, - 0x20, - 0x43, - 0x61, - 0x72, - 0x64, - 0x00, - 0x00, - 0x00, - }; - - sd_card->pre_cmd_err = 0; - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[2] != 0x53 || srb->cmnd[3] != 0x44 || - srb->cmnd[4] != 0x20 || srb->cmnd[5] != 0x43 || - srb->cmnd[6] != 0x61 || srb->cmnd[7] != 0x72 || - srb->cmnd[8] != 0x64) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - switch (srb->cmnd[1] & 0x0F) { - case 0: - sd_card->sd_pass_thru_en = 0; - break; - - case 1: - sd_card->sd_pass_thru_en = 1; - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - buf[5] = (CHK_SD(sd_card) == 1) ? 0x01 : 0x02; - if (chip->card_wp & SD_CARD) - buf[5] |= 0x80; - - buf[6] = (u8)(sd_card->sd_addr >> 16); - buf[7] = (u8)(sd_card->sd_addr >> 24); - - buf[15] = chip->max_lun; - - len = min_t(int, 18, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, len, srb); - - return TRANSPORT_GOOD; -} - -static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type, - int *rsp_len) -{ - if (!rsp_type || !rsp_len) - return STATUS_FAIL; - - switch (srb->cmnd[10]) { - case 0x03: - *rsp_type = SD_RSP_TYPE_R0; - *rsp_len = 0; - break; - - case 0x04: - *rsp_type = SD_RSP_TYPE_R1; - *rsp_len = 6; - break; - - case 0x05: - *rsp_type = SD_RSP_TYPE_R1b; - *rsp_len = 6; - break; - - case 0x06: - *rsp_type = SD_RSP_TYPE_R2; - *rsp_len = 17; - break; - - case 0x07: - *rsp_type = SD_RSP_TYPE_R3; - *rsp_len = 6; - break; - - default: - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len; - u8 cmd_idx, rsp_type; - bool standby = false, acmd = false; - u32 arg; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x02) - standby = true; - - if (srb->cmnd[1] & 0x01) - acmd = true; - - arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | - ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } - } -#else - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; -#endif - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, false); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - } - -#ifdef SUPPORT_SD_LOCK - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; -#endif - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -sd_execute_cmd_failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - return TRANSPORT_FAILED; -} - -int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len, i; - bool read_err = false, cmd13_checkbit = false; - u8 cmd_idx, rsp_type, bus_width; - bool standby = false, send_cmd12 = false, acmd = false; - u32 data_len; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = true; - - if (srb->cmnd[1] & 0x02) - standby = true; - - if (srb->cmnd[1] & 0x01) - acmd = true; - - data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] - << 8) | srb->cmnd[9]; - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } else { - bus_width = SD_BUS_WIDTH_4; - } - dev_dbg(rtsx_dev(chip), "bus_width = %d\n", bus_width); -#else - bus_width = SD_BUS_WIDTH_4; -#endif - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (data_len <= 512) { - int min_len; - u8 *buf; - u16 byte_cnt, blk_cnt; - u8 cmd[5]; - - byte_cnt = ((u16)(srb->cmnd[8] & 0x03) << 8) | srb->cmnd[9]; - blk_cnt = 1; - - cmd[0] = 0x40 | cmd_idx; - cmd[1] = srb->cmnd[3]; - cmd[2] = srb->cmnd[4]; - cmd[3] = srb->cmnd[5]; - cmd[4] = srb->cmnd[6]; - - buf = kmalloc(data_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, - blk_cnt, bus_width, buf, data_len, 2000); - if (retval != STATUS_SUCCESS) { - read_err = true; - kfree(buf); - rtsx_clear_sd_error(chip); - goto sd_execute_read_cmd_failed; - } - - min_len = min(data_len, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, min_len, srb); - - kfree(buf); - } else if (!(data_len & 0x1FF)) { - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, - 0xFF, (srb->cmnd[7] & 0xFE) >> 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, - 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, - 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, - srb->cmnd[3]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, - srb->cmnd[4]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, - srb->cmnd[5]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, - srb->cmnd[6]); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), - scsi_bufflen(srb), - scsi_sg_count(srb), - DMA_FROM_DEVICE, 10000); - if (retval < 0) { - read_err = true; - rtsx_clear_sd_error(chip); - goto sd_execute_read_cmd_failed; - } - - } else { - goto sd_execute_read_cmd_failed; - } - - retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (send_cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = true; - - for (i = 0; i < 3; i++) { - retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - cmd13_checkbit); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -sd_execute_read_cmd_failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (read_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - return TRANSPORT_FAILED; -} - -int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len, i; - bool write_err = false, cmd13_checkbit = false; - u8 cmd_idx, rsp_type; - bool standby = false, send_cmd12 = false, acmd = false; - u32 data_len, arg; -#ifdef SUPPORT_SD_LOCK - int lock_cmd_fail = 0; - u8 sd_lock_state = 0; - u8 lock_cmd_type = 0; -#endif - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = true; - - if (srb->cmnd[1] & 0x02) - standby = true; - - if (srb->cmnd[1] & 0x01) - acmd = true; - - data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] - << 8) | srb->cmnd[9]; - arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | - ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - sd_lock_state = sd_card->sd_lock_status; - sd_lock_state &= SD_LOCKED; - } -#endif - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } - } -#else - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; -#endif - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - - if (data_len <= 512) { - u16 i; - u8 *buf; - - buf = kmalloc(data_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, data_len, srb); - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) - lock_cmd_type = buf[0] & 0x0F; -#endif - - if (data_len > 256) { - rtsx_init_cmd(chip); - for (i = 0; i < 256; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - goto sd_execute_write_cmd_failed; - } - - rtsx_init_cmd(chip); - for (i = 256; i < data_len; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - goto sd_execute_write_cmd_failed; - } - } else { - rtsx_init_cmd(chip); - for (i = 0; i < data_len; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - goto sd_execute_write_cmd_failed; - } - } - - kfree(buf); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - srb->cmnd[8] & 0x03); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - srb->cmnd[9]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - 0x01); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, 250); - } else if (!(data_len & 0x1FF)) { - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, - 0xFF, (srb->cmnd[7] & 0xFE) >> 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, - 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), - scsi_bufflen(srb), - scsi_sg_count(srb), - DMA_TO_DEVICE, 10000); - - } else { - goto sd_execute_write_cmd_failed; - } - - if (retval < 0) { - write_err = true; - rtsx_clear_sd_error(chip); - goto sd_execute_write_cmd_failed; - } - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (lock_cmd_type == SD_ERASE) { - sd_card->sd_erase_status = SD_UNDER_ERASING; - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); - - retval = rtsx_send_cmd(chip, SD_CARD, 250); - if (retval < 0) { - write_err = true; - rtsx_clear_sd_error(chip); - goto sd_execute_write_cmd_failed; - } - - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "Lock command fail!\n"); - lock_cmd_fail = 1; - } - } -#endif /* SUPPORT_SD_LOCK */ - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (send_cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = true; - - for (i = 0; i < 3; i++) { - retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - cmd13_checkbit); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (!lock_cmd_fail) { - dev_dbg(rtsx_dev(chip), "lock_cmd_type = 0x%x\n", - lock_cmd_type); - if (lock_cmd_type & SD_CLR_PWD) - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - - if (lock_cmd_type & SD_SET_PWD) - sd_card->sd_lock_status |= SD_PWD_EXIST; - } - - dev_dbg(rtsx_dev(chip), "sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n", - sd_lock_state, sd_card->sd_lock_status); - if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { - sd_card->sd_lock_notify = 1; - if (sd_lock_state && - (sd_card->sd_lock_status & SD_LOCK_1BIT_MODE)) { - sd_card->sd_lock_status |= (SD_UNLOCK_POW_ON | SD_SDR_RST); - if (CHK_SD(sd_card)) { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - sd_card->sd_lock_status &= - ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - goto sd_execute_write_cmd_failed; - } - } - - sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - } - } - } - - if (lock_cmd_fail) { - scsi_set_resid(srb, 0); - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - return TRANSPORT_FAILED; - } -#endif /* SUPPORT_SD_LOCK */ - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -sd_execute_write_cmd_failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (write_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - return TRANSPORT_FAILED; -} - -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int count; - u16 data_len; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - data_len = ((u16)srb->cmnd[7] << 8) | srb->cmnd[8]; - - if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { - count = (data_len < 17) ? data_len : 17; - } else { - count = (data_len < 6) ? data_len : 6; - } - rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb); - - dev_dbg(rtsx_dev(chip), "Response length: %d\n", data_len); - dev_dbg(rtsx_dev(chip), "Response: 0x%x 0x%x 0x%x 0x%x\n", - sd_card->rsp[0], sd_card->rsp[1], - sd_card->rsp[2], sd_card->rsp[3]); - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[2] != 0x53 || srb->cmnd[3] != 0x44 || - srb->cmnd[4] != 0x20 || srb->cmnd[5] != 0x43 || - srb->cmnd[6] != 0x61 || srb->cmnd[7] != 0x72 || - srb->cmnd[8] != 0x64) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - switch (srb->cmnd[1] & 0x0F) { - case 0: -#ifdef SUPPORT_SD_LOCK - if (srb->cmnd[9] == 0x64) - sd_card->sd_lock_status |= SD_SDR_RST; -#endif - retval = reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - return TRANSPORT_FAILED; - } -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif - break; - - case 1: - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - return TRANSPORT_FAILED; - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -void sd_cleanup_work(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - - if (sd_card->seq_mode) { - dev_dbg(rtsx_dev(chip), "SD: stop transmission\n"); - sd_stop_seq_mode(chip); - sd_card->cleanup_counter = 0; - } -} - -int sd_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - if (retval) - return retval; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - mdelay(50); - } - - if (chip->asic_code) { - retval = sd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, - FPGA_SD_PULL_CTL_BIT); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -int release_sd_card(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - chip->card_ready &= ~SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->card_wp &= ~SD_CARD; - - chip->sd_io = 0; - chip->sd_int = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - memset(sd_card->raw_csd, 0, 16); - memset(sd_card->raw_scr, 0, 8); - - retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/sd.h b/drivers/staging/rts5208/sd.h deleted file mode 100644 index f4ff62653b56c3b03e2d9fe2384bca3c4f6dbfc1..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/sd.h +++ /dev/null @@ -1,289 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_SD_H -#define __REALTEK_RTSX_SD_H - -#include "rtsx_chip.h" - -#define SUPPORT_VOLTAGE 0x003C0000 - -/* Error Code */ -#define SD_NO_ERROR 0x0 -#define SD_CRC_ERR 0x80 -#define SD_TO_ERR 0x40 -#define SD_NO_CARD 0x20 -#define SD_BUSY 0x10 -#define SD_STS_ERR 0x08 -#define SD_RSP_TIMEOUT 0x04 -#define SD_IO_ERR 0x02 - -/* Return code for MMC switch bus */ -#define SWITCH_SUCCESS 0 -#define SWITCH_ERR 1 -#define SWITCH_FAIL 2 - -/* MMC/SD Command Index */ -/* Basic command (class 0) */ -#define GO_IDLE_STATE 0 -#define SEND_OP_COND 1 -#define ALL_SEND_CID 2 -#define SET_RELATIVE_ADDR 3 -#define SEND_RELATIVE_ADDR 3 -#define SET_DSR 4 -#define IO_SEND_OP_COND 5 -#define SWITCH 6 -#define SELECT_CARD 7 -#define DESELECT_CARD 7 -/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec - * while is "SEND_IF_COND" for SD 2.0 - */ -#define SEND_EXT_CSD 8 -#define SEND_IF_COND 8 - -#define SEND_CSD 9 -#define SEND_CID 10 -#define VOLTAGE_SWITCH 11 -#define READ_DAT_UTIL_STOP 11 -#define STOP_TRANSMISSION 12 -#define SEND_STATUS 13 -#define GO_INACTIVE_STATE 15 - -#define SET_BLOCKLEN 16 -#define READ_SINGLE_BLOCK 17 -#define READ_MULTIPLE_BLOCK 18 -#define SEND_TUNING_PATTERN 19 - -#define BUSTEST_R 14 -#define BUSTEST_W 19 - -#define WRITE_BLOCK 24 -#define WRITE_MULTIPLE_BLOCK 25 -#define PROGRAM_CSD 27 - -#define ERASE_WR_BLK_START 32 -#define ERASE_WR_BLK_END 33 -#define ERASE_CMD 38 - -#define LOCK_UNLOCK 42 -#define IO_RW_DIRECT 52 - -#define APP_CMD 55 -#define GEN_CMD 56 - -#define SET_BUS_WIDTH 6 -#define SD_STATUS 13 -#define SEND_NUM_WR_BLOCKS 22 -#define SET_WR_BLK_ERASE_COUNT 23 -#define SD_APP_OP_COND 41 -#define SET_CLR_CARD_DETECT 42 -#define SEND_SCR 51 - -#define SD_READ_COMPLETE 0x00 -#define SD_READ_TO 0x01 -#define SD_READ_ADVENCE 0x02 - -#define SD_CHECK_MODE 0x00 -#define SD_SWITCH_MODE 0x80 -#define SD_FUNC_GROUP_1 0x01 -#define SD_FUNC_GROUP_2 0x02 -#define SD_FUNC_GROUP_3 0x03 -#define SD_FUNC_GROUP_4 0x04 -#define SD_CHECK_SPEC_V1_1 0xFF - -#define NO_ARGUMENT 0x00 -#define CHECK_PATTERN 0x000000AA -#define VOLTAGE_SUPPLY_RANGE 0x00000100 -#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000 -#define SUPPORT_MAX_POWER_PERMANCE 0x10000000 -#define SUPPORT_1V8 0x01000000 - -#define SWITCH_NO_ERR 0x00 -#define CARD_NOT_EXIST 0x01 -#define SPEC_NOT_SUPPORT 0x02 -#define CHECK_MODE_ERR 0x03 -#define CHECK_NOT_READY 0x04 -#define SWITCH_CRC_ERR 0x05 -#define SWITCH_MODE_ERR 0x06 -#define SWITCH_PASS 0x07 - -#ifdef SUPPORT_SD_LOCK -#define SD_ERASE 0x08 -#define SD_LOCK 0x04 -#define SD_UNLOCK 0x00 -#define SD_CLR_PWD 0x02 -#define SD_SET_PWD 0x01 - -#define SD_PWD_LEN 0x10 - -#define SD_LOCKED 0x80 -#define SD_LOCK_1BIT_MODE 0x40 -#define SD_PWD_EXIST 0x20 -#define SD_UNLOCK_POW_ON 0x01 -#define SD_SDR_RST 0x02 - -#define SD_NOT_ERASE 0x00 -#define SD_UNDER_ERASING 0x01 -#define SD_COMPLETE_ERASE 0x02 - -#define SD_RW_FORBIDDEN 0x0F - -#endif - -#define HS_SUPPORT 0x01 -#define SDR50_SUPPORT 0x02 -#define SDR104_SUPPORT 0x03 -#define DDR50_SUPPORT 0x04 - -#define HS_SUPPORT_MASK 0x02 -#define SDR50_SUPPORT_MASK 0x04 -#define SDR104_SUPPORT_MASK 0x08 -#define DDR50_SUPPORT_MASK 0x10 - -#define HS_QUERY_SWITCH_OK 0x01 -#define SDR50_QUERY_SWITCH_OK 0x02 -#define SDR104_QUERY_SWITCH_OK 0x03 -#define DDR50_QUERY_SWITCH_OK 0x04 - -#define HS_SWITCH_BUSY 0x02 -#define SDR50_SWITCH_BUSY 0x04 -#define SDR104_SWITCH_BUSY 0x08 -#define DDR50_SWITCH_BUSY 0x10 - -#define FUNCTION_GROUP1_SUPPORT_OFFSET 0x0D -#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET 0x10 -#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET 0x1D - -#define DRIVING_TYPE_A 0x01 -#define DRIVING_TYPE_B 0x00 -#define DRIVING_TYPE_C 0x02 -#define DRIVING_TYPE_D 0x03 - -#define DRIVING_TYPE_A_MASK 0x02 -#define DRIVING_TYPE_B_MASK 0x01 -#define DRIVING_TYPE_C_MASK 0x04 -#define DRIVING_TYPE_D_MASK 0x08 - -#define TYPE_A_QUERY_SWITCH_OK 0x01 -#define TYPE_B_QUERY_SWITCH_OK 0x00 -#define TYPE_C_QUERY_SWITCH_OK 0x02 -#define TYPE_D_QUERY_SWITCH_OK 0x03 - -#define TYPE_A_SWITCH_BUSY 0x02 -#define TYPE_B_SWITCH_BUSY 0x01 -#define TYPE_C_SWITCH_BUSY 0x04 -#define TYPE_D_SWITCH_BUSY 0x08 - -#define FUNCTION_GROUP3_SUPPORT_OFFSET 0x09 -#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET 0x0F -#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET 0x19 - -#define CURRENT_LIMIT_200 0x00 -#define CURRENT_LIMIT_400 0x01 -#define CURRENT_LIMIT_600 0x02 -#define CURRENT_LIMIT_800 0x03 - -#define CURRENT_LIMIT_200_MASK 0x01 -#define CURRENT_LIMIT_400_MASK 0x02 -#define CURRENT_LIMIT_600_MASK 0x04 -#define CURRENT_LIMIT_800_MASK 0x08 - -#define CURRENT_LIMIT_200_QUERY_SWITCH_OK 0x00 -#define CURRENT_LIMIT_400_QUERY_SWITCH_OK 0x01 -#define CURRENT_LIMIT_600_QUERY_SWITCH_OK 0x02 -#define CURRENT_LIMIT_800_QUERY_SWITCH_OK 0x03 - -#define CURRENT_LIMIT_200_SWITCH_BUSY 0x01 -#define CURRENT_LIMIT_400_SWITCH_BUSY 0x02 -#define CURRENT_LIMIT_600_SWITCH_BUSY 0x04 -#define CURRENT_LIMIT_800_SWITCH_BUSY 0x08 - -#define FUNCTION_GROUP4_SUPPORT_OFFSET 0x07 -#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET 0x0F -#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET 0x17 - -#define DATA_STRUCTURE_VER_OFFSET 0x11 - -#define MAX_PHASE 31 - -#define MMC_8BIT_BUS 0x0010 -#define MMC_4BIT_BUS 0x0020 - -#define MMC_SWITCH_ERR 0x80 - -#define SD_IO_3V3 0 -#define SD_IO_1V8 1 - -#define TUNE_TX 0x00 -#define TUNE_RX 0x01 - -#define CHANGE_TX 0x00 -#define CHANGE_RX 0x01 - -#define DCM_HIGH_FREQUENCY_MODE 0x00 -#define DCM_LOW_FREQUENCY_MODE 0x01 - -#define DCM_HIGH_FREQUENCY_MODE_SET 0x0C -#define DCM_LOW_FREQUENCY_MODE_SET 0x00 - -#define MULTIPLY_BY_1 0x00 -#define MULTIPLY_BY_2 0x01 -#define MULTIPLY_BY_3 0x02 -#define MULTIPLY_BY_4 0x03 -#define MULTIPLY_BY_5 0x04 -#define MULTIPLY_BY_6 0x05 -#define MULTIPLY_BY_7 0x06 -#define MULTIPLY_BY_8 0x07 -#define MULTIPLY_BY_9 0x08 -#define MULTIPLY_BY_10 0x09 - -#define DIVIDE_BY_2 0x01 -#define DIVIDE_BY_3 0x02 -#define DIVIDE_BY_4 0x03 -#define DIVIDE_BY_5 0x04 -#define DIVIDE_BY_6 0x05 -#define DIVIDE_BY_7 0x06 -#define DIVIDE_BY_8 0x07 -#define DIVIDE_BY_9 0x08 -#define DIVIDE_BY_10 0x09 - -struct timing_phase_path { - int start; - int end; - int mid; - int len; -}; - -int sd_select_card(struct rtsx_chip *chip, int select); -int sd_pull_ctl_enable(struct rtsx_chip *chip); -int reset_sd_card(struct rtsx_chip *chip); -int sd_switch_clock(struct rtsx_chip *chip); -void sd_stop_seq_mode(struct rtsx_chip *chip); -int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt); -void sd_cleanup_work(struct rtsx_chip *chip); -int sd_power_off_card3v3(struct rtsx_chip *chip); -int release_sd_card(struct rtsx_chip *chip); -#ifdef SUPPORT_CPRM -int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, - bool special_check); -int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type); - -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_SD_H */ diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c deleted file mode 100644 index e88fe1a998f8126a3f5301155678875f282e8483..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/spi.c +++ /dev/null @@ -1,906 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include - -#include "rtsx.h" -#include "spi.h" - -static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct spi_info *spi = &chip->spi; - - spi->err_code = err_code; -} - -static int spi_init(struct rtsx_chip *chip) -{ - int retval; - - retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF, - CS_POLARITY_LOW | DTO_MSB_FIRST - | SPI_MASTER | SPI_MODE0 | SPI_AUTO); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK, - SAMPLE_DELAY_HALF); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int spi_set_init_para(struct rtsx_chip *chip) -{ - struct spi_info *spi = &chip->spi; - int retval; - - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF, - (u8)(spi->clk_div >> 8)); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF, - (u8)(spi->clk_div)); - if (retval) - return retval; - - retval = switch_clock(chip, spi->spi_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN, - SPI_CLK_EN); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN, - SPI_OUTPUT_EN); - if (retval) - return retval; - - wait_timeout(10); - - retval = spi_init(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sf_polling_status(struct rtsx_chip *chip, int msec) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_POLLING_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, msec); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_BUSY_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sf_enable_write(struct rtsx_chip *chip, u8 ins) -{ - struct spi_info *spi = &chip->spi; - int retval; - - if (!spi->write_en) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_C_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sf_disable_write(struct rtsx_chip *chip, u8 ins) -{ - struct spi_info *spi = &chip->spi; - int retval; - - if (!spi->write_en) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_C_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, - u16 len) -{ - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8)); - if (addr_mode) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADO_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CDO_MODE0); - } - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); -} - -static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - if (addr_mode) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_C_MODE0); - } - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int spi_init_eeprom(struct rtsx_chip *chip) -{ - int retval; - int clk; - - if (chip->asic_code) - clk = 30; - else - clk = CLK_30; - - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27); - if (retval) - return retval; - - retval = switch_clock(chip, clk); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN, - SPI_CLK_EN); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN, - SPI_OUTPUT_EN); - if (retval) - return retval; - - wait_timeout(10); - - retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF, - CS_POLARITY_HIGH | SPI_EEPROM_AUTO); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK, - SAMPLE_DELAY_HALF); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int spi_eeprom_program_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int spi_erase_eeprom_chip(struct rtsx_chip *chip) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val) -{ - int retval; - u8 data; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADI_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - wait_timeout(5); - retval = rtsx_read_register(chip, SPI_DATA, &data); - if (retval) - return retval; - - if (val) - *val = data; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct spi_info *spi = &chip->spi; - - dev_dbg(rtsx_dev(chip), "%s: err_code = 0x%x\n", __func__, - spi->err_code); - rtsx_stor_set_xfer_buf(&spi->err_code, - min_t(int, scsi_bufflen(srb), 1), srb); - scsi_set_resid(srb, scsi_bufflen(srb) - 1); - - return STATUS_SUCCESS; -} - -int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct spi_info *spi = &chip->spi; - - spi_set_err_code(chip, SPI_NO_ERR); - - if (chip->asic_code) - spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9]; - else - spi->spi_clock = srb->cmnd[3]; - - spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - spi->write_en = srb->cmnd[6]; - - dev_dbg(rtsx_dev(chip), "spi_clock = %d, clk_div = %d, write_en = %d\n", - spi->spi_clock, spi->clk_div, spi->write_en); - - return STATUS_SUCCESS; -} - -int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u16 len; - u8 *buf; - - spi_set_err_code(chip, SPI_NO_ERR); - - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - if (len > 512) { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - return STATUS_FAIL; - } - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]); - - if (len == 0) { - if (srb->cmnd[9]) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); - } - } else { - if (srb->cmnd[9]) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADI_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CDI_MODE0); - } - } - - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - if (len) { - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - retval = rtsx_read_ppbuf(chip, buf, len); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_READ_ERR); - kfree(buf); - return STATUS_FAIL; - } - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - scsi_set_resid(srb, 0); - - kfree(buf); - } - - return STATUS_SUCCESS; -} - -int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - unsigned int index = 0, offset = 0; - u8 ins, slow_read; - u32 addr; - u16 len; - u8 *buf; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) - << 8) | srb->cmnd[6]; - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - slow_read = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - while (len) { - u16 pagelen = SF_PAGE_LEN - (u8)addr; - - if (pagelen > len) - pagelen = len; - - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - - if (slow_read) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, - (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32); - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, - (u8)(pagelen >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, - (u8)pagelen); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADI_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, - SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, - DMA_FROM_DEVICE, 10000); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, - TO_XFER_BUF); - - addr += pagelen; - len -= pagelen; - } - - scsi_set_resid(srb, 0); - kfree(buf); - - return STATUS_SUCCESS; -} - -int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, program_mode; - u32 addr; - u16 len; - u8 *buf; - unsigned int index = 0, offset = 0; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) - << 8) | srb->cmnd[6]; - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - program_mode = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - if (program_mode == BYTE_PROGRAM) { - buf = kmalloc(4, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - while (len) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, - FROM_XFER_BUF); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, - buf[0]); - sf_program(chip, ins, 1, addr, 1); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - addr++; - len--; - } - - kfree(buf); - - } else if (program_mode == AAI_PROGRAM) { - int first_byte = 1; - - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(4, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - while (len) { - rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, - FROM_XFER_BUF); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, - buf[0]); - if (first_byte) { - sf_program(chip, ins, 1, addr, 1); - first_byte = 0; - } else { - sf_program(chip, ins, 0, 0, 1); - } - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - len--; - } - - kfree(buf); - - retval = sf_disable_write(chip, SPI_WRDI); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else if (program_mode == PAGE_PROGRAM) { - buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); - if (!buf) - return STATUS_NOMEM; - - while (len) { - u16 pagelen = SF_PAGE_LEN - (u8)addr; - - if (pagelen > len) - pagelen = len; - - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256); - sf_program(chip, ins, 1, addr, pagelen); - - rtsx_send_cmd_no_wait(chip); - - rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, - &offset, FROM_XFER_BUF); - - retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, - DMA_TO_DEVICE, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - addr += pagelen; - len -= pagelen; - } - - kfree(buf); - } else { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, erase_mode; - u32 addr; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) - << 8) | srb->cmnd[6]; - erase_mode = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - if (erase_mode == PAGE_ERASE) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sf_erase(chip, ins, 1, addr); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else if (erase_mode == CHIP_ERASE) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sf_erase(chip, ins, 0, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, status, ewsr; - - ins = srb->cmnd[3]; - status = srb->cmnd[4]; - ewsr = srb->cmnd[5]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_enable_write(chip, ewsr); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CDO_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/spi.h b/drivers/staging/rts5208/spi.h deleted file mode 100644 index dcf93c80b2d50a95fa77b5151e9d8dc6bfc3f694..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/spi.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_SPI_H -#define __REALTEK_RTSX_SPI_H - -/* SPI operation error */ -#define SPI_NO_ERR 0x00 -#define SPI_HW_ERR 0x01 -#define SPI_INVALID_COMMAND 0x02 -#define SPI_READ_ERR 0x03 -#define SPI_WRITE_ERR 0x04 -#define SPI_ERASE_ERR 0x05 -#define SPI_BUSY_ERR 0x06 - -/* Serial flash instruction */ -#define SPI_READ 0x03 -#define SPI_FAST_READ 0x0B -#define SPI_WREN 0x06 -#define SPI_WRDI 0x04 -#define SPI_RDSR 0x05 - -#define SF_PAGE_LEN 256 - -#define BYTE_PROGRAM 0 -#define AAI_PROGRAM 1 -#define PAGE_PROGRAM 2 - -#define PAGE_ERASE 0 -#define CHIP_ERASE 1 - -int spi_erase_eeprom_chip(struct rtsx_chip *chip); -int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr); -int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val); -int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val); -int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_SPI_H */ diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c deleted file mode 100644 index c0af378ada7162135956b3840f24393e52f5e424..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/xd.c +++ /dev/null @@ -1,2145 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#include -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "xd.h" - -static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no); -static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, - u8 start_page, u8 end_page); - -static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct xd_info *xd_card = &chip->xd_card; - - xd_card->err_code = err_code; -} - -static int xd_set_init_para(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - if (chip->asic_code) - xd_card->xd_clock = 47; - else - xd_card->xd_clock = CLK_50; - - retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_switch_clock(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len) -{ - int retval, i; - u8 *ptr; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_ID); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - for (i = 0; i < 4; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 20); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip) + 1; - if (id_buf && buf_len) { - if (buf_len > 4) - buf_len = 4; - memcpy(id_buf, ptr, buf_len); - } - - return STATUS_SUCCESS; -} - -static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode) -{ - struct xd_info *xd_card = &chip->xd_card; - - switch (mode) { - case XD_RW_ADDR: - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, - 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, - 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, - xd_card->addr_cycle | - XD_CALC_ECC | - XD_BA_NO_TRANSFORM); - break; - - case XD_ERASE_ADDR: - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, - 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, - 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, - (xd_card->addr_cycle - 1) | XD_CALC_ECC | - XD_BA_NO_TRANSFORM); - break; - - default: - break; - } -} - -static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr, - u8 *buf, int buf_len) -{ - int retval, i; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - for (i = 0; i < 6; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i), - 0, 0); - for (i = 0; i < 4; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i), - 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) - return STATUS_FAIL; - - if (buf && buf_len) { - u8 *ptr = rtsx_get_cmd_data(chip) + 1; - - if (buf_len > 11) - buf_len = 11; - memcpy(buf, ptr, buf_len); - } - - return STATUS_SUCCESS; -} - -static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset, - u8 *buf, int buf_len) -{ - int retval, i; - - if (!buf || buf_len < 0) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - for (i = 0; i < buf_len; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, - 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - memcpy(buf, rtsx_get_cmd_data(chip), buf_len); - - return STATUS_SUCCESS; -} - -static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, - int buf_len) -{ - int retval; - u8 reg; - - if (!buf || buf_len < 10) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 250); - if (retval == -ETIMEDOUT) { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, XD_PAGE_STATUS, ®); - if (retval) - return retval; - if (reg != XD_GPG) { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, XD_CTL, ®); - if (retval) - return retval; - if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { - retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - if (reg & XD_ECC1_ERROR) { - u8 ecc_bit, ecc_byte; - - retval = rtsx_read_register(chip, XD_ECC_BIT1, - &ecc_bit); - if (retval) - return retval; - retval = rtsx_read_register(chip, XD_ECC_BYTE1, - &ecc_byte); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", - ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n", - buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n", - buf[ecc_byte]); - } - } - } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) { - rtsx_clear_xd_error(chip); - - retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - if (reg & XD_ECC2_ERROR) { - u8 ecc_bit, ecc_byte; - - retval = rtsx_read_register(chip, XD_ECC_BIT2, - &ecc_bit); - if (retval) - return retval; - retval = rtsx_read_register(chip, XD_ECC_BYTE2, - &ecc_byte); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", - ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n", - buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n", - buf[ecc_byte]); - } - } - } else { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, - 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, - 0xFF, 0x69); - } - } -} - -static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip) -{ - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - } -} - -static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, - 0xFF, 0x53); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, - 0xFF, 0xA9); - } - } -} - -static int xd_pull_ctl_disable(struct rtsx_chip *chip) -{ - int retval; - - if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | - XD_D2_PD | - XD_D1_PD | - XD_D0_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | - XD_D6_PD | - XD_D5_PD | - XD_D4_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | - XD_CE_PD | - XD_CLE_PD | - XD_CD_PU); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | - XD_WE_PD | - XD_RE_PD | - XD_ALE_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | - SD_WP_PD | - SD_CD_PU | - SD_CMD_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, - 0xFF, 0x4B); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, - 0xFF, 0x69); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -static int reset_xd(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval, i, j; - u8 *ptr, id_buf[4], redunt[11]; - - retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, - XD_PGSTS_NOT_FF); - if (chip->asic_code) { - if (!CHECK_PID(chip, 0x5288)) - xd_fill_pull_ctl_disable(chip); - else - xd_fill_pull_ctl_stage1_barossa(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | - 0x20); - } - - if (!chip->ft2_fast_mode) - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT, - XD_NO_AUTO_PWR_OFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(250); - - rtsx_init_cmd(chip); - - if (chip->asic_code) { - xd_fill_pull_ctl_enable(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & - FPGA_XD_PULL_CTL_EN2) | - 0x20); - } - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = card_power_on(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -#ifdef SUPPORT_OCP - wait_timeout(50); - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - return STATUS_FAIL; - } -#endif - } - - rtsx_init_cmd(chip); - - if (chip->ft2_fast_mode) { - if (chip->asic_code) { - xd_fill_pull_ctl_enable(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & - FPGA_XD_PULL_CTL_EN2) | - 0x20); - } - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) - wait_timeout(200); - - retval = xd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Read ID to check if the timing setting is right */ - for (i = 0; i < 4; i++) { - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, - XD_TIME_SETUP_STEP * 3 + - XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF, - XD_TIME_SETUP_STEP * 3 + - XD_TIME_RW_STEP * (4 + i) + - XD_TIME_RWN_STEP * (3 + i)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_RESET); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip) + 1; - - dev_dbg(rtsx_dev(chip), "XD_DAT: 0x%x, XD_CTL: 0x%x\n", - ptr[0], ptr[1]); - - if (((ptr[0] & READY_FLAG) != READY_STATE) || - !(ptr[1] & XD_RDY)) - continue; - - retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "READ_ID: 0x%x 0x%x 0x%x 0x%x\n", - id_buf[0], id_buf[1], id_buf[2], id_buf[3]); - - xd_card->device_code = id_buf[1]; - - /* Check if the xD card is supported */ - switch (xd_card->device_code) { - case XD_4M_X8_512_1: - case XD_4M_X8_512_2: - xd_card->block_shift = 4; - xd_card->page_off = 0x0F; - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 8000; - XD_SET_4MB(xd_card); - break; - case XD_8M_X8_512: - xd_card->block_shift = 4; - xd_card->page_off = 0x0F; - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 16000; - break; - case XD_16M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 32000; - break; - case XD_32M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 2; - xd_card->capacity = 64000; - break; - case XD_64M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 4; - xd_card->capacity = 128000; - break; - case XD_128M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 8; - xd_card->capacity = 256000; - break; - case XD_256M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 16; - xd_card->capacity = 512000; - break; - case XD_512M_X8: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 32; - xd_card->capacity = 1024000; - break; - case XD_1G_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 64; - xd_card->capacity = 2048000; - break; - case XD_2G_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 128; - xd_card->capacity = 4096000; - break; - default: - continue; - } - - /* Confirm timing setting */ - for (j = 0; j < 10; j++) { - retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (id_buf[1] != xd_card->device_code) - break; - } - - if (j == 10) - break; - } - - if (i == 4) { - xd_card->block_shift = 0; - xd_card->page_off = 0; - xd_card->addr_cycle = 0; - xd_card->capacity = 0; - - return STATUS_FAIL; - } - - retval = xd_read_id(chip, READ_XD_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - dev_dbg(rtsx_dev(chip), "READ_XD_ID: 0x%x 0x%x 0x%x 0x%x\n", - id_buf[0], id_buf[1], id_buf[2], id_buf[3]); - if (id_buf[2] != XD_ID_CODE) - return STATUS_FAIL; - - /* Search CIS block */ - for (i = 0; i < 24; i++) { - u32 page_addr; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) - return STATUS_FAIL; - - page_addr = (u32)i << xd_card->block_shift; - - for (j = 0; j < 3; j++) { - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval == STATUS_SUCCESS) - break; - } - if (j == 3) - continue; - - if (redunt[BLOCK_STATUS] != XD_GBLK) - continue; - - j = 0; - if (redunt[PAGE_STATUS] != XD_GPG) { - for (j = 1; j <= 8; j++) { - retval = xd_read_redundant(chip, page_addr + j, - redunt, 11); - if (retval == STATUS_SUCCESS) { - if (redunt[PAGE_STATUS] == XD_GPG) - break; - } - } - - if (j == 9) - break; - } - - /* Check CIS data */ - if (redunt[BLOCK_STATUS] == XD_GBLK && - (redunt[PARITY] & XD_BA1_ALL0)) { - u8 buf[10]; - - page_addr += j; - - retval = xd_read_cis(chip, page_addr, buf, 10); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (buf[0] == 0x01 && buf[1] == 0x03 && - buf[2] == 0xD9 && - buf[3] == 0x01 && buf[4] == 0xFF && - buf[5] == 0x18 && buf[6] == 0x02 && - buf[7] == 0xDF && buf[8] == 0x01 && - buf[9] == 0x20) { - xd_card->cis_block = (u16)i; - } - } - - break; - } - - dev_dbg(rtsx_dev(chip), "CIS block: 0x%x\n", xd_card->cis_block); - if (xd_card->cis_block == 0xFFFF) - return STATUS_FAIL; - - chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity; - - return STATUS_SUCCESS; -} - -static int xd_check_data_blank(u8 *redunt) -{ - int i; - - for (i = 0; i < 6; i++) { - if (redunt[PAGE_STATUS + i] != 0xFF) - return 0; - } - - if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) - != (XD_ECC1_ALL1 | XD_ECC2_ALL1)) - return 0; - - for (i = 0; i < 4; i++) { - if (redunt[RESERVED0 + i] != 0xFF) - return 0; - } - - return 1; -} - -static u16 xd_load_log_block_addr(u8 *redunt) -{ - u16 addr = 0xFFFF; - - if (redunt[PARITY] & XD_BA1_BA2_EQL) - addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | - redunt[BLOCK_ADDR1_L]; - else if (redunt[PARITY] & XD_BA1_VALID) - addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | - redunt[BLOCK_ADDR1_L]; - else if (redunt[PARITY] & XD_BA2_VALID) - addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) | - redunt[BLOCK_ADDR2_L]; - - return addr; -} - -static int xd_init_l2p_tbl(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int size, i; - - dev_dbg(rtsx_dev(chip), "%s: zone_cnt = %d\n", __func__, - xd_card->zone_cnt); - - if (xd_card->zone_cnt < 1) - return STATUS_FAIL; - - size = xd_card->zone_cnt * sizeof(struct zone_entry); - dev_dbg(rtsx_dev(chip), "Buffer size for l2p table is %d\n", size); - - xd_card->zone = vmalloc(size); - if (!xd_card->zone) - return STATUS_ERROR; - - for (i = 0; i < xd_card->zone_cnt; i++) { - xd_card->zone[i].build_flag = 0; - xd_card->zone[i].l2p_table = NULL; - xd_card->zone[i].free_table = NULL; - xd_card->zone[i].get_index = 0; - xd_card->zone[i].set_index = 0; - xd_card->zone[i].unused_blk_cnt = 0; - } - - return STATUS_SUCCESS; -} - -static inline void free_zone(struct zone_entry *zone) -{ - if (!zone) - return; - - zone->build_flag = 0; - zone->set_index = 0; - zone->get_index = 0; - zone->unused_blk_cnt = 0; - vfree(zone->l2p_table); - zone->l2p_table = NULL; - vfree(zone->free_table); - zone->free_table = NULL; -} - -static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - int zone_no; - - zone_no = (int)phy_blk >> 10; - if (zone_no >= xd_card->zone_cnt) { - dev_dbg(rtsx_dev(chip), "Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n", - zone_no, xd_card->zone_cnt); - return; - } - zone = &xd_card->zone[zone_no]; - - if (!zone->free_table) { - if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) - return; - } - - if (zone->set_index >= XD_FREE_TABLE_CNT || - zone->set_index < 0) { - free_zone(zone); - dev_dbg(rtsx_dev(chip), "Set unused block fail, invalid set_index\n"); - return; - } - - dev_dbg(rtsx_dev(chip), "Set unused block to index %d\n", - zone->set_index); - - zone->free_table[zone->set_index++] = (u16)(phy_blk & 0x3ff); - if (zone->set_index >= XD_FREE_TABLE_CNT) - zone->set_index = 0; - zone->unused_blk_cnt++; -} - -static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - u32 phy_blk; - - if (zone_no >= xd_card->zone_cnt) { - dev_dbg(rtsx_dev(chip), "Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n", - zone_no, xd_card->zone_cnt); - return BLK_NOT_FOUND; - } - zone = &xd_card->zone[zone_no]; - - if (zone->unused_blk_cnt == 0 || - zone->set_index == zone->get_index) { - free_zone(zone); - dev_dbg(rtsx_dev(chip), "Get unused block fail, no unused block available\n"); - return BLK_NOT_FOUND; - } - if (zone->get_index >= XD_FREE_TABLE_CNT || zone->get_index < 0) { - free_zone(zone); - dev_dbg(rtsx_dev(chip), "Get unused block fail, invalid get_index\n"); - return BLK_NOT_FOUND; - } - - dev_dbg(rtsx_dev(chip), "Get unused block from index %d\n", - zone->get_index); - - phy_blk = zone->free_table[zone->get_index]; - zone->free_table[zone->get_index++] = 0xFFFF; - if (zone->get_index >= XD_FREE_TABLE_CNT) - zone->get_index = 0; - zone->unused_blk_cnt--; - - phy_blk += ((u32)(zone_no) << 10); - return phy_blk; -} - -static void xd_set_l2p_tbl(struct rtsx_chip *chip, - int zone_no, u16 log_off, u16 phy_off) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - - zone = &xd_card->zone[zone_no]; - zone->l2p_table[log_off] = phy_off; -} - -static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - int retval; - - zone = &xd_card->zone[zone_no]; - if (zone->l2p_table[log_off] == 0xFFFF) { - u32 phy_blk = 0; - int i; - -#ifdef XD_DELAY_WRITE - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "In %s, delay write fail!\n", - __func__); - return BLK_NOT_FOUND; - } -#endif - - if (zone->unused_blk_cnt <= 0) { - dev_dbg(rtsx_dev(chip), "No unused block!\n"); - return BLK_NOT_FOUND; - } - - for (i = 0; i < zone->unused_blk_cnt; i++) { - phy_blk = xd_get_unused_block(chip, zone_no); - if (phy_blk == BLK_NOT_FOUND) { - dev_dbg(rtsx_dev(chip), "No unused block available!\n"); - return BLK_NOT_FOUND; - } - - retval = xd_init_page(chip, phy_blk, log_off, - 0, xd_card->page_off + 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i >= zone->unused_blk_cnt) { - dev_dbg(rtsx_dev(chip), "No good unused block available!\n"); - return BLK_NOT_FOUND; - } - - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF)); - return phy_blk; - } - - return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10); -} - -int reset_xd_card(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - memset(xd_card, 0, sizeof(struct xd_info)); - - xd_card->block_shift = 0; - xd_card->page_off = 0; - xd_card->addr_cycle = 0; - xd_card->capacity = 0; - xd_card->zone_cnt = 0; - xd_card->cis_block = 0xFFFF; - xd_card->delay_write.delay_write_flag = 0; - - retval = enable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = reset_xd(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - u32 page_addr; - u8 reg = 0; - - dev_dbg(rtsx_dev(chip), "mark block 0x%x as bad block\n", phy_blk); - - if (phy_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF); - - page_addr = phy_blk << xd_card->block_shift; - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, - xd_card->page_off + 1); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) - xd_set_err_code(chip, XD_PRG_ERROR); - else - xd_set_err_code(chip, XD_TO_ERROR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, - u16 logoff, u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - u32 page_addr; - u8 reg = 0; - - dev_dbg(rtsx_dev(chip), "Init block 0x%x\n", phy_blk); - - if (start_page > end_page) - return STATUS_FAIL; - if (phy_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, - 0xFF, (u8)(logoff >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff); - - page_addr = (phy_blk << xd_card->block_shift) + start_page; - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, - XD_BA_TRANSFORM, XD_BA_TRANSFORM); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, - 0xFF, (end_page - start_page)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - } else { - xd_set_err_code(chip, XD_TO_ERROR); - } - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, - u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 old_page, new_page; - u8 i, reg = 0; - int retval; - - dev_dbg(rtsx_dev(chip), "Copy page from block 0x%x to block 0x%x\n", - old_blk, new_blk); - - if (start_page > end_page) - return STATUS_FAIL; - - if (old_blk == BLK_NOT_FOUND || new_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - old_page = (old_blk << xd_card->block_shift) + start_page; - new_page = (new_blk << xd_card->block_shift) + start_page; - - XD_CLR_BAD_NEWBLK(xd_card); - - retval = rtsx_write_register(chip, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - if (retval) - return retval; - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - rtsx_clear_xd_error(chip); - xd_set_err_code(chip, XD_NO_CARD); - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, old_page, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - reg = 0; - rtsx_read_register(chip, XD_CTL, ®); - if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) { - mdelay(100); - - if (detect_card_cd(chip, - XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - return STATUS_FAIL; - } - - if (((reg & XD_ECC1_ERROR) && - (reg & XD_ECC1_UNCORRECTABLE)) || - ((reg & XD_ECC2_ERROR) && - (reg & XD_ECC2_UNCORRECTABLE))) { - rtsx_write_register(chip, - XD_PAGE_STATUS, - 0xFF, - XD_BPG); - rtsx_write_register(chip, - XD_BLOCK_STATUS, - 0xFF, - XD_GBLK); - XD_SET_BAD_OLDBLK(xd_card); - dev_dbg(rtsx_dev(chip), "old block 0x%x ecc error\n", - old_blk); - } - } else { - xd_set_err_code(chip, XD_TO_ERROR); - return STATUS_FAIL; - } - } - - if (XD_CHK_BAD_OLDBLK(xd_card)) - rtsx_clear_xd_error(chip); - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, new_page, XD_RW_ADDR); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 300); - if (retval < 0) { - rtsx_clear_xd_error(chip); - reg = 0; - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, new_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - XD_SET_BAD_NEWBLK(xd_card); - } else { - xd_set_err_code(chip, XD_TO_ERROR); - } - return STATUS_FAIL; - } - - old_page++; - new_page++; - } - - return STATUS_SUCCESS; -} - -static int xd_reset_cmd(struct rtsx_chip *chip) -{ - int retval; - u8 *ptr; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_RESET); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip) + 1; - if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY)) - return STATUS_SUCCESS; - - return STATUS_FAIL; -} - -static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 page_addr; - u8 reg = 0, *ptr; - int i, retval; - - if (phy_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - page_addr = phy_blk << xd_card->block_shift; - - for (i = 0; i < 3; i++) { - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_ERASE); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 250); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - return STATUS_FAIL; - } - xd_set_err_code(chip, XD_ERASE_FAIL); - retval = xd_reset_cmd(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - continue; - } - - ptr = rtsx_get_cmd_data(chip) + 1; - if (*ptr & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; - } - - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_ERASE_FAIL); - return STATUS_FAIL; -} - -static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - int retval; - u32 start, end, i; - u16 max_logoff, cur_fst_page_logoff; - u16 cur_lst_page_logoff, ent_lst_page_logoff; - u8 redunt[11]; - - dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, zone_no); - - if (!xd_card->zone) { - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - return retval; - } - - if (xd_card->zone[zone_no].build_flag) { - dev_dbg(rtsx_dev(chip), "l2p table of zone %d has been built\n", - zone_no); - return STATUS_SUCCESS; - } - - zone = &xd_card->zone[zone_no]; - - if (!zone->l2p_table) { - zone->l2p_table = vmalloc(2000); - if (!zone->l2p_table) - goto build_fail; - } - memset((u8 *)(zone->l2p_table), 0xff, 2000); - - if (!zone->free_table) { - zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2); - if (!zone->free_table) - goto build_fail; - } - memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2); - - if (zone_no == 0) { - if (xd_card->cis_block == 0xFFFF) - start = 0; - else - start = xd_card->cis_block + 1; - if (XD_CHK_4MB(xd_card)) { - end = 0x200; - max_logoff = 499; - } else { - end = 0x400; - max_logoff = 999; - } - } else { - start = (u32)(zone_no) << 10; - end = (u32)(zone_no + 1) << 10; - max_logoff = 999; - } - - dev_dbg(rtsx_dev(chip), "start block 0x%x, end block 0x%x\n", - start, end); - - zone->set_index = 0; - zone->get_index = 0; - zone->unused_blk_cnt = 0; - - for (i = start; i < end; i++) { - u32 page_addr = i << xd_card->block_shift; - u32 phy_block; - - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) - continue; - - if (redunt[BLOCK_STATUS] != 0xFF) { - dev_dbg(rtsx_dev(chip), "bad block\n"); - continue; - } - - if (xd_check_data_blank(redunt)) { - dev_dbg(rtsx_dev(chip), "blank block\n"); - xd_set_unused_block(chip, i); - continue; - } - - cur_fst_page_logoff = xd_load_log_block_addr(redunt); - if (cur_fst_page_logoff == 0xFFFF || - cur_fst_page_logoff > max_logoff) { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - continue; - } - - if (zone_no == 0 && cur_fst_page_logoff == 0 && - redunt[PAGE_STATUS] != XD_GPG) - XD_SET_MBR_FAIL(xd_card); - - if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) { - zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); - continue; - } - - phy_block = zone->l2p_table[cur_fst_page_logoff] + - ((u32)((zone_no) << 10)); - - page_addr = ((i + 1) << xd_card->block_shift) - 1; - - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) - continue; - - cur_lst_page_logoff = xd_load_log_block_addr(redunt); - if (cur_lst_page_logoff == cur_fst_page_logoff) { - int m; - - page_addr = ((phy_block + 1) << - xd_card->block_shift) - 1; - - for (m = 0; m < 3; m++) { - retval = xd_read_redundant(chip, page_addr, - redunt, 11); - if (retval == STATUS_SUCCESS) - break; - } - - if (m == 3) { - zone->l2p_table[cur_fst_page_logoff] = - (u16)(i & 0x3FF); - retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, phy_block); - continue; - } - - ent_lst_page_logoff = xd_load_log_block_addr(redunt); - if (ent_lst_page_logoff != cur_fst_page_logoff) { - zone->l2p_table[cur_fst_page_logoff] = - (u16)(i & 0x3FF); - retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, phy_block); - continue; - } else { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - } - } else { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - } - } - - if (XD_CHK_4MB(xd_card)) - end = 500; - else - end = 1000; - - i = 0; - for (start = 0; start < end; start++) { - if (zone->l2p_table[start] == 0xFFFF) - i++; - } - - dev_dbg(rtsx_dev(chip), "Block count %d, invalid L2P entry %d\n", - end, i); - dev_dbg(rtsx_dev(chip), "Total unused block: %d\n", - zone->unused_blk_cnt); - - if ((zone->unused_blk_cnt - i) < 1) - chip->card_wp |= XD_CARD; - - zone->build_flag = 1; - - return STATUS_SUCCESS; - -build_fail: - vfree(zone->l2p_table); - zone->l2p_table = NULL; - vfree(zone->free_table); - zone->free_table = NULL; - - return STATUS_FAIL; -} - -static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_SET_CMD); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 200); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, - u32 log_blk, u8 start_page, u8 end_page, - u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 page_addr, new_blk; - u16 log_off; - u8 reg_val, page_cnt; - int zone_no, retval, i; - - if (start_page > end_page) - goto status_fail; - - page_cnt = end_page - start_page; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if ((phy_blk & 0x3FF) == 0x3FF) { - for (i = 0; i < 256; i++) { - page_addr = ((u32)i) << xd_card->block_shift; - - retval = xd_read_redundant(chip, page_addr, NULL, 0); - if (retval == STATUS_SUCCESS) - break; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - goto status_fail; - } - } - } - - page_addr = (phy_blk << xd_card->block_shift) + start_page; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - trans_dma_enable(chip->srb->sc_data_direction, chip, - page_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END | XD_PPB_EMPTY, - XD_TRANSFER_END | XD_PPB_EMPTY); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, - scsi_sg_count(chip->srb), - index, offset, DMA_FROM_DEVICE, - chip->xd_timeout); - if (retval < 0) { - rtsx_clear_xd_error(chip); - - if (retval == -ETIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - goto status_fail; - } else { - goto fail; - } - } - - return STATUS_SUCCESS; - -fail: - retval = rtsx_read_register(chip, XD_PAGE_STATUS, ®_val); - if (retval) - return retval; - - if (reg_val != XD_GPG) - xd_set_err_code(chip, XD_PRG_ERROR); - - retval = rtsx_read_register(chip, XD_CTL, ®_val); - if (retval) - return retval; - - if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) == - (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) || - ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) == - (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { - wait_timeout(100); - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - goto status_fail; - } - - xd_set_err_code(chip, XD_ECC_ERROR); - - new_blk = xd_get_unused_block(chip, zone_no); - if (new_blk == NO_NEW_BLK) { - XD_CLR_BAD_OLDBLK(xd_card); - goto status_fail; - } - - retval = xd_copy_page(chip, phy_blk, new_blk, 0, - xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - if (!XD_CHK_BAD_NEWBLK(xd_card)) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - } else { - XD_CLR_BAD_NEWBLK(xd_card); - } - XD_CLR_BAD_OLDBLK(xd_card); - goto status_fail; - } - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - xd_erase_block(chip, phy_blk); - xd_mark_bad_block(chip, phy_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } - -status_fail: - return STATUS_FAIL; -} - -static int xd_finish_write(struct rtsx_chip *chip, - u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval, zone_no; - u16 log_off; - - dev_dbg(rtsx_dev(chip), "old_blk = 0x%x, ", old_blk); - dev_dbg(rtsx_dev(chip), "new_blk = 0x%x, ", new_blk); - dev_dbg(rtsx_dev(chip), "log_blk = 0x%x\n", log_blk); - - if (page_off > xd_card->page_off) - return STATUS_FAIL; - - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (old_blk == BLK_NOT_FOUND) { - retval = xd_init_page(chip, new_blk, log_off, - page_off, xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - return STATUS_FAIL; - } - } else { - retval = xd_copy_page(chip, old_blk, new_blk, - page_off, xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - if (!XD_CHK_BAD_NEWBLK(xd_card)) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - } - XD_CLR_BAD_NEWBLK(xd_card); - return STATUS_FAIL; - } - - retval = xd_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { - if (XD_CHK_BAD_OLDBLK(xd_card)) { - xd_mark_bad_block(chip, old_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } else { - xd_set_unused_block(chip, old_blk); - } - } else { - xd_set_err_code(chip, XD_NO_ERROR); - XD_CLR_BAD_OLDBLK(xd_card); - } - } - - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - - return STATUS_SUCCESS; -} - -static int xd_prepare_write(struct rtsx_chip *chip, - u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n", - __func__, old_blk, new_blk, log_blk, (int)page_off); - - if (page_off) { - retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, - u32 new_blk, u32 log_blk, u8 start_page, - u8 end_page, u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 page_addr; - int zone_no, retval; - u16 log_off; - u8 page_cnt, reg_val; - - dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", - __func__, old_blk, new_blk, log_blk); - - if (start_page > end_page) - goto status_fail; - - page_cnt = end_page - start_page; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - page_addr = (new_blk << xd_card->block_shift) + start_page; - - retval = xd_send_cmd(chip, READ1_1); - if (retval != STATUS_SUCCESS) - goto status_fail; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, - 0xFF, (u8)(log_off >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, - XD_BA_TRANSFORM); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - trans_dma_enable(chip->srb->sc_data_direction, chip, - page_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_WRITE_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, - scsi_sg_count(chip->srb), - index, offset, DMA_TO_DEVICE, chip->xd_timeout); - if (retval < 0) { - rtsx_clear_xd_error(chip); - - if (retval == -ETIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - goto status_fail; - } else { - goto fail; - } - } - - if (end_page == (xd_card->page_off + 1)) { - xd_card->delay_write.delay_write_flag = 0; - - if (old_blk != BLK_NOT_FOUND) { - retval = xd_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { - if (XD_CHK_BAD_OLDBLK(xd_card)) { - xd_mark_bad_block(chip, old_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } else { - xd_set_unused_block(chip, old_blk); - } - } else { - xd_set_err_code(chip, XD_NO_ERROR); - XD_CLR_BAD_OLDBLK(xd_card); - } - } - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - } - - return STATUS_SUCCESS; - -fail: - retval = rtsx_read_register(chip, XD_DAT, ®_val); - if (retval) - return retval; - if (reg_val & PROGRAM_ERROR) { - xd_set_err_code(chip, XD_PRG_ERROR); - xd_mark_bad_block(chip, new_blk); - } - -status_fail: - return STATUS_FAIL; -} - -#ifdef XD_DELAY_WRITE -int xd_delay_write(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - struct xd_delay_write_tag *delay_write = &xd_card->delay_write; - int retval; - - if (delay_write->delay_write_flag) { - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - delay_write->delay_write_flag = 0; - retval = xd_finish_write(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->logblock, - delay_write->pageoff); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} -#endif - -int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt) -{ - struct xd_info *xd_card = &chip->xd_card; - unsigned int lun = SCSI_LUN(srb); -#ifdef XD_DELAY_WRITE - struct xd_delay_write_tag *delay_write = &xd_card->delay_write; -#endif - int retval, zone_no; - unsigned int index = 0, offset = 0; - u32 log_blk, old_blk = 0, new_blk = 0; - u16 log_off, total_sec_cnt = sector_cnt; - u8 start_page, end_page = 0, page_cnt; - u8 *ptr; - - xd_set_err_code(chip, XD_NO_ERROR); - - xd_card->cleanup_counter = 0; - - dev_dbg(rtsx_dev(chip), "%s: scsi_sg_count = %d\n", __func__, - scsi_sg_count(srb)); - - ptr = (u8 *)scsi_sglist(srb); - - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - log_blk = start_sector >> xd_card->block_shift; - start_page = (u8)start_sector & xd_card->page_off; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (xd_card->zone[zone_no].build_flag == 0) { - retval = xd_build_l2p_tbl(chip, zone_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { -#ifdef XD_DELAY_WRITE - if (delay_write->delay_write_flag && - delay_write->logblock == log_blk && - start_page > delay_write->pageoff) { - delay_write->delay_write_flag = 0; - if (delay_write->old_phyblock != BLK_NOT_FOUND) { - retval = xd_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->pageoff, - start_page); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - } - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page == delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else { - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#endif - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - new_blk = xd_get_unused_block(chip, zone_no); - if (old_blk == BLK_NOT_FOUND || - new_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - - retval = xd_prepare_write(chip, old_blk, new_blk, - log_blk, start_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != - STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#ifdef XD_DELAY_WRITE - } -#endif - } else { -#ifdef XD_DELAY_WRITE - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } -#endif - - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - if (old_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } - } - - dev_dbg(rtsx_dev(chip), "old_blk = 0x%x\n", old_blk); - - while (total_sec_cnt) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) - end_page = xd_card->page_off + 1; - else - end_page = start_page + (u8)total_sec_cnt; - - page_cnt = end_page - start_page; - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - retval = xd_read_multiple_pages(chip, old_blk, log_blk, - start_page, end_page, - ptr, &index, &offset); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } - } else { - retval = xd_write_multiple_pages(chip, old_blk, - new_blk, log_blk, - start_page, end_page, - ptr, &index, &offset); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - } - - total_sec_cnt -= page_cnt; - if (scsi_sg_count(srb) == 0) - ptr += page_cnt * 512; - - if (total_sec_cnt == 0) - break; - - log_blk++; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (xd_card->zone[zone_no].build_flag == 0) { - retval = xd_build_l2p_tbl(chip, zone_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - if (old_blk == BLK_NOT_FOUND) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - - return STATUS_FAIL; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - new_blk = xd_get_unused_block(chip, zone_no); - if (new_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - } - - start_page = 0; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE && - (end_page != (xd_card->page_off + 1))) { -#ifdef XD_DELAY_WRITE - delay_write->delay_write_flag = 1; - delay_write->old_phyblock = old_blk; - delay_write->new_phyblock = new_blk; - delay_write->logblock = log_blk; - delay_write->pageoff = end_page; -#else - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - retval = xd_finish_write(chip, old_blk, new_blk, - log_blk, end_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#endif - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -void xd_free_l2p_tbl(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int i = 0; - - if (xd_card->zone) { - for (i = 0; i < xd_card->zone_cnt; i++) { - vfree(xd_card->zone[i].l2p_table); - xd_card->zone[i].l2p_table = NULL; - vfree(xd_card->zone[i].free_table); - xd_card->zone[i].free_table = NULL; - } - vfree(xd_card->zone); - xd_card->zone = NULL; - } -} - -void xd_cleanup_work(struct rtsx_chip *chip) -{ -#ifdef XD_DELAY_WRITE - struct xd_info *xd_card = &chip->xd_card; - - if (xd_card->delay_write.delay_write_flag) { - dev_dbg(rtsx_dev(chip), "xD: delay write\n"); - xd_delay_write(chip); - xd_card->cleanup_counter = 0; - } -#endif -} - -int xd_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - if (retval) - return retval; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(50); - } - - if (chip->asic_code) { - retval = xd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, 0xFF, 0xDF); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -int release_xd_card(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - chip->card_ready &= ~XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->card_wp &= ~XD_CARD; - - xd_card->delay_write.delay_write_flag = 0; - - xd_free_l2p_tbl(chip); - - retval = xd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/xd.h b/drivers/staging/rts5208/xd.h deleted file mode 100644 index 98c00f268e56127dc2d5e4bbf8de3f3178cea056..0000000000000000000000000000000000000000 --- a/drivers/staging/rts5208/xd.h +++ /dev/null @@ -1,176 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@realsil.com.cn) - * Micky Ching (micky_ching@realsil.com.cn) - */ - -#ifndef __REALTEK_RTSX_XD_H -#define __REALTEK_RTSX_XD_H - -#define XD_DELAY_WRITE - -/* Error Codes */ -#define XD_NO_ERROR 0x00 -#define XD_NO_MEMORY 0x80 -#define XD_PRG_ERROR 0x40 -#define XD_NO_CARD 0x20 -#define XD_READ_FAIL 0x10 -#define XD_ERASE_FAIL 0x08 -#define XD_WRITE_FAIL 0x04 -#define XD_ECC_ERROR 0x02 -#define XD_TO_ERROR 0x01 - -/* XD Commands */ -#define READ1_1 0x00 -#define READ1_2 0x01 -#define READ2 0x50 -#define READ_ID 0x90 -#define RESET 0xff -#define PAGE_PRG_1 0x80 -#define PAGE_PRG_2 0x10 -#define BLK_ERASE_1 0x60 -#define BLK_ERASE_2 0xD0 -#define READ_STS 0x70 -#define READ_XD_ID 0x9A -#define COPY_BACK_512 0x8A -#define COPY_BACK_2K 0x85 -#define READ1_1_2 0x30 -#define READ1_1_3 0x35 -#define CHG_DAT_OUT_1 0x05 -#define RDM_DAT_OUT_1 0x05 -#define CHG_DAT_OUT_2 0xE0 -#define RDM_DAT_OUT_2 0xE0 -#define CHG_DAT_OUT_2 0xE0 -#define CHG_DAT_IN_1 0x85 -#define CACHE_PRG 0x15 - -/* Redundant Area Related */ -#define XD_EXTRA_SIZE 0x10 -#define XD_2K_EXTRA_SIZE 0x40 - -#define NOT_WRITE_PROTECTED 0x80 -#define READY_STATE 0x40 -#define PROGRAM_ERROR 0x01 -#define PROGRAM_ERROR_N_1 0x02 -#define INTERNAL_READY 0x20 -#define READY_FLAG 0x5F - -#define XD_8M_X8_512 0xE6 -#define XD_16M_X8_512 0x73 -#define XD_32M_X8_512 0x75 -#define XD_64M_X8_512 0x76 -#define XD_128M_X8_512 0x79 -#define XD_256M_X8_512 0x71 -#define XD_128M_X8_2048 0xF1 -#define XD_256M_X8_2048 0xDA -#define XD_512M_X8 0xDC -#define XD_128M_X16_2048 0xC1 -#define XD_4M_X8_512_1 0xE3 -#define XD_4M_X8_512_2 0xE5 -#define XD_1G_X8_512 0xD3 -#define XD_2G_X8_512 0xD5 - -#define XD_ID_CODE 0xB5 - -#define VENDOR_BLOCK 0xEFFF -#define CIS_BLOCK 0xDFFF - -#define BLK_NOT_FOUND 0xFFFFFFFF - -#define NO_NEW_BLK 0xFFFFFFFF - -#define PAGE_CORRECTABLE 0x0 -#define PAGE_NOTCORRECTABLE 0x1 - -#define NO_OFFSET 0x0 -#define WITH_OFFSET 0x1 - -#define SECT_PER_PAGE 4 -#define XD_ADDR_MODE_2C XD_ADDR_MODE_2A - -#define ZONE0_BAD_BLOCK 23 -#define NOT_ZONE0_BAD_BLOCK 24 - -#define XD_RW_ADDR 0x01 -#define XD_ERASE_ADDR 0x02 - -#define XD_PAGE_512(xd_card) \ -do { \ - (xd_card)->block_shift = 5; \ - (xd_card)->page_off = 0x1F; \ -} while (0) - -#define XD_SET_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag |= 0x01) -#define XD_CLR_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag &= ~0x01) -#define XD_CHK_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag & 0x01) - -#define XD_SET_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag |= 0x02) -#define XD_CLR_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag &= ~0x02) -#define XD_CHK_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag & 0x02) - -#define XD_SET_MBR_FAIL(xd_card) ((xd_card)->multi_flag |= 0x04) -#define XD_CLR_MBR_FAIL(xd_card) ((xd_card)->multi_flag &= ~0x04) -#define XD_CHK_MBR_FAIL(xd_card) ((xd_card)->multi_flag & 0x04) - -#define XD_SET_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag |= 0x08) -#define XD_CLR_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag &= ~0x08) -#define XD_CHK_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag & 0x08) - -#define XD_SET_4MB(xd_card) ((xd_card)->multi_flag |= 0x10) -#define XD_CLR_4MB(xd_card) ((xd_card)->multi_flag &= ~0x10) -#define XD_CHK_4MB(xd_card) ((xd_card)->multi_flag & 0x10) - -#define XD_SET_ECC_ERR(xd_card) ((xd_card)->multi_flag |= 0x40) -#define XD_CLR_ECC_ERR(xd_card) ((xd_card)->multi_flag &= ~0x40) -#define XD_CHK_ECC_ERR(xd_card) ((xd_card)->multi_flag & 0x40) - -#define PAGE_STATUS 0 -#define BLOCK_STATUS 1 -#define BLOCK_ADDR1_L 2 -#define BLOCK_ADDR1_H 3 -#define BLOCK_ADDR2_L 4 -#define BLOCK_ADDR2_H 5 -#define RESERVED0 6 -#define RESERVED1 7 -#define RESERVED2 8 -#define RESERVED3 9 -#define PARITY 10 - -#define CIS0_0 0 -#define CIS0_1 1 -#define CIS0_2 2 -#define CIS0_3 3 -#define CIS0_4 4 -#define CIS0_5 5 -#define CIS0_6 6 -#define CIS0_7 7 -#define CIS0_8 8 -#define CIS0_9 9 -#define CIS1_0 256 -#define CIS1_1 (256 + 1) -#define CIS1_2 (256 + 2) -#define CIS1_3 (256 + 3) -#define CIS1_4 (256 + 4) -#define CIS1_5 (256 + 5) -#define CIS1_6 (256 + 6) -#define CIS1_7 (256 + 7) -#define CIS1_8 (256 + 8) -#define CIS1_9 (256 + 9) - -int reset_xd_card(struct rtsx_chip *chip); -#ifdef XD_DELAY_WRITE -int xd_delay_write(struct rtsx_chip *chip); -#endif -int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt); -void xd_free_l2p_tbl(struct rtsx_chip *chip); -void xd_cleanup_work(struct rtsx_chip *chip); -int xd_power_off_card3v3(struct rtsx_chip *chip); -int release_xd_card(struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_XD_H */ diff --git a/drivers/staging/sm750fb/TODO b/drivers/staging/sm750fb/TODO index 481409eb3fb384f71a9fb91262b0e9010e5200bb..9dd57c56625704f2b9f377706620e995c63c1aae 100644 --- a/drivers/staging/sm750fb/TODO +++ b/drivers/staging/sm750fb/TODO @@ -12,8 +12,3 @@ TODO: Note: - This driver will be removed from staging after the drm driver is ready - The drm driver is getting ready at https://gitlab.com/sudipm/sm750/tree/sm750 - -Please send any patches to - Greg Kroah-Hartman - Sudip Mukherjee - Teddy Wang diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 133ed15f3dbcc07dc353c22d8522e11a08ee6f46..dc0d715ed97078ad0f0a41db78428db4f4135a76 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -96,7 +96,8 @@ static int bcm2835_audio_send_simple(struct bcm2835_audio_instance *instance, static int audio_vchi_callback(struct vchiq_instance *vchiq_instance, enum vchiq_reason reason, struct vchiq_header *header, - unsigned int handle, void *userdata) + unsigned int handle, + void *cb_data, void __user *cb_userdata) { struct bcm2835_audio_instance *instance = vchiq_get_service_userdata(vchiq_instance, handle); diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h index 6c40d8c1dde60723ddeb451733648b811d39be16..ee4469f4fc510e540fe5e11d793e50655ee068a1 100644 --- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h +++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h @@ -56,7 +56,7 @@ struct vchiq_service_base { enum vchiq_reason reason, struct vchiq_header *header, unsigned int handle, - void *bulk_userdata); + void *cb_data, void __user *cb_userdata); void *userdata; }; @@ -64,7 +64,8 @@ struct vchiq_completion_data_kernel { enum vchiq_reason reason; struct vchiq_header *header; void *service_userdata; - void *bulk_userdata; + void *cb_data; + void __user *cb_userdata; }; struct vchiq_service_params_kernel { @@ -73,7 +74,7 @@ struct vchiq_service_params_kernel { enum vchiq_reason reason, struct vchiq_header *header, unsigned int handle, - void *bulk_userdata); + void *cb_data, void __user *cb_userdata); void *userdata; short version; /* Increment for non-trivial changes */ short version_min; /* Update for incompatible changes */ diff --git a/drivers/staging/vc04_services/interface/TESTING b/drivers/staging/vc04_services/interface/TESTING index 273952dc9d85964266814f265c205e465d4ded5f..c98f688b07e0fe788c61619bf1acddc0ec32aeaa 100644 --- a/drivers/staging/vc04_services/interface/TESTING +++ b/drivers/staging/vc04_services/interface/TESTING @@ -52,10 +52,10 @@ Here are the most common kernel configurations: * Ping test - Command: vchiq_test -p 1 + Command: vchiq_test -p Expected output: - Ping test - service:echo, iters:1, version 3 + Ping test - service:echo, iters:1000, version 3 vchi ping (size 0) -> 57.000000us vchi ping (size 0, 0 async, 0 oneway) -> 122.000000us vchi bulk (size 0, 0 async, 0 oneway) -> 546.000000us diff --git a/drivers/staging/vc04_services/interface/TODO b/drivers/staging/vc04_services/interface/TODO index dfb1ee49633fe294bee2ca5f11b5add88d0200cc..f6f24600aa86240fba77169f62f3e657e42727c3 100644 --- a/drivers/staging/vc04_services/interface/TODO +++ b/drivers/staging/vc04_services/interface/TODO @@ -26,16 +26,3 @@ kthreads, userspace, limitations) could be very helpful for reviewers. The code follows the 80 characters limitation yet tends to go 3 or 4 levels of indentation deep making it very unpleasant to read. This is specially relevant in the character driver ioctl code and in the core thread functions. - -* Clean up Sparse warnings from __user annotations. See -vchiq_irq_queue_bulk_tx_rx(). Ensure that the address of "&waiter->bulk_waiter" -is never disclosed to userspace. - -* Fix behavior of message handling - -The polling behavior of vchiq_bulk_transmit(), vchiq_bulk_receive() and -vchiq_queue_kernel_message() looks broken. A possible signal should be -propagated back to user space to let the calling task handle it before -retrying. Hopefully these msleep(1) shouldn't be necessary anymore. - -https://lore.kernel.org/linux-staging/CAK8P3a3HGm1cPo4sW9fOY4E8AN8yAq3tevXxU5m8bmtmsU8WKw@mail.gmail.com/ diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 6c488b1e2624850d51fbc507965b66333521c86a..a4e83e5d619bc95f1d4ba311a201bba8c05cd030 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -36,7 +35,6 @@ #include "vchiq_arm.h" #include "vchiq_bus.h" #include "vchiq_debugfs.h" -#include "vchiq_pagelist.h" #define DEVICE_NAME "vchiq" @@ -48,7 +46,6 @@ #define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1 #define BELL0 0x00 -#define BELL2 0x08 #define ARM_DS_ACTIVE BIT(2) @@ -109,21 +106,9 @@ struct vchiq_arm_state { int first_connect; }; -struct vchiq_pagelist_info { - struct pagelist *pagelist; - size_t pagelist_buffer_size; - dma_addr_t dma_addr; - enum dma_data_direction dma_dir; - unsigned int num_pages; - unsigned int pages_need_release; - struct page **pages; - struct scatterlist *scatterlist; - unsigned int scatterlist_mapped; -}; - static int -vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data, - unsigned int size, enum vchiq_bulk_dir dir); +vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, + struct vchiq_bulk *bulk_params); static irqreturn_t vchiq_doorbell_irq(int irq, void *dev_id) @@ -146,35 +131,6 @@ vchiq_doorbell_irq(int irq, void *dev_id) return ret; } -static void -cleanup_pagelistinfo(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo) -{ - if (pagelistinfo->scatterlist_mapped) { - dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist, - pagelistinfo->num_pages, pagelistinfo->dma_dir); - } - - if (pagelistinfo->pages_need_release) - unpin_user_pages(pagelistinfo->pages, pagelistinfo->num_pages); - - dma_free_coherent(instance->state->dev, pagelistinfo->pagelist_buffer_size, - pagelistinfo->pagelist, pagelistinfo->dma_addr); -} - -static inline bool -is_adjacent_block(u32 *addrs, dma_addr_t addr, unsigned int k) -{ - u32 tmp; - - if (!k) - return false; - - tmp = (addrs[k - 1] & PAGE_MASK) + - (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT); - - return tmp == (addr & PAGE_MASK); -} - /* * This function is called by the vchiq stack once it has been connected to * the videocore and clients can start to use the stack. @@ -225,270 +181,6 @@ void vchiq_add_connected_callback(struct vchiq_device *device, void (*callback)( } EXPORT_SYMBOL(vchiq_add_connected_callback); -/* There is a potential problem with partial cache lines (pages?) - * at the ends of the block when reading. If the CPU accessed anything in - * the same line (page?) then it may have pulled old data into the cache, - * obscuring the new data underneath. We can solve this by transferring the - * partial cache lines separately, and allowing the ARM to copy into the - * cached area. - */ - -static struct vchiq_pagelist_info * -create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, - size_t count, unsigned short type) -{ - struct vchiq_drv_mgmt *drv_mgmt; - struct pagelist *pagelist; - struct vchiq_pagelist_info *pagelistinfo; - struct page **pages; - u32 *addrs; - unsigned int num_pages, offset, i, k; - int actual_pages; - size_t pagelist_size; - struct scatterlist *scatterlist, *sg; - int dma_buffers; - dma_addr_t dma_addr; - - if (count >= INT_MAX - PAGE_SIZE) - return NULL; - - drv_mgmt = dev_get_drvdata(instance->state->dev); - - if (buf) - offset = (uintptr_t)buf & (PAGE_SIZE - 1); - else - offset = (uintptr_t)ubuf & (PAGE_SIZE - 1); - num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE); - - if ((size_t)num_pages > (SIZE_MAX - sizeof(struct pagelist) - - sizeof(struct vchiq_pagelist_info)) / - (sizeof(u32) + sizeof(pages[0]) + - sizeof(struct scatterlist))) - return NULL; - - pagelist_size = sizeof(struct pagelist) + - (num_pages * sizeof(u32)) + - (num_pages * sizeof(pages[0]) + - (num_pages * sizeof(struct scatterlist))) + - sizeof(struct vchiq_pagelist_info); - - /* Allocate enough storage to hold the page pointers and the page - * list - */ - pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr, - GFP_KERNEL); - - dev_dbg(instance->state->dev, "arm: %pK\n", pagelist); - - if (!pagelist) - return NULL; - - addrs = pagelist->addrs; - pages = (struct page **)(addrs + num_pages); - scatterlist = (struct scatterlist *)(pages + num_pages); - pagelistinfo = (struct vchiq_pagelist_info *) - (scatterlist + num_pages); - - pagelist->length = count; - pagelist->type = type; - pagelist->offset = offset; - - /* Populate the fields of the pagelistinfo structure */ - pagelistinfo->pagelist = pagelist; - pagelistinfo->pagelist_buffer_size = pagelist_size; - pagelistinfo->dma_addr = dma_addr; - pagelistinfo->dma_dir = (type == PAGELIST_WRITE) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE; - pagelistinfo->num_pages = num_pages; - pagelistinfo->pages_need_release = 0; - pagelistinfo->pages = pages; - pagelistinfo->scatterlist = scatterlist; - pagelistinfo->scatterlist_mapped = 0; - - if (buf) { - unsigned long length = count; - unsigned int off = offset; - - for (actual_pages = 0; actual_pages < num_pages; - actual_pages++) { - struct page *pg = - vmalloc_to_page((buf + - (actual_pages * PAGE_SIZE))); - size_t bytes = PAGE_SIZE - off; - - if (!pg) { - cleanup_pagelistinfo(instance, pagelistinfo); - return NULL; - } - - if (bytes > length) - bytes = length; - pages[actual_pages] = pg; - length -= bytes; - off = 0; - } - /* do not try and release vmalloc pages */ - } else { - actual_pages = pin_user_pages_fast((unsigned long)ubuf & PAGE_MASK, num_pages, - type == PAGELIST_READ, pages); - - if (actual_pages != num_pages) { - dev_dbg(instance->state->dev, "arm: Only %d/%d pages locked\n", - actual_pages, num_pages); - - /* This is probably due to the process being killed */ - if (actual_pages > 0) - unpin_user_pages(pages, actual_pages); - cleanup_pagelistinfo(instance, pagelistinfo); - return NULL; - } - /* release user pages */ - pagelistinfo->pages_need_release = 1; - } - - /* - * Initialize the scatterlist so that the magic cookie - * is filled if debugging is enabled - */ - sg_init_table(scatterlist, num_pages); - /* Now set the pages for each scatterlist */ - for (i = 0; i < num_pages; i++) { - unsigned int len = PAGE_SIZE - offset; - - if (len > count) - len = count; - sg_set_page(scatterlist + i, pages[i], len, offset); - offset = 0; - count -= len; - } - - dma_buffers = dma_map_sg(instance->state->dev, - scatterlist, - num_pages, - pagelistinfo->dma_dir); - - if (dma_buffers == 0) { - cleanup_pagelistinfo(instance, pagelistinfo); - return NULL; - } - - pagelistinfo->scatterlist_mapped = 1; - - /* Combine adjacent blocks for performance */ - k = 0; - for_each_sg(scatterlist, sg, dma_buffers, i) { - unsigned int len = sg_dma_len(sg); - dma_addr_t addr = sg_dma_address(sg); - - /* Note: addrs is the address + page_count - 1 - * The firmware expects blocks after the first to be page- - * aligned and a multiple of the page size - */ - WARN_ON(len == 0); - WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); - WARN_ON(i && (addr & ~PAGE_MASK)); - if (is_adjacent_block(addrs, addr, k)) - addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT); - else - addrs[k++] = (addr & PAGE_MASK) | - (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1); - } - - /* Partial cache lines (fragments) require special measures */ - if ((type == PAGELIST_READ) && - ((pagelist->offset & (drv_mgmt->info->cache_line_size - 1)) || - ((pagelist->offset + pagelist->length) & - (drv_mgmt->info->cache_line_size - 1)))) { - char *fragments; - - if (down_interruptible(&drv_mgmt->free_fragments_sema)) { - cleanup_pagelistinfo(instance, pagelistinfo); - return NULL; - } - - WARN_ON(!drv_mgmt->free_fragments); - - down(&drv_mgmt->free_fragments_mutex); - fragments = drv_mgmt->free_fragments; - WARN_ON(!fragments); - drv_mgmt->free_fragments = *(char **)drv_mgmt->free_fragments; - up(&drv_mgmt->free_fragments_mutex); - pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + - (fragments - drv_mgmt->fragments_base) / drv_mgmt->fragments_size; - } - - return pagelistinfo; -} - -static void -free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo, - int actual) -{ - struct vchiq_drv_mgmt *drv_mgmt; - struct pagelist *pagelist = pagelistinfo->pagelist; - struct page **pages = pagelistinfo->pages; - unsigned int num_pages = pagelistinfo->num_pages; - - dev_dbg(instance->state->dev, "arm: %pK, %d\n", pagelistinfo->pagelist, actual); - - drv_mgmt = dev_get_drvdata(instance->state->dev); - - /* - * NOTE: dma_unmap_sg must be called before the - * cpu can touch any of the data/pages. - */ - dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist, - pagelistinfo->num_pages, pagelistinfo->dma_dir); - pagelistinfo->scatterlist_mapped = 0; - - /* Deal with any partial cache lines (fragments) */ - if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS && drv_mgmt->fragments_base) { - char *fragments = drv_mgmt->fragments_base + - (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) * - drv_mgmt->fragments_size; - int head_bytes, tail_bytes; - - head_bytes = (drv_mgmt->info->cache_line_size - pagelist->offset) & - (drv_mgmt->info->cache_line_size - 1); - tail_bytes = (pagelist->offset + actual) & - (drv_mgmt->info->cache_line_size - 1); - - if ((actual >= 0) && (head_bytes != 0)) { - if (head_bytes > actual) - head_bytes = actual; - - memcpy_to_page(pages[0], - pagelist->offset, - fragments, - head_bytes); - } - if ((actual >= 0) && (head_bytes < actual) && - (tail_bytes != 0)) - memcpy_to_page(pages[num_pages - 1], - (pagelist->offset + actual) & - (PAGE_SIZE - 1) & ~(drv_mgmt->info->cache_line_size - 1), - fragments + drv_mgmt->info->cache_line_size, - tail_bytes); - - down(&drv_mgmt->free_fragments_mutex); - *(char **)fragments = drv_mgmt->free_fragments; - drv_mgmt->free_fragments = fragments; - up(&drv_mgmt->free_fragments_mutex); - up(&drv_mgmt->free_fragments_sema); - } - - /* Need to mark all the pages dirty. */ - if (pagelist->type != PAGELIST_WRITE && - pagelistinfo->pages_need_release) { - unsigned int i; - - for (i = 0; i < num_pages; i++) - set_page_dirty(pages[i]); - } - - cleanup_pagelistinfo(instance, pagelistinfo); -} - static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state) { struct device *dev = &pdev->dev; @@ -616,58 +308,6 @@ static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state * return (struct vchiq_arm_state *)state->platform_state; } -void -remote_event_signal(struct vchiq_state *state, struct remote_event *event) -{ - struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(state->dev); - - /* - * Ensure that all writes to shared data structures have completed - * before signalling the peer. - */ - wmb(); - - event->fired = 1; - - dsb(sy); /* data barrier operation */ - - if (event->armed) - writel(0, mgmt->regs + BELL2); /* trigger vc interrupt */ -} - -int -vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset, - void __user *uoffset, int size, int dir) -{ - struct vchiq_pagelist_info *pagelistinfo; - - pagelistinfo = create_pagelist(instance, offset, uoffset, size, - (dir == VCHIQ_BULK_RECEIVE) - ? PAGELIST_READ - : PAGELIST_WRITE); - - if (!pagelistinfo) - return -ENOMEM; - - bulk->data = pagelistinfo->dma_addr; - - /* - * Store the pagelistinfo address in remote_data, - * which isn't used by the slave. - */ - bulk->remote_data = pagelistinfo; - - return 0; -} - -void -vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk) -{ - if (bulk && bulk->remote_data && bulk->actual) - free_pagelist(instance, (struct vchiq_pagelist_info *)bulk->remote_data, - bulk->actual); -} - void vchiq_dump_platform_state(struct seq_file *f) { seq_puts(f, " Platform: 2835 (VC master)\n"); @@ -851,34 +491,31 @@ int vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int handle, const void *data, unsigned int size, void *userdata, enum vchiq_bulk_mode mode) { + struct vchiq_bulk bulk_params = {}; int ret; - while (1) { - switch (mode) { - case VCHIQ_BULK_MODE_NOCALLBACK: - case VCHIQ_BULK_MODE_CALLBACK: - ret = vchiq_bulk_xfer_callback_interruptible(instance, handle, - (void *)data, NULL, - size, mode, userdata, - VCHIQ_BULK_TRANSMIT); - break; - case VCHIQ_BULK_MODE_BLOCKING: - ret = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size, - VCHIQ_BULK_TRANSMIT); - break; - default: - return -EINVAL; - } - - /* - * vchiq_*_bulk_transfer() may return -EAGAIN, so we need - * to implement a retry mechanism since this function is - * supposed to block until queued - */ - if (ret != -EAGAIN) - break; - - msleep(1); + switch (mode) { + case VCHIQ_BULK_MODE_NOCALLBACK: + case VCHIQ_BULK_MODE_CALLBACK: + + bulk_params.offset = (void *)data; + bulk_params.mode = mode; + bulk_params.size = size; + bulk_params.cb_data = userdata; + bulk_params.dir = VCHIQ_BULK_TRANSMIT; + + ret = vchiq_bulk_xfer_callback(instance, handle, &bulk_params); + break; + case VCHIQ_BULK_MODE_BLOCKING: + bulk_params.offset = (void *)data; + bulk_params.mode = mode; + bulk_params.size = size; + bulk_params.dir = VCHIQ_BULK_TRANSMIT; + + ret = vchiq_blocking_bulk_transfer(instance, handle, &bulk_params); + break; + default: + return -EINVAL; } return ret; @@ -889,34 +526,31 @@ int vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int handle, void *data, unsigned int size, void *userdata, enum vchiq_bulk_mode mode) { + struct vchiq_bulk bulk_params = {}; int ret; - while (1) { - switch (mode) { - case VCHIQ_BULK_MODE_NOCALLBACK: - case VCHIQ_BULK_MODE_CALLBACK: - ret = vchiq_bulk_xfer_callback_interruptible(instance, handle, - (void *)data, NULL, - size, mode, userdata, - VCHIQ_BULK_RECEIVE); - break; - case VCHIQ_BULK_MODE_BLOCKING: - ret = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size, - VCHIQ_BULK_RECEIVE); - break; - default: - return -EINVAL; - } - - /* - * vchiq_*_bulk_transfer() may return -EAGAIN, so we need - * to implement a retry mechanism since this function is - * supposed to block until queued - */ - if (ret != -EAGAIN) - break; - - msleep(1); + switch (mode) { + case VCHIQ_BULK_MODE_NOCALLBACK: + case VCHIQ_BULK_MODE_CALLBACK: + + bulk_params.offset = (void *)data; + bulk_params.mode = mode; + bulk_params.size = size; + bulk_params.cb_data = userdata; + bulk_params.dir = VCHIQ_BULK_RECEIVE; + + ret = vchiq_bulk_xfer_callback(instance, handle, &bulk_params); + break; + case VCHIQ_BULK_MODE_BLOCKING: + bulk_params.offset = (void *)data; + bulk_params.mode = mode; + bulk_params.size = size; + bulk_params.dir = VCHIQ_BULK_RECEIVE; + + ret = vchiq_blocking_bulk_transfer(instance, handle, &bulk_params); + break; + default: + return -EINVAL; } return ret; @@ -924,8 +558,8 @@ int vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int handle, EXPORT_SYMBOL(vchiq_bulk_receive); static int -vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data, - unsigned int size, enum vchiq_bulk_dir dir) +vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, + struct vchiq_bulk *bulk_params) { struct vchiq_service *service; struct bulk_waiter_node *waiter = NULL, *iter; @@ -953,13 +587,14 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl if (bulk) { /* This thread has an outstanding bulk transfer. */ /* FIXME: why compare a dma address to a pointer? */ - if ((bulk->data != (dma_addr_t)(uintptr_t)data) || (bulk->size != size)) { + if ((bulk->dma_addr != (dma_addr_t)(uintptr_t)bulk_params->dma_addr) || + (bulk->size != bulk_params->size)) { /* * This is not a retry of the previous one. * Cancel the signal when the transfer completes. */ spin_lock(&service->state->bulk_waiter_spinlock); - bulk->userdata = NULL; + bulk->waiter = NULL; spin_unlock(&service->state->bulk_waiter_spinlock); } } @@ -969,15 +604,16 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl return -ENOMEM; } - ret = vchiq_bulk_xfer_blocking_interruptible(instance, handle, data, NULL, size, - &waiter->bulk_waiter, dir); + bulk_params->waiter = &waiter->bulk_waiter; + + ret = vchiq_bulk_xfer_blocking(instance, handle, bulk_params); if ((ret != -EAGAIN) || fatal_signal_pending(current) || !waiter->bulk_waiter.bulk) { struct vchiq_bulk *bulk = waiter->bulk_waiter.bulk; if (bulk) { /* Cancel the signal when the transfer completes. */ spin_lock(&service->state->bulk_waiter_spinlock); - bulk->userdata = NULL; + bulk->waiter = NULL; spin_unlock(&service->state->bulk_waiter_spinlock); } kfree(waiter); @@ -996,7 +632,7 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl static int add_completion(struct vchiq_instance *instance, enum vchiq_reason reason, struct vchiq_header *header, struct user_service *user_service, - void *bulk_userdata) + void *cb_data, void __user *cb_userdata) { struct vchiq_completion_data_kernel *completion; struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(instance->state->dev); @@ -1026,7 +662,8 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason, completion->reason = reason; /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */ completion->service_userdata = user_service->service; - completion->bulk_userdata = bulk_userdata; + completion->cb_data = cb_data; + completion->cb_userdata = cb_userdata; if (reason == VCHIQ_SERVICE_CLOSED) { /* @@ -1057,8 +694,8 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason, static int service_single_message(struct vchiq_instance *instance, - enum vchiq_reason reason, - struct vchiq_service *service, void *bulk_userdata) + enum vchiq_reason reason, struct vchiq_service *service, + void *cb_data, void __user *cb_userdata) { struct user_service *user_service; @@ -1076,7 +713,7 @@ service_single_message(struct vchiq_instance *instance, dev_dbg(instance->state->dev, "arm: Inserting extra MESSAGE_AVAILABLE\n"); ret = add_completion(instance, reason, NULL, user_service, - bulk_userdata); + cb_data, cb_userdata); if (ret) return ret; } @@ -1094,7 +731,8 @@ service_single_message(struct vchiq_instance *instance, int service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, - struct vchiq_header *header, unsigned int handle, void *bulk_userdata) + struct vchiq_header *header, unsigned int handle, + void *cb_data, void __user *cb_userdata) { /* * How do we ensure the callback goes to the right client? @@ -1133,9 +771,9 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, rcu_read_unlock(); dev_dbg(service->state->dev, - "arm: service %p(%d,%p), reason %d, header %p, instance %p, bulk_userdata %p\n", + "arm: service %p(%d,%p), reason %d, header %p, instance %p, cb_data %p, cb_userdata %p\n", user_service, service->localport, user_service->userdata, - reason, header, instance, bulk_userdata); + reason, header, instance, cb_data, cb_userdata); if (header && user_service->is_vchi) { spin_lock(&service->state->msg_queue_spinlock); @@ -1147,8 +785,8 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, DEBUG_TRACE(SERVICE_CALLBACK_LINE); DEBUG_COUNT(MSG_QUEUE_FULL_COUNT); - ret = service_single_message(instance, reason, - service, bulk_userdata); + ret = service_single_message(instance, reason, service, + cb_data, cb_userdata); if (ret) { DEBUG_TRACE(SERVICE_CALLBACK_LINE); vchiq_service_put(service); @@ -1186,7 +824,7 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, return 0; return add_completion(instance, reason, header, user_service, - bulk_userdata); + cb_data, cb_userdata); } void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f) @@ -1273,7 +911,8 @@ static int vchiq_keepalive_vchiq_callback(struct vchiq_instance *instance, enum vchiq_reason reason, struct vchiq_header *header, - unsigned int service_user, void *bulk_user) + unsigned int service_user, + void *cb_data, void __user *cb_userdata) { dev_err(instance->state->dev, "suspend: %s: callback reason %d\n", __func__, reason); @@ -1715,7 +1354,6 @@ MODULE_DEVICE_TABLE(of, vchiq_of_match); static int vchiq_probe(struct platform_device *pdev) { - struct device_node *fw_node; const struct vchiq_platform_info *info; struct vchiq_drv_mgmt *mgmt; int ret; @@ -1724,8 +1362,8 @@ static int vchiq_probe(struct platform_device *pdev) if (!info) return -EINVAL; - fw_node = of_find_compatible_node(NULL, NULL, - "raspberrypi,bcm2835-firmware"); + struct device_node *fw_node __free(device_node) = + of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware"); if (!fw_node) { dev_err(&pdev->dev, "Missing firmware node\n"); return -ENOENT; @@ -1736,7 +1374,6 @@ static int vchiq_probe(struct platform_device *pdev) return -ENOMEM; mgmt->fw = devm_rpi_firmware_get(&pdev->dev, fw_node); - of_node_put(fw_node); if (!mgmt->fw) return -EPROBE_DEFER; @@ -1744,8 +1381,10 @@ static int vchiq_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mgmt); ret = vchiq_platform_init(pdev, &mgmt->state); - if (ret) - goto failed_platform_init; + if (ret) { + dev_err(&pdev->dev, "arm: Could not initialize vchiq platform\n"); + return ret; + } vchiq_debugfs_init(&mgmt->state); @@ -1759,18 +1398,13 @@ static int vchiq_probe(struct platform_device *pdev) ret = vchiq_register_chrdev(&pdev->dev); if (ret) { dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n"); - goto error_exit; + return ret; } bcm2835_audio = vchiq_device_register(&pdev->dev, "bcm2835-audio"); bcm2835_camera = vchiq_device_register(&pdev->dev, "bcm2835-camera"); return 0; - -failed_platform_init: - dev_err(&pdev->dev, "arm: Could not initialize vchiq platform\n"); -error_exit: - return ret; } static void vchiq_remove(struct platform_device *pdev) @@ -1797,7 +1431,7 @@ static struct platform_driver vchiq_driver = { .of_match_table = vchiq_of_match, }, .probe = vchiq_probe, - .remove_new = vchiq_remove, + .remove = vchiq_remove, }; static int __init vchiq_driver_init(void) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h index b402aac333d9b9c7babfbecc2faeac20bc397fc6..e32b02f990244b46ab97c463dab6a973fdd97033 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h @@ -155,7 +155,8 @@ static inline int vchiq_register_chrdev(struct device *parent) { return 0; } extern int service_callback(struct vchiq_instance *vchiq_instance, enum vchiq_reason reason, - struct vchiq_header *header, unsigned int handle, void *bulk_userdata); + struct vchiq_header *header, unsigned int handle, + void *cb_data, void __user *cb_userdata); extern void free_bulk_waiter(struct vchiq_instance *instance); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index 1f94db6e0cd984847207a2b3668af1326ac77820..8d5795db4f39f8003310a54ba369367c95e6c079 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -61,12 +63,16 @@ #define MAKE_REMOTE_USE (VCHIQ_MSG_REMOTE_USE << TYPE_SHIFT) #define MAKE_REMOTE_USE_ACTIVE (VCHIQ_MSG_REMOTE_USE_ACTIVE << TYPE_SHIFT) +#define PAGELIST_WRITE 0 +#define PAGELIST_READ 1 +#define PAGELIST_READ_WITH_FRAGMENTS 2 + +#define BELL2 0x08 + /* Ensure the fields are wide enough */ -static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0, 0, VCHIQ_PORT_MAX)) - == 0); +static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0, 0, VCHIQ_PORT_MAX)) == 0); static_assert(VCHIQ_MSG_TYPE(VCHIQ_MAKE_MSG(0, VCHIQ_PORT_MAX, 0)) == 0); -static_assert((unsigned int)VCHIQ_PORT_MAX < - (unsigned int)VCHIQ_PORT_FREE); +static_assert((unsigned int)VCHIQ_PORT_MAX < (unsigned int)VCHIQ_PORT_FREE); #define VCHIQ_MSGID_PADDING VCHIQ_MAKE_MSG(VCHIQ_MSG_PADDING, 0, 0) #define VCHIQ_MSGID_CLAIMED 0x40000000 @@ -449,15 +455,26 @@ mark_service_closing(struct vchiq_service *service) static inline int make_service_callback(struct vchiq_service *service, enum vchiq_reason reason, - struct vchiq_header *header, void *bulk_userdata) + struct vchiq_header *header, struct vchiq_bulk *bulk) { + void *cb_data = NULL; + void __user *cb_userdata = NULL; int status; - dev_dbg(service->state->dev, "core: %d: callback:%d (%s, %pK, %pK)\n", + /* + * If a bulk transfer is in progress, pass bulk->cb_*data to the + * callback function. + */ + if (bulk) { + cb_data = bulk->cb_data; + cb_userdata = bulk->cb_userdata; + } + + dev_dbg(service->state->dev, "core: %d: callback:%d (%s, %pK, %pK %pK)\n", service->state->id, service->localport, reason_names[reason], - header, bulk_userdata); + header, cb_data, cb_userdata); status = service->base.callback(service->instance, reason, header, service->handle, - bulk_userdata); + cb_data, cb_userdata); if (status && (status != -EAGAIN)) { dev_warn(service->state->dev, "core: %d: ignoring ERROR from callback to service %x\n", @@ -526,6 +543,25 @@ remote_event_wait(wait_queue_head_t *wq, struct remote_event *event) return ret; } +static void +remote_event_signal(struct vchiq_state *state, struct remote_event *event) +{ + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(state->dev); + + /* + * Ensure that all writes to shared data structures have completed + * before signalling the peer. + */ + wmb(); + + event->fired = 1; + + dsb(sy); /* data barrier operation */ + + if (event->armed) + writel(0, mgmt->regs + BELL2); /* trigger vc interrupt */ +} + /* * Acknowledge that the event has been signalled, and wake any waiters. Usually * called as a result of the doorbell being rung. @@ -911,6 +947,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, struct vchiq_service_quota *quota = NULL; struct vchiq_header *header; int type = VCHIQ_MSG_TYPE(msgid); + int svc_fourcc; size_t stride; @@ -922,7 +959,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, if (!(flags & QMFLAGS_NO_MUTEX_LOCK) && mutex_lock_killable(&state->slot_mutex)) - return -EAGAIN; + return -EINTR; if (type == VCHIQ_MSG_DATA) { int tx_end_index; @@ -962,8 +999,8 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, spin_unlock(&state->quota_spinlock); mutex_unlock(&state->slot_mutex); - if (wait_for_completion_interruptible(&state->data_quota_event)) - return -EAGAIN; + if (wait_for_completion_killable(&state->data_quota_event)) + return -EINTR; mutex_lock(&state->slot_mutex); spin_lock(&state->quota_spinlock); @@ -986,12 +1023,12 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, quota->message_use_count, quota->slot_use_count); VCHIQ_SERVICE_STATS_INC(service, quota_stalls); mutex_unlock(&state->slot_mutex); - if (wait_for_completion_interruptible("a->quota_event)) - return -EAGAIN; + if (wait_for_completion_killable("a->quota_event)) + return -EINTR; if (service->closing) return -EHOSTDOWN; if (mutex_lock_killable(&state->slot_mutex)) - return -EAGAIN; + return -EINTR; if (service->srvstate != VCHIQ_SRVSTATE_OPEN) { /* The service has been closed */ mutex_unlock(&state->slot_mutex); @@ -1103,17 +1140,13 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, header->msgid = msgid; header->size = size; - { - int svc_fourcc; - - svc_fourcc = service - ? service->base.fourcc - : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); + svc_fourcc = service ? service->base.fourcc + : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - dev_dbg(state->dev, "core_msg: Sent Msg %s(%u) to %p4cc s:%u d:%d len:%zu\n", - msg_type_str(VCHIQ_MSG_TYPE(msgid)), VCHIQ_MSG_TYPE(msgid), - &svc_fourcc, VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid), size); - } + dev_dbg(state->dev, "core_msg: Sent Msg %s(%u) to %p4cc s:%u d:%d len:%zu\n", + msg_type_str(VCHIQ_MSG_TYPE(msgid)), + VCHIQ_MSG_TYPE(msgid), &svc_fourcc, + VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid), size); /* Make sure the new header is visible to the peer. */ wmb(); @@ -1175,9 +1208,8 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size, VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid)); - callback_result = - copy_message_data(copy_callback, context, - header->data, size); + callback_result = copy_message_data(copy_callback, context, + header->data, size); if (callback_result < 0) { mutex_unlock(&state->slot_mutex); @@ -1288,6 +1320,42 @@ get_bulk_reason(struct vchiq_bulk *bulk) return VCHIQ_BULK_RECEIVE_DONE; } +static int service_notify_bulk(struct vchiq_service *service, + struct vchiq_bulk *bulk) +{ + if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) { + if (bulk->dir == VCHIQ_BULK_TRANSMIT) { + VCHIQ_SERVICE_STATS_INC(service, bulk_tx_count); + VCHIQ_SERVICE_STATS_ADD(service, bulk_tx_bytes, + bulk->actual); + } else { + VCHIQ_SERVICE_STATS_INC(service, bulk_rx_count); + VCHIQ_SERVICE_STATS_ADD(service, bulk_rx_bytes, + bulk->actual); + } + } else { + VCHIQ_SERVICE_STATS_INC(service, bulk_aborted_count); + } + + if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) { + struct bulk_waiter *waiter; + + spin_lock(&service->state->bulk_waiter_spinlock); + waiter = bulk->waiter; + if (waiter) { + waiter->actual = bulk->actual; + complete(&waiter->event); + } + spin_unlock(&service->state->bulk_waiter_spinlock); + } else if (bulk->mode == VCHIQ_BULK_MODE_CALLBACK) { + enum vchiq_reason reason = get_bulk_reason(bulk); + + return make_service_callback(service, reason, NULL, bulk); + } + + return 0; +} + /* Called by the slot handler - don't hold the bulk mutex */ static int notify_bulks(struct vchiq_service *service, struct vchiq_bulk_queue *queue, @@ -1311,38 +1379,10 @@ notify_bulks(struct vchiq_service *service, struct vchiq_bulk_queue *queue, * Only generate callbacks for non-dummy bulk * requests, and non-terminated services */ - if (bulk->data && service->instance) { - if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) { - if (bulk->dir == VCHIQ_BULK_TRANSMIT) { - VCHIQ_SERVICE_STATS_INC(service, bulk_tx_count); - VCHIQ_SERVICE_STATS_ADD(service, bulk_tx_bytes, - bulk->actual); - } else { - VCHIQ_SERVICE_STATS_INC(service, bulk_rx_count); - VCHIQ_SERVICE_STATS_ADD(service, bulk_rx_bytes, - bulk->actual); - } - } else { - VCHIQ_SERVICE_STATS_INC(service, bulk_aborted_count); - } - if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) { - struct bulk_waiter *waiter; - - spin_lock(&service->state->bulk_waiter_spinlock); - waiter = bulk->userdata; - if (waiter) { - waiter->actual = bulk->actual; - complete(&waiter->event); - } - spin_unlock(&service->state->bulk_waiter_spinlock); - } else if (bulk->mode == VCHIQ_BULK_MODE_CALLBACK) { - enum vchiq_reason reason = - get_bulk_reason(bulk); - status = make_service_callback(service, reason, NULL, - bulk->userdata); - if (status == -EAGAIN) - break; - } + if (bulk->dma_addr && service->instance) { + status = service_notify_bulk(service, bulk); + if (status == -EAGAIN) + break; } queue->remove++; @@ -1415,6 +1455,331 @@ poll_services(struct vchiq_state *state) poll_services_of_group(state, group); } +static void +cleanup_pagelistinfo(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo) +{ + if (pagelistinfo->scatterlist_mapped) { + dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist, + pagelistinfo->num_pages, pagelistinfo->dma_dir); + } + + if (pagelistinfo->pages_need_release) + unpin_user_pages(pagelistinfo->pages, pagelistinfo->num_pages); + + dma_free_coherent(instance->state->dev, pagelistinfo->pagelist_buffer_size, + pagelistinfo->pagelist, pagelistinfo->dma_addr); +} + +static inline bool +is_adjacent_block(u32 *addrs, dma_addr_t addr, unsigned int k) +{ + u32 tmp; + + if (!k) + return false; + + tmp = (addrs[k - 1] & PAGE_MASK) + + (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT); + + return tmp == (addr & PAGE_MASK); +} + +/* There is a potential problem with partial cache lines (pages?) + * at the ends of the block when reading. If the CPU accessed anything in + * the same line (page?) then it may have pulled old data into the cache, + * obscuring the new data underneath. We can solve this by transferring the + * partial cache lines separately, and allowing the ARM to copy into the + * cached area. + */ +static struct vchiq_pagelist_info * +create_pagelist(struct vchiq_instance *instance, struct vchiq_bulk *bulk) +{ + struct vchiq_drv_mgmt *drv_mgmt; + struct pagelist *pagelist; + struct vchiq_pagelist_info *pagelistinfo; + struct page **pages; + u32 *addrs; + unsigned int num_pages, offset, i, k; + int actual_pages; + size_t pagelist_size; + struct scatterlist *scatterlist, *sg; + int dma_buffers; + unsigned int cache_line_size; + dma_addr_t dma_addr; + size_t count = bulk->size; + unsigned short type = (bulk->dir == VCHIQ_BULK_RECEIVE) + ? PAGELIST_READ : PAGELIST_WRITE; + + if (count >= INT_MAX - PAGE_SIZE) + return NULL; + + drv_mgmt = dev_get_drvdata(instance->state->dev); + + if (bulk->offset) + offset = (uintptr_t)bulk->offset & (PAGE_SIZE - 1); + else + offset = (uintptr_t)bulk->uoffset & (PAGE_SIZE - 1); + num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE); + + if ((size_t)num_pages > (SIZE_MAX - sizeof(struct pagelist) - + sizeof(struct vchiq_pagelist_info)) / + (sizeof(u32) + sizeof(pages[0]) + + sizeof(struct scatterlist))) + return NULL; + + pagelist_size = sizeof(struct pagelist) + + (num_pages * sizeof(u32)) + + (num_pages * sizeof(pages[0]) + + (num_pages * sizeof(struct scatterlist))) + + sizeof(struct vchiq_pagelist_info); + + /* Allocate enough storage to hold the page pointers and the page + * list + */ + pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr, + GFP_KERNEL); + + dev_dbg(instance->state->dev, "arm: %pK\n", pagelist); + + if (!pagelist) + return NULL; + + addrs = pagelist->addrs; + pages = (struct page **)(addrs + num_pages); + scatterlist = (struct scatterlist *)(pages + num_pages); + pagelistinfo = (struct vchiq_pagelist_info *) + (scatterlist + num_pages); + + pagelist->length = count; + pagelist->type = type; + pagelist->offset = offset; + + /* Populate the fields of the pagelistinfo structure */ + pagelistinfo->pagelist = pagelist; + pagelistinfo->pagelist_buffer_size = pagelist_size; + pagelistinfo->dma_addr = dma_addr; + pagelistinfo->dma_dir = (type == PAGELIST_WRITE) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE; + pagelistinfo->num_pages = num_pages; + pagelistinfo->pages_need_release = 0; + pagelistinfo->pages = pages; + pagelistinfo->scatterlist = scatterlist; + pagelistinfo->scatterlist_mapped = 0; + + if (bulk->offset) { + unsigned long length = count; + unsigned int off = offset; + + for (actual_pages = 0; actual_pages < num_pages; + actual_pages++) { + struct page *pg = + vmalloc_to_page(((unsigned int *)bulk->offset + + (actual_pages * PAGE_SIZE))); + size_t bytes = PAGE_SIZE - off; + + if (!pg) { + cleanup_pagelistinfo(instance, pagelistinfo); + return NULL; + } + + if (bytes > length) + bytes = length; + pages[actual_pages] = pg; + length -= bytes; + off = 0; + } + /* do not try and release vmalloc pages */ + } else { + actual_pages = + pin_user_pages_fast((unsigned long)bulk->uoffset & PAGE_MASK, num_pages, + type == PAGELIST_READ, pages); + + if (actual_pages != num_pages) { + dev_dbg(instance->state->dev, "arm: Only %d/%d pages locked\n", + actual_pages, num_pages); + + /* This is probably due to the process being killed */ + if (actual_pages > 0) + unpin_user_pages(pages, actual_pages); + cleanup_pagelistinfo(instance, pagelistinfo); + return NULL; + } + /* release user pages */ + pagelistinfo->pages_need_release = 1; + } + + /* + * Initialize the scatterlist so that the magic cookie + * is filled if debugging is enabled + */ + sg_init_table(scatterlist, num_pages); + /* Now set the pages for each scatterlist */ + for (i = 0; i < num_pages; i++) { + unsigned int len = PAGE_SIZE - offset; + + if (len > count) + len = count; + sg_set_page(scatterlist + i, pages[i], len, offset); + offset = 0; + count -= len; + } + + dma_buffers = dma_map_sg(instance->state->dev, + scatterlist, + num_pages, + pagelistinfo->dma_dir); + + if (dma_buffers == 0) { + cleanup_pagelistinfo(instance, pagelistinfo); + return NULL; + } + + pagelistinfo->scatterlist_mapped = 1; + + /* Combine adjacent blocks for performance */ + k = 0; + for_each_sg(scatterlist, sg, dma_buffers, i) { + unsigned int len = sg_dma_len(sg); + dma_addr_t addr = sg_dma_address(sg); + + /* Note: addrs is the address + page_count - 1 + * The firmware expects blocks after the first to be page- + * aligned and a multiple of the page size + */ + WARN_ON(len == 0); + WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); + WARN_ON(i && (addr & ~PAGE_MASK)); + if (is_adjacent_block(addrs, addr, k)) + addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT); + else + addrs[k++] = (addr & PAGE_MASK) | + (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1); + } + + /* Partial cache lines (fragments) require special measures */ + cache_line_size = drv_mgmt->info->cache_line_size; + if ((type == PAGELIST_READ) && + ((pagelist->offset & (cache_line_size - 1)) || + ((pagelist->offset + pagelist->length) & (cache_line_size - 1)))) { + char *fragments; + + if (down_interruptible(&drv_mgmt->free_fragments_sema)) { + cleanup_pagelistinfo(instance, pagelistinfo); + return NULL; + } + + WARN_ON(!drv_mgmt->free_fragments); + + down(&drv_mgmt->free_fragments_mutex); + fragments = drv_mgmt->free_fragments; + WARN_ON(!fragments); + drv_mgmt->free_fragments = *(char **)drv_mgmt->free_fragments; + up(&drv_mgmt->free_fragments_mutex); + pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + + (fragments - drv_mgmt->fragments_base) / drv_mgmt->fragments_size; + } + + return pagelistinfo; +} + +static void +free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo, + int actual) +{ + struct vchiq_drv_mgmt *drv_mgmt; + struct pagelist *pagelist = pagelistinfo->pagelist; + struct page **pages = pagelistinfo->pages; + unsigned int num_pages = pagelistinfo->num_pages; + unsigned int cache_line_size; + + dev_dbg(instance->state->dev, "arm: %pK, %d\n", pagelistinfo->pagelist, actual); + + drv_mgmt = dev_get_drvdata(instance->state->dev); + + /* + * NOTE: dma_unmap_sg must be called before the + * cpu can touch any of the data/pages. + */ + dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist, + pagelistinfo->num_pages, pagelistinfo->dma_dir); + pagelistinfo->scatterlist_mapped = 0; + + /* Deal with any partial cache lines (fragments) */ + cache_line_size = drv_mgmt->info->cache_line_size; + if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS && drv_mgmt->fragments_base) { + char *fragments = drv_mgmt->fragments_base + + (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) * + drv_mgmt->fragments_size; + int head_bytes, tail_bytes; + + head_bytes = (cache_line_size - pagelist->offset) & + (cache_line_size - 1); + tail_bytes = (pagelist->offset + actual) & + (cache_line_size - 1); + + if ((actual >= 0) && (head_bytes != 0)) { + if (head_bytes > actual) + head_bytes = actual; + + memcpy_to_page(pages[0], pagelist->offset, + fragments, head_bytes); + } + if ((actual >= 0) && (head_bytes < actual) && + (tail_bytes != 0)) + memcpy_to_page(pages[num_pages - 1], + (pagelist->offset + actual) & + (PAGE_SIZE - 1) & ~(cache_line_size - 1), + fragments + cache_line_size, + tail_bytes); + + down(&drv_mgmt->free_fragments_mutex); + *(char **)fragments = drv_mgmt->free_fragments; + drv_mgmt->free_fragments = fragments; + up(&drv_mgmt->free_fragments_mutex); + up(&drv_mgmt->free_fragments_sema); + } + + /* Need to mark all the pages dirty. */ + if (pagelist->type != PAGELIST_WRITE && + pagelistinfo->pages_need_release) { + unsigned int i; + + for (i = 0; i < num_pages; i++) + set_page_dirty(pages[i]); + } + + cleanup_pagelistinfo(instance, pagelistinfo); +} + +static int +vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk) +{ + struct vchiq_pagelist_info *pagelistinfo; + + pagelistinfo = create_pagelist(instance, bulk); + + if (!pagelistinfo) + return -ENOMEM; + + bulk->dma_addr = pagelistinfo->dma_addr; + + /* + * Store the pagelistinfo address in remote_data, + * which isn't used by the slave. + */ + bulk->remote_data = pagelistinfo; + + return 0; +} + +static void +vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk) +{ + if (bulk && bulk->remote_data && bulk->actual) + free_pagelist(instance, (struct vchiq_pagelist_info *)bulk->remote_data, + bulk->actual); +} + /* Called with the bulk_mutex held */ static void abort_outstanding_bulks(struct vchiq_service *service, @@ -1452,7 +1817,7 @@ abort_outstanding_bulks(struct vchiq_service *service, service->remoteport, bulk->size, bulk->remote_size); } else { /* fabricate a matching dummy bulk */ - bulk->data = 0; + bulk->dma_addr = 0; bulk->size = 0; bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED; bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT : @@ -1468,8 +1833,10 @@ static int parse_open(struct vchiq_state *state, struct vchiq_header *header) { const struct vchiq_open_payload *payload; + struct vchiq_openack_payload ack_payload; struct vchiq_service *service = NULL; int msgid, size; + int openack_id; unsigned int localport, remoteport, fourcc; short version, version_min; @@ -1504,34 +1871,36 @@ parse_open(struct vchiq_state *state, struct vchiq_header *header) } service->peer_version = version; - if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) { - struct vchiq_openack_payload ack_payload = { - service->version - }; - int openack_id = MAKE_OPENACK(service->localport, remoteport); + if (service->srvstate != VCHIQ_SRVSTATE_LISTENING) + goto done; - if (state->version_common < - VCHIQ_VERSION_SYNCHRONOUS_MODE) - service->sync = 0; + ack_payload.version = service->version; + openack_id = MAKE_OPENACK(service->localport, remoteport); - /* Acknowledge the OPEN */ - if (service->sync) { - if (queue_message_sync(state, NULL, openack_id, memcpy_copy_callback, - &ack_payload, sizeof(ack_payload)) == -EAGAIN) - goto bail_not_ready; + if (state->version_common < VCHIQ_VERSION_SYNCHRONOUS_MODE) + service->sync = 0; - /* The service is now open */ - set_service_state(service, VCHIQ_SRVSTATE_OPENSYNC); - } else { - if (queue_message(state, NULL, openack_id, memcpy_copy_callback, - &ack_payload, sizeof(ack_payload), 0) == -EAGAIN) - goto bail_not_ready; + /* Acknowledge the OPEN */ + if (service->sync) { + if (queue_message_sync(state, NULL, openack_id, + memcpy_copy_callback, + &ack_payload, + sizeof(ack_payload)) == -EAGAIN) + goto bail_not_ready; - /* The service is now open */ - set_service_state(service, VCHIQ_SRVSTATE_OPEN); - } + /* The service is now open */ + set_service_state(service, VCHIQ_SRVSTATE_OPENSYNC); + } else { + if (queue_message(state, NULL, openack_id, + memcpy_copy_callback, &ack_payload, + sizeof(ack_payload), 0) == -EINTR) + goto bail_not_ready; + + /* The service is now open */ + set_service_state(service, VCHIQ_SRVSTATE_OPEN); } +done: /* Success - the message has been dealt with */ vchiq_service_put(service); return 1; @@ -1539,7 +1908,7 @@ parse_open(struct vchiq_state *state, struct vchiq_header *header) fail_open: /* No available service, or an invalid request - send a CLOSE */ if (queue_message(state, NULL, MAKE_CLOSE(0, VCHIQ_MSG_SRCPORT(msgid)), - NULL, NULL, 0, 0) == -EAGAIN) + NULL, NULL, 0, 0) == -EINTR) goto bail_not_ready; return 1; @@ -1753,7 +2122,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) dev_dbg(state->dev, "core: %d: prs %s@%pK (%d->%d) %x@%pad\n", state->id, msg_type_str(type), header, remoteport, - localport, bulk->actual, &bulk->data); + localport, bulk->actual, &bulk->dma_addr); dev_dbg(state->dev, "core: %d: prs:%d %cx li=%x ri=%x p=%x\n", state->id, localport, @@ -1786,7 +2155,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT) { /* Send a PAUSE in response */ if (queue_message(state, NULL, MAKE_PAUSE, NULL, NULL, 0, - QMFLAGS_NO_MUTEX_UNLOCK) == -EAGAIN) + QMFLAGS_NO_MUTEX_UNLOCK) == -EINTR) goto bail_not_ready; } /* At this point slot_mutex is held */ @@ -1903,7 +2272,7 @@ handle_poll(struct vchiq_state *state) case VCHIQ_CONNSTATE_PAUSING: if (queue_message(state, NULL, MAKE_PAUSE, NULL, NULL, 0, - QMFLAGS_NO_MUTEX_UNLOCK) != -EAGAIN) { + QMFLAGS_NO_MUTEX_UNLOCK) != -EINTR) { vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSE_SENT); } else { /* Retry later */ @@ -1913,7 +2282,7 @@ handle_poll(struct vchiq_state *state) case VCHIQ_CONNSTATE_RESUMING: if (queue_message(state, NULL, MAKE_RESUME, NULL, NULL, 0, - QMFLAGS_NO_MUTEX_LOCK) != -EAGAIN) { + QMFLAGS_NO_MUTEX_LOCK) != -EINTR) { vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED); } else { /* @@ -2662,56 +3031,58 @@ close_service_complete(struct vchiq_service *service, int failstate) * returned to user context. */ static int -vchiq_bulk_xfer_queue_msg_interruptible(struct vchiq_service *service, - void *offset, void __user *uoffset, - int size, void *userdata, - enum vchiq_bulk_mode mode, - enum vchiq_bulk_dir dir) +vchiq_bulk_xfer_queue_msg_killable(struct vchiq_service *service, + struct vchiq_bulk *bulk_params) { struct vchiq_bulk_queue *queue; struct bulk_waiter *bulk_waiter = NULL; struct vchiq_bulk *bulk; struct vchiq_state *state = service->state; - const char dir_char = (dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r'; - const int dir_msgtype = (dir == VCHIQ_BULK_TRANSMIT) ? + const char dir_char = (bulk_params->dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r'; + const int dir_msgtype = (bulk_params->dir == VCHIQ_BULK_TRANSMIT) ? VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX; int status = -EINVAL; int payload[2]; - if (mode == VCHIQ_BULK_MODE_BLOCKING) { - bulk_waiter = userdata; + if (bulk_params->mode == VCHIQ_BULK_MODE_BLOCKING) { + bulk_waiter = bulk_params->waiter; init_completion(&bulk_waiter->event); bulk_waiter->actual = 0; bulk_waiter->bulk = NULL; } - queue = (dir == VCHIQ_BULK_TRANSMIT) ? + queue = (bulk_params->dir == VCHIQ_BULK_TRANSMIT) ? &service->bulk_tx : &service->bulk_rx; if (mutex_lock_killable(&service->bulk_mutex)) - return -EAGAIN; + return -EINTR; if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS) { VCHIQ_SERVICE_STATS_INC(service, bulk_stalls); do { mutex_unlock(&service->bulk_mutex); - if (wait_for_completion_interruptible(&service->bulk_remove_event)) - return -EAGAIN; + if (wait_for_completion_killable(&service->bulk_remove_event)) + return -EINTR; if (mutex_lock_killable(&service->bulk_mutex)) - return -EAGAIN; + return -EINTR; } while (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS); } bulk = &queue->bulks[BULK_INDEX(queue->local_insert)]; - bulk->mode = mode; - bulk->dir = dir; - bulk->userdata = userdata; - bulk->size = size; + /* Initiliaze the 'bulk' slot with bulk parameters passed in. */ + bulk->mode = bulk_params->mode; + bulk->dir = bulk_params->dir; + bulk->waiter = bulk_params->waiter; + bulk->cb_data = bulk_params->cb_data; + bulk->cb_userdata = bulk_params->cb_userdata; + bulk->size = bulk_params->size; + bulk->offset = bulk_params->offset; + bulk->uoffset = bulk_params->uoffset; bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED; - if (vchiq_prepare_bulk_data(service->instance, bulk, offset, uoffset, size, dir)) + if (vchiq_prepare_bulk_data(service->instance, bulk)) goto unlock_error_exit; /* @@ -2722,21 +3093,21 @@ vchiq_bulk_xfer_queue_msg_interruptible(struct vchiq_service *service, dev_dbg(state->dev, "core: %d: bt (%d->%d) %cx %x@%pad %pK\n", state->id, service->localport, service->remoteport, - dir_char, size, &bulk->data, userdata); + dir_char, bulk->size, &bulk->dma_addr, bulk->cb_data); /* * The slot mutex must be held when the service is being closed, so * claim it here to ensure that isn't happening */ if (mutex_lock_killable(&state->slot_mutex)) { - status = -EAGAIN; + status = -EINTR; goto cancel_bulk_error_exit; } if (service->srvstate != VCHIQ_SRVSTATE_OPEN) goto unlock_both_error_exit; - payload[0] = lower_32_bits(bulk->data); + payload[0] = lower_32_bits(bulk->dma_addr); payload[1] = bulk->size; status = queue_message(state, NULL, @@ -2761,13 +3132,13 @@ vchiq_bulk_xfer_queue_msg_interruptible(struct vchiq_service *service, state->id, service->localport, dir_char, queue->local_insert, queue->remote_insert, queue->process); - if (bulk_waiter) { - bulk_waiter->bulk = bulk; - if (wait_for_completion_interruptible(&bulk_waiter->event)) - status = -EAGAIN; - else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED) - status = -EINVAL; - } + if (bulk_waiter) { + bulk_waiter->bulk = bulk; + if (wait_for_completion_killable(&bulk_waiter->event)) + status = -EINTR; + else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED) + status = -EINVAL; + } return status; @@ -2803,19 +3174,21 @@ vchiq_close_service_internal(struct vchiq_service *service, int close_recvd) if (close_recvd) { dev_err(state->dev, "core: (1) called in state %s\n", srvstate_names[service->srvstate]); - } else if (is_server) { - if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) { - status = -EINVAL; - } else { - service->client_id = 0; - service->remoteport = VCHIQ_PORT_FREE; - if (service->srvstate == VCHIQ_SRVSTATE_CLOSEWAIT) - set_service_state(service, VCHIQ_SRVSTATE_LISTENING); - } - complete(&service->remove_event); - } else { + break; + } else if (!is_server) { vchiq_free_service_internal(service); + break; + } + + if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) { + status = -EINVAL; + } else { + service->client_id = 0; + service->remoteport = VCHIQ_PORT_FREE; + if (service->srvstate == VCHIQ_SRVSTATE_CLOSEWAIT) + set_service_state(service, VCHIQ_SRVSTATE_LISTENING); } + complete(&service->remove_event); break; case VCHIQ_SRVSTATE_OPENING: if (close_recvd) { @@ -2945,6 +3318,7 @@ int vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instance) { struct vchiq_service *service; + int status = 0; int i; /* Find all services registered to this client and enable them. */ @@ -2956,9 +3330,10 @@ vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instanc } if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) { - if (queue_message(state, NULL, MAKE_CONNECT, NULL, NULL, 0, - QMFLAGS_IS_BLOCKING) == -EAGAIN) - return -EAGAIN; + status = queue_message(state, NULL, MAKE_CONNECT, NULL, NULL, 0, + QMFLAGS_IS_BLOCKING); + if (status) + return status; vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTING); } @@ -2971,7 +3346,7 @@ vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instanc complete(&state->connect); } - return 0; + return status; } void @@ -3105,12 +3480,10 @@ vchiq_remove_service(struct vchiq_instance *instance, unsigned int handle) } int -vchiq_bulk_xfer_blocking_interruptible(struct vchiq_instance *instance, unsigned int handle, - void *offset, void __user *uoffset, int size, - void __user *userdata, enum vchiq_bulk_dir dir) +vchiq_bulk_xfer_blocking(struct vchiq_instance *instance, unsigned int handle, + struct vchiq_bulk *bulk_params) { struct vchiq_service *service = find_service_by_handle(instance, handle); - enum vchiq_bulk_mode mode = VCHIQ_BULK_MODE_BLOCKING; int status = -EINVAL; if (!service) @@ -3119,15 +3492,13 @@ vchiq_bulk_xfer_blocking_interruptible(struct vchiq_instance *instance, unsigned if (service->srvstate != VCHIQ_SRVSTATE_OPEN) goto error_exit; - if (!offset && !uoffset) + if (!bulk_params->offset && !bulk_params->uoffset) goto error_exit; if (vchiq_check_service(service)) goto error_exit; - - status = vchiq_bulk_xfer_queue_msg_interruptible(service, offset, uoffset, size, - userdata, mode, dir); + status = vchiq_bulk_xfer_queue_msg_killable(service, bulk_params); error_exit: vchiq_service_put(service); @@ -3136,10 +3507,8 @@ error_exit: } int -vchiq_bulk_xfer_callback_interruptible(struct vchiq_instance *instance, unsigned int handle, - void *offset, void __user *uoffset, int size, - enum vchiq_bulk_mode mode, void *userdata, - enum vchiq_bulk_dir dir) +vchiq_bulk_xfer_callback(struct vchiq_instance *instance, unsigned int handle, + struct vchiq_bulk *bulk_params) { struct vchiq_service *service = find_service_by_handle(instance, handle); int status = -EINVAL; @@ -3147,21 +3516,20 @@ vchiq_bulk_xfer_callback_interruptible(struct vchiq_instance *instance, unsigned if (!service) return -EINVAL; - if (mode != VCHIQ_BULK_MODE_CALLBACK && - mode != VCHIQ_BULK_MODE_NOCALLBACK) + if (bulk_params->mode != VCHIQ_BULK_MODE_CALLBACK && + bulk_params->mode != VCHIQ_BULK_MODE_NOCALLBACK) goto error_exit; if (service->srvstate != VCHIQ_SRVSTATE_OPEN) goto error_exit; - if (!offset && !uoffset) + if (!bulk_params->offset && !bulk_params->uoffset) goto error_exit; if (vchiq_check_service(service)) goto error_exit; - status = vchiq_bulk_xfer_queue_msg_interruptible(service, offset, uoffset, - size, userdata, mode, dir); + status = vchiq_bulk_xfer_queue_msg_killable(service, bulk_params); error_exit: vchiq_service_put(service); @@ -3175,8 +3543,8 @@ error_exit: * and the call should be retried after being returned to user context. */ int -vchiq_bulk_xfer_waiting_interruptible(struct vchiq_instance *instance, - unsigned int handle, struct bulk_waiter *userdata) +vchiq_bulk_xfer_waiting(struct vchiq_instance *instance, + unsigned int handle, struct bulk_waiter *waiter) { struct vchiq_service *service = find_service_by_handle(instance, handle); struct bulk_waiter *bulk_waiter; @@ -3185,7 +3553,7 @@ vchiq_bulk_xfer_waiting_interruptible(struct vchiq_instance *instance, if (!service) return -EINVAL; - if (!userdata) + if (!waiter) goto error_exit; if (service->srvstate != VCHIQ_SRVSTATE_OPEN) @@ -3194,14 +3562,14 @@ vchiq_bulk_xfer_waiting_interruptible(struct vchiq_instance *instance, if (vchiq_check_service(service)) goto error_exit; - bulk_waiter = userdata; + bulk_waiter = waiter; vchiq_service_put(service); status = 0; - if (wait_for_completion_interruptible(&bulk_waiter->event)) - return -EAGAIN; + if (wait_for_completion_killable(&bulk_waiter->event)) + return -EINTR; else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED) return -EINVAL; @@ -3267,24 +3635,8 @@ error_exit: int vchiq_queue_kernel_message(struct vchiq_instance *instance, unsigned int handle, void *data, unsigned int size) { - int status; - - while (1) { - status = vchiq_queue_message(instance, handle, memcpy_copy_callback, - data, size); - - /* - * vchiq_queue_message() may return -EAGAIN, so we need to - * implement a retry mechanism since this function is supposed - * to block until queued - */ - if (status != -EAGAIN) - break; - - msleep(1); - } - - return status; + return vchiq_queue_message(instance, handle, memcpy_copy_callback, + data, size); } EXPORT_SYMBOL(vchiq_queue_kernel_message); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h index 468463f318018ca4ecb6cf6121098ba67934c1aa..9b4e766990a493d6e9d4e0604f2c84f4e7b77804 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h @@ -6,11 +6,12 @@ #include #include -#include +#include #include #include #include #include +#include #include #include @@ -113,12 +114,16 @@ enum vchiq_bulk_dir { struct vchiq_bulk { short mode; short dir; - void *userdata; - dma_addr_t data; + void *cb_data; + void __user *cb_userdata; + struct bulk_waiter *waiter; + dma_addr_t dma_addr; int size; void *remote_data; int remote_size; int actual; + void *offset; + void __user *uoffset; }; struct vchiq_bulk_queue { @@ -409,6 +414,28 @@ struct vchiq_state { struct opaque_platform_state *platform_state; }; +struct pagelist { + u32 length; + u16 type; + u16 offset; + u32 addrs[1]; /* N.B. 12 LSBs hold the number + * of following pages at consecutive + * addresses. + */ +}; + +struct vchiq_pagelist_info { + struct pagelist *pagelist; + size_t pagelist_buffer_size; + dma_addr_t dma_addr; + enum dma_data_direction dma_dir; + unsigned int num_pages; + unsigned int pages_need_release; + struct page **pages; + struct scatterlist *scatterlist; + unsigned int scatterlist_mapped; +}; + static inline bool vchiq_remote_initialised(const struct vchiq_state *state) { return state->remote && state->remote->initialised; @@ -471,19 +498,16 @@ extern void remote_event_pollall(struct vchiq_state *state); extern int -vchiq_bulk_xfer_waiting_interruptible(struct vchiq_instance *instance, - unsigned int handle, struct bulk_waiter *userdata); +vchiq_bulk_xfer_waiting(struct vchiq_instance *instance, unsigned int handle, + struct bulk_waiter *userdata); extern int -vchiq_bulk_xfer_blocking_interruptible(struct vchiq_instance *instance, unsigned int handle, - void *offset, void __user *uoffset, int size, - void __user *userdata, enum vchiq_bulk_dir dir); +vchiq_bulk_xfer_blocking(struct vchiq_instance *instance, unsigned int handle, + struct vchiq_bulk *bulk); extern int -vchiq_bulk_xfer_callback_interruptible(struct vchiq_instance *instance, unsigned int handle, - void *offset, void __user *uoffset, int size, - enum vchiq_bulk_mode mode, void *userdata, - enum vchiq_bulk_dir dir); +vchiq_bulk_xfer_callback(struct vchiq_instance *instance, unsigned int handle, + struct vchiq_bulk *bulk); extern void vchiq_dump_state(struct seq_file *f, struct vchiq_state *state); @@ -529,13 +553,6 @@ vchiq_queue_message(struct vchiq_instance *instance, unsigned int handle, void *context, size_t size); -int vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset, - void __user *uoffset, int size, int dir); - -void vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk); - -void remote_event_signal(struct vchiq_state *state, struct remote_event *event); - void vchiq_dump_platform_state(struct seq_file *f); void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h index fabffd81b1ec9a1d5e522496f26ee9262216aa47..b29e6693c949937e7b161c047634f0e8d69c27dc 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h @@ -4,7 +4,8 @@ #ifndef VCHIQ_DEBUGFS_H #define VCHIQ_DEBUGFS_H -#include "vchiq_core.h" +struct vchiq_state; +struct vchiq_instance; struct vchiq_debugfs_node { struct dentry *dentry; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c index d41a4624cc92c39eafa1bfdb229b15c3c21ff6aa..454f4341650306654d1365653ab3b570795f3331 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c @@ -288,7 +288,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, { struct vchiq_service *service; struct bulk_waiter_node *waiter = NULL, *iter; - void *userdata; + struct vchiq_bulk bulk_params = {}; int status = 0; int ret; @@ -303,12 +303,14 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, goto out; } - userdata = &waiter->bulk_waiter; - - status = vchiq_bulk_xfer_blocking_interruptible(instance, args->handle, - NULL, args->data, args->size, - userdata, dir); + bulk_params.uoffset = args->data; + bulk_params.mode = args->mode; + bulk_params.size = args->size; + bulk_params.dir = dir; + bulk_params.waiter = &waiter->bulk_waiter; + status = vchiq_bulk_xfer_blocking(instance, args->handle, + &bulk_params); } else if (args->mode == VCHIQ_BULK_MODE_WAITING) { mutex_lock(&instance->bulk_waiter_list_mutex); list_for_each_entry(iter, &instance->bulk_waiter_list, @@ -328,16 +330,18 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, } dev_dbg(service->state->dev, "arm: found bulk_waiter %pK for pid %d\n", waiter, current->pid); - userdata = &waiter->bulk_waiter; - status = vchiq_bulk_xfer_waiting_interruptible(instance, args->handle, userdata); + status = vchiq_bulk_xfer_waiting(instance, args->handle, + &waiter->bulk_waiter); } else { - userdata = args->userdata; - - status = vchiq_bulk_xfer_callback_interruptible(instance, args->handle, NULL, - args->data, args->size, - args->mode, userdata, dir); - + bulk_params.uoffset = args->data; + bulk_params.mode = args->mode; + bulk_params.size = args->size; + bulk_params.dir = dir; + bulk_params.cb_userdata = args->userdata; + + status = vchiq_bulk_xfer_callback(instance, args->handle, + &bulk_params); } if (!waiter) { @@ -350,7 +354,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, if (waiter->bulk_waiter.bulk) { /* Cancel the signal when the transfer completes. */ spin_lock(&service->state->bulk_waiter_spinlock); - waiter->bulk_waiter.bulk->userdata = NULL; + waiter->bulk_waiter.bulk->waiter = NULL; spin_unlock(&service->state->bulk_waiter_spinlock); } kfree(waiter); @@ -410,7 +414,7 @@ struct vchiq_completion_data32 { enum vchiq_reason reason; compat_uptr_t header; compat_uptr_t service_userdata; - compat_uptr_t bulk_userdata; + compat_uptr_t cb_data; }; static int vchiq_put_completion(struct vchiq_completion_data __user *buf, @@ -424,7 +428,7 @@ static int vchiq_put_completion(struct vchiq_completion_data __user *buf, .reason = completion->reason, .header = ptr_to_compat(completion->header), .service_userdata = ptr_to_compat(completion->service_userdata), - .bulk_userdata = ptr_to_compat(completion->bulk_userdata), + .cb_data = ptr_to_compat(completion->cb_userdata), }; if (copy_to_user(&buf32[index], &tmp, sizeof(tmp))) return -EFAULT; @@ -545,11 +549,7 @@ static int vchiq_ioc_await_completion(struct vchiq_instance *instance, !instance->use_close_delivered) vchiq_service_put(service); - /* - * FIXME: address space mismatch, does bulk_userdata - * actually point to user or kernel memory? - */ - user_completion.bulk_userdata = completion->bulk_userdata; + user_completion.cb_userdata = completion->cb_userdata; if (vchiq_put_completion(args->buf, &user_completion, ret)) { if (ret == 0) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h index 17550831f86cb9b1fdd7231875593aa2bcd47833..afb71a83cfe7035e5dd61003fa99fd514ca18047 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h @@ -47,7 +47,7 @@ struct vchiq_completion_data { enum vchiq_reason reason; struct vchiq_header __user *header; void __user *service_userdata; - void __user *bulk_userdata; + void __user *cb_userdata; }; struct vchiq_await_completion { diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_pagelist.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_pagelist.h deleted file mode 100644 index ebd12bfabb63753ac55bd6deb873170948f7b231..0000000000000000000000000000000000000000 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_pagelist.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */ - -#ifndef VCHIQ_PAGELIST_H -#define VCHIQ_PAGELIST_H - -#define PAGELIST_WRITE 0 -#define PAGELIST_READ 1 -#define PAGELIST_READ_WITH_FRAGMENTS 2 - -struct pagelist { - u32 length; - u16 type; - u16 offset; - u32 addrs[1]; /* N.B. 12 LSBs hold the number - * of following pages at consecutive - * addresses. - */ -}; - -#endif /* VCHIQ_PAGELIST_H */ diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 67489c334f7b2dc0d55027659de76ad2bbd37983..3fe482bd279390a7586c49bde00f38c61558ca8e 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -551,7 +551,8 @@ static void bulk_abort_cb(struct vchiq_mmal_instance *instance, /* incoming event service callback */ static int mmal_service_callback(struct vchiq_instance *vchiq_instance, enum vchiq_reason reason, struct vchiq_header *header, - unsigned int handle, void *bulk_ctx) + unsigned int handle, void *cb_data, + void __user *cb_userdata) { struct vchiq_mmal_instance *instance = vchiq_get_service_userdata(vchiq_instance, handle); u32 msg_len; @@ -626,11 +627,11 @@ static int mmal_service_callback(struct vchiq_instance *vchiq_instance, break; case VCHIQ_BULK_RECEIVE_DONE: - bulk_receive_cb(instance, bulk_ctx); + bulk_receive_cb(instance, cb_data); break; case VCHIQ_BULK_RECEIVE_ABORTED: - bulk_abort_cb(instance, bulk_ctx); + bulk_abort_cb(instance, cb_data); break; case VCHIQ_SERVICE_CLOSED: diff --git a/drivers/staging/vme_user/vme_bridge.h b/drivers/staging/vme_user/vme_bridge.h index 9bdc41bb6602102048f8c619fee37b345b3e735c..abf880d68b124cb8cd3603d86efcc7b7bd49709c 100644 --- a/drivers/staging/vme_user/vme_bridge.h +++ b/drivers/staging/vme_user/vme_bridge.h @@ -128,39 +128,49 @@ struct vme_bridge { struct mutex irq_mtx; /* Slave Functions */ - int (*slave_get)(struct vme_slave_resource *, int *, unsigned long long *, - unsigned long long *, dma_addr_t *, u32 *, u32 *); - int (*slave_set)(struct vme_slave_resource *, int, unsigned long long, - unsigned long long, dma_addr_t, u32, u32); + int (*slave_get)(struct vme_slave_resource *image, int *enabled, + unsigned long long *vme_base, unsigned long long *size, + dma_addr_t *buf_base, u32 *aspace, u32 *cycle); + int (*slave_set)(struct vme_slave_resource *image, int enabled, + unsigned long long vme_base, unsigned long long size, + dma_addr_t buf_base, u32 aspace, u32 cycle); /* Master Functions */ - int (*master_get)(struct vme_master_resource *, int *, unsigned long long *, - unsigned long long *, u32 *, u32 *, u32 *); - int (*master_set)(struct vme_master_resource *, int, unsigned long long, - unsigned long long, u32, u32, u32); - ssize_t (*master_read)(struct vme_master_resource *, void *, size_t, loff_t); - ssize_t (*master_write)(struct vme_master_resource *, void *, size_t, loff_t); - unsigned int (*master_rmw)(struct vme_master_resource *, unsigned int, - unsigned int, unsigned int, loff_t); + int (*master_get)(struct vme_master_resource *image, int *enabled, + unsigned long long *vme_base, unsigned long long *size, + u32 *aspace, u32 *cycle, u32 *dwidth); + int (*master_set)(struct vme_master_resource *image, int enabled, + unsigned long long vme_base, unsigned long long size, + u32 aspace, u32 cycle, u32 dwidth); + ssize_t (*master_read)(struct vme_master_resource *image, void *buf, + size_t count, loff_t offset); + ssize_t (*master_write)(struct vme_master_resource *image, void *buf, + size_t count, loff_t offset); + unsigned int (*master_rmw)(struct vme_master_resource *image, + unsigned int mask, unsigned int compare, + unsigned int swap, loff_t offset); /* DMA Functions */ - int (*dma_list_add)(struct vme_dma_list *, struct vme_dma_attr *, - struct vme_dma_attr *, size_t); - int (*dma_list_exec)(struct vme_dma_list *); - int (*dma_list_empty)(struct vme_dma_list *); + int (*dma_list_add)(struct vme_dma_list *list, struct vme_dma_attr *src, + struct vme_dma_attr *dest, size_t count); + int (*dma_list_exec)(struct vme_dma_list *list); + int (*dma_list_empty)(struct vme_dma_list *list); /* Interrupt Functions */ - void (*irq_set)(struct vme_bridge *, int, int, int); - int (*irq_generate)(struct vme_bridge *, int, int); + void (*irq_set)(struct vme_bridge *bridge, int level, int state, int sync); + int (*irq_generate)(struct vme_bridge *bridge, int level, int statid); /* Location monitor functions */ - int (*lm_set)(struct vme_lm_resource *, unsigned long long, u32, u32); - int (*lm_get)(struct vme_lm_resource *, unsigned long long *, u32 *, u32 *); - int (*lm_attach)(struct vme_lm_resource *, int, void (*callback)(void *), void *); - int (*lm_detach)(struct vme_lm_resource *, int); + int (*lm_set)(struct vme_lm_resource *lm, unsigned long long lm_base, + u32 aspace, u32 cycle); + int (*lm_get)(struct vme_lm_resource *lm, unsigned long long *lm_base, + u32 *aspace, u32 *cycle); + int (*lm_attach)(struct vme_lm_resource *lm, int monitor, + void (*callback)(void *), void *data); + int (*lm_detach)(struct vme_lm_resource *lm, int monitor); /* CR/CSR space functions */ - int (*slot_get)(struct vme_bridge *); + int (*slot_get)(struct vme_bridge *bridge); /* Bridge parent interface */ void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *dma); diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig deleted file mode 100644 index 077f62ebe80cddb6b269d98ee1c4767185913c9c..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config VT6655 - tristate "VIA Technologies VT6655 support" - depends on PCI && HAS_IOPORT && MAC80211 && m - help - This is a vendor-written driver for VIA VT6655. diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile deleted file mode 100644 index e70357ec0af8a1e229b9e3fa9259a0b0e6cef52b..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -vt6655_stage-y += device_main.o \ - card.o \ - channel.o \ - mac.o \ - baseband.o \ - rxtx.o \ - dpc.o \ - power.o \ - srom.o \ - key.o \ - rf.o - -obj-$(CONFIG_VT6655) += vt6655_stage.o diff --git a/drivers/staging/vt6655/TODO b/drivers/staging/vt6655/TODO deleted file mode 100644 index 27654bd0ff5d76125d9c18b746b8ae35018926b3..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/TODO +++ /dev/null @@ -1,20 +0,0 @@ -TODO: -- remove __cplusplus ifdefs -- done -- prepare for merge with vt6656 driver: - - rename DEVICE_PRT() to DBG_PRT() -- done - - share 80211*.h includes - - split rf.c - - remove dead code - - abstract VT3253 chipset specific code -- add common vt665x infrastructure -- kill ttype.h -- switch to use MAC80211 -- verify unsigned long usage for x86-64 arch -- reduce .data footprint -- use kernel coding style -- checkpatch.pl fixes -- sparse fixes -- integrate with drivers/net/wireless - -Please send any patches to Greg Kroah-Hartman -and Philipp Hortmann . diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c deleted file mode 100644 index f7824396c5ff7009226858aeee573dd685c866c5..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/baseband.c +++ /dev/null @@ -1,2257 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions to access baseband - * - * Author: Kyle Hsu - * - * Date: Aug.22, 2002 - * - * Functions: - * bb_get_frame_time - Calculate data frame transmitting time - * bb_read_embedded - Embedded read baseband register via MAC - * bb_write_embedded - Embedded write baseband register via MAC - * bb_vt3253_init - VIA VT3253 baseband chip init code - * - * Revision History: - * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. - * 08-07-2003 Bryan YC Fan: Add MAXIM2827/2825 and RFMD2959 support. - * 08-26-2003 Kyle Hsu : Modify BBuGetFrameTime() and - * BBvCalculateParameter(). - * cancel the setting of MAC_REG_SOFTPWRCTL on - * BBbVT3253Init(). - * Add the comments. - * 09-01-2003 Bryan YC Fan: RF & BB tables updated. - * Modified BBvLoopbackOn & BBvLoopbackOff(). - * - * - */ - -#include "mac.h" -#include "baseband.h" -#include "srom.h" -#include "rf.h" - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -#define CB_VT3253_INIT_FOR_RFMD 446 -static const unsigned char by_vt3253_init_tab_rfmd[CB_VT3253_INIT_FOR_RFMD][2] = { - {0x00, 0x30}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x00}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x70}, - {0x09, 0x45}, - {0x0a, 0x2a}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x01}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x9d}, - {0x1c, 0x05}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0xa8}, - {0x2e, 0x1a}, - {0x2f, 0x0c}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0x00}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x0d}, - {0x3e, 0x51}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x06}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x08}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x80}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x14}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0x44}, - {0x61, 0x04}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0x04}, - {0x67, 0xb7}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - {0x6c, 0x00}, - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x0b}, - {0x81, 0x00}, - {0x82, 0x3c}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x08}, - {0x8b, 0xa6}, - {0x8c, 0x84}, - {0x8d, 0x47}, - {0x8e, 0xbb}, - {0x8f, 0x02}, - {0x90, 0x21}, - {0x91, 0x0c}, - {0x92, 0x04}, - {0x93, 0x22}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xeb}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x00}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0x00}, - {0xa4, 0x00}, - {0xa5, 0x00}, - {0xa6, 0x10}, - {0xa7, 0x04}, - {0xa8, 0x10}, - {0xa9, 0x00}, - {0xaa, 0x8f}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x80}, - {0xb0, 0x38}, - {0xb1, 0x00}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0xee}, - {0xb5, 0xff}, - {0xb6, 0x10}, - {0xb7, 0x00}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x00}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x10}, - {0xc1, 0x10}, - {0xc2, 0x18}, - {0xc3, 0x20}, - {0xc4, 0x10}, - {0xc5, 0x00}, - {0xc6, 0x22}, - {0xc7, 0x14}, - {0xc8, 0x0f}, - {0xc9, 0x08}, - {0xca, 0xa4}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x10}, - {0xce, 0x20}, - {0xcf, 0x00}, - {0xd0, 0x00}, - {0xd1, 0x10}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x10}, - {0xd5, 0x33}, - {0xd6, 0x70}, - {0xd7, 0x01}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0x00}, - {0xe2, 0xcc}, - {0xe3, 0x04}, - {0xe4, 0x08}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x0e}, - {0xe8, 0x88}, - {0xe9, 0xd4}, - {0xea, 0x05}, - {0xeb, 0xf0}, - {0xec, 0x79}, - {0xed, 0x0f}, - {0xee, 0x04}, - {0xef, 0x04}, - {0xf0, 0x00}, - {0xf1, 0x00}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xF0, 0x00}, - {0xF1, 0xF8}, - {0xF0, 0x80}, - {0xF0, 0x00}, - {0xF1, 0xF4}, - {0xF0, 0x81}, - {0xF0, 0x01}, - {0xF1, 0xF0}, - {0xF0, 0x82}, - {0xF0, 0x02}, - {0xF1, 0xEC}, - {0xF0, 0x83}, - {0xF0, 0x03}, - {0xF1, 0xE8}, - {0xF0, 0x84}, - {0xF0, 0x04}, - {0xF1, 0xE4}, - {0xF0, 0x85}, - {0xF0, 0x05}, - {0xF1, 0xE0}, - {0xF0, 0x86}, - {0xF0, 0x06}, - {0xF1, 0xDC}, - {0xF0, 0x87}, - {0xF0, 0x07}, - {0xF1, 0xD8}, - {0xF0, 0x88}, - {0xF0, 0x08}, - {0xF1, 0xD4}, - {0xF0, 0x89}, - {0xF0, 0x09}, - {0xF1, 0xD0}, - {0xF0, 0x8A}, - {0xF0, 0x0A}, - {0xF1, 0xCC}, - {0xF0, 0x8B}, - {0xF0, 0x0B}, - {0xF1, 0xC8}, - {0xF0, 0x8C}, - {0xF0, 0x0C}, - {0xF1, 0xC4}, - {0xF0, 0x8D}, - {0xF0, 0x0D}, - {0xF1, 0xC0}, - {0xF0, 0x8E}, - {0xF0, 0x0E}, - {0xF1, 0xBC}, - {0xF0, 0x8F}, - {0xF0, 0x0F}, - {0xF1, 0xB8}, - {0xF0, 0x90}, - {0xF0, 0x10}, - {0xF1, 0xB4}, - {0xF0, 0x91}, - {0xF0, 0x11}, - {0xF1, 0xB0}, - {0xF0, 0x92}, - {0xF0, 0x12}, - {0xF1, 0xAC}, - {0xF0, 0x93}, - {0xF0, 0x13}, - {0xF1, 0xA8}, - {0xF0, 0x94}, - {0xF0, 0x14}, - {0xF1, 0xA4}, - {0xF0, 0x95}, - {0xF0, 0x15}, - {0xF1, 0xA0}, - {0xF0, 0x96}, - {0xF0, 0x16}, - {0xF1, 0x9C}, - {0xF0, 0x97}, - {0xF0, 0x17}, - {0xF1, 0x98}, - {0xF0, 0x98}, - {0xF0, 0x18}, - {0xF1, 0x94}, - {0xF0, 0x99}, - {0xF0, 0x19}, - {0xF1, 0x90}, - {0xF0, 0x9A}, - {0xF0, 0x1A}, - {0xF1, 0x8C}, - {0xF0, 0x9B}, - {0xF0, 0x1B}, - {0xF1, 0x88}, - {0xF0, 0x9C}, - {0xF0, 0x1C}, - {0xF1, 0x84}, - {0xF0, 0x9D}, - {0xF0, 0x1D}, - {0xF1, 0x80}, - {0xF0, 0x9E}, - {0xF0, 0x1E}, - {0xF1, 0x7C}, - {0xF0, 0x9F}, - {0xF0, 0x1F}, - {0xF1, 0x78}, - {0xF0, 0xA0}, - {0xF0, 0x20}, - {0xF1, 0x74}, - {0xF0, 0xA1}, - {0xF0, 0x21}, - {0xF1, 0x70}, - {0xF0, 0xA2}, - {0xF0, 0x22}, - {0xF1, 0x6C}, - {0xF0, 0xA3}, - {0xF0, 0x23}, - {0xF1, 0x68}, - {0xF0, 0xA4}, - {0xF0, 0x24}, - {0xF1, 0x64}, - {0xF0, 0xA5}, - {0xF0, 0x25}, - {0xF1, 0x60}, - {0xF0, 0xA6}, - {0xF0, 0x26}, - {0xF1, 0x5C}, - {0xF0, 0xA7}, - {0xF0, 0x27}, - {0xF1, 0x58}, - {0xF0, 0xA8}, - {0xF0, 0x28}, - {0xF1, 0x54}, - {0xF0, 0xA9}, - {0xF0, 0x29}, - {0xF1, 0x50}, - {0xF0, 0xAA}, - {0xF0, 0x2A}, - {0xF1, 0x4C}, - {0xF0, 0xAB}, - {0xF0, 0x2B}, - {0xF1, 0x48}, - {0xF0, 0xAC}, - {0xF0, 0x2C}, - {0xF1, 0x44}, - {0xF0, 0xAD}, - {0xF0, 0x2D}, - {0xF1, 0x40}, - {0xF0, 0xAE}, - {0xF0, 0x2E}, - {0xF1, 0x3C}, - {0xF0, 0xAF}, - {0xF0, 0x2F}, - {0xF1, 0x38}, - {0xF0, 0xB0}, - {0xF0, 0x30}, - {0xF1, 0x34}, - {0xF0, 0xB1}, - {0xF0, 0x31}, - {0xF1, 0x30}, - {0xF0, 0xB2}, - {0xF0, 0x32}, - {0xF1, 0x2C}, - {0xF0, 0xB3}, - {0xF0, 0x33}, - {0xF1, 0x28}, - {0xF0, 0xB4}, - {0xF0, 0x34}, - {0xF1, 0x24}, - {0xF0, 0xB5}, - {0xF0, 0x35}, - {0xF1, 0x20}, - {0xF0, 0xB6}, - {0xF0, 0x36}, - {0xF1, 0x1C}, - {0xF0, 0xB7}, - {0xF0, 0x37}, - {0xF1, 0x18}, - {0xF0, 0xB8}, - {0xF0, 0x38}, - {0xF1, 0x14}, - {0xF0, 0xB9}, - {0xF0, 0x39}, - {0xF1, 0x10}, - {0xF0, 0xBA}, - {0xF0, 0x3A}, - {0xF1, 0x0C}, - {0xF0, 0xBB}, - {0xF0, 0x3B}, - {0xF1, 0x08}, - {0xF0, 0x00}, - {0xF0, 0x3C}, - {0xF1, 0x04}, - {0xF0, 0xBD}, - {0xF0, 0x3D}, - {0xF1, 0x00}, - {0xF0, 0xBE}, - {0xF0, 0x3E}, - {0xF1, 0x00}, - {0xF0, 0xBF}, - {0xF0, 0x3F}, - {0xF1, 0x00}, - {0xF0, 0xC0}, - {0xF0, 0x00}, -}; - -#define CB_VT3253B0_INIT_FOR_RFMD 256 -static const unsigned char vt3253b0_rfmd[CB_VT3253B0_INIT_FOR_RFMD][2] = { - {0x00, 0x31}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x81}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x38}, - {0x09, 0x45}, - {0x0a, 0x2a}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x00}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x8e}, - {0x1c, 0x06}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0x34}, - {0x2e, 0x18}, - {0x2f, 0x0c}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0xf8}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x09}, - {0x3e, 0x0d}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x08}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x08}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x80}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x14}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0x39}, - {0x61, 0x83}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0xc0}, - {0x67, 0x49}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - {0x6c, 0x00}, - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x89}, - {0x81, 0x00}, - {0x82, 0x0e}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x0e}, - {0x8b, 0xa7}, - {0x8c, 0x88}, - {0x8d, 0x47}, - {0x8e, 0xaa}, - {0x8f, 0x02}, - {0x90, 0x23}, - {0x91, 0x0c}, - {0x92, 0x06}, - {0x93, 0x08}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xeb}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x00}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0xcd}, - {0xa4, 0x07}, - {0xa5, 0x33}, - {0xa6, 0x18}, - {0xa7, 0x00}, - {0xa8, 0x18}, - {0xa9, 0x00}, - {0xaa, 0x28}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x18}, - {0xb0, 0x38}, - {0xb1, 0x30}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0x00}, - {0xb5, 0x00}, - {0xb6, 0x84}, - {0xb7, 0xfd}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x00}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x10}, - {0xc1, 0x20}, - {0xc2, 0x18}, - {0xc3, 0x20}, - {0xc4, 0x10}, - {0xc5, 0x2c}, - {0xc6, 0x1e}, - {0xc7, 0x10}, - {0xc8, 0x12}, - {0xc9, 0x01}, - {0xca, 0x6f}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x10}, - {0xce, 0x00}, - {0xcf, 0x22}, - {0xd0, 0x00}, - {0xd1, 0x10}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x10}, - {0xd5, 0x33}, - {0xd6, 0x80}, - {0xd7, 0x21}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0xB3}, - {0xe2, 0x00}, - {0xe3, 0x00}, - {0xe4, 0x00}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x18}, - {0xe8, 0x08}, - {0xe9, 0xd4}, - {0xea, 0x00}, - {0xeb, 0xff}, - {0xec, 0x79}, - {0xed, 0x10}, - {0xee, 0x30}, - {0xef, 0x02}, - {0xf0, 0x00}, - {0xf1, 0x09}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xfa, 0x00}, - {0xfb, 0x00}, - {0xfc, 0x00}, - {0xfd, 0x00}, - {0xfe, 0x00}, - {0xff, 0x00}, -}; - -#define CB_VT3253B0_AGC_FOR_RFMD2959 195 -/* For RFMD2959 */ -static -unsigned char vt3253b0_agc4_rfmd2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = { - {0xF0, 0x00}, - {0xF1, 0x3E}, - {0xF0, 0x80}, - {0xF0, 0x00}, - {0xF1, 0x3E}, - {0xF0, 0x81}, - {0xF0, 0x01}, - {0xF1, 0x3E}, - {0xF0, 0x82}, - {0xF0, 0x02}, - {0xF1, 0x3E}, - {0xF0, 0x83}, - {0xF0, 0x03}, - {0xF1, 0x3B}, - {0xF0, 0x84}, - {0xF0, 0x04}, - {0xF1, 0x39}, - {0xF0, 0x85}, - {0xF0, 0x05}, - {0xF1, 0x38}, - {0xF0, 0x86}, - {0xF0, 0x06}, - {0xF1, 0x37}, - {0xF0, 0x87}, - {0xF0, 0x07}, - {0xF1, 0x36}, - {0xF0, 0x88}, - {0xF0, 0x08}, - {0xF1, 0x35}, - {0xF0, 0x89}, - {0xF0, 0x09}, - {0xF1, 0x35}, - {0xF0, 0x8A}, - {0xF0, 0x0A}, - {0xF1, 0x34}, - {0xF0, 0x8B}, - {0xF0, 0x0B}, - {0xF1, 0x34}, - {0xF0, 0x8C}, - {0xF0, 0x0C}, - {0xF1, 0x33}, - {0xF0, 0x8D}, - {0xF0, 0x0D}, - {0xF1, 0x32}, - {0xF0, 0x8E}, - {0xF0, 0x0E}, - {0xF1, 0x31}, - {0xF0, 0x8F}, - {0xF0, 0x0F}, - {0xF1, 0x30}, - {0xF0, 0x90}, - {0xF0, 0x10}, - {0xF1, 0x2F}, - {0xF0, 0x91}, - {0xF0, 0x11}, - {0xF1, 0x2F}, - {0xF0, 0x92}, - {0xF0, 0x12}, - {0xF1, 0x2E}, - {0xF0, 0x93}, - {0xF0, 0x13}, - {0xF1, 0x2D}, - {0xF0, 0x94}, - {0xF0, 0x14}, - {0xF1, 0x2C}, - {0xF0, 0x95}, - {0xF0, 0x15}, - {0xF1, 0x2B}, - {0xF0, 0x96}, - {0xF0, 0x16}, - {0xF1, 0x2B}, - {0xF0, 0x97}, - {0xF0, 0x17}, - {0xF1, 0x2A}, - {0xF0, 0x98}, - {0xF0, 0x18}, - {0xF1, 0x29}, - {0xF0, 0x99}, - {0xF0, 0x19}, - {0xF1, 0x28}, - {0xF0, 0x9A}, - {0xF0, 0x1A}, - {0xF1, 0x27}, - {0xF0, 0x9B}, - {0xF0, 0x1B}, - {0xF1, 0x26}, - {0xF0, 0x9C}, - {0xF0, 0x1C}, - {0xF1, 0x25}, - {0xF0, 0x9D}, - {0xF0, 0x1D}, - {0xF1, 0x24}, - {0xF0, 0x9E}, - {0xF0, 0x1E}, - {0xF1, 0x24}, - {0xF0, 0x9F}, - {0xF0, 0x1F}, - {0xF1, 0x23}, - {0xF0, 0xA0}, - {0xF0, 0x20}, - {0xF1, 0x22}, - {0xF0, 0xA1}, - {0xF0, 0x21}, - {0xF1, 0x21}, - {0xF0, 0xA2}, - {0xF0, 0x22}, - {0xF1, 0x20}, - {0xF0, 0xA3}, - {0xF0, 0x23}, - {0xF1, 0x20}, - {0xF0, 0xA4}, - {0xF0, 0x24}, - {0xF1, 0x1F}, - {0xF0, 0xA5}, - {0xF0, 0x25}, - {0xF1, 0x1E}, - {0xF0, 0xA6}, - {0xF0, 0x26}, - {0xF1, 0x1D}, - {0xF0, 0xA7}, - {0xF0, 0x27}, - {0xF1, 0x1C}, - {0xF0, 0xA8}, - {0xF0, 0x28}, - {0xF1, 0x1B}, - {0xF0, 0xA9}, - {0xF0, 0x29}, - {0xF1, 0x1B}, - {0xF0, 0xAA}, - {0xF0, 0x2A}, - {0xF1, 0x1A}, - {0xF0, 0xAB}, - {0xF0, 0x2B}, - {0xF1, 0x1A}, - {0xF0, 0xAC}, - {0xF0, 0x2C}, - {0xF1, 0x19}, - {0xF0, 0xAD}, - {0xF0, 0x2D}, - {0xF1, 0x18}, - {0xF0, 0xAE}, - {0xF0, 0x2E}, - {0xF1, 0x17}, - {0xF0, 0xAF}, - {0xF0, 0x2F}, - {0xF1, 0x16}, - {0xF0, 0xB0}, - {0xF0, 0x30}, - {0xF1, 0x15}, - {0xF0, 0xB1}, - {0xF0, 0x31}, - {0xF1, 0x15}, - {0xF0, 0xB2}, - {0xF0, 0x32}, - {0xF1, 0x15}, - {0xF0, 0xB3}, - {0xF0, 0x33}, - {0xF1, 0x14}, - {0xF0, 0xB4}, - {0xF0, 0x34}, - {0xF1, 0x13}, - {0xF0, 0xB5}, - {0xF0, 0x35}, - {0xF1, 0x12}, - {0xF0, 0xB6}, - {0xF0, 0x36}, - {0xF1, 0x11}, - {0xF0, 0xB7}, - {0xF0, 0x37}, - {0xF1, 0x10}, - {0xF0, 0xB8}, - {0xF0, 0x38}, - {0xF1, 0x0F}, - {0xF0, 0xB9}, - {0xF0, 0x39}, - {0xF1, 0x0E}, - {0xF0, 0xBA}, - {0xF0, 0x3A}, - {0xF1, 0x0D}, - {0xF0, 0xBB}, - {0xF0, 0x3B}, - {0xF1, 0x0C}, - {0xF0, 0xBC}, - {0xF0, 0x3C}, - {0xF1, 0x0B}, - {0xF0, 0xBD}, - {0xF0, 0x3D}, - {0xF1, 0x0B}, - {0xF0, 0xBE}, - {0xF0, 0x3E}, - {0xF1, 0x0A}, - {0xF0, 0xBF}, - {0xF0, 0x3F}, - {0xF1, 0x09}, - {0xF0, 0x00}, -}; - -#define CB_VT3253B0_INIT_FOR_AIROHA2230 256 -/* For AIROHA */ -static -unsigned char vt3253b0_airoha2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { - {0x00, 0x31}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x80}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x70}, - {0x09, 0x41}, - {0x0a, 0x2A}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x00}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x8f}, - {0x1c, 0x09}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0x4a}, - {0x2e, 0x00}, - {0x2f, 0x0a}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0x79}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x0b}, - {0x3e, 0x48}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x08}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x09}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x73}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x15}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0xe4}, - {0x61, 0x80}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0x98}, - {0x67, 0x0a}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - {0x6c, 0x00}, /* RobertYu:20050125, request by JJSue */ - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x8c}, - {0x81, 0x01}, - {0x82, 0x09}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x0f}, - {0x8b, 0xb7}, - {0x8c, 0x88}, - {0x8d, 0x47}, - {0x8e, 0xaa}, - {0x8f, 0x02}, - {0x90, 0x22}, - {0x91, 0x00}, - {0x92, 0x00}, - {0x93, 0x00}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xeb}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x01}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0x00}, - {0xa4, 0x00}, - {0xa5, 0x00}, - {0xa6, 0x10}, - {0xa7, 0x00}, - {0xa8, 0x18}, - {0xa9, 0x00}, - {0xaa, 0x00}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x18}, - {0xb0, 0x38}, - {0xb1, 0x30}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0xff}, - {0xb5, 0x0f}, - {0xb6, 0xe4}, - {0xb7, 0xe2}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x01}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x18}, - {0xc1, 0x20}, - {0xc2, 0x07}, - {0xc3, 0x18}, - {0xc4, 0xff}, - {0xc5, 0x2c}, - {0xc6, 0x0c}, - {0xc7, 0x0a}, - {0xc8, 0x0e}, - {0xc9, 0x01}, - {0xca, 0x68}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x10}, - {0xce, 0x00}, - {0xcf, 0x25}, - {0xd0, 0x40}, - {0xd1, 0x12}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x10}, - {0xd5, 0x28}, - {0xd6, 0x80}, - {0xd7, 0x2A}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0xB3}, - {0xe2, 0x00}, - {0xe3, 0x00}, - {0xe4, 0x00}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x1C}, - {0xe8, 0x00}, - {0xe9, 0xf4}, - {0xea, 0x00}, - {0xeb, 0xff}, - {0xec, 0x79}, - {0xed, 0x20}, - {0xee, 0x30}, - {0xef, 0x01}, - {0xf0, 0x00}, - {0xf1, 0x3e}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xfa, 0x00}, - {0xfb, 0x00}, - {0xfc, 0x00}, - {0xfd, 0x00}, - {0xfe, 0x00}, - {0xff, 0x00}, -}; - -#define CB_VT3253B0_INIT_FOR_UW2451 256 -/* For UW2451 */ -static unsigned char vt3253b0_uw2451[CB_VT3253B0_INIT_FOR_UW2451][2] = { - {0x00, 0x31}, - {0x01, 0x00}, - {0x02, 0x00}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x81}, - {0x06, 0x00}, - {0x07, 0x00}, - {0x08, 0x38}, - {0x09, 0x45}, - {0x0a, 0x28}, - {0x0b, 0x76}, - {0x0c, 0x00}, - {0x0d, 0x00}, - {0x0e, 0x80}, - {0x0f, 0x00}, - {0x10, 0x00}, - {0x11, 0x00}, - {0x12, 0x00}, - {0x13, 0x00}, - {0x14, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, - {0x17, 0x00}, - {0x18, 0x00}, - {0x19, 0x00}, - {0x1a, 0x00}, - {0x1b, 0x8f}, - {0x1c, 0x0f}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x00}, - {0x21, 0x00}, - {0x22, 0x00}, - {0x23, 0x00}, - {0x24, 0x00}, - {0x25, 0x4a}, - {0x26, 0x00}, - {0x27, 0x00}, - {0x28, 0x00}, - {0x29, 0x00}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x00}, - {0x2d, 0x18}, - {0x2e, 0x00}, - {0x2f, 0x0a}, - {0x30, 0x26}, - {0x31, 0x5b}, - {0x32, 0x00}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x00}, - {0x36, 0xaa}, - {0x37, 0xaa}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0x00}, - {0x3b, 0x00}, - {0x3c, 0x00}, - {0x3d, 0x03}, - {0x3e, 0x1d}, - {0x3f, 0x04}, - {0x40, 0x00}, - {0x41, 0x08}, - {0x42, 0x00}, - {0x43, 0x08}, - {0x44, 0x08}, - {0x45, 0x14}, - {0x46, 0x05}, - {0x47, 0x09}, - {0x48, 0x00}, - {0x49, 0x00}, - {0x4a, 0x00}, - {0x4b, 0x00}, - {0x4c, 0x09}, - {0x4d, 0x90}, - {0x4e, 0x00}, - {0x4f, 0xc5}, - {0x50, 0x15}, - {0x51, 0x19}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x56, 0x00}, - {0x57, 0x00}, - {0x58, 0x00}, - {0x59, 0xb0}, - {0x5a, 0x00}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e, 0x00}, - {0x5f, 0x00}, - {0x60, 0xb3}, - {0x61, 0x81}, - {0x62, 0x00}, - {0x63, 0x00}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0x57}, - {0x67, 0x6c}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - {0x6c, 0x00}, /* RobertYu:20050125, request by JJSue */ - {0x6d, 0x03}, - {0x6e, 0x01}, - {0x6f, 0x00}, - {0x70, 0x00}, - {0x71, 0x00}, - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x00}, - {0x75, 0x00}, - {0x76, 0x00}, - {0x77, 0x00}, - {0x78, 0x00}, - {0x79, 0x00}, - {0x7a, 0x00}, - {0x7b, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x00}, - {0x7e, 0x00}, - {0x7f, 0x00}, - {0x80, 0x8c}, - {0x81, 0x00}, - {0x82, 0x0e}, - {0x83, 0x00}, - {0x84, 0x00}, - {0x85, 0x00}, - {0x86, 0x00}, - {0x87, 0x00}, - {0x88, 0x08}, - {0x89, 0x00}, - {0x8a, 0x0e}, - {0x8b, 0xa7}, - {0x8c, 0x88}, - {0x8d, 0x47}, - {0x8e, 0xaa}, - {0x8f, 0x02}, - {0x90, 0x00}, - {0x91, 0x00}, - {0x92, 0x00}, - {0x93, 0x00}, - {0x94, 0x00}, - {0x95, 0x00}, - {0x96, 0x00}, - {0x97, 0xe3}, - {0x98, 0x00}, - {0x99, 0x00}, - {0x9a, 0x00}, - {0x9b, 0x00}, - {0x9c, 0x00}, - {0x9d, 0x00}, - {0x9e, 0x00}, - {0x9f, 0x00}, - {0xa0, 0x00}, - {0xa1, 0x00}, - {0xa2, 0x00}, - {0xa3, 0x00}, - {0xa4, 0x00}, - {0xa5, 0x00}, - {0xa6, 0x10}, - {0xa7, 0x00}, - {0xa8, 0x18}, - {0xa9, 0x00}, - {0xaa, 0x00}, - {0xab, 0x00}, - {0xac, 0x00}, - {0xad, 0x00}, - {0xae, 0x00}, - {0xaf, 0x18}, - {0xb0, 0x18}, - {0xb1, 0x30}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0x00}, - {0xb5, 0x00}, - {0xb6, 0x00}, - {0xb7, 0x00}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xba, 0x00}, - {0xbb, 0x03}, - {0xbc, 0x01}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc0, 0x10}, - {0xc1, 0x20}, - {0xc2, 0x00}, - {0xc3, 0x20}, - {0xc4, 0x00}, - {0xc5, 0x2c}, - {0xc6, 0x1c}, - {0xc7, 0x10}, - {0xc8, 0x10}, - {0xc9, 0x01}, - {0xca, 0x68}, - {0xcb, 0xa7}, - {0xcc, 0x3c}, - {0xcd, 0x09}, - {0xce, 0x00}, - {0xcf, 0x20}, - {0xd0, 0x40}, - {0xd1, 0x10}, - {0xd2, 0x00}, - {0xd3, 0x00}, - {0xd4, 0x20}, - {0xd5, 0x28}, - {0xd6, 0xa0}, - {0xd7, 0x2a}, - {0xd8, 0x00}, - {0xd9, 0x00}, - {0xda, 0x00}, - {0xdb, 0x00}, - {0xdc, 0x00}, - {0xdd, 0x00}, - {0xde, 0x00}, - {0xdf, 0x00}, - {0xe0, 0x00}, - {0xe1, 0xd3}, - {0xe2, 0xc0}, - {0xe3, 0x00}, - {0xe4, 0x00}, - {0xe5, 0x10}, - {0xe6, 0x00}, - {0xe7, 0x12}, - {0xe8, 0x12}, - {0xe9, 0x34}, - {0xea, 0x00}, - {0xeb, 0xff}, - {0xec, 0x79}, - {0xed, 0x20}, - {0xee, 0x30}, - {0xef, 0x01}, - {0xf0, 0x00}, - {0xf1, 0x3e}, - {0xf2, 0x00}, - {0xf3, 0x00}, - {0xf4, 0x00}, - {0xf5, 0x00}, - {0xf6, 0x00}, - {0xf7, 0x00}, - {0xf8, 0x00}, - {0xf9, 0x00}, - {0xfa, 0x00}, - {0xfb, 0x00}, - {0xfc, 0x00}, - {0xfd, 0x00}, - {0xfe, 0x00}, - {0xff, 0x00}, -}; - -#define CB_VT3253B0_AGC 193 -/* For AIROHA */ -static unsigned char vt3253b0_agc[CB_VT3253B0_AGC][2] = { - {0xF0, 0x00}, - {0xF1, 0x00}, - {0xF0, 0x80}, - {0xF0, 0x01}, - {0xF1, 0x00}, - {0xF0, 0x81}, - {0xF0, 0x02}, - {0xF1, 0x02}, - {0xF0, 0x82}, - {0xF0, 0x03}, - {0xF1, 0x04}, - {0xF0, 0x83}, - {0xF0, 0x03}, - {0xF1, 0x04}, - {0xF0, 0x84}, - {0xF0, 0x04}, - {0xF1, 0x06}, - {0xF0, 0x85}, - {0xF0, 0x05}, - {0xF1, 0x06}, - {0xF0, 0x86}, - {0xF0, 0x06}, - {0xF1, 0x06}, - {0xF0, 0x87}, - {0xF0, 0x07}, - {0xF1, 0x08}, - {0xF0, 0x88}, - {0xF0, 0x08}, - {0xF1, 0x08}, - {0xF0, 0x89}, - {0xF0, 0x09}, - {0xF1, 0x0A}, - {0xF0, 0x8A}, - {0xF0, 0x0A}, - {0xF1, 0x0A}, - {0xF0, 0x8B}, - {0xF0, 0x0B}, - {0xF1, 0x0C}, - {0xF0, 0x8C}, - {0xF0, 0x0C}, - {0xF1, 0x0C}, - {0xF0, 0x8D}, - {0xF0, 0x0D}, - {0xF1, 0x0E}, - {0xF0, 0x8E}, - {0xF0, 0x0E}, - {0xF1, 0x0E}, - {0xF0, 0x8F}, - {0xF0, 0x0F}, - {0xF1, 0x10}, - {0xF0, 0x90}, - {0xF0, 0x10}, - {0xF1, 0x10}, - {0xF0, 0x91}, - {0xF0, 0x11}, - {0xF1, 0x12}, - {0xF0, 0x92}, - {0xF0, 0x12}, - {0xF1, 0x12}, - {0xF0, 0x93}, - {0xF0, 0x13}, - {0xF1, 0x14}, - {0xF0, 0x94}, - {0xF0, 0x14}, - {0xF1, 0x14}, - {0xF0, 0x95}, - {0xF0, 0x15}, - {0xF1, 0x16}, - {0xF0, 0x96}, - {0xF0, 0x16}, - {0xF1, 0x16}, - {0xF0, 0x97}, - {0xF0, 0x17}, - {0xF1, 0x18}, - {0xF0, 0x98}, - {0xF0, 0x18}, - {0xF1, 0x18}, - {0xF0, 0x99}, - {0xF0, 0x19}, - {0xF1, 0x1A}, - {0xF0, 0x9A}, - {0xF0, 0x1A}, - {0xF1, 0x1A}, - {0xF0, 0x9B}, - {0xF0, 0x1B}, - {0xF1, 0x1C}, - {0xF0, 0x9C}, - {0xF0, 0x1C}, - {0xF1, 0x1C}, - {0xF0, 0x9D}, - {0xF0, 0x1D}, - {0xF1, 0x1E}, - {0xF0, 0x9E}, - {0xF0, 0x1E}, - {0xF1, 0x1E}, - {0xF0, 0x9F}, - {0xF0, 0x1F}, - {0xF1, 0x20}, - {0xF0, 0xA0}, - {0xF0, 0x20}, - {0xF1, 0x20}, - {0xF0, 0xA1}, - {0xF0, 0x21}, - {0xF1, 0x22}, - {0xF0, 0xA2}, - {0xF0, 0x22}, - {0xF1, 0x22}, - {0xF0, 0xA3}, - {0xF0, 0x23}, - {0xF1, 0x24}, - {0xF0, 0xA4}, - {0xF0, 0x24}, - {0xF1, 0x24}, - {0xF0, 0xA5}, - {0xF0, 0x25}, - {0xF1, 0x26}, - {0xF0, 0xA6}, - {0xF0, 0x26}, - {0xF1, 0x26}, - {0xF0, 0xA7}, - {0xF0, 0x27}, - {0xF1, 0x28}, - {0xF0, 0xA8}, - {0xF0, 0x28}, - {0xF1, 0x28}, - {0xF0, 0xA9}, - {0xF0, 0x29}, - {0xF1, 0x2A}, - {0xF0, 0xAA}, - {0xF0, 0x2A}, - {0xF1, 0x2A}, - {0xF0, 0xAB}, - {0xF0, 0x2B}, - {0xF1, 0x2C}, - {0xF0, 0xAC}, - {0xF0, 0x2C}, - {0xF1, 0x2C}, - {0xF0, 0xAD}, - {0xF0, 0x2D}, - {0xF1, 0x2E}, - {0xF0, 0xAE}, - {0xF0, 0x2E}, - {0xF1, 0x2E}, - {0xF0, 0xAF}, - {0xF0, 0x2F}, - {0xF1, 0x30}, - {0xF0, 0xB0}, - {0xF0, 0x30}, - {0xF1, 0x30}, - {0xF0, 0xB1}, - {0xF0, 0x31}, - {0xF1, 0x32}, - {0xF0, 0xB2}, - {0xF0, 0x32}, - {0xF1, 0x32}, - {0xF0, 0xB3}, - {0xF0, 0x33}, - {0xF1, 0x34}, - {0xF0, 0xB4}, - {0xF0, 0x34}, - {0xF1, 0x34}, - {0xF0, 0xB5}, - {0xF0, 0x35}, - {0xF1, 0x36}, - {0xF0, 0xB6}, - {0xF0, 0x36}, - {0xF1, 0x36}, - {0xF0, 0xB7}, - {0xF0, 0x37}, - {0xF1, 0x38}, - {0xF0, 0xB8}, - {0xF0, 0x38}, - {0xF1, 0x38}, - {0xF0, 0xB9}, - {0xF0, 0x39}, - {0xF1, 0x3A}, - {0xF0, 0xBA}, - {0xF0, 0x3A}, - {0xF1, 0x3A}, - {0xF0, 0xBB}, - {0xF0, 0x3B}, - {0xF1, 0x3C}, - {0xF0, 0xBC}, - {0xF0, 0x3C}, - {0xF1, 0x3C}, - {0xF0, 0xBD}, - {0xF0, 0x3D}, - {0xF1, 0x3E}, - {0xF0, 0xBE}, - {0xF0, 0x3E}, - {0xF1, 0x3E}, - {0xF0, 0xBF}, - {0xF0, 0x00}, -}; - -static const unsigned short awc_frame_time[MAX_RATE] = { - 10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216 -}; - -/*--------------------- Export Variables --------------------------*/ -/* - * Description: Calculate data frame transmitting time - * - * Parameters: - * In: - * preamble_type - Preamble Type - * by_pkt_type - PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA - * cb_frame_length - Baseband Type - * tx_rate - Tx Rate - * Out: - * - * Return Value: FrameTime - * - */ -unsigned int bb_get_frame_time(unsigned char preamble_type, - unsigned char by_pkt_type, - unsigned int cb_frame_length, - unsigned short tx_rate) -{ - unsigned int frame_time; - unsigned int preamble; - unsigned int tmp; - unsigned int rate_idx = (unsigned int)tx_rate; - unsigned int rate = 0; - - if (rate_idx > RATE_54M) - return 0; - - rate = (unsigned int)awc_frame_time[rate_idx]; - - if (rate_idx <= 3) { /* CCK mode */ - if (preamble_type == PREAMBLE_SHORT) - preamble = 96; - else - preamble = 192; - frame_time = (cb_frame_length * 80) / rate; /* ????? */ - tmp = (frame_time * rate) / 80; - if (cb_frame_length != tmp) - frame_time++; - - return preamble + frame_time; - } - frame_time = (cb_frame_length * 8 + 22) / rate; /* ???????? */ - tmp = ((frame_time * rate) - 22) / 8; - if (cb_frame_length != tmp) - frame_time++; - - frame_time = frame_time * 4; /* ??????? */ - if (by_pkt_type != PK_TYPE_11A) - frame_time += 6; /* ?????? */ - - return 20 + frame_time; /* ?????? */ -} - -/* - * Description: Calculate Length, Service, and Signal fields of Phy for Tx - * - * Parameters: - * In: - * priv - Device Structure - * frame_length - Tx Frame Length - * tx_rate - Tx Rate - * Out: - * struct vnt_phy_field *phy - * - pointer to Phy Length field - * - pointer to Phy Service field - * - pointer to Phy Signal field - * - * Return Value: none - * - */ -void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, - u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy) -{ - u32 bit_count; - u32 count = 0; - u32 tmp; - int ext_bit; - u8 preamble_type = priv->preamble_type; - - bit_count = frame_length * 8; - ext_bit = false; - - switch (tx_rate) { - case RATE_1M: - count = bit_count; - - phy->signal = 0x00; - - break; - case RATE_2M: - count = bit_count / 2; - - if (preamble_type == PREAMBLE_SHORT) - phy->signal = 0x09; - else - phy->signal = 0x01; - - break; - case RATE_5M: - count = (bit_count * 10) / 55; - tmp = (count * 55) / 10; - - if (tmp != bit_count) - count++; - - if (preamble_type == PREAMBLE_SHORT) - phy->signal = 0x0a; - else - phy->signal = 0x02; - - break; - case RATE_11M: - count = bit_count / 11; - tmp = count * 11; - - if (tmp != bit_count) { - count++; - - if ((bit_count - tmp) <= 3) - ext_bit = true; - } - - if (preamble_type == PREAMBLE_SHORT) - phy->signal = 0x0b; - else - phy->signal = 0x03; - - break; - case RATE_6M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x9b; - else - phy->signal = 0x8b; - - break; - case RATE_9M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x9f; - else - phy->signal = 0x8f; - - break; - case RATE_12M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x9a; - else - phy->signal = 0x8a; - - break; - case RATE_18M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x9e; - else - phy->signal = 0x8e; - - break; - case RATE_24M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x99; - else - phy->signal = 0x89; - - break; - case RATE_36M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x9d; - else - phy->signal = 0x8d; - - break; - case RATE_48M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x98; - else - phy->signal = 0x88; - - break; - case RATE_54M: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x9c; - else - phy->signal = 0x8c; - break; - default: - if (pkt_type == PK_TYPE_11A) - phy->signal = 0x9c; - else - phy->signal = 0x8c; - break; - } - - if (pkt_type == PK_TYPE_11B) { - phy->service = 0x00; - if (ext_bit) - phy->service |= 0x80; - phy->len = cpu_to_le16((u16)count); - } else { - phy->service = 0x00; - phy->len = cpu_to_le16((u16)frame_length); - } -} - -/* - * Description: Read a byte from BASEBAND, by embedded programming - * - * Parameters: - * In: - * iobase - I/O base address - * by_bb_addr - address of register in Baseband - * Out: - * pby_data - data read - * - * Return Value: true if succeeded; false if failed. - * - */ -bool bb_read_embedded(struct vnt_private *priv, unsigned char by_bb_addr, - unsigned char *pby_data) -{ - void __iomem *iobase = priv->port_offset; - unsigned short ww; - unsigned char by_value; - - /* BB reg offset */ - iowrite8(by_bb_addr, iobase + MAC_REG_BBREGADR); - - /* turn on REGR */ - vt6655_mac_reg_bits_on(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGR); - /* W_MAX_TIMEOUT is the timeout period */ - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - by_value = ioread8(iobase + MAC_REG_BBREGCTL); - if (by_value & BBREGCTL_DONE) - break; - } - - /* get BB data */ - *pby_data = ioread8(iobase + MAC_REG_BBREGDATA); - - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x30)\n"); - return false; - } - return true; -} - -/* - * Description: Write a Byte to BASEBAND, by embedded programming - * - * Parameters: - * In: - * iobase - I/O base address - * by_bb_addr - address of register in Baseband - * by_data - data to write - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ -bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr, - unsigned char by_data) -{ - void __iomem *iobase = priv->port_offset; - unsigned short ww; - unsigned char by_value; - - /* BB reg offset */ - iowrite8(by_bb_addr, iobase + MAC_REG_BBREGADR); - /* set BB data */ - iowrite8(by_data, iobase + MAC_REG_BBREGDATA); - - /* turn on BBREGCTL_REGW */ - vt6655_mac_reg_bits_on(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGW); - /* W_MAX_TIMEOUT is the timeout period */ - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - by_value = ioread8(iobase + MAC_REG_BBREGCTL); - if (by_value & BBREGCTL_DONE) - break; - } - - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x31)\n"); - return false; - } - return true; -} - -/* - * Description: VIA VT3253 Baseband chip init function - * - * Parameters: - * In: - * iobase - I/O base address - * byRevId - Revision ID - * rf_type - RF type - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -bool bb_vt3253_init(struct vnt_private *priv) -{ - bool result = true; - int ii; - void __iomem *iobase = priv->port_offset; - unsigned char rf_type = priv->rf_type; - unsigned char by_local_id = priv->local_id; - - if (rf_type == RF_RFMD2959) { - if (by_local_id <= REV_ID_VT3253_A1) { - for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) - result &= bb_write_embedded(priv, - by_vt3253_init_tab_rfmd[ii][0], - by_vt3253_init_tab_rfmd[ii][1]); - - } else { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++) - result &= bb_write_embedded(priv, - vt3253b0_rfmd[ii][0], - vt3253b0_rfmd[ii][1]); - - for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) - result &= bb_write_embedded(priv, - vt3253b0_agc4_rfmd2959[ii][0], - vt3253b0_agc4_rfmd2959[ii][1]); - - iowrite32(0x23, iobase + MAC_REG_ITRTMSET); - vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0)); - } - priv->bbvga[0] = 0x18; - priv->bbvga[1] = 0x0A; - priv->bbvga[2] = 0x0; - priv->bbvga[3] = 0x0; - priv->dbm_threshold[0] = -70; - priv->dbm_threshold[1] = -50; - priv->dbm_threshold[2] = 0; - priv->dbm_threshold[3] = 0; - } else if ((rf_type == RF_AIROHA) || (rf_type == RF_AL2230S)) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - result &= bb_write_embedded(priv, - vt3253b0_airoha2230[ii][0], - vt3253b0_airoha2230[ii][1]); - - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - result &= bb_write_embedded(priv, - vt3253b0_agc[ii][0], vt3253b0_agc[ii][1]); - - priv->bbvga[0] = 0x1C; - priv->bbvga[1] = 0x10; - priv->bbvga[2] = 0x0; - priv->bbvga[3] = 0x0; - priv->dbm_threshold[0] = -70; - priv->dbm_threshold[1] = -48; - priv->dbm_threshold[2] = 0; - priv->dbm_threshold[3] = 0; - } else if (rf_type == RF_UW2451) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) - result &= bb_write_embedded(priv, - vt3253b0_uw2451[ii][0], - vt3253b0_uw2451[ii][1]); - - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - result &= bb_write_embedded(priv, - vt3253b0_agc[ii][0], - vt3253b0_agc[ii][1]); - - iowrite8(0x23, iobase + MAC_REG_ITRTMSET); - vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0)); - - priv->bbvga[0] = 0x14; - priv->bbvga[1] = 0x0A; - priv->bbvga[2] = 0x0; - priv->bbvga[3] = 0x0; - priv->dbm_threshold[0] = -60; - priv->dbm_threshold[1] = -50; - priv->dbm_threshold[2] = 0; - priv->dbm_threshold[3] = 0; - } else if (rf_type == RF_VT3226) { - for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - result &= bb_write_embedded(priv, - vt3253b0_airoha2230[ii][0], - vt3253b0_airoha2230[ii][1]); - - for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - result &= bb_write_embedded(priv, - vt3253b0_agc[ii][0], vt3253b0_agc[ii][1]); - - priv->bbvga[0] = 0x1C; - priv->bbvga[1] = 0x10; - priv->bbvga[2] = 0x0; - priv->bbvga[3] = 0x0; - priv->dbm_threshold[0] = -70; - priv->dbm_threshold[1] = -48; - priv->dbm_threshold[2] = 0; - priv->dbm_threshold[3] = 0; - /* Fix VT3226 DFC system timing issue */ - vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT); - /* {{ RobertYu: 20050104 */ - } else { - /* No VGA Table now */ - priv->update_bbvga = false; - priv->bbvga[0] = 0x1C; - } - - if (by_local_id > REV_ID_VT3253_A1) { - bb_write_embedded(priv, 0x04, 0x7F); - bb_write_embedded(priv, 0x0D, 0x01); - } - - return result; -} - -/* - * Description: Set ShortSlotTime mode - * - * Parameters: - * In: - * priv - Device Structure - * Out: - * none - * - * Return Value: none - * - */ -void -bb_set_short_slot_time(struct vnt_private *priv) -{ - unsigned char by_bb_rx_conf = 0; - unsigned char by_bb_vga = 0; - - bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */ - - if (priv->short_slot_time) - by_bb_rx_conf &= 0xDF; /* 1101 1111 */ - else - by_bb_rx_conf |= 0x20; /* 0010 0000 */ - - /* patch for 3253B0 Baseband with Cardbus module */ - bb_read_embedded(priv, 0xE7, &by_bb_vga); - if (by_bb_vga == priv->bbvga[0]) - by_bb_rx_conf |= 0x20; /* 0010 0000 */ - - bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */ -} - -void bb_set_vga_gain_offset(struct vnt_private *priv, unsigned char by_data) -{ - unsigned char by_bb_rx_conf = 0; - - bb_write_embedded(priv, 0xE7, by_data); - - bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */ - /* patch for 3253B0 Baseband with Cardbus module */ - if (by_data == priv->bbvga[0]) - by_bb_rx_conf |= 0x20; /* 0010 0000 */ - else if (priv->short_slot_time) - by_bb_rx_conf &= 0xDF; /* 1101 1111 */ - else - by_bb_rx_conf |= 0x20; /* 0010 0000 */ - priv->bbvga_current = by_data; - bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */ -} - -/* - * Description: Baseband SoftwareReset - * - * Parameters: - * In: - * iobase - I/O base address - * Out: - * none - * - * Return Value: none - * - */ -void -bb_software_reset(struct vnt_private *priv) -{ - bb_write_embedded(priv, 0x50, 0x40); - bb_write_embedded(priv, 0x50, 0); - bb_write_embedded(priv, 0x9C, 0x01); - bb_write_embedded(priv, 0x9C, 0); -} - -/* - * Description: Set Tx Antenna mode - * - * Parameters: - * In: - * priv - Device Structure - * by_antenna_mode - Antenna Mode - * Out: - * none - * - * Return Value: none - * - */ - -void -bb_set_tx_antenna_mode(struct vnt_private *priv, unsigned char by_antenna_mode) -{ - unsigned char by_bb_tx_conf; - - bb_read_embedded(priv, 0x09, &by_bb_tx_conf); /* CR09 */ - if (by_antenna_mode == ANT_DIVERSITY) { - /* bit 1 is diversity */ - by_bb_tx_conf |= 0x02; - } else if (by_antenna_mode == ANT_A) { - /* bit 2 is ANTSEL */ - by_bb_tx_conf &= 0xF9; /* 1111 1001 */ - } else if (by_antenna_mode == ANT_B) { - by_bb_tx_conf &= 0xFD; /* 1111 1101 */ - by_bb_tx_conf |= 0x04; - } - bb_write_embedded(priv, 0x09, by_bb_tx_conf); /* CR09 */ -} - -/* - * Description: Set Rx Antenna mode - * - * Parameters: - * In: - * priv - Device Structure - * by_antenna_mode - Antenna Mode - * Out: - * none - * - * Return Value: none - * - */ - -void -bb_set_rx_antenna_mode(struct vnt_private *priv, unsigned char by_antenna_mode) -{ - unsigned char by_bb_rx_conf; - - bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */ - if (by_antenna_mode == ANT_DIVERSITY) { - by_bb_rx_conf |= 0x01; - - } else if (by_antenna_mode == ANT_A) { - by_bb_rx_conf &= 0xFC; /* 1111 1100 */ - } else if (by_antenna_mode == ANT_B) { - by_bb_rx_conf &= 0xFE; /* 1111 1110 */ - by_bb_rx_conf |= 0x02; - } - bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */ -} - -/* - * Description: bb_set_deep_sleep - * - * Parameters: - * In: - * priv - Device Structure - * Out: - * none - * - * Return Value: none - * - */ -void -bb_set_deep_sleep(struct vnt_private *priv, unsigned char by_local_id) -{ - bb_write_embedded(priv, 0x0C, 0x17); /* CR12 */ - bb_write_embedded(priv, 0x0D, 0xB9); /* CR13 */ -} - diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h deleted file mode 100644 index e4a02c240a1c1c3f453229ef7538b4be8568ef94..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/baseband.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions to access baseband - * - * Author: Jerry Chen - * - * Date: Jun. 5, 2002 - * - */ - -#ifndef __BASEBAND_H__ -#define __BASEBAND_H__ - -#include "device.h" - -/* - * Registers in the BASEBAND - */ -#define BB_MAX_CONTEXT_SIZE 256 - -/* - * Baseband RF pair definition in eeprom (Bits 6..0) - */ - -#define PREAMBLE_LONG 0 -#define PREAMBLE_SHORT 1 - -#define F5G 0 -#define F2_4G 1 - -#define TOP_RATE_54M 0x80000000 -#define TOP_RATE_48M 0x40000000 -#define TOP_RATE_36M 0x20000000 -#define TOP_RATE_24M 0x10000000 -#define TOP_RATE_18M 0x08000000 -#define TOP_RATE_12M 0x04000000 -#define TOP_RATE_11M 0x02000000 -#define TOP_RATE_9M 0x01000000 -#define TOP_RATE_6M 0x00800000 -#define TOP_RATE_55M 0x00400000 -#define TOP_RATE_2M 0x00200000 -#define TOP_RATE_1M 0x00100000 - -unsigned int bb_get_frame_time(unsigned char preamble_type, - unsigned char by_pkt_type, - unsigned int cb_frame_length, - unsigned short w_rate); - -void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, - u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy); - -bool bb_read_embedded(struct vnt_private *priv, unsigned char by_bb_addr, - unsigned char *pby_data); -bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr, - unsigned char by_data); - -void bb_set_short_slot_time(struct vnt_private *priv); -void bb_set_vga_gain_offset(struct vnt_private *priv, unsigned char by_data); - -/* VT3253 Baseband */ -bool bb_vt3253_init(struct vnt_private *priv); -void bb_software_reset(struct vnt_private *priv); -void bb_set_tx_antenna_mode(struct vnt_private *priv, - unsigned char by_antenna_mode); -void bb_set_rx_antenna_mode(struct vnt_private *priv, - unsigned char by_antenna_mode); -void bb_set_deep_sleep(struct vnt_private *priv, unsigned char by_local_id); - -#endif /* __BASEBAND_H__ */ diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c deleted file mode 100644 index 6a2e390e94939a9c6e0181f920de4d550c4c772c..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/card.c +++ /dev/null @@ -1,836 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Provide functions to setup NIC operation mode - * Functions: - * s_vSafeResetTx - Rest Tx - * card_set_rspinf - Set RSPINF - * CARDvUpdateBasicTopRate - Update BasicTopRate - * CARDbAddBasicRate - Add to BasicRateSet - * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet - * card_get_tsf_offset - Calculate TSFOffset - * vt6655_get_current_tsf - Read Current NIC TSF counter - * card_get_next_tbtt - Calculate Next Beacon TSF counter - * CARDvSetFirstNextTBTT - Set NIC Beacon time - * CARDvUpdateNextTBTT - Sync. NIC Beacon time - * card_radio_power_off - Turn Off NIC Radio Power - * - * Revision History: - * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. - * 08-26-2003 Kyle Hsu: Modify the definition type of iobase. - * 09-01-2003 Bryan YC Fan: Add vUpdateIFS(). - * - */ - -#include "card.h" -#include "baseband.h" -#include "mac.h" -#include "desc.h" -#include "rf.h" -#include "power.h" - -/*--------------------- Static Definitions -------------------------*/ - -#define C_SIFS_A 16 /* micro sec. */ -#define C_SIFS_BG 10 - -#define C_EIFS 80 /* micro sec. */ - -#define C_SLOT_SHORT 9 /* micro sec. */ -#define C_SLOT_LONG 20 - -#define C_CWMIN_A 15 /* slot time */ -#define C_CWMIN_B 31 - -#define C_CWMAX 1023 /* slot time */ - -#define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */ - -/*--------------------- Static Variables --------------------------*/ - -static const unsigned short rx_bcn_tsf_off[MAX_RATE] = { - 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3}; - -/*--------------------- Static Functions --------------------------*/ - -static void vt6655_mac_set_bb_type(void __iomem *iobase, u32 mask) -{ - u32 reg_value; - - reg_value = ioread32(iobase + MAC_REG_ENCFG); - reg_value = reg_value & ~ENCFG_BBTYPE_MASK; - reg_value = reg_value | mask; - iowrite32(reg_value, iobase + MAC_REG_ENCFG); -} - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. - * - * Parameters: - * In: - * wRate - Tx Rate - * byPktType - Tx Packet type - * Out: - * tx_rate - pointer to RSPINF TxRate field - * rsv_time - pointer to RSPINF RsvTime field - * - * Return Value: none - */ -static void calculate_ofdmr_parameter(unsigned char rate, - u8 bb_type, - unsigned char *tx_rate, - unsigned char *rsv_time) -{ - switch (rate) { - case RATE_6M: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x9B; - *rsv_time = 44; - } else { - *tx_rate = 0x8B; - *rsv_time = 50; - } - break; - - case RATE_9M: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x9F; - *rsv_time = 36; - } else { - *tx_rate = 0x8F; - *rsv_time = 42; - } - break; - - case RATE_12M: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x9A; - *rsv_time = 32; - } else { - *tx_rate = 0x8A; - *rsv_time = 38; - } - break; - - case RATE_18M: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x9E; - *rsv_time = 28; - } else { - *tx_rate = 0x8E; - *rsv_time = 34; - } - break; - - case RATE_36M: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x9D; - *rsv_time = 24; - } else { - *tx_rate = 0x8D; - *rsv_time = 30; - } - break; - - case RATE_48M: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x98; - *rsv_time = 24; - } else { - *tx_rate = 0x88; - *rsv_time = 30; - } - break; - - case RATE_54M: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x9C; - *rsv_time = 24; - } else { - *tx_rate = 0x8C; - *rsv_time = 30; - } - break; - - case RATE_24M: - default: - if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *tx_rate = 0x99; - *rsv_time = 28; - } else { - *tx_rate = 0x89; - *rsv_time = 34; - } - break; - } -} - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: Update IFS - * - * Parameters: - * In: - * priv - The adapter to be set - * Out: - * none - * - * Return Value: None. - */ -bool card_set_phy_parameter(struct vnt_private *priv, u8 bb_type) -{ - unsigned char cw_max_min = 0; - unsigned char slot = 0; - unsigned char sifs = 0; - unsigned char difs = 0; - int i; - - /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ - if (bb_type == BB_TYPE_11A) { - vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11A); - bb_write_embedded(priv, 0x88, 0x03); - slot = C_SLOT_SHORT; - sifs = C_SIFS_A; - difs = C_SIFS_A + 2 * C_SLOT_SHORT; - cw_max_min = 0xA4; - } else if (bb_type == BB_TYPE_11B) { - vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11B); - bb_write_embedded(priv, 0x88, 0x02); - slot = C_SLOT_LONG; - sifs = C_SIFS_BG; - difs = C_SIFS_BG + 2 * C_SLOT_LONG; - cw_max_min = 0xA5; - } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ - vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11G); - bb_write_embedded(priv, 0x88, 0x08); - sifs = C_SIFS_BG; - - if (priv->short_slot_time) { - slot = C_SLOT_SHORT; - difs = C_SIFS_BG + 2 * C_SLOT_SHORT; - } else { - slot = C_SLOT_LONG; - difs = C_SIFS_BG + 2 * C_SLOT_LONG; - } - - cw_max_min = 0xa4; - - for (i = RATE_54M; i >= RATE_6M; i--) { - if (priv->basic_rates & ((u32)(0x1 << i))) { - cw_max_min |= 0x1; - break; - } - } - } - - if (priv->rf_type == RF_RFMD2959) { - /* - * bcs TX_PE will reserve 3 us hardware's processing - * time here is 2 us. - */ - sifs -= 3; - difs -= 3; - /* - * TX_PE will reserve 3 us for MAX2829 A mode only, it is for - * better TX throughput; MAC will need 2 us to process, so the - * SIFS, DIFS can be shorter by 2 us. - */ - } - - if (priv->sifs != sifs) { - priv->sifs = sifs; - iowrite8(priv->sifs, priv->port_offset + MAC_REG_SIFS); - } - if (priv->difs != difs) { - priv->difs = difs; - iowrite8(priv->difs, priv->port_offset + MAC_REG_DIFS); - } - if (priv->eifs != C_EIFS) { - priv->eifs = C_EIFS; - iowrite8(priv->eifs, priv->port_offset + MAC_REG_EIFS); - } - if (priv->slot != slot) { - priv->slot = slot; - iowrite8(priv->slot, priv->port_offset + MAC_REG_SLOT); - - bb_set_short_slot_time(priv); - } - if (priv->cw_max_min != cw_max_min) { - priv->cw_max_min = cw_max_min; - iowrite8(priv->cw_max_min, priv->port_offset + MAC_REG_CWMAXMIN0); - } - - priv->packet_type = card_get_pkt_type(priv); - - card_set_rspinf(priv, bb_type); - - return true; -} - -/* - * Description: Sync. TSF counter to BSS - * Get TSF offset and write to HW - * - * Parameters: - * In: - * priv - The adapter to be sync. - * rx_rate - data rate of receive beacon - * bss_timestamp - Rx BCN's TSF - * qwLocalTSF - Local TSF - * Out: - * none - * - * Return Value: none - */ -bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate, - u64 bss_timestamp) -{ - u64 local_tsf; - u64 tsf_offset = 0; - - local_tsf = vt6655_get_current_tsf(priv); - - if (bss_timestamp != local_tsf) { - tsf_offset = card_get_tsf_offset(rx_rate, bss_timestamp, - local_tsf); - /* adjust TSF, HW's TSF add TSF Offset reg */ - tsf_offset = le64_to_cpu(tsf_offset); - iowrite32((u32)tsf_offset, priv->port_offset + MAC_REG_TSFOFST); - iowrite32((u32)(tsf_offset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4); - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); - } - return true; -} - -/* - * Description: Set NIC TSF counter for first Beacon time - * Get NEXTTBTT from adjusted TSF and Beacon Interval - * - * Parameters: - * In: - * priv - The adapter to be set. - * beacon_interval - Beacon Interval - * Out: - * none - * - * Return Value: true if succeed; otherwise false - */ -bool card_set_beacon_period(struct vnt_private *priv, - unsigned short beacon_interval) -{ - u64 next_tbtt; - - next_tbtt = vt6655_get_current_tsf(priv); /* Get Local TSF counter */ - - next_tbtt = card_get_next_tbtt(next_tbtt, beacon_interval); - - /* set HW beacon interval */ - iowrite16(beacon_interval, priv->port_offset + MAC_REG_BI); - priv->beacon_interval = beacon_interval; - /* Set NextTBTT */ - next_tbtt = le64_to_cpu(next_tbtt); - iowrite32((u32)next_tbtt, priv->port_offset + MAC_REG_NEXTTBTT); - iowrite32((u32)(next_tbtt >> 32), priv->port_offset + MAC_REG_NEXTTBTT + 4); - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); - - return true; -} - -/* - * Description: Turn off Radio power - * - * Parameters: - * In: - * priv - The adapter to be turned off - * Out: - * none - * - */ -void card_radio_power_off(struct vnt_private *priv) -{ - if (priv->radio_off) - return; - - switch (priv->rf_type) { - case RF_RFMD2959: - vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL, - SOFTPWRCTL_TXPEINV); - vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_SOFTPWRCTL, - SOFTPWRCTL_SWPE1); - break; - - case RF_AIROHA: - case RF_AL2230S: - vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL, - SOFTPWRCTL_SWPE2); - vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL, - SOFTPWRCTL_SWPE3); - break; - } - - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON); - - bb_set_deep_sleep(priv, priv->local_id); - - priv->radio_off = true; - pr_debug("chester power off\n"); - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ -} - -void card_safe_reset_tx(struct vnt_private *priv) -{ - unsigned int uu; - struct vnt_tx_desc *curr_td; - - /* initialize TD index */ - priv->tail_td[0] = &priv->ap_td0_rings[0]; - priv->apCurrTD[0] = &priv->ap_td0_rings[0]; - - priv->tail_td[1] = &priv->ap_td1_rings[0]; - priv->apCurrTD[1] = &priv->ap_td1_rings[0]; - - for (uu = 0; uu < TYPE_MAXTD; uu++) - priv->iTDUsed[uu] = 0; - - for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) { - curr_td = &priv->ap_td0_rings[uu]; - curr_td->td0.owner = OWNED_BY_HOST; - /* init all Tx Packet pointer to NULL */ - } - for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) { - curr_td = &priv->ap_td1_rings[uu]; - curr_td->td0.owner = OWNED_BY_HOST; - /* init all Tx Packet pointer to NULL */ - } - - /* set MAC TD pointer */ - vt6655_mac_set_curr_tx_desc_addr(TYPE_TXDMA0, priv, priv->td0_pool_dma); - - vt6655_mac_set_curr_tx_desc_addr(TYPE_AC0DMA, priv, priv->td1_pool_dma); - - /* set MAC Beacon TX pointer */ - iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR); -} - -/* - * Description: - * Reset Rx - * - * Parameters: - * In: - * priv - Pointer to the adapter - * Out: - * none - * - * Return Value: none - */ -void CARDvSafeResetRx(struct vnt_private *priv) -{ - unsigned int uu; - struct vnt_rx_desc *pDesc; - - /* initialize RD index */ - priv->pCurrRD[0] = &priv->aRD0Ring[0]; - priv->pCurrRD[1] = &priv->aRD1Ring[0]; - - /* init state, all RD is chip's */ - for (uu = 0; uu < priv->opts.rx_descs0; uu++) { - pDesc = &priv->aRD0Ring[uu]; - pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); - pDesc->rd0.owner = OWNED_BY_NIC; - pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); - } - - /* init state, all RD is chip's */ - for (uu = 0; uu < priv->opts.rx_descs1; uu++) { - pDesc = &priv->aRD1Ring[uu]; - pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); - pDesc->rd0.owner = OWNED_BY_NIC; - pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); - } - - /* set perPkt mode */ - iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL0); - iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL1); - /* set MAC RD pointer */ - vt6655_mac_set_curr_rx_0_desc_addr(priv, priv->rd0_pool_dma); - - vt6655_mac_set_curr_rx_1_desc_addr(priv, priv->rd1_pool_dma); -} - -/* - * Description: Get response Control frame rate in CCK mode - * - * Parameters: - * In: - * priv - The adapter to be set - * wRateIdx - Receiving data rate - * Out: - * none - * - * Return Value: response Control frame rate - */ -static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv, - unsigned short wRateIdx) -{ - unsigned int ui = (unsigned int)wRateIdx; - - while (ui > RATE_1M) { - if (priv->basic_rates & ((u32)0x1 << ui)) - return (unsigned short)ui; - - ui--; - } - return (unsigned short)RATE_1M; -} - -/* - * Description: Get response Control frame rate in OFDM mode - * - * Parameters: - * In: - * priv - The adapter to be set - * wRateIdx - Receiving data rate - * Out: - * none - * - * Return Value: response Control frame rate - */ -static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv, - unsigned short wRateIdx) -{ - unsigned int ui = (unsigned int)wRateIdx; - - pr_debug("BASIC RATE: %X\n", priv->basic_rates); - - if (!CARDbIsOFDMinBasicRate((void *)priv)) { - pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx); - if (wRateIdx > RATE_24M) - wRateIdx = RATE_24M; - return wRateIdx; - } - while (ui > RATE_11M) { - if (priv->basic_rates & ((u32)0x1 << ui)) { - pr_debug("%s : %d\n", __func__, ui); - return (unsigned short)ui; - } - ui--; - } - pr_debug("%s: 6M\n", __func__); - return (unsigned short)RATE_24M; -} - -/* - * Description: Set RSPINF - * - * Parameters: - * In: - * priv - The adapter to be set - * Out: - * none - * - * Return Value: None. - */ -void card_set_rspinf(struct vnt_private *priv, u8 bb_type) -{ - union vnt_phy_field_swap phy; - unsigned char byTxRate, byRsvTime; /* For OFDM */ - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - /* Set to Page1 */ - VT6655_MAC_SELECT_PAGE1(priv->port_offset); - - /* RSPINF_b_1 */ - vnt_get_phy_field(priv, 14, - CARDwGetCCKControlRate(priv, RATE_1M), - PK_TYPE_11B, &phy.field_read); - - /* swap over to get correct write order */ - swap(phy.swap[0], phy.swap[1]); - - iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_1); - - /* RSPINF_b_2 */ - vnt_get_phy_field(priv, 14, - CARDwGetCCKControlRate(priv, RATE_2M), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_2); - - /* RSPINF_b_5 */ - vnt_get_phy_field(priv, 14, - CARDwGetCCKControlRate(priv, RATE_5M), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_5); - - /* RSPINF_b_11 */ - vnt_get_phy_field(priv, 14, - CARDwGetCCKControlRate(priv, RATE_11M), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11); - - /* RSPINF_a_6 */ - calculate_ofdmr_parameter(RATE_6M, - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6); - /* RSPINF_a_9 */ - calculate_ofdmr_parameter(RATE_9M, - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9); - /* RSPINF_a_12 */ - calculate_ofdmr_parameter(RATE_12M, - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12); - /* RSPINF_a_18 */ - calculate_ofdmr_parameter(RATE_18M, - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18); - /* RSPINF_a_24 */ - calculate_ofdmr_parameter(RATE_24M, - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24); - /* RSPINF_a_36 */ - calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, - RATE_36M), - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36); - /* RSPINF_a_48 */ - calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, - RATE_48M), - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48); - /* RSPINF_a_54 */ - calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, - RATE_54M), - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54); - /* RSPINF_a_72 */ - calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, - RATE_54M), - bb_type, - &byTxRate, - &byRsvTime); - iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_72); - /* Set to Page0 */ - VT6655_MAC_SELECT_PAGE0(priv->port_offset); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -void CARDvUpdateBasicTopRate(struct vnt_private *priv) -{ - unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; - unsigned char ii; - - /* Determines the highest basic rate. */ - for (ii = RATE_54M; ii >= RATE_6M; ii--) { - if ((priv->basic_rates) & ((u32)(1 << ii))) { - byTopOFDM = ii; - break; - } - } - priv->byTopOFDMBasicRate = byTopOFDM; - - for (ii = RATE_11M;; ii--) { - if ((priv->basic_rates) & ((u32)(1 << ii))) { - byTopCCK = ii; - break; - } - if (ii == RATE_1M) - break; - } - priv->byTopCCKBasicRate = byTopCCK; -} - -bool CARDbIsOFDMinBasicRate(struct vnt_private *priv) -{ - int ii; - - for (ii = RATE_54M; ii >= RATE_6M; ii--) { - if ((priv->basic_rates) & ((u32)BIT(ii))) - return true; - } - return false; -} - -unsigned char card_get_pkt_type(struct vnt_private *priv) -{ - if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B) - return (unsigned char)priv->byBBType; - else if (CARDbIsOFDMinBasicRate((void *)priv)) - return PK_TYPE_11GA; - else - return PK_TYPE_11GB; -} - -/* - * Description: Calculate TSF offset of two TSF input - * Get TSF Offset from RxBCN's TSF and local TSF - * - * Parameters: - * In: - * priv - The adapter to be sync. - * qwTSF1 - Rx BCN's TSF - * qwTSF2 - Local TSF - * Out: - * none - * - * Return Value: TSF Offset value - */ -u64 card_get_tsf_offset(unsigned char rx_rate, u64 qwTSF1, u64 qwTSF2) -{ - unsigned short wRxBcnTSFOffst; - - wRxBcnTSFOffst = rx_bcn_tsf_off[rx_rate % MAX_RATE]; - - qwTSF2 += (u64)wRxBcnTSFOffst; - - return qwTSF1 - qwTSF2; -} - -/* - * Description: Read NIC TSF counter - * Get local TSF counter - * - * Parameters: - * In: - * priv - The adapter to be read - * Out: - * none - * - * Return Value: Current TSF counter - */ -u64 vt6655_get_current_tsf(struct vnt_private *priv) -{ - void __iomem *iobase = priv->port_offset; - unsigned short ww; - unsigned char data; - u32 low, high; - - vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - data = ioread8(iobase + MAC_REG_TFTCTL); - if (!(data & TFTCTL_TSFCNTRRD)) - break; - } - if (ww == W_MAX_TIMEOUT) - return 0; - low = ioread32(iobase + MAC_REG_TSFCNTR); - high = ioread32(iobase + MAC_REG_TSFCNTR + 4); - return le64_to_cpu(low + ((u64)high << 32)); -} - -/* - * Description: Read NIC TSF counter - * Get NEXTTBTT from adjusted TSF and Beacon Interval - * - * Parameters: - * In: - * qwTSF - Current TSF counter - * wbeaconInterval - Beacon Interval - * Out: - * qwCurrTSF - Current TSF counter - * - * Return Value: TSF value of next Beacon - */ -u64 card_get_next_tbtt(u64 qwTSF, unsigned short beacon_interval) -{ - u32 beacon_int; - - beacon_int = beacon_interval * 1024; - if (beacon_int) { - do_div(qwTSF, beacon_int); - qwTSF += 1; - qwTSF *= beacon_int; - } - - return qwTSF; -} - -/* - * Description: Set NIC TSF counter for first Beacon time - * Get NEXTTBTT from adjusted TSF and Beacon Interval - * - * Parameters: - * In: - * iobase - IO Base - * beacon_interval - Beacon Interval - * Out: - * none - * - * Return Value: none - */ -void CARDvSetFirstNextTBTT(struct vnt_private *priv, - unsigned short beacon_interval) -{ - void __iomem *iobase = priv->port_offset; - u64 next_tbtt; - - next_tbtt = vt6655_get_current_tsf(priv); /* Get Local TSF counter */ - - next_tbtt = card_get_next_tbtt(next_tbtt, beacon_interval); - /* Set NextTBTT */ - next_tbtt = le64_to_cpu(next_tbtt); - iowrite32((u32)next_tbtt, iobase + MAC_REG_NEXTTBTT); - iowrite32((u32)(next_tbtt >> 32), iobase + MAC_REG_NEXTTBTT + 4); - vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); -} - -/* - * Description: Sync NIC TSF counter for Beacon time - * Get NEXTTBTT and write to HW - * - * Parameters: - * In: - * priv - The adapter to be set - * qwTSF - Current TSF counter - * beacon_interval - Beacon Interval - * Out: - * none - * - * Return Value: none - */ -void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, - unsigned short beacon_interval) -{ - void __iomem *iobase = priv->port_offset; - - qwTSF = card_get_next_tbtt(qwTSF, beacon_interval); - /* Set NextTBTT */ - qwTSF = le64_to_cpu(qwTSF); - iowrite32((u32)qwTSF, iobase + MAC_REG_NEXTTBTT); - iowrite32((u32)(qwTSF >> 32), iobase + MAC_REG_NEXTTBTT + 4); - vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); - pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF); -} diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h deleted file mode 100644 index f6b462ebca51cd885e0d528a0d4901aa436d8025..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/card.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Provide functions to setup NIC operation mode - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __CARD_H__ -#define __CARD_H__ - -#include -#include - -/* - * Loopback mode - * - * LOBYTE is MAC LB mode, HIBYTE is MII LB mode - */ -#define CARD_LB_NONE MAKEWORD(MAC_LB_NONE, 0) -/* PHY must ISO, avoid MAC loopback packet go out */ -#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) -#define CARD_LB_PHY MAKEWORD(MAC_LB_EXT, 0) - -#define DEFAULT_MSDU_LIFETIME 512 /* ms */ -#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */ - -#define DEFAULT_MGN_LIFETIME 8 /* ms */ -#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ - -#define CB_MAX_CHANNEL_24G 14 -#define CB_MAX_CHANNEL_5G 42 -#define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G + CB_MAX_CHANNEL_5G) - -struct vnt_private; - -void card_set_rspinf(struct vnt_private *priv, u8 bb_type); -void CARDvUpdateBasicTopRate(struct vnt_private *priv); -bool CARDbIsOFDMinBasicRate(struct vnt_private *priv); -void CARDvSetFirstNextTBTT(struct vnt_private *priv, - unsigned short beacon_interval); -void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, - unsigned short beacon_interval); -u64 vt6655_get_current_tsf(struct vnt_private *priv); -u64 card_get_next_tbtt(u64 qwTSF, unsigned short beacon_interval); -u64 card_get_tsf_offset(unsigned char rx_rate, u64 qwTSF1, u64 qwTSF2); -unsigned char card_get_pkt_type(struct vnt_private *priv); -void card_safe_reset_tx(struct vnt_private *priv); -void CARDvSafeResetRx(struct vnt_private *priv); -void card_radio_power_off(struct vnt_private *priv); -bool card_set_phy_parameter(struct vnt_private *priv, u8 bb_type); -bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate, - u64 bss_timestamp); -bool card_set_beacon_period(struct vnt_private *priv, - unsigned short beacon_interval); - -#endif /* __CARD_H__ */ diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c deleted file mode 100644 index 771c1364b0f08ef39f2048fef68bf9ef79f5456f..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/channel.c +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - */ - -#include "baseband.h" -#include "channel.h" -#include "device.h" -#include "rf.h" - -static struct ieee80211_rate vnt_rates_bg[] = { - { .bitrate = 10, .hw_value = RATE_1M }, - { .bitrate = 20, .hw_value = RATE_2M }, - { .bitrate = 55, .hw_value = RATE_5M }, - { .bitrate = 110, .hw_value = RATE_11M }, - { .bitrate = 60, .hw_value = RATE_6M }, - { .bitrate = 90, .hw_value = RATE_9M }, - { .bitrate = 120, .hw_value = RATE_12M }, - { .bitrate = 180, .hw_value = RATE_18M }, - { .bitrate = 240, .hw_value = RATE_24M }, - { .bitrate = 360, .hw_value = RATE_36M }, - { .bitrate = 480, .hw_value = RATE_48M }, - { .bitrate = 540, .hw_value = RATE_54M }, -}; - -static struct ieee80211_channel vnt_channels_2ghz[] = { - { .center_freq = 2412, .hw_value = 1 }, - { .center_freq = 2417, .hw_value = 2 }, - { .center_freq = 2422, .hw_value = 3 }, - { .center_freq = 2427, .hw_value = 4 }, - { .center_freq = 2432, .hw_value = 5 }, - { .center_freq = 2437, .hw_value = 6 }, - { .center_freq = 2442, .hw_value = 7 }, - { .center_freq = 2447, .hw_value = 8 }, - { .center_freq = 2452, .hw_value = 9 }, - { .center_freq = 2457, .hw_value = 10 }, - { .center_freq = 2462, .hw_value = 11 }, - { .center_freq = 2467, .hw_value = 12 }, - { .center_freq = 2472, .hw_value = 13 }, - { .center_freq = 2484, .hw_value = 14 } -}; - -static struct ieee80211_supported_band vnt_supported_2ghz_band = { - .channels = vnt_channels_2ghz, - .n_channels = ARRAY_SIZE(vnt_channels_2ghz), - .bitrates = vnt_rates_bg, - .n_bitrates = ARRAY_SIZE(vnt_rates_bg), -}; - -static void vnt_init_band(struct vnt_private *priv, - struct ieee80211_supported_band *supported_band, - enum nl80211_band band) -{ - int i; - - for (i = 0; i < supported_band->n_channels; i++) { - supported_band->channels[i].max_power = 0x3f; - supported_band->channels[i].flags = - IEEE80211_CHAN_NO_HT40; - } - - priv->hw->wiphy->bands[band] = supported_band; -} - -void vnt_init_bands(struct vnt_private *priv) -{ - vnt_init_band(priv, &vnt_supported_2ghz_band, NL80211_BAND_2GHZ); -} - -/** - * set_channel() - Set NIC media channel - * - * @priv: The adapter to be set - * @ch: Channel to be set - * - * Return Value: true if succeeded; false if failed. - * - */ -bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch) -{ - bool ret = true; - - if (priv->current_ch == ch->hw_value) - return ret; - - /* Set VGA to max sensitivity */ - if (priv->update_bbvga && - priv->bbvga_current != priv->bbvga[0]) { - priv->bbvga_current = priv->bbvga[0]; - - bb_set_vga_gain_offset(priv, priv->bbvga_current); - } - - /* clear NAV */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_MACCR, MACCR_CLRNAV); - - /* TX_PE will reserve 3 us for MAX2829 A mode only, - * it is for better TX throughput - */ - - priv->current_ch = ch->hw_value; - ret &= RFbSelectChannel(priv, priv->rf_type, - ch->hw_value); - - /* Init Synthesizer Table */ - if (priv->bEnablePSMode) - rf_write_wake_prog_syn(priv, priv->rf_type, ch->hw_value); - - bb_software_reset(priv); - - if (priv->local_id > REV_ID_VT3253_B1) { - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - /* set HW default power register */ - VT6655_MAC_SELECT_PAGE1(priv->port_offset); - RFbSetPower(priv, RATE_1M, priv->current_ch); - iowrite8(priv->cur_pwr, priv->port_offset + MAC_REG_PWRCCK); - RFbSetPower(priv, RATE_6M, priv->current_ch); - iowrite8(priv->cur_pwr, priv->port_offset + MAC_REG_PWROFDM); - VT6655_MAC_SELECT_PAGE0(priv->port_offset); - - spin_unlock_irqrestore(&priv->lock, flags); - } - - if (priv->byBBType == BB_TYPE_11B) - RFbSetPower(priv, RATE_1M, priv->current_ch); - else - RFbSetPower(priv, RATE_6M, priv->current_ch); - - return ret; -} diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h deleted file mode 100644 index 78b2d82317e52dd18d807ea8f732d66ffb2de682..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/channel.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - */ - -#ifndef _CHANNEL_H_ -#define _CHANNEL_H_ - -#include "card.h" - -void vnt_init_bands(struct vnt_private *priv); - -bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch); - -#endif /* _CHANNEL_H_ */ diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h deleted file mode 100644 index 17a40c53b8ffd0c336990d9a9b3c6890148352ec..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/desc.h +++ /dev/null @@ -1,249 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose:The header file of descriptor - * - * Revision History: - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __DESC_H__ -#define __DESC_H__ - -#include -#include -#include "linux/ieee80211.h" - -#define B_OWNED_BY_CHIP 1 -#define B_OWNED_BY_HOST 0 - -/* Bits in the RSR register */ -#define RSR_ADDRBROAD 0x80 -#define RSR_ADDRMULTI 0x40 -#define RSR_ADDRUNI 0x00 -#define RSR_IVLDTYP 0x20 -#define RSR_IVLDLEN 0x10 /* invalid len (> 2312 byte) */ -#define RSR_BSSIDOK 0x08 -#define RSR_CRCOK 0x04 -#define RSR_BCNSSIDOK 0x02 -#define RSR_ADDROK 0x01 - -/* Bits in the new RSR register */ -#define NEWRSR_DECRYPTOK 0x10 -#define NEWRSR_CFPIND 0x08 -#define NEWRSR_HWUTSF 0x04 -#define NEWRSR_BCNHITAID 0x02 -#define NEWRSR_BCNHITAID0 0x01 - -/* Bits in the TSR0 register */ -#define TSR0_PWRSTS1_2 0xC0 -#define TSR0_PWRSTS7 0x20 -#define TSR0_NCR 0x1F - -/* Bits in the TSR1 register */ -#define TSR1_TERR 0x80 -#define TSR1_PWRSTS4_6 0x70 -#define TSR1_RETRYTMO 0x08 -#define TSR1_TMO 0x04 -#define TSR1_PWRSTS3 0x02 -#define ACK_DATA 0x01 - -/* Bits in the TCR register */ -#define EDMSDU 0x04 /* end of sdu */ -#define TCR_EDP 0x02 /* end of packet */ -#define TCR_STP 0x01 /* start of packet */ - -/* max transmit or receive buffer size */ -#define CB_MAX_BUF_SIZE 2900U - /* NOTE: must be multiple of 4 */ -#define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE -#define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE - -#define CB_BEACON_BUF_SIZE 512U - -#define CB_MAX_RX_DESC 128 -#define CB_MIN_RX_DESC 16 -#define CB_MAX_TX_DESC 64 -#define CB_MIN_TX_DESC 16 - -#define CB_MAX_RECEIVED_PACKETS 16 - /* - * limit our receive routine to indicating - * this many at a time for 2 reasons: - * 1. driver flow control to protocol layer - * 2. limit the time used in ISR routine - */ - -#define CB_EXTRA_RD_NUM 32 -#define CB_RD_NUM 32 -#define CB_TD_NUM 32 - -/* - * max number of physical segments in a single NDIS packet. Above this - * threshold, the packet is copied into a single physically contiguous buffer - */ -#define CB_MAX_SEGMENT 4 - -#define CB_MIN_MAP_REG_NUM 4 -#define CB_MAX_MAP_REG_NUM CB_MAX_TX_DESC - -#define CB_PROTOCOL_RESERVED_SECTION 16 - -/* - * if retrys excess 15 times , tx will abort, and if tx fifo underflow, - * tx will fail, we should try to resend it - */ -#define CB_MAX_TX_ABORT_RETRY 3 - -/* WMAC definition FIFO Control */ -#define FIFOCTL_AUTO_FB_1 0x1000 -#define FIFOCTL_AUTO_FB_0 0x0800 -#define FIFOCTL_GRPACK 0x0400 -#define FIFOCTL_11GA 0x0300 -#define FIFOCTL_11GB 0x0200 -#define FIFOCTL_11B 0x0100 -#define FIFOCTL_11A 0x0000 -#define FIFOCTL_RTS 0x0080 -#define FIFOCTL_ISDMA0 0x0040 -#define FIFOCTL_GENINT 0x0020 -#define FIFOCTL_TMOEN 0x0010 -#define FIFOCTL_LRETRY 0x0008 -#define FIFOCTL_CRCDIS 0x0004 -#define FIFOCTL_NEEDACK 0x0002 -#define FIFOCTL_LHEAD 0x0001 - -/* WMAC definition Frag Control */ -#define FRAGCTL_AES 0x0300 -#define FRAGCTL_TKIP 0x0200 -#define FRAGCTL_LEGACY 0x0100 -#define FRAGCTL_NONENCRYPT 0x0000 -#define FRAGCTL_ENDFRAG 0x0003 -#define FRAGCTL_MIDFRAG 0x0002 -#define FRAGCTL_STAFRAG 0x0001 -#define FRAGCTL_NONFRAG 0x0000 - -#define TYPE_TXDMA0 0 -#define TYPE_AC0DMA 1 -#define TYPE_ATIMDMA 2 -#define TYPE_SYNCDMA 3 -#define TYPE_MAXTD 2 - -#define TYPE_BEACONDMA 4 - -#define TYPE_RXDMA0 0 -#define TYPE_RXDMA1 1 -#define TYPE_MAXRD 2 - -/* TD_INFO flags control bit */ -#define TD_FLAGS_NETIF_SKB 0x01 /* check if need release skb */ -/* check if called from private skb (hostap) */ -#define TD_FLAGS_PRIV_SKB 0x02 -#define TD_FLAGS_PS_RETRY 0x04 /* check if PS STA frame re-transmit */ - -/* - * ref_sk_buff is used for mapping the skb structure between pre-built - * driver-obj & running kernel. Since different kernel version (2.4x) may - * change skb structure, i.e. pre-built driver-obj may link to older skb that - * leads error. - */ - -struct vnt_rd_info { - struct sk_buff *skb; - dma_addr_t skb_dma; -}; - -struct vnt_rdes0 { - volatile __le16 res_count; -#ifdef __BIG_ENDIAN - union { - volatile u16 f15_reserved; - struct { - volatile u8 f8_reserved1; - volatile u8 owner:1; - volatile u8 f7_reserved:7; - } __packed; - } __packed; -#else - u16 f15_reserved:15; - u16 owner:1; -#endif -} __packed; - -struct vnt_rdes1 { - __le16 req_count; - u16 reserved; -} __packed; - -/* Rx descriptor*/ -struct vnt_rx_desc { - volatile struct vnt_rdes0 rd0; - volatile struct vnt_rdes1 rd1; - volatile __le32 buff_addr; - volatile __le32 next_desc; - struct vnt_rx_desc *next __aligned(8); - struct vnt_rd_info *rd_info __aligned(8); -} __packed; - -struct vnt_tdes0 { - volatile u8 tsr0; - volatile u8 tsr1; -#ifdef __BIG_ENDIAN - union { - volatile u16 f15_txtime; - struct { - volatile u8 f8_reserved; - volatile u8 owner:1; - volatile u8 f7_reserved:7; - } __packed; - } __packed; -#else - volatile u16 f15_txtime:15; - volatile u16 owner:1; -#endif -} __packed; - -struct vnt_tdes1 { - volatile __le16 req_count; - volatile u8 tcr; - volatile u8 reserved; -} __packed; - -struct vnt_td_info { - void *mic_hdr; - struct sk_buff *skb; - unsigned char *buf; - dma_addr_t buf_dma; - u16 req_count; - u8 flags; -}; - -/* transmit descriptor */ -struct vnt_tx_desc { - volatile struct vnt_tdes0 td0; - volatile struct vnt_tdes1 td1; - volatile __le32 buff_addr; - volatile __le32 next_desc; - struct vnt_tx_desc *next __aligned(8); - struct vnt_td_info *td_info __aligned(8); -} __packed; - -/* Length, Service, and Signal fields of Phy for Tx */ -struct vnt_phy_field { - u8 signal; - u8 service; - __le16 len; -} __packed; - -union vnt_phy_field_swap { - struct vnt_phy_field field_read; - u16 swap[2]; - u32 field_write; -}; - -#endif /* __DESC_H__ */ diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h deleted file mode 100644 index 5eaab6b172d370966d089db3b8a8eb3014f2a469..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/device.h +++ /dev/null @@ -1,292 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: MAC Data structure - * - * Author: Tevin Chen - * - * Date: Mar 17, 1997 - * - */ - -#ifndef __DEVICE_H__ -#define __DEVICE_H__ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* device specific */ - -#include "device_cfg.h" -#include "card.h" -#include "srom.h" -#include "desc.h" -#include "key.h" -#include "mac.h" - -/*--------------------- Export Definitions -------------------------*/ - -#define RATE_1M 0 -#define RATE_2M 1 -#define RATE_5M 2 -#define RATE_11M 3 -#define RATE_6M 4 -#define RATE_9M 5 -#define RATE_12M 6 -#define RATE_18M 7 -#define RATE_24M 8 -#define RATE_36M 9 -#define RATE_48M 10 -#define RATE_54M 11 -#define MAX_RATE 12 - -#define AUTO_FB_NONE 0 -#define AUTO_FB_0 1 -#define AUTO_FB_1 2 - -#define FB_RATE0 0 -#define FB_RATE1 1 - -/* Antenna Mode */ -#define ANT_A 0 -#define ANT_B 1 -#define ANT_DIVERSITY 2 -#define ANT_RXD_TXA 3 -#define ANT_RXD_TXB 4 -#define ANT_UNKNOWN 0xFF - -#define BB_VGA_LEVEL 4 -#define BB_VGA_CHANGE_THRESHOLD 16 - -#define MAKE_BEACON_RESERVED 10 /* (us) */ - -/* BUILD OBJ mode */ - -#define AVAIL_TD(p, q) ((p)->opts.tx_descs[(q)] - ((p)->iTDUsed[(q)])) - -/* 0:11A 1:11B 2:11G */ -#define BB_TYPE_11A 0 -#define BB_TYPE_11B 1 -#define BB_TYPE_11G 2 - -/* 0:11a, 1:11b, 2:11gb (only CCK in BasicRate), 3:11ga (OFDM in BasicRate) */ -#define PK_TYPE_11A 0 -#define PK_TYPE_11B 1 -#define PK_TYPE_11GB 2 -#define PK_TYPE_11GA 3 - -#define OWNED_BY_HOST 0 -#define OWNED_BY_NIC 1 - -struct vnt_options { - int rx_descs0; /* Number of RX descriptors0 */ - int rx_descs1; /* Number of RX descriptors1 */ - int tx_descs[2]; /* Number of TX descriptors 0, 1 */ - int int_works; /* interrupt limits */ - int short_retry; - int long_retry; - int bbp_type; - u32 flags; -}; - -struct vnt_private { - struct pci_dev *pcid; - /* mac80211 */ - struct ieee80211_hw *hw; - struct ieee80211_vif *vif; - unsigned long key_entry_inuse; - u32 basic_rates; - u16 current_aid; - int mc_list_count; - u8 mac_hw; - -/* dma addr, rx/tx pool */ - dma_addr_t pool_dma; - dma_addr_t rd0_pool_dma; - dma_addr_t rd1_pool_dma; - - dma_addr_t td0_pool_dma; - dma_addr_t td1_pool_dma; - - dma_addr_t tx_bufs_dma0; - dma_addr_t tx_bufs_dma1; - dma_addr_t tx_beacon_dma; - - unsigned char *tx0_bufs; - unsigned char *tx1_bufs; - unsigned char *tx_beacon_bufs; - - void __iomem *port_offset; - u32 memaddr; - u32 ioaddr; - - spinlock_t lock; - - volatile int iTDUsed[TYPE_MAXTD]; - - struct vnt_tx_desc *apCurrTD[TYPE_MAXTD]; - struct vnt_tx_desc *tail_td[TYPE_MAXTD]; - - struct vnt_tx_desc *ap_td0_rings; - struct vnt_tx_desc *ap_td1_rings; - - struct vnt_rx_desc *aRD0Ring; - struct vnt_rx_desc *aRD1Ring; - struct vnt_rx_desc *pCurrRD[TYPE_MAXRD]; - - struct vnt_options opts; - - u32 flags; - - u32 rx_buf_sz; - u8 rx_rate; - - u32 rx_bytes; - - /* Version control */ - unsigned char local_id; - unsigned char rf_type; - - unsigned char max_pwr_level; - unsigned char byZoneType; - bool bZoneRegExist; - unsigned char byOriginalZonetype; - - unsigned char abyCurrentNetAddr[ETH_ALEN]; __aligned(2) - bool bLinkPass; /* link status: OK or fail */ - - unsigned int current_rssi; - unsigned char byCurrSQ; - - unsigned long dwTxAntennaSel; - unsigned long dwRxAntennaSel; - unsigned char byAntennaCount; - unsigned char byRxAntennaMode; - unsigned char byTxAntennaMode; - bool bTxRxAntInv; - - unsigned char *pbyTmpBuff; - unsigned int uSIFS; /* Current SIFS */ - unsigned int uDIFS; /* Current DIFS */ - unsigned int uEIFS; /* Current EIFS */ - unsigned int uSlot; /* Current SlotTime */ - unsigned int uCwMin; /* Current CwMin */ - unsigned int uCwMax; /* CwMax is fixed on 1023. */ - /* PHY parameter */ - unsigned char sifs; - unsigned char difs; - unsigned char eifs; - unsigned char slot; - unsigned char cw_max_min; - - u8 byBBType; /* 0:11A, 1:11B, 2:11G */ - u8 packet_type; /* - * 0:11a,1:11b,2:11gb (only CCK - * in BasicRate), 3:11ga (OFDM in - * Basic Rate) - */ - unsigned short wBasicRate; - unsigned char byACKRate; - unsigned char byTopOFDMBasicRate; - unsigned char byTopCCKBasicRate; - - unsigned char byMinChannel; - unsigned char byMaxChannel; - - unsigned char preamble_type; - unsigned char byShortPreamble; - - unsigned short wCurrentRate; - unsigned char byShortRetryLimit; - unsigned char byLongRetryLimit; - enum nl80211_iftype op_mode; - bool bBSSIDFilter; - unsigned short wMaxTransmitMSDULifetime; - - bool bEncryptionEnable; - bool bLongHeader; - bool short_slot_time; - bool bProtectMode; - bool bNonERPPresent; - bool bBarkerPreambleMd; - - bool bRadioControlOff; - bool radio_off; - bool bEnablePSMode; - unsigned short wListenInterval; - bool bPWBitOn; - - /* GPIO Radio Control */ - unsigned char byRadioCtl; - unsigned char byGPIO; - bool hw_radio_off; - bool bPrvActive4RadioOFF; - bool bGPIOBlockRead; - - /* Beacon related */ - unsigned short wSeqCounter; - unsigned short wBCNBufLen; - bool bBeaconBufReady; - bool bBeaconSent; - bool bIsBeaconBufReadySet; - unsigned int cbBeaconBufReadySetCnt; - bool bFixRate; - u16 current_ch; - - bool bAES; - - unsigned char byAutoFBCtrl; - - /* For Update BaseBand VGA Gain Offset */ - bool update_bbvga; - unsigned int uBBVGADiffCount; - unsigned char bbvga_new; - unsigned char bbvga_current; - unsigned char bbvga[BB_VGA_LEVEL]; - long dbm_threshold[BB_VGA_LEVEL]; - - unsigned char bb_pre_edrssi; - unsigned char byBBPreEDIndex; - - unsigned long dwDiagRefCount; - - /* For FOE Tuning */ - unsigned char byFOETuning; - - /* For RF Power table */ - unsigned char byCCKPwr; - unsigned char byOFDMPwrG; - unsigned char cur_pwr; - char byCurPwrdBm; - unsigned char abyCCKPwrTbl[CB_MAX_CHANNEL_24G + 1]; - unsigned char abyOFDMPwrTbl[CB_MAX_CHANNEL + 1]; - char abyCCKDefaultPwr[CB_MAX_CHANNEL_24G + 1]; - char abyOFDMDefaultPwr[CB_MAX_CHANNEL + 1]; - char abyRegPwr[CB_MAX_CHANNEL + 1]; - char abyLocalPwr[CB_MAX_CHANNEL + 1]; - - /* BaseBand Loopback Use */ - unsigned char byBBCR4d; - unsigned char byBBCRc9; - unsigned char byBBCR88; - unsigned char byBBCR09; - - unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */ - - unsigned short beacon_interval; - u16 wake_up_count; - - struct work_struct interrupt_work; - - struct ieee80211_low_level_stats low_stats; -}; - -#endif diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h deleted file mode 100644 index 2d647a3619bad19c087314400efae2ca892b739e..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/device_cfg.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Driver configuration header - * Author: Lyndon Chen - * - * Date: Dec 17, 2002 - * - */ - -#ifndef __DEVICE_CONFIG_H -#define __DEVICE_CONFIG_H - -#include - -#define VID_TABLE_SIZE 64 -#define MCAST_TABLE_SIZE 64 -#define MCAM_SIZE 32 -#define VCAM_SIZE 32 -#define TX_QUEUE_NO 8 - -#define DEVICE_NAME "vt6655" -#define DEVICE_FULL_DRV_NAM "VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver" - -#ifndef MAJOR_VERSION -#define MAJOR_VERSION 1 -#endif - -#ifndef MINOR_VERSION -#define MINOR_VERSION 17 -#endif - -#ifndef DEVICE_VERSION -#define DEVICE_VERSION "1.19.12" -#endif - -#include -#include - -#define PKT_BUF_SZ 2390 - -#endif diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c deleted file mode 100644 index bf3ecf72020666170bfa00c3b6a7ab4d9086350b..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/device_main.c +++ /dev/null @@ -1,1868 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: driver entry for initial, open, close, tx and rx. - * - * Author: Lyndon Chen - * - * Date: Jan 8, 2003 - * - * Functions: - * - * vt6655_probe - module initial (insmod) driver entry - * vt6655_remove - module remove entry - * device_free_info - device structure resource free function - * device_print_info - print out resource - * device_rx_srv - rx service function - * device_alloc_rx_buf - rx buffer pre-allocated function - * device_free_rx_buf - free rx buffer function - * device_free_tx_buf - free tx buffer function - * device_init_rd0_ring - initial rd dma0 ring - * device_init_rd1_ring - initial rd dma1 ring - * device_init_td0_ring - initial tx dma0 ring buffer - * device_init_td1_ring - initial tx dma1 ring buffer - * device_init_registers - initial MAC & BBP & RF internal registers. - * device_init_rings - initial tx/rx ring buffer - * device_free_rings - free all allocated ring buffer - * device_tx_srv - tx interrupt service function - * - * Revision History: - */ - -#include -#include "device.h" -#include "card.h" -#include "channel.h" -#include "baseband.h" -#include "mac.h" -#include "power.h" -#include "rxtx.h" -#include "dpc.h" -#include "rf.h" -#include -#include -#include - -/*--------------------- Static Definitions -------------------------*/ -/* - * Define module options - */ -MODULE_AUTHOR("VIA Networking Technologies, Inc., "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver"); - -#define DEVICE_PARAM(N, D) - -#define RX_DESC_MIN0 16 -#define RX_DESC_MAX0 128 -#define RX_DESC_DEF0 32 -DEVICE_PARAM(RxDescriptors0, "Number of receive descriptors0"); - -#define RX_DESC_MIN1 16 -#define RX_DESC_MAX1 128 -#define RX_DESC_DEF1 32 -DEVICE_PARAM(RxDescriptors1, "Number of receive descriptors1"); - -#define TX_DESC_MIN0 16 -#define TX_DESC_MAX0 128 -#define TX_DESC_DEF0 32 -DEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0"); - -#define TX_DESC_MIN1 16 -#define TX_DESC_MAX1 128 -#define TX_DESC_DEF1 64 -DEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1"); - -#define INT_WORKS_DEF 20 -#define INT_WORKS_MIN 10 -#define INT_WORKS_MAX 64 - -DEVICE_PARAM(int_works, "Number of packets per interrupt services"); - -#define RTS_THRESH_DEF 2347 - -#define FRAG_THRESH_DEF 2346 - -#define SHORT_RETRY_MIN 0 -#define SHORT_RETRY_MAX 31 -#define SHORT_RETRY_DEF 8 - -DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits"); - -#define LONG_RETRY_MIN 0 -#define LONG_RETRY_MAX 15 -#define LONG_RETRY_DEF 4 - -DEVICE_PARAM(LongRetryLimit, "long frame retry limits"); - -/* BasebandType[] baseband type selected - * 0: indicate 802.11a type - * 1: indicate 802.11b type - * 2: indicate 802.11g type - */ -#define BBP_TYPE_MIN 0 -#define BBP_TYPE_MAX 2 -#define BBP_TYPE_DEF 2 - -DEVICE_PARAM(BasebandType, "baseband type"); - -/* - * Static vars definitions - */ -static const struct pci_device_id vt6655_pci_id_table[] = { - { PCI_VDEVICE(VIA, 0x3253) }, - { 0, } -}; - -/*--------------------- Static Functions --------------------------*/ - -static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent); -static void device_free_info(struct vnt_private *priv); -static void device_print_info(struct vnt_private *priv); - -static void vt6655_mac_write_bssid_addr(void __iomem *iobase, const u8 *mac_addr); -static void vt6655_mac_read_ether_addr(void __iomem *iobase, u8 *mac_addr); - -static int device_init_rd0_ring(struct vnt_private *priv); -static int device_init_rd1_ring(struct vnt_private *priv); -static int device_init_td0_ring(struct vnt_private *priv); -static int device_init_td1_ring(struct vnt_private *priv); - -static int device_rx_srv(struct vnt_private *priv, unsigned int idx); -static int device_tx_srv(struct vnt_private *priv, unsigned int idx); -static bool device_alloc_rx_buf(struct vnt_private *, struct vnt_rx_desc *); -static void device_free_rx_buf(struct vnt_private *priv, - struct vnt_rx_desc *rd); -static void device_init_registers(struct vnt_private *priv); -static void device_free_tx_buf(struct vnt_private *, struct vnt_tx_desc *); -static void device_free_td0_ring(struct vnt_private *priv); -static void device_free_td1_ring(struct vnt_private *priv); -static void device_free_rd0_ring(struct vnt_private *priv); -static void device_free_rd1_ring(struct vnt_private *priv); -static void device_free_rings(struct vnt_private *priv); - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -static void vt6655_remove(struct pci_dev *pcid) -{ - struct vnt_private *priv = pci_get_drvdata(pcid); - - if (!priv) - return; - device_free_info(priv); -} - -static void device_get_options(struct vnt_private *priv) -{ - struct vnt_options *opts = &priv->opts; - - opts->rx_descs0 = RX_DESC_DEF0; - opts->rx_descs1 = RX_DESC_DEF1; - opts->tx_descs[0] = TX_DESC_DEF0; - opts->tx_descs[1] = TX_DESC_DEF1; - opts->int_works = INT_WORKS_DEF; - - opts->short_retry = SHORT_RETRY_DEF; - opts->long_retry = LONG_RETRY_DEF; - opts->bbp_type = BBP_TYPE_DEF; -} - -static void -device_set_options(struct vnt_private *priv) -{ - priv->byShortRetryLimit = priv->opts.short_retry; - priv->byLongRetryLimit = priv->opts.long_retry; - priv->byBBType = priv->opts.bbp_type; - priv->packet_type = priv->byBBType; - priv->byAutoFBCtrl = AUTO_FB_0; - priv->update_bbvga = true; - priv->preamble_type = 0; - - pr_debug(" byShortRetryLimit= %d\n", (int)priv->byShortRetryLimit); - pr_debug(" byLongRetryLimit= %d\n", (int)priv->byLongRetryLimit); - pr_debug(" preamble_type= %d\n", (int)priv->preamble_type); - pr_debug(" byShortPreamble= %d\n", (int)priv->byShortPreamble); - pr_debug(" byBBType= %d\n", (int)priv->byBBType); -} - -static void vt6655_mac_write_bssid_addr(void __iomem *iobase, const u8 *mac_addr) -{ - iowrite8(1, iobase + MAC_REG_PAGE1SEL); - for (int i = 0; i < 6; i++) - iowrite8(mac_addr[i], iobase + MAC_REG_BSSID0 + i); - iowrite8(0, iobase + MAC_REG_PAGE1SEL); -} - -static void vt6655_mac_read_ether_addr(void __iomem *iobase, u8 *mac_addr) -{ - iowrite8(1, iobase + MAC_REG_PAGE1SEL); - for (int i = 0; i < 6; i++) - mac_addr[i] = ioread8(iobase + MAC_REG_PAR0 + i); - iowrite8(0, iobase + MAC_REG_PAGE1SEL); -} - -static void vt6655_mac_dma_ctl(void __iomem *iobase, u8 reg_index) -{ - u32 reg_value; - - reg_value = ioread32(iobase + reg_index); - if (reg_value & DMACTL_RUN) - iowrite32(DMACTL_WAKE, iobase + reg_index); - else - iowrite32(DMACTL_RUN, iobase + reg_index); -} - -static void vt6655_mac_set_bits(void __iomem *iobase, u32 mask) -{ - u32 reg_value; - - reg_value = ioread32(iobase + MAC_REG_ENCFG); - reg_value = reg_value | mask; - iowrite32(reg_value, iobase + MAC_REG_ENCFG); -} - -static void vt6655_mac_clear_bits(void __iomem *iobase, u32 mask) -{ - u32 reg_value; - - reg_value = ioread32(iobase + MAC_REG_ENCFG); - reg_value = reg_value & ~mask; - iowrite32(reg_value, iobase + MAC_REG_ENCFG); -} - -static void vt6655_mac_en_protect_md(void __iomem *iobase) -{ - vt6655_mac_set_bits(iobase, ENCFG_PROTECTMD); -} - -static void vt6655_mac_dis_protect_md(void __iomem *iobase) -{ - vt6655_mac_clear_bits(iobase, ENCFG_PROTECTMD); -} - -static void vt6655_mac_en_barker_preamble_md(void __iomem *iobase) -{ - vt6655_mac_set_bits(iobase, ENCFG_BARKERPREAM); -} - -static void vt6655_mac_dis_barker_preamble_md(void __iomem *iobase) -{ - vt6655_mac_clear_bits(iobase, ENCFG_BARKERPREAM); -} - -/* - * Initialisation of MAC & BBP registers - */ - -static void device_init_registers(struct vnt_private *priv) -{ - unsigned long flags; - unsigned int ii; - unsigned char byValue; - unsigned char byCCKPwrdBm = 0; - unsigned char byOFDMPwrdBm = 0; - - MACbShutdown(priv); - bb_software_reset(priv); - - /* Do MACbSoftwareReset in MACvInitialize */ - MACbSoftwareReset(priv); - - priv->bAES = false; - - /* Only used in 11g type, sync with ERP IE */ - priv->bProtectMode = false; - - priv->bNonERPPresent = false; - priv->bBarkerPreambleMd = false; - priv->wCurrentRate = RATE_1M; - priv->byTopOFDMBasicRate = RATE_24M; - priv->byTopCCKBasicRate = RATE_1M; - - /* init MAC */ - MACvInitialize(priv); - - /* Get Local ID */ - priv->local_id = ioread8(priv->port_offset + MAC_REG_LOCALID); - - spin_lock_irqsave(&priv->lock, flags); - - SROMvReadAllContents(priv->port_offset, priv->abyEEPROM); - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Get Channel range */ - priv->byMinChannel = 1; - priv->byMaxChannel = CB_MAX_CHANNEL; - - /* Get Antena */ - byValue = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_ANTENNA); - if (byValue & EEP_ANTINV) - priv->bTxRxAntInv = true; - else - priv->bTxRxAntInv = false; - - byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); - /* if not set default is All */ - if (byValue == 0) - byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); - - if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { - priv->byAntennaCount = 2; - priv->byTxAntennaMode = ANT_B; - priv->dwTxAntennaSel = 1; - priv->dwRxAntennaSel = 1; - - if (priv->bTxRxAntInv) - priv->byRxAntennaMode = ANT_A; - else - priv->byRxAntennaMode = ANT_B; - } else { - priv->byAntennaCount = 1; - priv->dwTxAntennaSel = 0; - priv->dwRxAntennaSel = 0; - - if (byValue & EEP_ANTENNA_AUX) { - priv->byTxAntennaMode = ANT_A; - - if (priv->bTxRxAntInv) - priv->byRxAntennaMode = ANT_B; - else - priv->byRxAntennaMode = ANT_A; - } else { - priv->byTxAntennaMode = ANT_B; - - if (priv->bTxRxAntInv) - priv->byRxAntennaMode = ANT_A; - else - priv->byRxAntennaMode = ANT_B; - } - } - - /* Set initial antenna mode */ - bb_set_tx_antenna_mode(priv, priv->byTxAntennaMode); - bb_set_rx_antenna_mode(priv, priv->byRxAntennaMode); - - /* zonetype initial */ - priv->byOriginalZonetype = priv->abyEEPROM[EEP_OFS_ZONETYPE]; - - if (!priv->bZoneRegExist) - priv->byZoneType = priv->abyEEPROM[EEP_OFS_ZONETYPE]; - - pr_debug("priv->byZoneType = %x\n", priv->byZoneType); - - /* Init RF module */ - RFbInit(priv); - - /* Get Desire Power Value */ - priv->cur_pwr = 0xFF; - priv->byCCKPwr = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_PWR_CCK); - priv->byOFDMPwrG = SROMbyReadEmbedded(priv->port_offset, - EEP_OFS_PWR_OFDMG); - - /* Load power Table */ - for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) { - priv->abyCCKPwrTbl[ii + 1] = - SROMbyReadEmbedded(priv->port_offset, - (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL)); - if (priv->abyCCKPwrTbl[ii + 1] == 0) - priv->abyCCKPwrTbl[ii + 1] = priv->byCCKPwr; - - priv->abyOFDMPwrTbl[ii + 1] = - SROMbyReadEmbedded(priv->port_offset, - (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL)); - if (priv->abyOFDMPwrTbl[ii + 1] == 0) - priv->abyOFDMPwrTbl[ii + 1] = priv->byOFDMPwrG; - - priv->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm; - priv->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm; - } - - /* recover 12,13 ,14channel for EUROPE by 11 channel */ - for (ii = 11; ii < 14; ii++) { - priv->abyCCKPwrTbl[ii] = priv->abyCCKPwrTbl[10]; - priv->abyOFDMPwrTbl[ii] = priv->abyOFDMPwrTbl[10]; - } - - /* Load OFDM A Power Table */ - for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { - priv->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] = - SROMbyReadEmbedded(priv->port_offset, - (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL)); - - priv->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] = - SROMbyReadEmbedded(priv->port_offset, - (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm)); - } - - if (priv->local_id > REV_ID_VT3253_B1) { - VT6655_MAC_SELECT_PAGE1(priv->port_offset); - - iowrite8(MSRCTL1_TXPWR | MSRCTL1_CSAPAREN, priv->port_offset + MAC_REG_MSRCTL + 1); - - VT6655_MAC_SELECT_PAGE0(priv->port_offset); - } - - /* use relative tx timeout and 802.11i D4 */ - vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_CFG, - (CFG_TKIPOPT | CFG_NOTXTIMEOUT)); - - /* set performance parameter by registry */ - vt6655_mac_set_short_retry_limit(priv, priv->byShortRetryLimit); - MACvSetLongRetryLimit(priv, priv->byLongRetryLimit); - - /* reset TSF counter */ - iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL); - /* enable TSF counter */ - iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL); - - /* initialize BBP registers */ - bb_vt3253_init(priv); - - if (priv->update_bbvga) { - priv->bbvga_current = priv->bbvga[0]; - priv->bbvga_new = priv->bbvga_current; - bb_set_vga_gain_offset(priv, priv->bbvga[0]); - } - - bb_set_rx_antenna_mode(priv, priv->byRxAntennaMode); - bb_set_tx_antenna_mode(priv, priv->byTxAntennaMode); - - /* Set BB and packet type at the same time. */ - /* Set Short Slot Time, xIFS, and RSPINF. */ - priv->wCurrentRate = RATE_54M; - - priv->radio_off = false; - - priv->byRadioCtl = SROMbyReadEmbedded(priv->port_offset, - EEP_OFS_RADIOCTL); - priv->hw_radio_off = false; - - if (priv->byRadioCtl & EEP_RADIOCTL_ENABLE) { - /* Get GPIO */ - priv->byGPIO = ioread8(priv->port_offset + MAC_REG_GPIOCTL1); - - if (((priv->byGPIO & GPIO0_DATA) && - !(priv->byRadioCtl & EEP_RADIOCTL_INV)) || - (!(priv->byGPIO & GPIO0_DATA) && - (priv->byRadioCtl & EEP_RADIOCTL_INV))) - priv->hw_radio_off = true; - } - - if (priv->hw_radio_off || priv->bRadioControlOff) - card_radio_power_off(priv); - - /* get Permanent network address */ - SROMvReadEtherAddress(priv->port_offset, priv->abyCurrentNetAddr); - pr_debug("Network address = %pM\n", priv->abyCurrentNetAddr); - - /* reset Tx pointer */ - CARDvSafeResetRx(priv); - /* reset Rx pointer */ - card_safe_reset_tx(priv); - - if (priv->local_id <= REV_ID_VT3253_A1) - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_RCR, RCR_WPAERR); - - /* Turn On Rx DMA */ - vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL0); - vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL1); - - /* start the adapter */ - iowrite8(HOSTCR_MACEN | HOSTCR_RXON | HOSTCR_TXON, priv->port_offset + MAC_REG_HOSTCR); -} - -static void device_print_info(struct vnt_private *priv) -{ - dev_info(&priv->pcid->dev, "MAC=%pM IO=0x%lx Mem=0x%lx IRQ=%d\n", - priv->abyCurrentNetAddr, (unsigned long)priv->ioaddr, - (unsigned long)priv->port_offset, priv->pcid->irq); -} - -static void device_free_info(struct vnt_private *priv) -{ - if (!priv) - return; - - if (priv->mac_hw) - ieee80211_unregister_hw(priv->hw); - - if (priv->port_offset) - iounmap(priv->port_offset); - - if (priv->pcid) - pci_release_regions(priv->pcid); - - if (priv->hw) - ieee80211_free_hw(priv->hw); -} - -static bool device_init_rings(struct vnt_private *priv) -{ - void *vir_pool; - - /*allocate all RD/TD rings a single pool*/ - vir_pool = dma_alloc_coherent(&priv->pcid->dev, - priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) + - priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc) + - priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc) + - priv->opts.tx_descs[1] * sizeof(struct vnt_tx_desc), - &priv->pool_dma, GFP_ATOMIC); - if (!vir_pool) { - dev_err(&priv->pcid->dev, "allocate desc dma memory failed\n"); - return false; - } - - priv->aRD0Ring = vir_pool; - priv->aRD1Ring = vir_pool + - priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc); - - priv->rd0_pool_dma = priv->pool_dma; - priv->rd1_pool_dma = priv->rd0_pool_dma + - priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc); - - priv->tx0_bufs = dma_alloc_coherent(&priv->pcid->dev, - priv->opts.tx_descs[0] * PKT_BUF_SZ + - priv->opts.tx_descs[1] * PKT_BUF_SZ + - CB_BEACON_BUF_SIZE + - CB_MAX_BUF_SIZE, - &priv->tx_bufs_dma0, GFP_ATOMIC); - if (!priv->tx0_bufs) { - dev_err(&priv->pcid->dev, "allocate buf dma memory failed\n"); - - dma_free_coherent(&priv->pcid->dev, - priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) + - priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc) + - priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc) + - priv->opts.tx_descs[1] * sizeof(struct vnt_tx_desc), - vir_pool, priv->pool_dma); - return false; - } - - priv->td0_pool_dma = priv->rd1_pool_dma + - priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc); - - priv->td1_pool_dma = priv->td0_pool_dma + - priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc); - - /* vir_pool: pvoid type */ - priv->ap_td0_rings = vir_pool - + priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) - + priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc); - - priv->ap_td1_rings = vir_pool - + priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) - + priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc) - + priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc); - - priv->tx1_bufs = priv->tx0_bufs + - priv->opts.tx_descs[0] * PKT_BUF_SZ; - - priv->tx_beacon_bufs = priv->tx1_bufs + - priv->opts.tx_descs[1] * PKT_BUF_SZ; - - priv->pbyTmpBuff = priv->tx_beacon_bufs + - CB_BEACON_BUF_SIZE; - - priv->tx_bufs_dma1 = priv->tx_bufs_dma0 + - priv->opts.tx_descs[0] * PKT_BUF_SZ; - - priv->tx_beacon_dma = priv->tx_bufs_dma1 + - priv->opts.tx_descs[1] * PKT_BUF_SZ; - - return true; -} - -static void device_free_rings(struct vnt_private *priv) -{ - dma_free_coherent(&priv->pcid->dev, - priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) + - priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc) + - priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc) + - priv->opts.tx_descs[1] * sizeof(struct vnt_tx_desc), - priv->aRD0Ring, priv->pool_dma); - - dma_free_coherent(&priv->pcid->dev, - priv->opts.tx_descs[0] * PKT_BUF_SZ + - priv->opts.tx_descs[1] * PKT_BUF_SZ + - CB_BEACON_BUF_SIZE + - CB_MAX_BUF_SIZE, - priv->tx0_bufs, priv->tx_bufs_dma0); -} - -static int device_init_rd0_ring(struct vnt_private *priv) -{ - int i; - dma_addr_t curr = priv->rd0_pool_dma; - struct vnt_rx_desc *desc; - int ret; - - /* Init the RD0 ring entries */ - for (i = 0; i < priv->opts.rx_descs0; - i ++, curr += sizeof(struct vnt_rx_desc)) { - desc = &priv->aRD0Ring[i]; - desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL); - if (!desc->rd_info) { - ret = -ENOMEM; - goto err_free_desc; - } - - if (!device_alloc_rx_buf(priv, desc)) { - dev_err(&priv->pcid->dev, "can not alloc rx bufs\n"); - ret = -ENOMEM; - goto err_free_rd; - } - - desc->next = &priv->aRD0Ring[(i + 1) % priv->opts.rx_descs0]; - desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc)); - } - - if (i > 0) - priv->aRD0Ring[i - 1].next_desc = cpu_to_le32(priv->rd0_pool_dma); - priv->pCurrRD[0] = &priv->aRD0Ring[0]; - - return 0; - -err_free_rd: - kfree(desc->rd_info); - -err_free_desc: - while (i--) { - desc = &priv->aRD0Ring[i]; - device_free_rx_buf(priv, desc); - kfree(desc->rd_info); - } - - return ret; -} - -static int device_init_rd1_ring(struct vnt_private *priv) -{ - int i; - dma_addr_t curr = priv->rd1_pool_dma; - struct vnt_rx_desc *desc; - int ret; - - /* Init the RD1 ring entries */ - for (i = 0; i < priv->opts.rx_descs1; - i ++, curr += sizeof(struct vnt_rx_desc)) { - desc = &priv->aRD1Ring[i]; - desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL); - if (!desc->rd_info) { - ret = -ENOMEM; - goto err_free_desc; - } - - if (!device_alloc_rx_buf(priv, desc)) { - dev_err(&priv->pcid->dev, "can not alloc rx bufs\n"); - ret = -ENOMEM; - goto err_free_rd; - } - - desc->next = &priv->aRD1Ring[(i + 1) % priv->opts.rx_descs1]; - desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc)); - } - - if (i > 0) - priv->aRD1Ring[i - 1].next_desc = cpu_to_le32(priv->rd1_pool_dma); - priv->pCurrRD[1] = &priv->aRD1Ring[0]; - - return 0; - -err_free_rd: - kfree(desc->rd_info); - -err_free_desc: - while (i--) { - desc = &priv->aRD1Ring[i]; - device_free_rx_buf(priv, desc); - kfree(desc->rd_info); - } - - return ret; -} - -static void device_free_rd0_ring(struct vnt_private *priv) -{ - int i; - - for (i = 0; i < priv->opts.rx_descs0; i++) { - struct vnt_rx_desc *desc = &priv->aRD0Ring[i]; - - device_free_rx_buf(priv, desc); - kfree(desc->rd_info); - } -} - -static void device_free_rd1_ring(struct vnt_private *priv) -{ - int i; - - for (i = 0; i < priv->opts.rx_descs1; i++) { - struct vnt_rx_desc *desc = &priv->aRD1Ring[i]; - - device_free_rx_buf(priv, desc); - kfree(desc->rd_info); - } -} - -static int device_init_td0_ring(struct vnt_private *priv) -{ - int i; - dma_addr_t curr; - struct vnt_tx_desc *desc; - int ret; - - curr = priv->td0_pool_dma; - for (i = 0; i < priv->opts.tx_descs[0]; - i++, curr += sizeof(struct vnt_tx_desc)) { - desc = &priv->ap_td0_rings[i]; - desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL); - if (!desc->td_info) { - ret = -ENOMEM; - goto err_free_desc; - } - - desc->td_info->buf = priv->tx0_bufs + i * PKT_BUF_SZ; - desc->td_info->buf_dma = priv->tx_bufs_dma0 + i * PKT_BUF_SZ; - - desc->next = &(priv->ap_td0_rings[(i + 1) % priv->opts.tx_descs[0]]); - desc->next_desc = cpu_to_le32(curr + - sizeof(struct vnt_tx_desc)); - } - - if (i > 0) - priv->ap_td0_rings[i - 1].next_desc = cpu_to_le32(priv->td0_pool_dma); - priv->tail_td[0] = priv->apCurrTD[0] = &priv->ap_td0_rings[0]; - - return 0; - -err_free_desc: - while (i--) { - desc = &priv->ap_td0_rings[i]; - kfree(desc->td_info); - } - - return ret; -} - -static int device_init_td1_ring(struct vnt_private *priv) -{ - int i; - dma_addr_t curr; - struct vnt_tx_desc *desc; - int ret; - - /* Init the TD ring entries */ - curr = priv->td1_pool_dma; - for (i = 0; i < priv->opts.tx_descs[1]; - i++, curr += sizeof(struct vnt_tx_desc)) { - desc = &priv->ap_td1_rings[i]; - desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL); - if (!desc->td_info) { - ret = -ENOMEM; - goto err_free_desc; - } - - desc->td_info->buf = priv->tx1_bufs + i * PKT_BUF_SZ; - desc->td_info->buf_dma = priv->tx_bufs_dma1 + i * PKT_BUF_SZ; - - desc->next = &(priv->ap_td1_rings[(i + 1) % priv->opts.tx_descs[1]]); - desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_tx_desc)); - } - - if (i > 0) - priv->ap_td1_rings[i - 1].next_desc = cpu_to_le32(priv->td1_pool_dma); - priv->tail_td[1] = priv->apCurrTD[1] = &priv->ap_td1_rings[0]; - - return 0; - -err_free_desc: - while (i--) { - desc = &priv->ap_td1_rings[i]; - kfree(desc->td_info); - } - - return ret; -} - -static void device_free_td0_ring(struct vnt_private *priv) -{ - int i; - - for (i = 0; i < priv->opts.tx_descs[0]; i++) { - struct vnt_tx_desc *desc = &priv->ap_td0_rings[i]; - struct vnt_td_info *td_info = desc->td_info; - - dev_kfree_skb(td_info->skb); - kfree(desc->td_info); - } -} - -static void device_free_td1_ring(struct vnt_private *priv) -{ - int i; - - for (i = 0; i < priv->opts.tx_descs[1]; i++) { - struct vnt_tx_desc *desc = &priv->ap_td1_rings[i]; - struct vnt_td_info *td_info = desc->td_info; - - dev_kfree_skb(td_info->skb); - kfree(desc->td_info); - } -} - -/*-----------------------------------------------------------------*/ - -static int device_rx_srv(struct vnt_private *priv, unsigned int idx) -{ - struct vnt_rx_desc *rd; - int works = 0; - - for (rd = priv->pCurrRD[idx]; - rd->rd0.owner == OWNED_BY_HOST; - rd = rd->next) { - if (works++ > 15) - break; - - if (!rd->rd_info->skb) - break; - - if (vnt_receive_frame(priv, rd)) { - if (!device_alloc_rx_buf(priv, rd)) { - dev_err(&priv->pcid->dev, - "can not allocate rx buf\n"); - break; - } - } - rd->rd0.owner = OWNED_BY_NIC; - } - - priv->pCurrRD[idx] = rd; - - return works; -} - -static bool device_alloc_rx_buf(struct vnt_private *priv, - struct vnt_rx_desc *rd) -{ - struct vnt_rd_info *rd_info = rd->rd_info; - - rd_info->skb = dev_alloc_skb((int)priv->rx_buf_sz); - if (!rd_info->skb) - return false; - - rd_info->skb_dma = - dma_map_single(&priv->pcid->dev, - skb_put(rd_info->skb, skb_tailroom(rd_info->skb)), - priv->rx_buf_sz, DMA_FROM_DEVICE); - if (dma_mapping_error(&priv->pcid->dev, rd_info->skb_dma)) { - dev_kfree_skb(rd_info->skb); - rd_info->skb = NULL; - return false; - } - - *((unsigned int *)&rd->rd0) = 0; /* FIX cast */ - - rd->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); - rd->rd0.owner = OWNED_BY_NIC; - rd->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); - rd->buff_addr = cpu_to_le32(rd_info->skb_dma); - - return true; -} - -static void device_free_rx_buf(struct vnt_private *priv, - struct vnt_rx_desc *rd) -{ - struct vnt_rd_info *rd_info = rd->rd_info; - - dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, - priv->rx_buf_sz, DMA_FROM_DEVICE); - dev_kfree_skb(rd_info->skb); -} - -static const u8 fallback_rate0[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, - {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, - {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} -}; - -static const u8 fallback_rate1[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M} -}; - -static int vnt_int_report_rate(struct vnt_private *priv, - struct vnt_td_info *context, u8 tsr0, u8 tsr1) -{ - struct vnt_tx_fifo_head *fifo_head; - struct ieee80211_tx_info *info; - struct ieee80211_rate *rate; - u16 fb_option; - u8 tx_retry = (tsr0 & TSR0_NCR); - s8 idx; - - if (!context) - return -ENOMEM; - - if (!context->skb) - return -EINVAL; - - fifo_head = (struct vnt_tx_fifo_head *)context->buf; - fb_option = (le16_to_cpu(fifo_head->fifo_ctl) & - (FIFOCTL_AUTO_FB_0 | FIFOCTL_AUTO_FB_1)); - - info = IEEE80211_SKB_CB(context->skb); - idx = info->control.rates[0].idx; - - if (fb_option && !(tsr1 & TSR1_TERR)) { - u8 tx_rate; - u8 retry = tx_retry; - - rate = ieee80211_get_tx_rate(priv->hw, info); - tx_rate = rate->hw_value - RATE_18M; - - if (retry > 4) - retry = 4; - - if (fb_option & FIFOCTL_AUTO_FB_0) - tx_rate = fallback_rate0[tx_rate][retry]; - else if (fb_option & FIFOCTL_AUTO_FB_1) - tx_rate = fallback_rate1[tx_rate][retry]; - - if (info->band == NL80211_BAND_5GHZ) - idx = tx_rate - RATE_6M; - else - idx = tx_rate; - } - - ieee80211_tx_info_clear_status(info); - - info->status.rates[0].count = tx_retry; - - if (!(tsr1 & TSR1_TERR)) { - info->status.rates[0].idx = idx; - - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; - else - info->flags |= IEEE80211_TX_STAT_ACK; - } - - return 0; -} - -static int device_tx_srv(struct vnt_private *priv, unsigned int idx) -{ - struct vnt_tx_desc *desc; - int works = 0; - unsigned char byTsr0; - unsigned char byTsr1; - - for (desc = priv->tail_td[idx]; priv->iTDUsed[idx] > 0; desc = desc->next) { - if (desc->td0.owner == OWNED_BY_NIC) - break; - if (works++ > 15) - break; - - byTsr0 = desc->td0.tsr0; - byTsr1 = desc->td0.tsr1; - - /* Only the status of first TD in the chain is correct */ - if (desc->td1.tcr & TCR_STP) { - if ((desc->td_info->flags & TD_FLAGS_NETIF_SKB) != 0) { - if (!(byTsr1 & TSR1_TERR)) { - if (byTsr0 != 0) { - pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n", - (int)idx, byTsr1, - byTsr0); - } - } else { - pr_debug(" Tx[%d] dropped & tsr1[%02X] tsr0[%02X]\n", - (int)idx, byTsr1, byTsr0); - } - } - - if (byTsr1 & TSR1_TERR) { - if ((desc->td_info->flags & TD_FLAGS_PRIV_SKB) != 0) { - pr_debug(" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X]\n", - (int)idx, byTsr1, byTsr0); - } - } - - vnt_int_report_rate(priv, desc->td_info, byTsr0, byTsr1); - - device_free_tx_buf(priv, desc); - priv->iTDUsed[idx]--; - } - } - - priv->tail_td[idx] = desc; - - return works; -} - -static void device_error(struct vnt_private *priv, unsigned short status) -{ - if (status & ISR_FETALERR) { - dev_err(&priv->pcid->dev, "Hardware fatal error\n"); - - MACbShutdown(priv); - return; - } -} - -static void device_free_tx_buf(struct vnt_private *priv, - struct vnt_tx_desc *desc) -{ - struct vnt_td_info *td_info = desc->td_info; - struct sk_buff *skb = td_info->skb; - - if (skb) - ieee80211_tx_status_irqsafe(priv->hw, skb); - - td_info->skb = NULL; - td_info->flags = 0; -} - -static void vnt_check_bb_vga(struct vnt_private *priv) -{ - long dbm; - int i; - - if (!priv->update_bbvga) - return; - - if (priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) - return; - - if (!(priv->vif->cfg.assoc && priv->current_rssi)) - return; - - RFvRSSITodBm(priv, (u8)priv->current_rssi, &dbm); - - for (i = 0; i < BB_VGA_LEVEL; i++) { - if (dbm < priv->dbm_threshold[i]) { - priv->bbvga_new = priv->bbvga[i]; - break; - } - } - - if (priv->bbvga_new == priv->bbvga_current) { - priv->uBBVGADiffCount = 1; - return; - } - - priv->uBBVGADiffCount++; - - if (priv->uBBVGADiffCount == 1) { - /* first VGA diff gain */ - bb_set_vga_gain_offset(priv, priv->bbvga_new); - - dev_dbg(&priv->pcid->dev, - "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)dbm, priv->bbvga_new, - priv->bbvga_current, - (int)priv->uBBVGADiffCount); - } - - if (priv->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) { - dev_dbg(&priv->pcid->dev, - "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)dbm, priv->bbvga_new, - priv->bbvga_current, - (int)priv->uBBVGADiffCount); - - bb_set_vga_gain_offset(priv, priv->bbvga_new); - } -} - -static void vnt_interrupt_process(struct vnt_private *priv) -{ - struct ieee80211_low_level_stats *low_stats = &priv->low_stats; - int max_count = 0; - u32 mib_counter; - u32 isr; - unsigned long flags; - - isr = ioread32(priv->port_offset + MAC_REG_ISR); - - if (isr == 0) - return; - - if (isr == 0xffffffff) { - pr_debug("isr = 0xffff\n"); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - - /* Read low level stats */ - mib_counter = ioread32(priv->port_offset + MAC_REG_MIBCNTR); - - low_stats->dot11RTSSuccessCount += mib_counter & 0xff; - low_stats->dot11RTSFailureCount += (mib_counter >> 8) & 0xff; - low_stats->dot11ACKFailureCount += (mib_counter >> 16) & 0xff; - low_stats->dot11FCSErrorCount += (mib_counter >> 24) & 0xff; - - /* - * TBD.... - * Must do this after doing rx/tx, cause ISR bit is slow - * than RD/TD write back - * update ISR counter - */ - while (isr && priv->vif) { - iowrite32(isr, priv->port_offset + MAC_REG_ISR); - - if (isr & ISR_FETALERR) { - pr_debug(" ISR_FETALERR\n"); - iowrite8(0, priv->port_offset + MAC_REG_SOFTPWRCTL); - iowrite16(SOFTPWRCTL_SWPECTI, priv->port_offset + MAC_REG_SOFTPWRCTL); - device_error(priv, isr); - } - - if (isr & ISR_TBTT) { - if (priv->op_mode != NL80211_IFTYPE_ADHOC) - vnt_check_bb_vga(priv); - - priv->bBeaconSent = false; - if (priv->bEnablePSMode) - PSbIsNextTBTTWakeUp((void *)priv); - - if ((priv->op_mode == NL80211_IFTYPE_AP || - priv->op_mode == NL80211_IFTYPE_ADHOC) && - priv->vif->bss_conf.enable_beacon) - MACvOneShotTimer1MicroSec(priv, - (priv->vif->bss_conf.beacon_int - - MAKE_BEACON_RESERVED) << 10); - - /* TODO: adhoc PS mode */ - } - - if (isr & ISR_BNTX) { - if (priv->op_mode == NL80211_IFTYPE_ADHOC) { - priv->bIsBeaconBufReadySet = false; - priv->cbBeaconBufReadySetCnt = 0; - } - - priv->bBeaconSent = true; - } - - if (isr & ISR_RXDMA0) - max_count += device_rx_srv(priv, TYPE_RXDMA0); - - if (isr & ISR_RXDMA1) - max_count += device_rx_srv(priv, TYPE_RXDMA1); - - if (isr & ISR_TXDMA0) - max_count += device_tx_srv(priv, TYPE_TXDMA0); - - if (isr & ISR_AC0DMA) - max_count += device_tx_srv(priv, TYPE_AC0DMA); - - if (isr & ISR_SOFTTIMER1) { - if (priv->vif->bss_conf.enable_beacon) - vnt_beacon_make(priv, priv->vif); - } - - /* If both buffers available wake the queue */ - if (AVAIL_TD(priv, TYPE_TXDMA0) && - AVAIL_TD(priv, TYPE_AC0DMA) && - ieee80211_queue_stopped(priv->hw, 0)) - ieee80211_wake_queues(priv->hw); - - isr = ioread32(priv->port_offset + MAC_REG_ISR); - - vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL0); - vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL1); - - if (max_count > priv->opts.int_works) - break; - } - - spin_unlock_irqrestore(&priv->lock, flags); -} - -static void vnt_interrupt_work(struct work_struct *work) -{ - struct vnt_private *priv = - container_of(work, struct vnt_private, interrupt_work); - - if (priv->vif) - vnt_interrupt_process(priv); - - iowrite32(IMR_MASK_VALUE, priv->port_offset + MAC_REG_IMR); -} - -static irqreturn_t vnt_interrupt(int irq, void *arg) -{ - struct vnt_private *priv = arg; - - schedule_work(&priv->interrupt_work); - - iowrite32(0, priv->port_offset + MAC_REG_IMR); - - return IRQ_HANDLED; -} - -static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct vnt_tx_desc *head_td; - u32 dma_idx; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - if (ieee80211_is_data(hdr->frame_control)) - dma_idx = TYPE_AC0DMA; - else - dma_idx = TYPE_TXDMA0; - - if (AVAIL_TD(priv, dma_idx) < 1) { - spin_unlock_irqrestore(&priv->lock, flags); - ieee80211_stop_queues(priv->hw); - return -ENOMEM; - } - - head_td = priv->apCurrTD[dma_idx]; - - head_td->td1.tcr = 0; - - head_td->td_info->skb = skb; - - if (dma_idx == TYPE_AC0DMA) - head_td->td_info->flags = TD_FLAGS_NETIF_SKB; - - priv->apCurrTD[dma_idx] = head_td->next; - - spin_unlock_irqrestore(&priv->lock, flags); - - vnt_generate_fifo_header(priv, dma_idx, head_td, skb); - - spin_lock_irqsave(&priv->lock, flags); - - priv->bPWBitOn = false; - - /* Set TSR1 & ReqCount in TxDescHead */ - head_td->td1.tcr |= (TCR_STP | TCR_EDP | EDMSDU); - head_td->td1.req_count = cpu_to_le16(head_td->td_info->req_count); - - head_td->buff_addr = cpu_to_le32(head_td->td_info->buf_dma); - - /* Poll Transmit the adapter */ - wmb(); - head_td->td0.owner = OWNED_BY_NIC; - wmb(); /* second memory barrier */ - - if (head_td->td_info->flags & TD_FLAGS_NETIF_SKB) - vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_AC0DMACTL); - else - vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_TXDMACTL0); - - priv->iTDUsed[dma_idx]++; - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static void vnt_tx_80211(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct vnt_private *priv = hw->priv; - - if (vnt_tx_packet(priv, skb)) - ieee80211_free_txskb(hw, skb); -} - -static int vnt_start(struct ieee80211_hw *hw) -{ - struct vnt_private *priv = hw->priv; - int ret; - - priv->rx_buf_sz = PKT_BUF_SZ; - if (!device_init_rings(priv)) - return -ENOMEM; - - ret = request_irq(priv->pcid->irq, vnt_interrupt, - IRQF_SHARED, "vt6655", priv); - if (ret) { - dev_dbg(&priv->pcid->dev, "failed to start irq\n"); - goto err_free_rings; - } - - dev_dbg(&priv->pcid->dev, "call device init rd0 ring\n"); - ret = device_init_rd0_ring(priv); - if (ret) - goto err_free_irq; - ret = device_init_rd1_ring(priv); - if (ret) - goto err_free_rd0_ring; - ret = device_init_td0_ring(priv); - if (ret) - goto err_free_rd1_ring; - ret = device_init_td1_ring(priv); - if (ret) - goto err_free_td0_ring; - - device_init_registers(priv); - - dev_dbg(&priv->pcid->dev, "enable MAC interrupt\n"); - iowrite32(IMR_MASK_VALUE, priv->port_offset + MAC_REG_IMR); - - ieee80211_wake_queues(hw); - - return 0; - -err_free_td0_ring: - device_free_td0_ring(priv); -err_free_rd1_ring: - device_free_rd1_ring(priv); -err_free_rd0_ring: - device_free_rd0_ring(priv); -err_free_irq: - free_irq(priv->pcid->irq, priv); -err_free_rings: - device_free_rings(priv); - return ret; -} - -static void vnt_stop(struct ieee80211_hw *hw, bool suspend) -{ - struct vnt_private *priv = hw->priv; - - ieee80211_stop_queues(hw); - - cancel_work_sync(&priv->interrupt_work); - - MACbShutdown(priv); - MACbSoftwareReset(priv); - card_radio_power_off(priv); - - device_free_td0_ring(priv); - device_free_td1_ring(priv); - device_free_rd0_ring(priv); - device_free_rd1_ring(priv); - device_free_rings(priv); - - free_irq(priv->pcid->irq, priv); -} - -static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - priv->vif = vif; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_ADHOC: - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_RCR, RCR_UNICAST); - - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - - break; - case NL80211_IFTYPE_AP: - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_RCR, RCR_UNICAST); - - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP); - - break; - default: - return -EOPNOTSUPP; - } - - priv->op_mode = vif->type; - - return 0; -} - -static void vnt_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_ADHOC: - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX); - vt6655_mac_reg_bits_off(priv->port_offset, - MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - break; - case NL80211_IFTYPE_AP: - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX); - vt6655_mac_reg_bits_off(priv->port_offset, - MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP); - break; - default: - break; - } - - priv->op_mode = NL80211_IFTYPE_UNSPECIFIED; -} - -static int vnt_config(struct ieee80211_hw *hw, u32 changed) -{ - struct vnt_private *priv = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - u8 bb_type; - - if (changed & IEEE80211_CONF_CHANGE_PS) { - if (conf->flags & IEEE80211_CONF_PS) - PSvEnablePowerSaving(priv, conf->listen_interval); - else - PSvDisablePowerSaving(priv); - } - - if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || - (conf->flags & IEEE80211_CONF_OFFCHANNEL)) { - set_channel(priv, conf->chandef.chan); - - if (conf->chandef.chan->band == NL80211_BAND_5GHZ) - bb_type = BB_TYPE_11A; - else - bb_type = BB_TYPE_11G; - - if (priv->byBBType != bb_type) { - priv->byBBType = bb_type; - - card_set_phy_parameter(priv, priv->byBBType); - } - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - if (priv->byBBType == BB_TYPE_11B) - priv->wCurrentRate = RATE_1M; - else - priv->wCurrentRate = RATE_54M; - - RFbSetPower(priv, priv->wCurrentRate, - conf->chandef.chan->hw_value); - } - - return 0; -} - -static void vnt_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *conf, u64 changed) -{ - struct vnt_private *priv = hw->priv; - - priv->current_aid = vif->cfg.aid; - - if (changed & BSS_CHANGED_BSSID && conf->bssid) { - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - vt6655_mac_write_bssid_addr(priv->port_offset, conf->bssid); - - spin_unlock_irqrestore(&priv->lock, flags); - } - - if (changed & BSS_CHANGED_BASIC_RATES) { - priv->basic_rates = conf->basic_rates; - - CARDvUpdateBasicTopRate(priv); - - dev_dbg(&priv->pcid->dev, - "basic rates %x\n", conf->basic_rates); - } - - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - if (conf->use_short_preamble) { - vt6655_mac_en_barker_preamble_md(priv->port_offset); - priv->preamble_type = true; - } else { - vt6655_mac_dis_barker_preamble_md(priv->port_offset); - priv->preamble_type = false; - } - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - if (conf->use_cts_prot) - vt6655_mac_en_protect_md(priv->port_offset); - else - vt6655_mac_dis_protect_md(priv->port_offset); - } - - if (changed & BSS_CHANGED_ERP_SLOT) { - if (conf->use_short_slot) - priv->short_slot_time = true; - else - priv->short_slot_time = false; - - card_set_phy_parameter(priv, priv->byBBType); - bb_set_vga_gain_offset(priv, priv->bbvga[0]); - } - - if (changed & BSS_CHANGED_TXPOWER) - RFbSetPower(priv, priv->wCurrentRate, - conf->chanreq.oper.chan->hw_value); - - if (changed & BSS_CHANGED_BEACON_ENABLED) { - dev_dbg(&priv->pcid->dev, - "Beacon enable %d\n", conf->enable_beacon); - - if (conf->enable_beacon) { - vnt_beacon_enable(priv, vif, conf); - - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX); - } else { - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR, - TCR_AUTOBCNTX); - } - } - - if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) && - priv->op_mode != NL80211_IFTYPE_AP) { - if (vif->cfg.assoc && conf->beacon_rate) { - card_update_tsf(priv, conf->beacon_rate->hw_value, - conf->sync_tsf); - - card_set_beacon_period(priv, conf->beacon_int); - - CARDvSetFirstNextTBTT(priv, conf->beacon_int); - } else { - iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL); - iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL); - } - } -} - -static u64 vnt_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - struct vnt_private *priv = hw->priv; - struct netdev_hw_addr *ha; - u64 mc_filter = 0; - u32 bit_nr = 0; - - netdev_hw_addr_list_for_each(ha, mc_list) { - bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; - - mc_filter |= 1ULL << (bit_nr & 0x3f); - } - - priv->mc_list_count = mc_list->count; - - return mc_filter; -} - -static void vnt_configure(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast) -{ - struct vnt_private *priv = hw->priv; - u8 rx_mode = 0; - - *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC; - - rx_mode = ioread8(priv->port_offset + MAC_REG_RCR); - - dev_dbg(&priv->pcid->dev, "rx mode in = %x\n", rx_mode); - - if (changed_flags & FIF_ALLMULTI) { - if (*total_flags & FIF_ALLMULTI) { - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->mc_list_count > 2) { - VT6655_MAC_SELECT_PAGE1(priv->port_offset); - - iowrite32(0xffffffff, priv->port_offset + MAC_REG_MAR0); - iowrite32(0xffffffff, priv->port_offset + MAC_REG_MAR0 + 4); - - VT6655_MAC_SELECT_PAGE0(priv->port_offset); - } else { - VT6655_MAC_SELECT_PAGE1(priv->port_offset); - - multicast = le64_to_cpu(multicast); - iowrite32((u32)multicast, priv->port_offset + MAC_REG_MAR0); - iowrite32((u32)(multicast >> 32), - priv->port_offset + MAC_REG_MAR0 + 4); - - VT6655_MAC_SELECT_PAGE0(priv->port_offset); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - rx_mode |= RCR_MULTICAST | RCR_BROADCAST; - } else { - rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST); - } - } - - if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) { - rx_mode |= RCR_MULTICAST | RCR_BROADCAST; - - if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) - rx_mode &= ~RCR_BSSID; - else - rx_mode |= RCR_BSSID; - } - - iowrite8(rx_mode, priv->port_offset + MAC_REG_RCR); - - dev_dbg(&priv->pcid->dev, "rx mode out= %x\n", rx_mode); -} - -static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct vnt_private *priv = hw->priv; - - switch (cmd) { - case SET_KEY: - if (vnt_set_keys(hw, sta, vif, key)) - return -EOPNOTSUPP; - break; - case DISABLE_KEY: - if (test_bit(key->hw_key_idx, &priv->key_entry_inuse)) - clear_bit(key->hw_key_idx, &priv->key_entry_inuse); - break; - default: - break; - } - - return 0; -} - -static int vnt_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct vnt_private *priv = hw->priv; - - memcpy(stats, &priv->low_stats, sizeof(*stats)); - - return 0; -} - -static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - u64 tsf; - - tsf = vt6655_get_current_tsf(priv); - - return tsf; -} - -static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u64 tsf) -{ - struct vnt_private *priv = hw->priv; - - CARDvUpdateNextTBTT(priv, tsf, vif->bss_conf.beacon_int); -} - -static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - /* reset TSF counter */ - iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL); -} - -static const struct ieee80211_ops vnt_mac_ops = { - .add_chanctx = ieee80211_emulate_add_chanctx, - .remove_chanctx = ieee80211_emulate_remove_chanctx, - .change_chanctx = ieee80211_emulate_change_chanctx, - .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, - .tx = vnt_tx_80211, - .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = vnt_start, - .stop = vnt_stop, - .add_interface = vnt_add_interface, - .remove_interface = vnt_remove_interface, - .config = vnt_config, - .bss_info_changed = vnt_bss_info_changed, - .prepare_multicast = vnt_prepare_multicast, - .configure_filter = vnt_configure, - .set_key = vnt_set_key, - .get_stats = vnt_get_stats, - .get_tsf = vnt_get_tsf, - .set_tsf = vnt_set_tsf, - .reset_tsf = vnt_reset_tsf, -}; - -static int vnt_init(struct vnt_private *priv) -{ - SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr); - - vnt_init_bands(priv); - - if (ieee80211_register_hw(priv->hw)) - return -ENODEV; - - priv->mac_hw = true; - - card_radio_power_off(priv); - - return 0; -} - -static int -vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) -{ - struct vnt_private *priv; - struct ieee80211_hw *hw; - struct wiphy *wiphy; - int rc; - - dev_notice(&pcid->dev, - "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION); - - dev_notice(&pcid->dev, - "Copyright (c) 2003 VIA Networking Technologies, Inc.\n"); - - hw = ieee80211_alloc_hw(sizeof(*priv), &vnt_mac_ops); - if (!hw) { - dev_err(&pcid->dev, "could not register ieee80211_hw\n"); - return -ENOMEM; - } - - priv = hw->priv; - priv->pcid = pcid; - - spin_lock_init(&priv->lock); - - priv->hw = hw; - - SET_IEEE80211_DEV(priv->hw, &pcid->dev); - - if (pci_enable_device(pcid)) { - device_free_info(priv); - return -ENODEV; - } - - dev_dbg(&pcid->dev, - "Before get pci_info memaddr is %x\n", priv->memaddr); - - pci_set_master(pcid); - - priv->memaddr = pci_resource_start(pcid, 0); - priv->ioaddr = pci_resource_start(pcid, 1); - priv->port_offset = ioremap(priv->memaddr & PCI_BASE_ADDRESS_MEM_MASK, - 256); - if (!priv->port_offset) { - dev_err(&pcid->dev, ": Failed to IO remapping ..\n"); - device_free_info(priv); - return -ENODEV; - } - - rc = pci_request_regions(pcid, DEVICE_NAME); - if (rc) { - dev_err(&pcid->dev, ": Failed to find PCI device\n"); - device_free_info(priv); - return -ENODEV; - } - - if (dma_set_mask(&pcid->dev, DMA_BIT_MASK(32))) { - dev_err(&pcid->dev, ": Failed to set dma 32 bit mask\n"); - device_free_info(priv); - return -ENODEV; - } - - INIT_WORK(&priv->interrupt_work, vnt_interrupt_work); - - /* do reset */ - if (!MACbSoftwareReset(priv)) { - dev_err(&pcid->dev, ": Failed to access MAC hardware..\n"); - device_free_info(priv); - return -ENODEV; - } - /* initial to reload eeprom */ - MACvInitialize(priv); - vt6655_mac_read_ether_addr(priv->port_offset, priv->abyCurrentNetAddr); - - /* Get RFType */ - priv->rf_type = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_RFTYPE); - priv->rf_type &= RF_MASK; - - dev_dbg(&pcid->dev, "RF Type = %x\n", priv->rf_type); - - device_get_options(priv); - device_set_options(priv); - - wiphy = priv->hw->wiphy; - - wiphy->frag_threshold = FRAG_THRESH_DEF; - wiphy->rts_threshold = RTS_THRESH_DEF; - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); - - ieee80211_hw_set(priv->hw, TIMING_BEACON_ONLY); - ieee80211_hw_set(priv->hw, SIGNAL_DBM); - ieee80211_hw_set(priv->hw, RX_INCLUDES_FCS); - ieee80211_hw_set(priv->hw, REPORTS_TX_ACK_STATUS); - ieee80211_hw_set(priv->hw, SUPPORTS_PS); - - priv->hw->max_signal = 100; - - if (vnt_init(priv)) { - device_free_info(priv); - return -ENODEV; - } - - device_print_info(priv); - pci_set_drvdata(pcid, priv); - - return 0; -} - -/*------------------------------------------------------------------*/ - -static int __maybe_unused vt6655_suspend(struct device *dev_d) -{ - struct vnt_private *priv = dev_get_drvdata(dev_d); - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - MACbShutdown(priv); - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static int __maybe_unused vt6655_resume(struct device *dev_d) -{ - device_wakeup_disable(dev_d); - - return 0; -} - -MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table); - -static SIMPLE_DEV_PM_OPS(vt6655_pm_ops, vt6655_suspend, vt6655_resume); - -static struct pci_driver device_driver = { - .name = DEVICE_NAME, - .id_table = vt6655_pci_id_table, - .probe = vt6655_probe, - .remove = vt6655_remove, - .driver.pm = &vt6655_pm_ops, -}; - -module_pci_driver(device_driver); diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c deleted file mode 100644 index 7ada188e2048946e4934049d22af613eb53492af..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/dpc.c +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: handle dpc rx functions - * - * Author: Lyndon Chen - * - * Date: May 20, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "device.h" -#include "baseband.h" -#include "rf.h" -#include "dpc.h" - -static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb, - u16 bytes_received) -{ - struct ieee80211_hw *hw = priv->hw; - struct ieee80211_supported_band *sband; - struct ieee80211_rx_status rx_status = { 0 }; - struct ieee80211_hdr *hdr; - __le16 fc; - u8 *rsr, *new_rsr, *rssi; - __le64 *tsf_time; - u16 frame_size; - int ii, r; - u8 *rx_rate; - u8 *skb_data; - u8 rate_idx = 0; - u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; - long rx_dbm; - - /* [31:16]RcvByteCount ( not include 4-byte Status ) */ - frame_size = le16_to_cpu(*((__le16 *)(skb->data + 2))); - if (frame_size > 2346 || frame_size < 14) { - dev_dbg(&priv->pcid->dev, "------- WRONG Length 1\n"); - return false; - } - - skb_data = (u8 *)skb->data; - - rx_rate = skb_data + 1; - - sband = hw->wiphy->bands[hw->conf.chandef.chan->band]; - - for (r = RATE_1M; r < MAX_RATE; r++) { - if (*rx_rate == rate[r]) - break; - } - - priv->rx_rate = r; - - for (ii = 0; ii < sband->n_bitrates; ii++) { - if (sband->bitrates[ii].hw_value == r) { - rate_idx = ii; - break; - } - } - - if (ii == sband->n_bitrates) { - dev_dbg(&priv->pcid->dev, "Wrong RxRate %x\n", *rx_rate); - return false; - } - - tsf_time = (__le64 *)(skb_data + bytes_received - 12); - new_rsr = skb_data + bytes_received - 3; - rssi = skb_data + bytes_received - 2; - rsr = skb_data + bytes_received - 1; - if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN)) - return false; - - RFvRSSITodBm(priv, *rssi, &rx_dbm); - - priv->bb_pre_edrssi = (u8)rx_dbm + 1; - priv->current_rssi = *rssi; - - skb_pull(skb, 4); - skb_trim(skb, frame_size); - - rx_status.mactime = le64_to_cpu(*tsf_time); - rx_status.band = hw->conf.chandef.chan->band; - rx_status.signal = rx_dbm; - rx_status.flag = 0; - rx_status.freq = hw->conf.chandef.chan->center_freq; - - if (!(*rsr & RSR_CRCOK)) - rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; - - hdr = (struct ieee80211_hdr *)(skb->data); - fc = hdr->frame_control; - - rx_status.rate_idx = rate_idx; - - if (ieee80211_has_protected(fc)) { - if (priv->local_id > REV_ID_VT3253_A1) - rx_status.flag |= RX_FLAG_DECRYPTED; - - /* Drop packet */ - if (!(*new_rsr & NEWRSR_DECRYPTOK)) - return false; - } - - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - - ieee80211_rx_irqsafe(priv->hw, skb); - - return true; -} - -bool vnt_receive_frame(struct vnt_private *priv, struct vnt_rx_desc *curr_rd) -{ - struct vnt_rd_info *rd_info = curr_rd->rd_info; - struct sk_buff *skb; - u16 frame_size; - - skb = rd_info->skb; - - dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, - priv->rx_buf_sz, DMA_FROM_DEVICE); - - frame_size = le16_to_cpu(curr_rd->rd1.req_count) - - le16_to_cpu(curr_rd->rd0.res_count); - - if ((frame_size > 2364) || (frame_size < 33)) { - /* Frame Size error drop this packet.*/ - dev_dbg(&priv->pcid->dev, "Wrong frame size %d\n", frame_size); - dev_kfree_skb_irq(skb); - return true; - } - - if (vnt_rx_data(priv, skb, frame_size)) - return true; - - dev_kfree_skb_irq(skb); - - return true; -} diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h deleted file mode 100644 index 40364c0ab7f64f2fbc50620f7f72690be05d2504..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/dpc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: - * - * Author: Jerry Chen - * - * Date: Jun. 27, 2002 - * - */ - -#ifndef __DPC_H__ -#define __DPC_H__ - -#include "device.h" - -bool vnt_receive_frame(struct vnt_private *priv, struct vnt_rx_desc *curr_rd); - -#endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c deleted file mode 100644 index 1469015eb5b4a63a55772637edcb6dae6acb428f..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/key.c +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions for 802.11i Key management - * - * Author: Jerry Chen - * - * Date: May 29, 2003 - * - */ - -#include "key.h" -#include "mac.h" - -static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, - struct ieee80211_key_conf *key, u32 key_type, - u32 mode, bool onfly_latch) -{ - struct vnt_private *priv = hw->priv; - u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u16 key_mode = 0; - u32 entry = 0; - u8 *bssid; - u8 key_inx = key->keyidx; - u8 i; - - if (mac_addr) - bssid = mac_addr; - else - bssid = &broadcast[0]; - - if (key_type != VNT_KEY_DEFAULTKEY) { - for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { - if (!test_bit(i, &priv->key_entry_inuse)) { - set_bit(i, &priv->key_entry_inuse); - - key->hw_key_idx = i; - entry = key->hw_key_idx; - break; - } - } - } - - switch (key_type) { - case VNT_KEY_DEFAULTKEY: - /* default key last entry */ - entry = MAX_KEY_TABLE - 1; - key->hw_key_idx = entry; - fallthrough; - case VNT_KEY_ALLGROUP: - key_mode |= VNT_KEY_ALLGROUP; - if (onfly_latch) - key_mode |= VNT_KEY_ONFLY_ALL; - fallthrough; - case VNT_KEY_GROUP_ADDRESS: - key_mode |= mode; - fallthrough; - case VNT_KEY_GROUP: - key_mode |= (mode << 4); - key_mode |= VNT_KEY_GROUP; - break; - case VNT_KEY_PAIRWISE: - key_mode |= mode; - key_inx = 4; - break; - default: - return -EINVAL; - } - - if (onfly_latch) - key_mode |= VNT_KEY_ONFLY; - - if (mode == KEY_CTL_WEP) { - if (key->keylen == WLAN_KEY_LEN_WEP40) - key->key[15] &= 0x7f; - if (key->keylen == WLAN_KEY_LEN_WEP104) - key->key[15] |= 0x80; - } - - MACvSetKeyEntry(priv, key_mode, entry, key_inx, - bssid, (u32 *)key->key, priv->local_id); - - return 0; -} - -int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - struct ieee80211_vif *vif, struct ieee80211_key_conf *key) -{ - struct ieee80211_bss_conf *conf = &vif->bss_conf; - struct vnt_private *priv = hw->priv; - u8 *mac_addr = NULL; - u8 key_dec_mode = 0; - int ret = 0; - u32 u; - - if (sta) - mac_addr = &sta->addr[0]; - - switch (key->cipher) { - case 0: - for (u = 0 ; u < MAX_KEY_TABLE; u++) - MACvDisableKeyEntry(priv, u); - return ret; - - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - for (u = 0; u < MAX_KEY_TABLE; u++) - MACvDisableKeyEntry(priv, u); - - vnt_set_keymode(hw, mac_addr, - key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, true); - - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - - return ret; - case WLAN_CIPHER_SUITE_TKIP: - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - - key_dec_mode = KEY_CTL_TKIP; - - break; - case WLAN_CIPHER_SUITE_CCMP: - key_dec_mode = KEY_CTL_CCMP; - - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - } - - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { - vnt_set_keymode(hw, mac_addr, - key, VNT_KEY_PAIRWISE, key_dec_mode, true); - } else { - vnt_set_keymode(hw, mac_addr, - key, VNT_KEY_DEFAULTKEY, key_dec_mode, true); - - vnt_set_keymode(hw, (u8 *)conf->bssid, - key, VNT_KEY_GROUP_ADDRESS, key_dec_mode, true); - } - - return 0; -} diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h deleted file mode 100644 index d88da9dfb5c3be3a3b4d5b6a550f18f42360ecf0..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/key.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions for 802.11i Key management - * - * Author: Jerry Chen - * - * Date: May 29, 2003 - * - */ - -#ifndef __KEY_H__ -#define __KEY_H__ - -#include - -/*--------------------- Export Definitions -------------------------*/ -#define MAX_GROUP_KEY 4 -#define MAX_KEY_TABLE 11 -#define MAX_KEY_LEN 32 -#define AES_KEY_LEN 16 - -#define AUTHENTICATOR_KEY 0x10000000 -#define USE_KEYRSC 0x20000000 -#define PAIRWISE_KEY 0x40000000 -#define TRANSMIT_KEY 0x80000000 - -#define GROUP_KEY 0x00000000 - -#define KEY_CTL_WEP 0x00 -#define KEY_CTL_NONE 0x01 -#define KEY_CTL_TKIP 0x02 -#define KEY_CTL_CCMP 0x03 -#define KEY_CTL_INVALID 0xFF - -#define VNT_KEY_DEFAULTKEY 0x1 -#define VNT_KEY_GROUP_ADDRESS 0x2 -#define VNT_KEY_ALLGROUP 0x4 -#define VNT_KEY_GROUP 0x40 -#define VNT_KEY_PAIRWISE 0x00 -#define VNT_KEY_ONFLY 0x8000 -#define VNT_KEY_ONFLY_ALL 0x4000 - -struct vnt_private; - -int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - struct ieee80211_vif *vif, struct ieee80211_key_conf *key); - -#endif /* __KEY_H__ */ diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c deleted file mode 100644 index b4ebc7d319619065cbdf1153581c7ce9212772b2..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/mac.c +++ /dev/null @@ -1,851 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: MAC routines - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Functions: - * vt6655_mac_is_reg_bits_off - Test if All test Bits Off - * vt6655_mac_set_short_retry_limit - Set 802.11 Short Retry limit - * MACvSetLongRetryLimit - Set 802.11 Long Retry limit - * vt6655_mac_set_loopback_mode - Set MAC Loopback Mode - * vt6655_mac_save_context - Save Context of MAC Registers - * vt6655_mac_restore_context - Restore Context of MAC Registers - * MACbSoftwareReset - Software Reset MAC - * vt6655_mac_safe_rx_off - Turn Off MAC Rx - * vt6655_mac_safe_tx_off - Turn Off MAC Tx - * vt6655_mac_safe_stop - Stop MAC function - * MACbShutdown - Shut down MAC - * MACvInitialize - Initialize MAC - * MACvSetCurrRxDescAddr - Set Rx Descriptors Address - * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address - * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address - * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC - * - * Revision History: - * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53 - * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()& - * MACvEnableBusSusEn() - * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry - * - */ - -#include "mac.h" - -void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask) -{ - unsigned char reg_value; - - reg_value = ioread8(iobase + reg_offset); - iowrite8(reg_value | bit_mask, iobase + reg_offset); -} - -void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask) -{ - unsigned short reg_value; - - reg_value = ioread16(iobase + reg_offset); - iowrite16(reg_value | (bit_mask), iobase + reg_offset); -} - -void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask) -{ - unsigned char reg_value; - - reg_value = ioread8(iobase + reg_offset); - iowrite8(reg_value & ~(bit_mask), iobase + reg_offset); -} - -void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask) -{ - unsigned short reg_value; - - reg_value = ioread16(iobase + reg_offset); - iowrite16(reg_value & ~(bit_mask), iobase + reg_offset); -} - -static void vt6655_mac_clear_stck_ds(void __iomem *iobase) -{ - u8 reg_value; - - reg_value = ioread8(iobase + MAC_REG_STICKHW); - reg_value = reg_value & 0xFC; - iowrite8(reg_value, iobase + MAC_REG_STICKHW); -} - -/* - * Description: - * Test if all test bits off - * - * Parameters: - * In: - * io_base - Base Address for MAC - * reg_offset - Offset of MAC Register - * mask - Test bits - * Out: - * none - * - * Return Value: true if all test bits Off; otherwise false - * - */ -static bool vt6655_mac_is_reg_bits_off(struct vnt_private *priv, - unsigned char reg_offset, - unsigned char mask) -{ - void __iomem *io_base = priv->port_offset; - - return !(ioread8(io_base + reg_offset) & mask); -} - -/* - * Description: - * Set 802.11 Short Retry Limit - * - * Parameters: - * In: - * io_base - Base Address for MAC - * retry_limit - Retry Limit - * Out: - * none - * - * Return Value: none - * - */ -void vt6655_mac_set_short_retry_limit(struct vnt_private *priv, unsigned char retry_limit) -{ - void __iomem *io_base = priv->port_offset; - /* set SRT */ - iowrite8(retry_limit, io_base + MAC_REG_SRT); -} - -/* - * Description: - * Set 802.11 Long Retry Limit - * - * Parameters: - * In: - * io_base - Base Address for MAC - * byRetryLimit- Retry Limit - * Out: - * none - * - * Return Value: none - * - */ -void MACvSetLongRetryLimit(struct vnt_private *priv, - unsigned char byRetryLimit) -{ - void __iomem *io_base = priv->port_offset; - /* set LRT */ - iowrite8(byRetryLimit, io_base + MAC_REG_LRT); -} - -/* - * Description: - * Set MAC Loopback mode - * - * Parameters: - * In: - * io_base - Base Address for MAC - * loopback_mode - Loopback Mode - * Out: - * none - * - * Return Value: none - * - */ -static void vt6655_mac_set_loopback_mode(struct vnt_private *priv, u8 loopback_mode) -{ - void __iomem *io_base = priv->port_offset; - - loopback_mode <<= 6; - /* set TCR */ - iowrite8((ioread8(io_base + MAC_REG_TEST) & 0x3f) | loopback_mode, io_base + MAC_REG_TEST); -} - -/* - * Description: - * Save MAC registers to context buffer - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * cxt_buf - Context buffer - * - * Return Value: none - * - */ -static void vt6655_mac_save_context(struct vnt_private *priv, u8 *cxt_buf) -{ - void __iomem *io_base = priv->port_offset; - - /* read page0 register */ - memcpy_fromio(cxt_buf, io_base, MAC_MAX_CONTEXT_SIZE_PAGE0); - - VT6655_MAC_SELECT_PAGE1(io_base); - - /* read page1 register */ - memcpy_fromio(cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, io_base, - MAC_MAX_CONTEXT_SIZE_PAGE1); - - VT6655_MAC_SELECT_PAGE0(io_base); -} - -/* - * Description: - * Restore MAC registers from context buffer - * - * Parameters: - * In: - * io_base - Base Address for MAC - * cxt_buf - Context buffer - * Out: - * none - * - * Return Value: none - * - */ -static void vt6655_mac_restore_context(struct vnt_private *priv, u8 *cxt_buf) -{ - void __iomem *io_base = priv->port_offset; - - VT6655_MAC_SELECT_PAGE1(io_base); - /* restore page1 */ - memcpy_toio(io_base, cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, - MAC_MAX_CONTEXT_SIZE_PAGE1); - - VT6655_MAC_SELECT_PAGE0(io_base); - - /* restore RCR,TCR,IMR... */ - memcpy_toio(io_base + MAC_REG_RCR, cxt_buf + MAC_REG_RCR, - MAC_REG_ISR - MAC_REG_RCR); - - /* restore MAC Config. */ - memcpy_toio(io_base + MAC_REG_LRT, cxt_buf + MAC_REG_LRT, - MAC_REG_PAGE1SEL - MAC_REG_LRT); - - iowrite8(*(cxt_buf + MAC_REG_CFG), io_base + MAC_REG_CFG); - - /* restore PS Config. */ - memcpy_toio(io_base + MAC_REG_PSCFG, cxt_buf + MAC_REG_PSCFG, - MAC_REG_BBREGCTL - MAC_REG_PSCFG); - - /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */ - iowrite32(*(u32 *)(cxt_buf + MAC_REG_TXDMAPTR0), - io_base + MAC_REG_TXDMAPTR0); - iowrite32(*(u32 *)(cxt_buf + MAC_REG_AC0DMAPTR), - io_base + MAC_REG_AC0DMAPTR); - iowrite32(*(u32 *)(cxt_buf + MAC_REG_BCNDMAPTR), - io_base + MAC_REG_BCNDMAPTR); - iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR0), - io_base + MAC_REG_RXDMAPTR0); - iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR1), - io_base + MAC_REG_RXDMAPTR1); -} - -/* - * Description: - * Software Reset MAC - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * none - * - * Return Value: true if Reset Success; otherwise false - * - */ -bool MACbSoftwareReset(struct vnt_private *priv) -{ - void __iomem *io_base = priv->port_offset; - unsigned short ww; - - /* turn on HOSTCR_SOFTRST, just write 0x01 to reset */ - iowrite8(0x01, io_base + MAC_REG_HOSTCR); - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_SOFTRST)) - break; - } - if (ww == W_MAX_TIMEOUT) - return false; - return true; -} - -/* - * Description: - * save some important register's value, then do reset, then restore - * register's value - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -static void vt6655_mac_save_soft_reset(struct vnt_private *priv) -{ - u8 tmp_reg_data[MAC_MAX_CONTEXT_SIZE_PAGE0 + MAC_MAX_CONTEXT_SIZE_PAGE1]; - - /* PATCH.... - * save some important register's value, then do - * reset, then restore register's value - */ - /* save MAC context */ - vt6655_mac_save_context(priv, tmp_reg_data); - /* do reset */ - MACbSoftwareReset(priv); - /* restore MAC context, except CR0 */ - vt6655_mac_restore_context(priv, tmp_reg_data); -} - -/* - * Description: - * Turn Off MAC Rx - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -static bool vt6655_mac_safe_rx_off(struct vnt_private *priv) -{ - void __iomem *io_base = priv->port_offset; - unsigned short ww; - - /* turn off wow temp for turn off Rx safely */ - - /* Clear RX DMA0,1 */ - iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL0); - iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL1); - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread32(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x10)\n"); - return false; - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread32(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x11)\n"); - return false; - } - - /* try to safe shutdown RX */ - vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_RXON); - /* W_MAX_TIMEOUT is the timeout period */ - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_RXONST)) - break; - } - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x12)\n"); - return false; - } - return true; -} - -/* - * Description: - * Turn Off MAC Tx - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -static bool vt6655_mac_safe_tx_off(struct vnt_private *priv) -{ - void __iomem *io_base = priv->port_offset; - unsigned short ww; - - /* Clear TX DMA */ - /* Tx0 */ - iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_TXDMACTL0); - /* AC0 */ - iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_AC0DMACTL); - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread32(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x20)\n"); - return false; - } - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread32(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x21)\n"); - return false; - } - - /* try to safe shutdown TX */ - vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_TXON); - - /* W_MAX_TIMEOUT is the timeout period */ - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_TXONST)) - break; - } - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x24)\n"); - return false; - } - return true; -} - -/* - * Description: - * Stop MAC function - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -static bool vt6655_mac_safe_stop(struct vnt_private *priv) -{ - void __iomem *io_base = priv->port_offset; - - vt6655_mac_reg_bits_off(io_base, MAC_REG_TCR, TCR_AUTOBCNTX); - - if (!vt6655_mac_safe_rx_off(priv)) { - pr_debug(" vt6655_mac_safe_rx_off == false)\n"); - vt6655_mac_save_soft_reset(priv); - return false; - } - if (!vt6655_mac_safe_tx_off(priv)) { - pr_debug(" vt6655_mac_safe_tx_off == false)\n"); - vt6655_mac_save_soft_reset(priv); - return false; - } - - vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN); - - return true; -} - -/* - * Description: - * Shut Down MAC - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -bool MACbShutdown(struct vnt_private *priv) -{ - void __iomem *io_base = priv->port_offset; - /* disable MAC IMR */ - iowrite32(0, io_base + MAC_REG_IMR); - vt6655_mac_set_loopback_mode(priv, MAC_LB_INTERNAL); - /* stop the adapter */ - if (!vt6655_mac_safe_stop(priv)) { - vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE); - return false; - } - vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE); - return true; -} - -/* - * Description: - * Initialize MAC - * - * Parameters: - * In: - * io_base - Base Address for MAC - * Out: - * none - * - * Return Value: none - * - */ -void MACvInitialize(struct vnt_private *priv) -{ - void __iomem *io_base = priv->port_offset; - /* clear sticky bits */ - vt6655_mac_clear_stck_ds(io_base); - /* disable force PME-enable */ - iowrite8(PME_OVR, io_base + MAC_REG_PMC1); - /* only 3253 A */ - - /* do reset */ - MACbSoftwareReset(priv); - - /* reset TSF counter */ - iowrite8(TFTCTL_TSFCNTRST, io_base + MAC_REG_TFTCTL); - /* enable TSF counter */ - iowrite8(TFTCTL_TSFCNTREN, io_base + MAC_REG_TFTCTL); -} - -/* - * Description: - * Set the chip with current rx descriptor address - * - * Parameters: - * In: - * io_base - Base Address for MAC - * curr_desc_addr - Descriptor Address - * Out: - * none - * - * Return Value: none - * - */ -void vt6655_mac_set_curr_rx_0_desc_addr(struct vnt_private *priv, u32 curr_desc_addr) -{ - void __iomem *io_base = priv->port_offset; - unsigned short ww; - unsigned char org_dma_ctl; - - org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL0); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0 + 2); - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread8(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN)) - break; - } - - iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR0); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0); -} - -/* - * Description: - * Set the chip with current rx descriptor address - * - * Parameters: - * In: - * io_base - Base Address for MAC - * curr_desc_addr - Descriptor Address - * Out: - * none - * - * Return Value: none - * - */ -void vt6655_mac_set_curr_rx_1_desc_addr(struct vnt_private *priv, u32 curr_desc_addr) -{ - void __iomem *io_base = priv->port_offset; - unsigned short ww; - unsigned char org_dma_ctl; - - org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL1); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1 + 2); - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread8(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN)) - break; - } - - iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR1); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1); -} - -/* - * Description: - * Set the chip with current tx0 descriptor address - * - * Parameters: - * In: - * io_base - Base Address for MAC - * curr_desc_addr - Descriptor Address - * Out: - * none - * - * Return Value: none - * - */ -static void vt6655_mac_set_curr_tx_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr) -{ - void __iomem *io_base = priv->port_offset; - unsigned short ww; - unsigned char org_dma_ctl; - - org_dma_ctl = ioread8(io_base + MAC_REG_TXDMACTL0); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0 + 2); - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread8(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN)) - break; - } - - iowrite32(curr_desc_addr, io_base + MAC_REG_TXDMAPTR0); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0); -} - -/* - * Description: - * Set the chip with current AC0 descriptor address - * - * Parameters: - * In: - * io_base - Base Address for MAC - * curr_desc_addr - Descriptor Address - * Out: - * none - * - * Return Value: none - * - */ -/* TxDMA1 = AC0DMA */ -static void vt6655_mac_set_curr_ac_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr) -{ - void __iomem *io_base = priv->port_offset; - unsigned short ww; - unsigned char org_dma_ctl; - - org_dma_ctl = ioread8(io_base + MAC_REG_AC0DMACTL); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL + 2); - - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (!(ioread8(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN)) - break; - } - if (ww == W_MAX_TIMEOUT) - pr_debug(" DBG_PORT80(0x26)\n"); - iowrite32(curr_desc_addr, io_base + MAC_REG_AC0DMAPTR); - if (org_dma_ctl & DMACTL_RUN) - iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL); -} - -void vt6655_mac_set_curr_tx_desc_addr(int tx_type, struct vnt_private *priv, u32 curr_desc_addr) -{ - if (tx_type == TYPE_AC0DMA) - vt6655_mac_set_curr_ac_0_desc_addr_ex(priv, curr_desc_addr); - else if (tx_type == TYPE_TXDMA0) - vt6655_mac_set_curr_tx_0_desc_addr_ex(priv, curr_desc_addr); -} - -/* - * Description: - * Micro Second Delay via MAC - * - * Parameters: - * In: - * io_base - Base Address for MAC - * uDelay - Delay time (timer resolution is 4 us) - * Out: - * none - * - * Return Value: none - * - */ -void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay) -{ - void __iomem *io_base = priv->port_offset; - unsigned char byValue; - unsigned int uu, ii; - - iowrite8(0, io_base + MAC_REG_TMCTL0); - iowrite32(uDelay, io_base + MAC_REG_TMDATA0); - iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL0); - for (ii = 0; ii < 66; ii++) { /* assume max PCI clock is 66Mhz */ - for (uu = 0; uu < uDelay; uu++) { - byValue = ioread8(io_base + MAC_REG_TMCTL0); - if ((byValue == 0) || - (byValue & TMCTL_TSUSP)) { - iowrite8(0, io_base + MAC_REG_TMCTL0); - return; - } - } - } - iowrite8(0, io_base + MAC_REG_TMCTL0); -} - -/* - * Description: - * Micro Second One shot timer via MAC - * - * Parameters: - * In: - * io_base - Base Address for MAC - * uDelay - Delay time - * Out: - * none - * - * Return Value: none - * - */ -void MACvOneShotTimer1MicroSec(struct vnt_private *priv, - unsigned int uDelayTime) -{ - void __iomem *io_base = priv->port_offset; - - iowrite8(0, io_base + MAC_REG_TMCTL1); - iowrite32(uDelayTime, io_base + MAC_REG_TMDATA1); - iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL1); -} - -void MACvSetMISCFifo(struct vnt_private *priv, unsigned short offset, - u32 data) -{ - void __iomem *io_base = priv->port_offset; - - if (offset > 273) - return; - iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); - iowrite32(data, io_base + MAC_REG_MISCFFDATA); - iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); -} - -bool MACbPSWakeup(struct vnt_private *priv) -{ - void __iomem *io_base = priv->port_offset; - unsigned int ww; - /* Read PSCTL */ - if (vt6655_mac_is_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_PS)) - return true; - - /* Disable PS */ - vt6655_mac_reg_bits_off(io_base, MAC_REG_PSCTL, PSCTL_PSEN); - - /* Check if SyncFlushOK */ - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - if (ioread8(io_base + MAC_REG_PSCTL) & PSCTL_WAKEDONE) - break; - } - if (ww == W_MAX_TIMEOUT) { - pr_debug(" DBG_PORT80(0x33)\n"); - return false; - } - return true; -} - -/* - * Description: - * Set the Key by MISCFIFO - * - * Parameters: - * In: - * io_base - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ - -void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl, - unsigned int uEntryIdx, unsigned int uKeyIdx, - unsigned char *pbyAddr, u32 *pdwKey, - unsigned char local_id) -{ - void __iomem *io_base = priv->port_offset; - unsigned short offset; - u32 data; - int ii; - - if (local_id <= 1) - return; - - offset = MISCFIFO_KEYETRY0; - offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); - - data = 0; - data |= wKeyCtl; - data <<= 16; - data |= MAKEWORD(*(pbyAddr + 4), *(pbyAddr + 5)); - pr_debug("1. offset: %d, Data: %X, KeyCtl:%X\n", - offset, data, wKeyCtl); - - iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); - iowrite32(data, io_base + MAC_REG_MISCFFDATA); - iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); - offset++; - - data = 0; - data |= *(pbyAddr + 3); - data <<= 8; - data |= *(pbyAddr + 2); - data <<= 8; - data |= *(pbyAddr + 1); - data <<= 8; - data |= *pbyAddr; - pr_debug("2. offset: %d, Data: %X\n", offset, data); - - iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); - iowrite32(data, io_base + MAC_REG_MISCFFDATA); - iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); - offset++; - - offset += (uKeyIdx * 4); - for (ii = 0; ii < 4; ii++) { - /* always push 128 bits */ - pr_debug("3.(%d) offset: %d, Data: %X\n", - ii, offset + ii, *pdwKey); - iowrite16(offset + ii, io_base + MAC_REG_MISCFFNDEX); - iowrite32(*pdwKey++, io_base + MAC_REG_MISCFFDATA); - iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); - } -} - -/* - * Description: - * Disable the Key Entry by MISCFIFO - * - * Parameters: - * In: - * io_base - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ -void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx) -{ - void __iomem *io_base = priv->port_offset; - unsigned short offset; - - offset = MISCFIFO_KEYETRY0; - offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); - - iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); - iowrite32(0, io_base + MAC_REG_MISCFFDATA); - iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); -} diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h deleted file mode 100644 index a33af28522276324034edc884ae2823ad7a68ad0..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/mac.h +++ /dev/null @@ -1,580 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: MAC routines - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Revision History: - * 07-01-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. - * 08-25-2003 Kyle Hsu: Porting MAC functions from sim53. - * 09-03-2003 Bryan YC Fan: Add vt6655_mac_dis_protect_md & vt6655_mac_en_protect_md - */ - -#ifndef __MAC_H__ -#define __MAC_H__ - -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ -/* Registers in the MAC */ -#define MAC_MAX_CONTEXT_SIZE_PAGE0 256 -#define MAC_MAX_CONTEXT_SIZE_PAGE1 128 - -/* Registers not related to 802.11b */ -#define MAC_REG_BCFG0 0x00 -#define MAC_REG_BCFG1 0x01 -#define MAC_REG_FCR0 0x02 -#define MAC_REG_FCR1 0x03 -#define MAC_REG_BISTCMD 0x04 -#define MAC_REG_BISTSR0 0x05 -#define MAC_REG_BISTSR1 0x06 -#define MAC_REG_BISTSR2 0x07 -#define MAC_REG_I2MCSR 0x08 -#define MAC_REG_I2MTGID 0x09 -#define MAC_REG_I2MTGAD 0x0A -#define MAC_REG_I2MCFG 0x0B -#define MAC_REG_I2MDIPT 0x0C -#define MAC_REG_I2MDOPT 0x0E -#define MAC_REG_PMC0 0x10 -#define MAC_REG_PMC1 0x11 -#define MAC_REG_STICKHW 0x12 -#define MAC_REG_LOCALID 0x14 -#define MAC_REG_TESTCFG 0x15 -#define MAC_REG_JUMPER0 0x16 -#define MAC_REG_JUMPER1 0x17 -#define MAC_REG_TMCTL0 0x18 -#define MAC_REG_TMCTL1 0x19 -#define MAC_REG_TMDATA0 0x1C - -/* MAC Parameter related */ -#define MAC_REG_LRT 0x20 -#define MAC_REG_SRT 0x21 -#define MAC_REG_SIFS 0x22 -#define MAC_REG_DIFS 0x23 -#define MAC_REG_EIFS 0x24 -#define MAC_REG_SLOT 0x25 -#define MAC_REG_BI 0x26 -#define MAC_REG_CWMAXMIN0 0x28 -#define MAC_REG_LINKOFFTOTM 0x2A -#define MAC_REG_SWTMOT 0x2B -#define MAC_REG_MIBCNTR 0x2C -#define MAC_REG_RTSOKCNT 0x2C -#define MAC_REG_RTSFAILCNT 0x2D -#define MAC_REG_ACKFAILCNT 0x2E -#define MAC_REG_FCSERRCNT 0x2F - -/* TSF Related */ -#define MAC_REG_TSFCNTR 0x30 -#define MAC_REG_NEXTTBTT 0x38 -#define MAC_REG_TSFOFST 0x40 -#define MAC_REG_TFTCTL 0x48 - -/* WMAC Control/Status Related */ -#define MAC_REG_ENCFG 0x4C -#define MAC_REG_PAGE1SEL 0x4F -#define MAC_REG_CFG 0x50 -#define MAC_REG_TEST 0x52 -#define MAC_REG_HOSTCR 0x54 -#define MAC_REG_MACCR 0x55 -#define MAC_REG_RCR 0x56 -#define MAC_REG_TCR 0x57 -#define MAC_REG_IMR 0x58 -#define MAC_REG_ISR 0x5C - -/* Power Saving Related */ -#define MAC_REG_PSCFG 0x60 -#define MAC_REG_PSCTL 0x61 -#define MAC_REG_PSPWRSIG 0x62 -#define MAC_REG_BBCR13 0x63 -#define MAC_REG_AIDATIM 0x64 -#define MAC_REG_PWBT 0x66 -#define MAC_REG_WAKEOKTMR 0x68 -#define MAC_REG_CALTMR 0x69 -#define MAC_REG_SYNSPACCNT 0x6A -#define MAC_REG_WAKSYNOPT 0x6B - -/* Baseband/IF Control Group */ -#define MAC_REG_BBREGCTL 0x6C -#define MAC_REG_CHANNEL 0x6D -#define MAC_REG_BBREGADR 0x6E -#define MAC_REG_BBREGDATA 0x6F -#define MAC_REG_IFREGCTL 0x70 -#define MAC_REG_IFDATA 0x71 -#define MAC_REG_ITRTMSET 0x74 -#define MAC_REG_PAPEDELAY 0x77 -#define MAC_REG_SOFTPWRCTL 0x78 -#define MAC_REG_GPIOCTL0 0x7A -#define MAC_REG_GPIOCTL1 0x7B - -/* MAC DMA Related Group */ -#define MAC_REG_TXDMACTL0 0x7C -#define MAC_REG_TXDMAPTR0 0x80 -#define MAC_REG_AC0DMACTL 0x84 -#define MAC_REG_AC0DMAPTR 0x88 -#define MAC_REG_BCNDMACTL 0x8C -#define MAC_REG_BCNDMAPTR 0x90 -#define MAC_REG_RXDMACTL0 0x94 -#define MAC_REG_RXDMAPTR0 0x98 -#define MAC_REG_RXDMACTL1 0x9C -#define MAC_REG_RXDMAPTR1 0xA0 -#define MAC_REG_SYNCDMACTL 0xA4 -#define MAC_REG_SYNCDMAPTR 0xA8 -#define MAC_REG_ATIMDMACTL 0xAC -#define MAC_REG_ATIMDMAPTR 0xB0 - -/* MiscFF PIO related */ -#define MAC_REG_MISCFFNDEX 0xB4 -#define MAC_REG_MISCFFCTL 0xB6 -#define MAC_REG_MISCFFDATA 0xB8 - -/* Extend SW Timer */ -#define MAC_REG_TMDATA1 0xBC - -/* WOW Related Group */ -#define MAC_REG_WAKEUPEN0 0xC0 -#define MAC_REG_WAKEUPEN1 0xC1 -#define MAC_REG_WAKEUPSR0 0xC2 -#define MAC_REG_WAKEUPSR1 0xC3 -#define MAC_REG_WAKE128_0 0xC4 -#define MAC_REG_WAKE128_1 0xD4 -#define MAC_REG_WAKE128_2 0xE4 -#define MAC_REG_WAKE128_3 0xF4 - -/************** Page 1 ******************/ -#define MAC_REG_CRC_128_0 0x04 -#define MAC_REG_CRC_128_1 0x06 -#define MAC_REG_CRC_128_2 0x08 -#define MAC_REG_CRC_128_3 0x0A - -/* MAC Configuration Group */ -#define MAC_REG_PAR0 0x0C -#define MAC_REG_PAR4 0x10 -#define MAC_REG_BSSID0 0x14 -#define MAC_REG_BSSID4 0x18 -#define MAC_REG_MAR0 0x1C -#define MAC_REG_MAR4 0x20 - -/* MAC RSPPKT INFO Group */ -#define MAC_REG_RSPINF_B_1 0x24 -#define MAC_REG_RSPINF_B_2 0x28 -#define MAC_REG_RSPINF_B_5 0x2C -#define MAC_REG_RSPINF_B_11 0x30 -#define MAC_REG_RSPINF_A_6 0x34 -#define MAC_REG_RSPINF_A_9 0x36 -#define MAC_REG_RSPINF_A_12 0x38 -#define MAC_REG_RSPINF_A_18 0x3A -#define MAC_REG_RSPINF_A_24 0x3C -#define MAC_REG_RSPINF_A_36 0x3E -#define MAC_REG_RSPINF_A_48 0x40 -#define MAC_REG_RSPINF_A_54 0x42 -#define MAC_REG_RSPINF_A_72 0x44 - -/* 802.11h relative */ -#define MAC_REG_QUIETINIT 0x60 -#define MAC_REG_QUIETGAP 0x62 -#define MAC_REG_QUIETDUR 0x64 -#define MAC_REG_MSRCTL 0x66 -#define MAC_REG_MSRBBSTS 0x67 -#define MAC_REG_MSRSTART 0x68 -#define MAC_REG_MSRDURATION 0x70 -#define MAC_REG_CCAFRACTION 0x72 -#define MAC_REG_PWRCCK 0x73 -#define MAC_REG_PWROFDM 0x7C - -/* Bits in the BCFG0 register */ -#define BCFG0_PERROFF 0x40 -#define BCFG0_MRDMDIS 0x20 -#define BCFG0_MRDLDIS 0x10 -#define BCFG0_MWMEN 0x08 -#define BCFG0_VSERREN 0x02 -#define BCFG0_LATMEN 0x01 - -/* Bits in the BCFG1 register */ -#define BCFG1_CFUNOPT 0x80 -#define BCFG1_CREQOPT 0x40 -#define BCFG1_DMA8 0x10 -#define BCFG1_ARBITOPT 0x08 -#define BCFG1_PCIMEN 0x04 -#define BCFG1_MIOEN 0x02 -#define BCFG1_CISDLYEN 0x01 - -/* Bits in RAMBIST registers */ -#define BISTCMD_TSTPAT5 0x00 -#define BISTCMD_TSTPATA 0x80 -#define BISTCMD_TSTERR 0x20 -#define BISTCMD_TSTPATF 0x18 -#define BISTCMD_TSTPAT0 0x10 -#define BISTCMD_TSTMODE 0x04 -#define BISTCMD_TSTITTX 0x03 -#define BISTCMD_TSTATRX 0x02 -#define BISTCMD_TSTATTX 0x01 -#define BISTCMD_TSTRX 0x00 -#define BISTSR0_BISTGO 0x01 -#define BISTSR1_TSTSR 0x01 -#define BISTSR2_CMDPRTEN 0x02 -#define BISTSR2_RAMTSTEN 0x01 - -/* Bits in the I2MCFG EEPROM register */ -#define I2MCFG_BOUNDCTL 0x80 -#define I2MCFG_WAITCTL 0x20 -#define I2MCFG_SCLOECTL 0x10 -#define I2MCFG_WBUSYCTL 0x08 -#define I2MCFG_NORETRY 0x04 -#define I2MCFG_I2MLDSEQ 0x02 -#define I2MCFG_I2CMFAST 0x01 - -/* Bits in the I2MCSR EEPROM register */ -#define I2MCSR_EEMW 0x80 -#define I2MCSR_EEMR 0x40 -#define I2MCSR_AUTOLD 0x08 -#define I2MCSR_NACK 0x02 -#define I2MCSR_DONE 0x01 - -/* Bits in the PMC1 register */ -#define SPS_RST 0x80 -#define PCISTIKY 0x40 -#define PME_OVR 0x02 - -/* Bits in the STICKYHW register */ -#define STICKHW_DS1_SHADOW 0x02 -#define STICKHW_DS0_SHADOW 0x01 - -/* Bits in the TMCTL register */ -#define TMCTL_TSUSP 0x04 -#define TMCTL_TMD 0x02 -#define TMCTL_TE 0x01 - -/* Bits in the TFTCTL register */ -#define TFTCTL_HWUTSF 0x80 -#define TFTCTL_TBTTSYNC 0x40 -#define TFTCTL_HWUTSFEN 0x20 -#define TFTCTL_TSFCNTRRD 0x10 -#define TFTCTL_TBTTSYNCEN 0x08 -#define TFTCTL_TSFSYNCEN 0x04 -#define TFTCTL_TSFCNTRST 0x02 -#define TFTCTL_TSFCNTREN 0x01 - -/* Bits in the EnhanceCFG register */ -#define ENCFG_BARKERPREAM 0x00020000 -#define ENCFG_NXTBTTCFPSTR 0x00010000 -#define ENCFG_BCNSUSCLR 0x00000200 -#define ENCFG_BCNSUSIND 0x00000100 -#define ENCFG_CFP_PROTECTEN 0x00000040 -#define ENCFG_PROTECTMD 0x00000020 -#define ENCFG_HWPARCFP 0x00000010 -#define ENCFG_CFNULRSP 0x00000004 -#define ENCFG_BBTYPE_MASK 0x00000003 -#define ENCFG_BBTYPE_G 0x00000002 -#define ENCFG_BBTYPE_B 0x00000001 -#define ENCFG_BBTYPE_A 0x00000000 - -/* Bits in the Page1Sel register */ -#define PAGE1_SEL 0x01 - -/* Bits in the CFG register */ -#define CFG_TKIPOPT 0x80 -#define CFG_RXDMAOPT 0x40 -#define CFG_TMOT_SW 0x20 -#define CFG_TMOT_HWLONG 0x10 -#define CFG_TMOT_HW 0x00 -#define CFG_CFPENDOPT 0x08 -#define CFG_BCNSUSEN 0x04 -#define CFG_NOTXTIMEOUT 0x02 -#define CFG_NOBUFOPT 0x01 - -/* Bits in the TEST register */ -#define TEST_LBEXT 0x80 -#define TEST_LBINT 0x40 -#define TEST_LBNONE 0x00 -#define TEST_SOFTINT 0x20 -#define TEST_CONTTX 0x10 -#define TEST_TXPE 0x08 -#define TEST_NAVDIS 0x04 -#define TEST_NOCTS 0x02 -#define TEST_NOACK 0x01 - -/* Bits in the HOSTCR register */ -#define HOSTCR_TXONST 0x80 -#define HOSTCR_RXONST 0x40 -#define HOSTCR_ADHOC 0x20 /* Network Type 1 = Ad-hoc */ -#define HOSTCR_AP 0x10 /* Port Type 1 = AP */ -#define HOSTCR_TXON 0x08 /* 0000 1000 */ -#define HOSTCR_RXON 0x04 /* 0000 0100 */ -#define HOSTCR_MACEN 0x02 /* 0000 0010 */ -#define HOSTCR_SOFTRST 0x01 /* 0000 0001 */ - -/* Bits in the MACCR register */ -#define MACCR_SYNCFLUSHOK 0x04 -#define MACCR_SYNCFLUSH 0x02 -#define MACCR_CLRNAV 0x01 - -/* Bits in the MAC_REG_GPIOCTL0 register */ -#define LED_ACTSET 0x01 -#define LED_RFOFF 0x02 -#define LED_NOCONNECT 0x04 - -/* Bits in the RCR register */ -#define RCR_SSID 0x80 -#define RCR_RXALLTYPE 0x40 -#define RCR_UNICAST 0x20 -#define RCR_BROADCAST 0x10 -#define RCR_MULTICAST 0x08 -#define RCR_WPAERR 0x04 -#define RCR_ERRCRC 0x02 -#define RCR_BSSID 0x01 - -/* Bits in the TCR register */ -#define TCR_SYNCDCFOPT 0x02 -#define TCR_AUTOBCNTX 0x01 /* Beacon automatically transmit enable */ - -/* Bits in the IMR register */ -#define IMR_MEASURESTART 0x80000000 -#define IMR_QUIETSTART 0x20000000 -#define IMR_RADARDETECT 0x10000000 -#define IMR_MEASUREEND 0x08000000 -#define IMR_SOFTTIMER1 0x00200000 -#define IMR_RXDMA1 0x00001000 /* 0000 0000 0001 0000 0000 0000 */ -#define IMR_RXNOBUF 0x00000800 -#define IMR_MIBNEARFULL 0x00000400 -#define IMR_SOFTINT 0x00000200 -#define IMR_FETALERR 0x00000100 -#define IMR_WATCHDOG 0x00000080 -#define IMR_SOFTTIMER 0x00000040 -#define IMR_GPIO 0x00000020 -#define IMR_TBTT 0x00000010 -#define IMR_RXDMA0 0x00000008 -#define IMR_BNTX 0x00000004 -#define IMR_AC0DMA 0x00000002 -#define IMR_TXDMA0 0x00000001 - -/* Bits in the ISR register */ -#define ISR_MEASURESTART 0x80000000 -#define ISR_QUIETSTART 0x20000000 -#define ISR_RADARDETECT 0x10000000 -#define ISR_MEASUREEND 0x08000000 -#define ISR_SOFTTIMER1 0x00200000 -#define ISR_RXDMA1 0x00001000 /* 0000 0000 0001 0000 0000 0000 */ -#define ISR_RXNOBUF 0x00000800 /* 0000 0000 0000 1000 0000 0000 */ -#define ISR_MIBNEARFULL 0x00000400 /* 0000 0000 0000 0100 0000 0000 */ -#define ISR_SOFTINT 0x00000200 -#define ISR_FETALERR 0x00000100 -#define ISR_WATCHDOG 0x00000080 -#define ISR_SOFTTIMER 0x00000040 -#define ISR_GPIO 0x00000020 -#define ISR_TBTT 0x00000010 -#define ISR_RXDMA0 0x00000008 -#define ISR_BNTX 0x00000004 -#define ISR_AC0DMA 0x00000002 -#define ISR_TXDMA0 0x00000001 - -/* Bits in the PSCFG register */ -#define PSCFG_PHILIPMD 0x40 -#define PSCFG_WAKECALEN 0x20 -#define PSCFG_WAKETMREN 0x10 -#define PSCFG_BBPSPROG 0x08 -#define PSCFG_WAKESYN 0x04 -#define PSCFG_SLEEPSYN 0x02 -#define PSCFG_AUTOSLEEP 0x01 - -/* Bits in the PSCTL register */ -#define PSCTL_WAKEDONE 0x20 -#define PSCTL_PS 0x10 -#define PSCTL_GO2DOZE 0x08 -#define PSCTL_LNBCN 0x04 -#define PSCTL_ALBCN 0x02 -#define PSCTL_PSEN 0x01 - -/* Bits in the PSPWSIG register */ -#define PSSIG_WPE3 0x80 -#define PSSIG_WPE2 0x40 -#define PSSIG_WPE1 0x20 -#define PSSIG_WRADIOPE 0x10 -#define PSSIG_SPE3 0x08 -#define PSSIG_SPE2 0x04 -#define PSSIG_SPE1 0x02 -#define PSSIG_SRADIOPE 0x01 - -/* Bits in the BBREGCTL register */ -#define BBREGCTL_DONE 0x04 -#define BBREGCTL_REGR 0x02 -#define BBREGCTL_REGW 0x01 - -/* Bits in the IFREGCTL register */ -#define IFREGCTL_DONE 0x04 -#define IFREGCTL_IFRF 0x02 -#define IFREGCTL_REGW 0x01 - -/* Bits in the SOFTPWRCTL register */ -#define SOFTPWRCTL_RFLEOPT 0x0800 -#define SOFTPWRCTL_TXPEINV 0x0200 -#define SOFTPWRCTL_SWPECTI 0x0100 -#define SOFTPWRCTL_SWPAPE 0x0020 -#define SOFTPWRCTL_SWCALEN 0x0010 -#define SOFTPWRCTL_SWRADIO_PE 0x0008 -#define SOFTPWRCTL_SWPE2 0x0004 -#define SOFTPWRCTL_SWPE1 0x0002 -#define SOFTPWRCTL_SWPE3 0x0001 - -/* Bits in the GPIOCTL1 register */ -#define GPIO1_DATA1 0x20 -#define GPIO1_MD1 0x10 -#define GPIO1_DATA0 0x02 -#define GPIO1_MD0 0x01 - -/* Bits in the DMACTL register */ -#define DMACTL_CLRRUN 0x00080000 -#define DMACTL_RUN 0x00000008 -#define DMACTL_WAKE 0x00000004 -#define DMACTL_DEAD 0x00000002 -#define DMACTL_ACTIVE 0x00000001 - -/* Bits in the RXDMACTL0 register */ -#define RX_PERPKT 0x00000100 -#define RX_PERPKTCLR 0x01000000 - -/* Bits in the BCNDMACTL register */ -#define BEACON_READY 0x01 - -/* Bits in the MISCFFCTL register */ -#define MISCFFCTL_WRITE 0x0001 - -/* Bits in WAKEUPEN0 */ -#define WAKEUPEN0_DIRPKT 0x10 -#define WAKEUPEN0_LINKOFF 0x08 -#define WAKEUPEN0_ATIMEN 0x04 -#define WAKEUPEN0_TIMEN 0x02 -#define WAKEUPEN0_MAGICEN 0x01 - -/* Bits in WAKEUPEN1 */ -#define WAKEUPEN1_128_3 0x08 -#define WAKEUPEN1_128_2 0x04 -#define WAKEUPEN1_128_1 0x02 -#define WAKEUPEN1_128_0 0x01 - -/* Bits in WAKEUPSR0 */ -#define WAKEUPSR0_DIRPKT 0x10 -#define WAKEUPSR0_LINKOFF 0x08 -#define WAKEUPSR0_ATIMEN 0x04 -#define WAKEUPSR0_TIMEN 0x02 -#define WAKEUPSR0_MAGICEN 0x01 - -/* Bits in WAKEUPSR1 */ -#define WAKEUPSR1_128_3 0x08 -#define WAKEUPSR1_128_2 0x04 -#define WAKEUPSR1_128_1 0x02 -#define WAKEUPSR1_128_0 0x01 - -/* Bits in the MAC_REG_GPIOCTL register */ -#define GPIO0_MD 0x01 -#define GPIO0_DATA 0x02 -#define GPIO0_INTMD 0x04 -#define GPIO1_MD 0x10 -#define GPIO1_DATA 0x20 - -/* Bits in the MSRCTL register */ -#define MSRCTL_FINISH 0x80 -#define MSRCTL_READY 0x40 -#define MSRCTL_RADARDETECT 0x20 -#define MSRCTL_EN 0x10 -#define MSRCTL_QUIETTXCHK 0x08 -#define MSRCTL_QUIETRPT 0x04 -#define MSRCTL_QUIETINT 0x02 -#define MSRCTL_QUIETEN 0x01 - -/* Bits in the MSRCTL1 register */ -#define MSRCTL1_TXPWR 0x08 -#define MSRCTL1_CSAPAREN 0x04 -#define MSRCTL1_TXPAUSE 0x01 - -/* Loopback mode */ -#define MAC_LB_EXT 0x02 -#define MAC_LB_INTERNAL 0x01 -#define MAC_LB_NONE 0x00 - -#define DEFAULT_BI 0x200 - -/* MiscFIFO Offset */ -#define MISCFIFO_KEYETRY0 32 -#define MISCFIFO_KEYENTRYSIZE 22 -#define MISCFIFO_SYNINFO_IDX 10 -#define MISCFIFO_SYNDATA_IDX 11 -#define MISCFIFO_SYNDATASIZE 21 - -/* enabled mask value of irq */ -#define IMR_MASK_VALUE (IMR_SOFTTIMER1 | \ - IMR_RXDMA1 | \ - IMR_RXNOBUF | \ - IMR_MIBNEARFULL | \ - IMR_SOFTINT | \ - IMR_FETALERR | \ - IMR_WATCHDOG | \ - IMR_SOFTTIMER | \ - IMR_GPIO | \ - IMR_TBTT | \ - IMR_RXDMA0 | \ - IMR_BNTX | \ - IMR_AC0DMA | \ - IMR_TXDMA0) - -/* max time out delay time */ -#define W_MAX_TIMEOUT 0xFFF0U - -/* wait time within loop */ -#define CB_DELAY_LOOP_WAIT 10 /* 10ms */ - -/* revision id */ -#define REV_ID_VT3253_A0 0x00 -#define REV_ID_VT3253_A1 0x01 -#define REV_ID_VT3253_B0 0x08 -#define REV_ID_VT3253_B1 0x09 - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -#define VT6655_MAC_SELECT_PAGE0(iobase) iowrite8(0, (iobase) + MAC_REG_PAGE1SEL) - -#define VT6655_MAC_SELECT_PAGE1(iobase) iowrite8(1, (iobase) + MAC_REG_PAGE1SEL) - -#define MAKEWORD(lb, hb) \ - ((unsigned short)(((unsigned char)(lb)) | (((unsigned short)((unsigned char)(hb))) << 8))) - -void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask); -void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask); -void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask); -void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask); - -void vt6655_mac_set_short_retry_limit(struct vnt_private *priv, unsigned char retry_limit); - -void MACvSetLongRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit); - -bool MACbSoftwareReset(struct vnt_private *priv); -bool MACbShutdown(struct vnt_private *priv); -void MACvInitialize(struct vnt_private *priv); -void vt6655_mac_set_curr_rx_0_desc_addr(struct vnt_private *priv, u32 curr_desc_addr); -void vt6655_mac_set_curr_rx_1_desc_addr(struct vnt_private *priv, u32 curr_desc_addr); -void vt6655_mac_set_curr_tx_desc_addr(int tx_type, struct vnt_private *priv, u32 curr_desc_addr); -void MACvSetCurrSyncDescAddrEx(struct vnt_private *priv, - u32 curr_desc_addr); -void MACvSetCurrATIMDescAddrEx(struct vnt_private *priv, - u32 curr_desc_addr); -void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay); -void MACvOneShotTimer1MicroSec(struct vnt_private *priv, unsigned int uDelayTime); - -void MACvSetMISCFifo(struct vnt_private *priv, unsigned short wOffset, - u32 dwData); - -bool MACbPSWakeup(struct vnt_private *priv); - -void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl, - unsigned int uEntryIdx, unsigned int uKeyIdx, - unsigned char *pbyAddr, u32 *pdwKey, - unsigned char local_id); -void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx); - -#endif /* __MAC_H__ */ diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c deleted file mode 100644 index 8527ad3eff4862dcd72deeb0d8a4167027105050..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/power.c +++ /dev/null @@ -1,144 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Handles 802.11 power management functions - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - * Functions: - * PSvEnablePowerSaving - Enable Power Saving Mode - * PSvDiasblePowerSaving - Disable Power Saving Mode - * PSbConsiderPowerDown - Decide if we can Power Down - * PSvSendPSPOLL - Send PS-POLL packet - * PSbSendNullPacket - Send Null packet - * PSbIsNextTBTTWakeUp - Decide if we need to wake up at next Beacon - * - * Revision History: - * - */ - -#include "mac.h" -#include "device.h" -#include "power.h" -#include "card.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* - * - * Routine Description: - * Enable hw power saving functions - * - * Return Value: - * None. - * - */ - -void PSvEnablePowerSaving(struct vnt_private *priv, - unsigned short wListenInterval) -{ - u16 wAID = priv->current_aid | BIT(14) | BIT(15); - - /* set period of power up before TBTT */ - iowrite16(C_PWBT, priv->port_offset + MAC_REG_PWBT); - if (priv->op_mode != NL80211_IFTYPE_ADHOC) { - /* set AID */ - iowrite16(wAID, priv->port_offset + MAC_REG_AIDATIM); - } - - /* Set AutoSleep */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - - /* Set HWUTSF */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); - - if (wListenInterval >= 2) { - /* clear always listen beacon */ - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN); - /* first time set listen next beacon */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_LNBCN); - } else { - /* always listen beacon */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN); - } - - /* enable power saving hw function */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_PSEN); - priv->bEnablePSMode = true; - - priv->bPWBitOn = true; - pr_debug("PS:Power Saving Mode Enable...\n"); -} - -/* - * - * Routine Description: - * Disable hw power saving functions - * - * Return Value: - * None. - * - */ - -void PSvDisablePowerSaving(struct vnt_private *priv) -{ - /* disable power saving hw function */ - MACbPSWakeup(priv); - - /* clear AutoSleep */ - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - - /* clear HWUTSF */ - vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); - - /* set always listen beacon */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN); - - priv->bEnablePSMode = false; - - priv->bPWBitOn = false; -} - -/* - * - * Routine Description: - * Check if Next TBTT must wake up - * - * Return Value: - * None. - * - */ - -bool PSbIsNextTBTTWakeUp(struct vnt_private *priv) -{ - struct ieee80211_hw *hw = priv->hw; - struct ieee80211_conf *conf = &hw->conf; - bool wake_up = false; - - if (conf->listen_interval > 1) { - if (!priv->wake_up_count) - priv->wake_up_count = conf->listen_interval; - - --priv->wake_up_count; - - if (priv->wake_up_count == 1) { - /* Turn on wake up to listen next beacon */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_LNBCN); - wake_up = true; - } - } - - return wake_up; -} diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h deleted file mode 100644 index 060516f81f5bbd14e8f7a013b7b1bf602a14ffca..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/power.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Handles 802.11 power management functions - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - */ - -#ifndef __POWER_H__ -#define __POWER_H__ - -#include "device.h" - -#define C_PWBT 1000 /* micro sec. power up before TBTT */ -#define PS_FAST_INTERVAL 1 /* Fast power saving listen interval */ -#define PS_MAX_INTERVAL 4 /* MAX power saving listen interval */ - -void PSvDisablePowerSaving(struct vnt_private *priv); - -void PSvEnablePowerSaving(struct vnt_private *priv, unsigned short wListenInterval); - -bool PSbIsNextTBTTWakeUp(struct vnt_private *priv); - -#endif /* __POWER_H__ */ diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c deleted file mode 100644 index d319ec21c97b89d45e2f9aed4d05174b3a7aef02..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/rf.c +++ /dev/null @@ -1,535 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: rf function code - * - * Author: Jerry Chen - * - * Date: Feb. 19, 2004 - * - * Functions: - * IFRFbWriteEmbedded - Embedded write RF register via MAC - * - * Revision History: - * RobertYu 2005 - * chester 2008 - * - */ - -#include "mac.h" -#include "srom.h" -#include "rf.h" -#include "baseband.h" - -#define BY_AL2230_REG_LEN 23 /* 24bit */ -#define CB_AL2230_INIT_SEQ 15 -#define SWITCH_CHANNEL_DELAY_AL2230 200 /* us */ -#define AL2230_PWR_IDX_LEN 64 - -#define BY_AL7230_REG_LEN 23 /* 24bit */ -#define CB_AL7230_INIT_SEQ 16 -#define SWITCH_CHANNEL_DELAY_AL7230 200 /* us */ -#define AL7230_PWR_IDX_LEN 64 - -static const unsigned long al2230_init_table[CB_AL2230_INIT_SEQ] = { - 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x01A00200 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x00FFF300 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0F4DC500 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0805B600 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0146C700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x00068800 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0403B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x00DBBA00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x00099B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0BDFFC00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x00000D00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x00580F00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW -}; - -static const unsigned long al2230_channel_table0[CB_MAX_CHANNEL] = { - 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 1, Tf = 2412MHz */ - 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 2, Tf = 2417MHz */ - 0x03E79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 3, Tf = 2422MHz */ - 0x03E79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 4, Tf = 2427MHz */ - 0x03F7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 5, Tf = 2432MHz */ - 0x03F7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 6, Tf = 2437MHz */ - 0x03E7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 7, Tf = 2442MHz */ - 0x03E7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 8, Tf = 2447MHz */ - 0x03F7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 9, Tf = 2452MHz */ - 0x03F7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 10, Tf = 2457MHz */ - 0x03E7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 11, Tf = 2462MHz */ - 0x03E7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 12, Tf = 2467MHz */ - 0x03F7C000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 13, Tf = 2472MHz */ - 0x03E7C000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW /* channel = 14, Tf = 2412M */ -}; - -static const unsigned long al2230_channel_table1[CB_MAX_CHANNEL] = { - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 1, Tf = 2412MHz */ - 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 2, Tf = 2417MHz */ - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 3, Tf = 2422MHz */ - 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 4, Tf = 2427MHz */ - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 5, Tf = 2432MHz */ - 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 6, Tf = 2437MHz */ - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 7, Tf = 2442MHz */ - 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 8, Tf = 2447MHz */ - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 9, Tf = 2452MHz */ - 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 10, Tf = 2457MHz */ - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 11, Tf = 2462MHz */ - 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 12, Tf = 2467MHz */ - 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 13, Tf = 2472MHz */ - 0x06666100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW /* channel = 14, Tf = 2412M */ -}; - -static unsigned long al2230_power_table[AL2230_PWR_IDX_LEN] = { - 0x04040900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04041900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04042900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04043900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04044900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04045900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04046900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04047900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04048900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04049900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0404A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0404B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0404C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0404D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0404E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0404F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04050900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04051900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04052900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04053900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04054900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04055900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04056900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04057900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04058900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04059900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0405A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0405B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0405C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0405D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0405E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0405F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04060900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04061900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04062900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04063900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04064900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04065900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04066900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04067900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04068900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04069900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0406A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0406B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0406C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0406D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0406E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0406F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04070900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04071900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04072900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04073900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04074900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04075900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04076900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04077900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04078900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x04079900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0407A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0407B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0407C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0407D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0407E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, - 0x0407F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW -}; - -/* - * Description: Write to IF/RF, by embedded programming - * - * Parameters: - * In: - * iobase - I/O base address - * dwData - data to write - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ -bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData) -{ - void __iomem *iobase = priv->port_offset; - unsigned short ww; - unsigned long dwValue; - - iowrite32((u32)dwData, iobase + MAC_REG_IFREGCTL); - - /* W_MAX_TIMEOUT is the timeout period */ - for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { - dwValue = ioread32(iobase + MAC_REG_IFREGCTL); - if (dwValue & IFREGCTL_DONE) - break; - } - - if (ww == W_MAX_TIMEOUT) - return false; - - return true; -} - -/* - * Description: AIROHA IFRF chip init function - * - * Parameters: - * In: - * iobase - I/O base address - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ -static bool RFbAL2230Init(struct vnt_private *priv) -{ - void __iomem *iobase = priv->port_offset; - int ii; - bool ret; - - ret = true; - - /* 3-wire control for normal mode */ - iowrite8(0, iobase + MAC_REG_SOFTPWRCTL); - - vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, - (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); - /* PLL Off */ - vt6655_mac_word_reg_bits_off(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - - /* patch abnormal AL2230 frequency output */ - IFRFbWriteEmbedded(priv, (0x07168700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW)); - - for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) - ret &= IFRFbWriteEmbedded(priv, al2230_init_table[ii]); - MACvTimer0MicroSDelay(priv, 30); /* delay 30 us */ - - /* PLL On */ - vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); - - MACvTimer0MicroSDelay(priv, 150);/* 150us */ - ret &= IFRFbWriteEmbedded(priv, (0x00d80f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW)); - MACvTimer0MicroSDelay(priv, 30);/* 30us */ - ret &= IFRFbWriteEmbedded(priv, (0x00780f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW)); - MACvTimer0MicroSDelay(priv, 30);/* 30us */ - ret &= IFRFbWriteEmbedded(priv, - al2230_init_table[CB_AL2230_INIT_SEQ - 1]); - - vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | - SOFTPWRCTL_SWPE2 | - SOFTPWRCTL_SWPECTI | - SOFTPWRCTL_TXPEINV)); - - /* 3-wire control for power saving mode */ - iowrite8(PSSIG_WPE3 | PSSIG_WPE2, iobase + MAC_REG_PSPWRSIG); - - return ret; -} - -static bool RFbAL2230SelectChannel(struct vnt_private *priv, unsigned char byChannel) -{ - void __iomem *iobase = priv->port_offset; - bool ret; - - ret = true; - - ret &= IFRFbWriteEmbedded(priv, al2230_channel_table0[byChannel - 1]); - ret &= IFRFbWriteEmbedded(priv, al2230_channel_table1[byChannel - 1]); - - /* Set Channel[7] = 0 to tell H/W channel is changing now. */ - iowrite8(byChannel & 0x7F, iobase + MAC_REG_CHANNEL); - MACvTimer0MicroSDelay(priv, SWITCH_CHANNEL_DELAY_AL2230); - /* Set Channel[7] = 1 to tell H/W channel change is done. */ - iowrite8(byChannel | 0x80, iobase + MAC_REG_CHANNEL); - - return ret; -} - -/* - * Description: RF init function - * - * Parameters: - * In: - * byBBType - * rf_type - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ -bool RFbInit(struct vnt_private *priv) -{ - bool ret = true; - - switch (priv->rf_type) { - case RF_AIROHA: - case RF_AL2230S: - priv->max_pwr_level = AL2230_PWR_IDX_LEN; - ret = RFbAL2230Init(priv); - break; - case RF_NOTHING: - ret = true; - break; - default: - ret = false; - break; - } - return ret; -} - -/* - * Description: Select channel - * - * Parameters: - * In: - * rf_type - * byChannel - Channel number - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ -bool RFbSelectChannel(struct vnt_private *priv, unsigned char rf_type, - u16 byChannel) -{ - bool ret = true; - - switch (rf_type) { - case RF_AIROHA: - case RF_AL2230S: - ret = RFbAL2230SelectChannel(priv, byChannel); - break; - /*{{ RobertYu: 20050104 */ - case RF_NOTHING: - ret = true; - break; - default: - ret = false; - break; - } - return ret; -} - -/* - * Description: Write WakeProgSyn - * - * Parameters: - * In: - * priv - Device Structure - * rf_type - RF type - * channel - Channel number - * - * Return Value: true if succeeded; false if failed. - * - */ -bool rf_write_wake_prog_syn(struct vnt_private *priv, unsigned char rf_type, - u16 channel) -{ - void __iomem *iobase = priv->port_offset; - int i; - unsigned char init_count = 0; - unsigned char sleep_count = 0; - unsigned short idx = MISCFIFO_SYNDATA_IDX; - - iowrite16(0, iobase + MAC_REG_MISCFFNDEX); - switch (rf_type) { - case RF_AIROHA: - case RF_AL2230S: - - if (channel > CB_MAX_CHANNEL_24G) - return false; - - /* Init Reg + Channel Reg (2) */ - init_count = CB_AL2230_INIT_SEQ + 2; - sleep_count = 0; - - for (i = 0; i < CB_AL2230_INIT_SEQ; i++) - MACvSetMISCFifo(priv, idx++, al2230_init_table[i]); - - MACvSetMISCFifo(priv, idx++, al2230_channel_table0[channel - 1]); - MACvSetMISCFifo(priv, idx++, al2230_channel_table1[channel - 1]); - break; - - /* Need to check, PLLON need to be low for channel setting */ - - case RF_NOTHING: - return true; - - default: - return false; - } - - MACvSetMISCFifo(priv, MISCFIFO_SYNINFO_IDX, (unsigned long)MAKEWORD(sleep_count, init_count)); - - return true; -} - -/* - * Description: Set Tx power - * - * Parameters: - * In: - * iobase - I/O base address - * dwRFPowerTable - RF Tx Power Setting - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ -bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH) -{ - bool ret; - unsigned char byPwr = 0; - unsigned char byDec = 0; - - if (priv->dwDiagRefCount != 0) - return true; - - if ((uCH < 1) || (uCH > CB_MAX_CHANNEL)) - return false; - - switch (rate) { - case RATE_1M: - case RATE_2M: - case RATE_5M: - case RATE_11M: - if (uCH > CB_MAX_CHANNEL_24G) - return false; - - byPwr = priv->abyCCKPwrTbl[uCH]; - break; - case RATE_6M: - case RATE_9M: - case RATE_12M: - case RATE_18M: - byPwr = priv->abyOFDMPwrTbl[uCH]; - byDec = byPwr + 10; - - if (byDec >= priv->max_pwr_level) - byDec = priv->max_pwr_level - 1; - - byPwr = byDec; - break; - case RATE_24M: - case RATE_36M: - case RATE_48M: - case RATE_54M: - byPwr = priv->abyOFDMPwrTbl[uCH]; - break; - } - - if (priv->cur_pwr == byPwr) - return true; - - ret = RFbRawSetPower(priv, byPwr, rate); - if (ret) - priv->cur_pwr = byPwr; - - return ret; -} - -/* - * Description: Set Tx power - * - * Parameters: - * In: - * iobase - I/O base address - * dwRFPowerTable - RF Tx Power Setting - * Out: - * none - * - * Return Value: true if succeeded; false if failed. - * - */ - -bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr, - unsigned int rate) -{ - bool ret = true; - - if (byPwr >= priv->max_pwr_level) - return false; - - switch (priv->rf_type) { - case RF_AIROHA: - ret &= IFRFbWriteEmbedded(priv, al2230_power_table[byPwr]); - if (rate <= RATE_11M) - ret &= IFRFbWriteEmbedded(priv, 0x0001B400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW); - else - ret &= IFRFbWriteEmbedded(priv, 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW); - - break; - - case RF_AL2230S: - ret &= IFRFbWriteEmbedded(priv, al2230_power_table[byPwr]); - if (rate <= RATE_11M) { - ret &= IFRFbWriteEmbedded(priv, 0x040C1400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW); - ret &= IFRFbWriteEmbedded(priv, 0x00299B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW); - } else { - ret &= IFRFbWriteEmbedded(priv, 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW); - ret &= IFRFbWriteEmbedded(priv, 0x00099B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW); - } - - break; - - default: - break; - } - return ret; -} - -/* - * - * Routine Description: - * Translate RSSI to dBm - * - * Parameters: - * In: - * priv - The adapter to be translated - * byCurrRSSI - RSSI to be translated - * Out: - * pdwdbm - Translated dbm number - * - * Return Value: none - * - */ -void -RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI, long *pldBm) -{ - unsigned char byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03); - long b = (byCurrRSSI & 0x3F); - long a = 0; - unsigned char abyAIROHARF[4] = {0, 18, 0, 40}; - - switch (priv->rf_type) { - case RF_AIROHA: - case RF_AL2230S: - a = abyAIROHARF[byIdx]; - break; - default: - break; - } - - *pldBm = -1 * (a + b * 2); -} - diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h deleted file mode 100644 index 8eef100c7ef29e9aef650c715e6ca8d037aafbda..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/rf.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: - * - * Author: Jerry Chen - * - * Date: Feb. 19, 2004 - * - */ - -#ifndef __RF_H__ -#define __RF_H__ - -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ -/* - * Baseband RF pair definition in eeprom (Bits 6..0) - */ -#define RF_RFMD2959 0x01 -#define RF_MAXIMAG 0x02 -#define RF_AIROHA 0x03 - -#define RF_UW2451 0x05 -#define RF_MAXIMG 0x06 -#define RF_MAXIM2829 0x07 /* RobertYu: 20041118 */ -#define RF_UW2452 0x08 /* RobertYu: 20041210 */ -#define RF_AIROHA7230 0x0a /* RobertYu: 20050104 */ -#define RF_UW2453 0x0b - -#define RF_VT3226 0x09 -#define RF_AL2230S 0x0e - -#define RF_NOTHING 0x7E -#define RF_EMU 0x80 -#define RF_MASK 0x7F - -#define ZONE_FCC 0 -#define ZONE_MKK1 1 -#define ZONE_ETSI 2 -#define ZONE_IC 3 -#define ZONE_SPAIN 4 -#define ZONE_FRANCE 5 -#define ZONE_MKK 6 -#define ZONE_ISRAEL 7 - -/* [20050104] CB_MAXIM2829_CHANNEL_5G_HIGH, CB_UW2452_CHANNEL_5G_HIGH: 40==>41 */ -#define CB_MAXIM2829_CHANNEL_5G_HIGH 41 /* Index41: channel = 100, Tf = 5500MHz, set the (A3:A0=0101) D6=1 */ -#define CB_UW2452_CHANNEL_5G_HIGH 41 /* [20041210] Index41: channel = 100, Tf = 5500MHz, change VCO2->VCO3 */ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData); -bool RFbSelectChannel(struct vnt_private *priv, unsigned char rf_type, u16 byChannel); -bool RFbInit(struct vnt_private *priv); -bool rf_write_wake_prog_syn(struct vnt_private *priv, unsigned char rf_type, u16 channel); -bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH); -bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr, - unsigned int rate); - -void RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI, - long *pldBm); - -#endif /* __RF_H__ */ diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c deleted file mode 100644 index 3705cb1e87b635553e18be672c9b35144bcfef64..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/rxtx.c +++ /dev/null @@ -1,1462 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: handle WMAC/802.3/802.11 rx & tx functions - * - * Author: Lyndon Chen - * - * Date: May 20, 2003 - * - * Functions: - * s_vGenerateTxParameter - Generate tx dma required parameter. - * vGenerateMACHeader - Translate 802.3 to 802.11 header - * cbGetFragCount - Calculate fragment number count - * csBeacon_xmit - beacon tx function - * csMgmt_xmit - management tx function - * s_cbFillTxBufHead - fulfill tx dma buffer header - * s_uGetDataDuration - get tx data required duration - * s_uFillDataHead- fulfill tx data duration header - * s_uGetRTSCTSDuration- get rtx/cts required duration - * get_rtscts_time- get rts/cts reserved time - * s_uGetTxRsvTime- get frame reserved time - * s_vFillCTSHead- fulfill CTS ctl header - * s_vFillFragParameter- Set fragment ctl parameter. - * s_vFillRTSHead- fulfill RTS ctl header - * s_vFillTxKey- fulfill tx encrypt key - * s_vSWencryption- Software encrypt header - * vDMA0_tx_80211- tx 802.11 frame via dma0 - * vGenerateFIFOHeader- Generate tx FIFO ctl header - * - * Revision History: - * - */ - -#include "device.h" -#include "rxtx.h" -#include "card.h" -#include "mac.h" -#include "baseband.h" -#include "rf.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ -/* if packet size < 256 -> in-direct send - * vpacket size >= 256 -> direct send - */ -#define CRITICAL_PACKET_LEN 256 - -static const unsigned short time_stamp_off[2][MAX_RATE] = { - {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */ - {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */ -}; - -static const unsigned short fb_opt0[2][5] = { - {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */ - {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */ -}; - -static const unsigned short fb_opt1[2][5] = { - {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */ - {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */ -}; - -#define RTSDUR_BB 0 -#define RTSDUR_BA 1 -#define RTSDUR_AA 2 -#define CTSDUR_BA 3 -#define RTSDUR_BA_F0 4 -#define RTSDUR_AA_F0 5 -#define RTSDUR_BA_F1 6 -#define RTSDUR_AA_F1 7 -#define CTSDUR_BA_F0 8 -#define CTSDUR_BA_F1 9 -#define DATADUR_B 10 -#define DATADUR_A 11 -#define DATADUR_A_F0 12 -#define DATADUR_A_F1 13 - -/*--------------------- Static Functions --------------------------*/ -static -void -s_vFillRTSHead( - struct vnt_private *pDevice, - unsigned char byPktType, - void *pvRTS, - unsigned int cbFrameLength, - bool bNeedAck, - bool bDisCRC, - struct ieee80211_hdr *hdr, - unsigned short wCurrentRate, - unsigned char byFBOption -); - -static -void -s_vGenerateTxParameter( - struct vnt_private *pDevice, - unsigned char byPktType, - struct vnt_tx_fifo_head *, - void *pvRrvTime, - void *pvRTS, - void *pvCTS, - unsigned int cbFrameSize, - bool bNeedACK, - unsigned int uDMAIdx, - void *psEthHeader, - unsigned short wCurrentRate -); - -static unsigned int -s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, - unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD, - unsigned int uNodeIndex); - -static -__le16 -s_uFillDataHead( - struct vnt_private *pDevice, - unsigned char byPktType, - void *pTxDataHead, - unsigned int cbFrameLength, - unsigned int uDMAIdx, - bool bNeedAck, - unsigned int uFragIdx, - unsigned int cbLastFragmentSize, - unsigned int uMACfragNum, - unsigned char byFBOption, - unsigned short wCurrentRate, - bool is_pspoll -); - -/*--------------------- Export Variables --------------------------*/ - -static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) -{ - return cpu_to_le16(time_stamp_off[priv->preamble_type % 2] - [rate % MAX_RATE]); -} - -/* byPktType : PK_TYPE_11A 0 - * PK_TYPE_11B 1 - * PK_TYPE_11GB 2 - * PK_TYPE_11GA 3 - */ -static -unsigned int -s_uGetTxRsvTime( - struct vnt_private *pDevice, - unsigned char byPktType, - unsigned int cbFrameLength, - unsigned short wRate, - bool bNeedAck -) -{ - unsigned int uDataTime, uAckTime; - - uDataTime = bb_get_frame_time(pDevice->preamble_type, byPktType, cbFrameLength, wRate); - - if (!bNeedAck) - return uDataTime; - - /* - * CCK mode - 11b - * OFDM mode - 11g 2.4G & 11a 5G - */ - uAckTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, - byPktType == PK_TYPE_11B ? - pDevice->byTopCCKBasicRate : - pDevice->byTopOFDMBasicRate); - - return uDataTime + pDevice->uSIFS + uAckTime; -} - -static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type, - u32 frame_length, u16 rate, bool need_ack) -{ - return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type, - frame_length, rate, need_ack)); -} - -/* byFreqType: 0=>5GHZ 1=>2.4GHZ */ -static __le16 get_rtscts_time(struct vnt_private *priv, - unsigned char rts_rsvtype, - unsigned char pkt_type, - unsigned int frame_length, - unsigned short current_rate) -{ - unsigned int rrv_time = 0; - unsigned int rts_time = 0; - unsigned int cts_time = 0; - unsigned int ack_time = 0; - unsigned int data_time = 0; - - data_time = bb_get_frame_time(priv->preamble_type, pkt_type, frame_length, current_rate); - if (rts_rsvtype == 0) { /* RTSTxRrvTime_bb */ - rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate); - ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate); - cts_time = ack_time; - } else if (rts_rsvtype == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */ - rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate); - cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate); - ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate); - } else if (rts_rsvtype == 2) { /* RTSTxRrvTime_aa */ - rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopOFDMBasicRate); - ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate); - cts_time = ack_time; - } else if (rts_rsvtype == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */ - cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate); - ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate); - rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS; - return cpu_to_le16((u16)rrv_time); - } - - /* RTSRrvTime */ - rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS; - return cpu_to_le16((u16)rrv_time); -} - -/* byFreqType 0: 5GHz, 1:2.4Ghz */ -static -unsigned int -s_uGetDataDuration( - struct vnt_private *pDevice, - unsigned char byDurType, - unsigned int cbFrameLength, - unsigned char byPktType, - unsigned short wRate, - bool bNeedAck, - unsigned int uFragIdx, - unsigned int cbLastFragmentSize, - unsigned int uMACfragNum, - unsigned char byFBOption -) -{ - bool bLastFrag = false; - unsigned int uAckTime = 0, uNextPktTime = 0, len; - - if (uFragIdx == (uMACfragNum - 1)) - bLastFrag = true; - - if (uFragIdx == (uMACfragNum - 2)) - len = cbLastFragmentSize; - else - len = cbFrameLength; - - switch (byDurType) { - case DATADUR_B: /* DATADUR_B */ - if (bNeedAck) { - uAckTime = bb_get_frame_time(pDevice->preamble_type, - byPktType, 14, - pDevice->byTopCCKBasicRate); - } - /* Non Frag or Last Frag */ - if ((uMACfragNum == 1) || bLastFrag) { - if (!bNeedAck) - return 0; - } else { - /* First Frag or Mid Frag */ - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, - len, wRate, bNeedAck); - } - - return pDevice->uSIFS + uAckTime + uNextPktTime; - - case DATADUR_A: /* DATADUR_A */ - if (bNeedAck) { - uAckTime = bb_get_frame_time(pDevice->preamble_type, - byPktType, 14, - pDevice->byTopOFDMBasicRate); - } - /* Non Frag or Last Frag */ - if ((uMACfragNum == 1) || bLastFrag) { - if (!bNeedAck) - return 0; - } else { - /* First Frag or Mid Frag */ - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, - len, wRate, bNeedAck); - } - - return pDevice->uSIFS + uAckTime + uNextPktTime; - - case DATADUR_A_F0: /* DATADUR_A_F0 */ - case DATADUR_A_F1: /* DATADUR_A_F1 */ - if (bNeedAck) { - uAckTime = bb_get_frame_time(pDevice->preamble_type, - byPktType, 14, - pDevice->byTopOFDMBasicRate); - } - /* Non Frag or Last Frag */ - if ((uMACfragNum == 1) || bLastFrag) { - if (!bNeedAck) - return 0; - } else { - /* First Frag or Mid Frag */ - if (wRate < RATE_18M) - wRate = RATE_18M; - else if (wRate > RATE_54M) - wRate = RATE_54M; - - wRate -= RATE_18M; - - if (byFBOption == AUTO_FB_0) - wRate = fb_opt0[FB_RATE0][wRate]; - else - wRate = fb_opt1[FB_RATE0][wRate]; - - uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, - len, wRate, bNeedAck); - } - - return pDevice->uSIFS + uAckTime + uNextPktTime; - - default: - break; - } - - return 0; -} - -/* byFreqType: 0=>5GHZ 1=>2.4GHZ */ -static -__le16 -s_uGetRTSCTSDuration( - struct vnt_private *pDevice, - unsigned char byDurType, - unsigned int cbFrameLength, - unsigned char byPktType, - unsigned short wRate, - bool bNeedAck, - unsigned char byFBOption -) -{ - unsigned int uCTSTime = 0, uDurTime = 0; - - switch (byDurType) { - case RTSDUR_BB: /* RTSDuration_bb */ - uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate); - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case RTSDUR_BA: /* RTSDuration_ba */ - uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate); - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case RTSDUR_AA: /* RTSDuration_aa */ - uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate); - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case CTSDUR_BA: /* CTSDuration_ba */ - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck); - break; - - case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */ - uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); - else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); - - break; - - case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */ - uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); - else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); - - break; - - case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */ - uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); - else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); - - break; - - case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */ - uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate); - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); - else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); - - break; - - case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */ - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck); - else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck); - - break; - - case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */ - if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck); - else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) - uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck); - - break; - - default: - break; - } - - return cpu_to_le16((u16)uDurTime); -} - -static -__le16 -s_uFillDataHead( - struct vnt_private *pDevice, - unsigned char byPktType, - void *pTxDataHead, - unsigned int cbFrameLength, - unsigned int uDMAIdx, - bool bNeedAck, - unsigned int uFragIdx, - unsigned int cbLastFragmentSize, - unsigned int uMACfragNum, - unsigned char byFBOption, - unsigned short wCurrentRate, - bool is_pspoll -) -{ - struct vnt_tx_datahead_ab *buf = pTxDataHead; - - if (!pTxDataHead) - return 0; - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - /* Auto Fallback */ - struct vnt_tx_datahead_g_fb *buf = pTxDataHead; - - if (byFBOption == AUTO_FB_NONE) { - struct vnt_tx_datahead_g *buf = pTxDataHead; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, - byPktType, &buf->a); - - vnt_get_phy_field(pDevice, cbFrameLength, - pDevice->byTopCCKBasicRate, - PK_TYPE_11B, &buf->b); - - if (is_pspoll) { - __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); - - buf->duration_a = dur; - buf->duration_b = dur; - } else { - /* Get Duration and TimeStamp */ - buf->duration_a = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, - byPktType, wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - buf->duration_b = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, - PK_TYPE_11B, pDevice->byTopCCKBasicRate, - bNeedAck, uFragIdx, cbLastFragmentSize, - uMACfragNum, byFBOption)); - } - - buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate); - buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate); - - return buf->duration_a; - } - - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, - byPktType, &buf->a); - - vnt_get_phy_field(pDevice, cbFrameLength, - pDevice->byTopCCKBasicRate, - PK_TYPE_11B, &buf->b); - /* Get Duration and TimeStamp */ - buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); - buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, - pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); - buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); - buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); - - buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate); - buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate); - - return buf->duration_a; - /* if (byFBOption == AUTO_FB_NONE) */ - } else if (byPktType == PK_TYPE_11A) { - struct vnt_tx_datahead_ab *buf = pTxDataHead; - - if (byFBOption != AUTO_FB_NONE) { - /* Auto Fallback */ - struct vnt_tx_datahead_a_fb *buf = pTxDataHead; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, - byPktType, &buf->a); - - /* Get Duration and TimeStampOff */ - buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); - buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); - buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); - buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); - return buf->duration; - } - - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, - byPktType, &buf->ab); - - if (is_pspoll) { - __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); - - buf->duration = dur; - } else { - /* Get Duration and TimeStampOff */ - buf->duration = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - } - - buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); - return buf->duration; - } - - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, - byPktType, &buf->ab); - - if (is_pspoll) { - __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); - - buf->duration = dur; - } else { - /* Get Duration and TimeStampOff */ - buf->duration = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, - wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - } - - buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); - return buf->duration; -} - -static -void -s_vFillRTSHead( - struct vnt_private *pDevice, - unsigned char byPktType, - void *pvRTS, - unsigned int cbFrameLength, - bool bNeedAck, - bool bDisCRC, - struct ieee80211_hdr *hdr, - unsigned short wCurrentRate, - unsigned char byFBOption -) -{ - unsigned int uRTSFrameLen = 20; - - if (!pvRTS) - return; - - if (bDisCRC) { - /* When CRCDIS bit is on, H/W forgot to generate FCS for - * RTS frame, in this case we need to decrease its length by 4. - */ - uRTSFrameLen -= 4; - } - - /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, - * so we don't need to take them into account. - * Otherwise, we need to modify codes for them. - */ - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - if (byFBOption == AUTO_FB_NONE) { - struct vnt_rts_g *buf = pvRTS; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, uRTSFrameLen, - pDevice->byTopCCKBasicRate, - PK_TYPE_11B, &buf->b); - - vnt_get_phy_field(pDevice, uRTSFrameLen, - pDevice->byTopOFDMBasicRate, - byPktType, &buf->a); - /* Get Duration */ - buf->duration_bb = - s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, - cbFrameLength, PK_TYPE_11B, - pDevice->byTopCCKBasicRate, - bNeedAck, byFBOption); - buf->duration_aa = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->duration_ba = - s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - - buf->data.duration = buf->duration_aa; - /* Get RTS Frame body */ - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_RTS); - - ether_addr_copy(buf->data.ra, hdr->addr1); - ether_addr_copy(buf->data.ta, hdr->addr2); - } else { - struct vnt_rts_g_fb *buf = pvRTS; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, uRTSFrameLen, - pDevice->byTopCCKBasicRate, - PK_TYPE_11B, &buf->b); - - vnt_get_phy_field(pDevice, uRTSFrameLen, - pDevice->byTopOFDMBasicRate, - byPktType, &buf->a); - /* Get Duration */ - buf->duration_bb = - s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, - cbFrameLength, PK_TYPE_11B, - pDevice->byTopCCKBasicRate, - bNeedAck, byFBOption); - buf->duration_aa = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->duration_ba = - s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->rts_duration_ba_f0 = - s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->rts_duration_aa_f0 = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->rts_duration_ba_f1 = - s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->rts_duration_aa_f1 = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->data.duration = buf->duration_aa; - /* Get RTS Frame body */ - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_RTS); - - ether_addr_copy(buf->data.ra, hdr->addr1); - ether_addr_copy(buf->data.ta, hdr->addr2); - } /* if (byFBOption == AUTO_FB_NONE) */ - } else if (byPktType == PK_TYPE_11A) { - if (byFBOption == AUTO_FB_NONE) { - struct vnt_rts_ab *buf = pvRTS; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, uRTSFrameLen, - pDevice->byTopOFDMBasicRate, - byPktType, &buf->ab); - /* Get Duration */ - buf->duration = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->data.duration = buf->duration; - /* Get RTS Frame body */ - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_RTS); - - ether_addr_copy(buf->data.ra, hdr->addr1); - ether_addr_copy(buf->data.ta, hdr->addr2); - } else { - struct vnt_rts_a_fb *buf = pvRTS; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, uRTSFrameLen, - pDevice->byTopOFDMBasicRate, - byPktType, &buf->a); - /* Get Duration */ - buf->duration = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->rts_duration_f0 = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->rts_duration_f1 = - s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - buf->data.duration = buf->duration; - /* Get RTS Frame body */ - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_RTS); - - ether_addr_copy(buf->data.ra, hdr->addr1); - ether_addr_copy(buf->data.ta, hdr->addr2); - } - } else if (byPktType == PK_TYPE_11B) { - struct vnt_rts_ab *buf = pvRTS; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, uRTSFrameLen, - pDevice->byTopCCKBasicRate, - PK_TYPE_11B, &buf->ab); - /* Get Duration */ - buf->duration = - s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, - byPktType, wCurrentRate, bNeedAck, - byFBOption); - - buf->data.duration = buf->duration; - /* Get RTS Frame body */ - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - ether_addr_copy(buf->data.ra, hdr->addr1); - ether_addr_copy(buf->data.ta, hdr->addr2); - } -} - -static -void -s_vFillCTSHead( - struct vnt_private *pDevice, - unsigned int uDMAIdx, - unsigned char byPktType, - void *pvCTS, - unsigned int cbFrameLength, - bool bNeedAck, - bool bDisCRC, - unsigned short wCurrentRate, - unsigned char byFBOption -) -{ - unsigned int uCTSFrameLen = 14; - - if (!pvCTS) - return; - - if (bDisCRC) { - /* When CRCDIS bit is on, H/W forgot to generate FCS for - * CTS frame, in this case we need to decrease its length by 4. - */ - uCTSFrameLen -= 4; - } - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) { - /* Auto Fall back */ - struct vnt_cts_fb *buf = pvCTS; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, uCTSFrameLen, - pDevice->byTopCCKBasicRate, - PK_TYPE_11B, &buf->b); - - buf->duration_ba = - s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - - /* Get CTSDuration_ba_f0 */ - buf->cts_duration_ba_f0 = - s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - - /* Get CTSDuration_ba_f1 */ - buf->cts_duration_ba_f1 = - s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - - /* Get CTS Frame body */ - buf->data.duration = buf->duration_ba; - - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_CTS); - - buf->reserved2 = 0x0; - - ether_addr_copy(buf->data.ra, - pDevice->abyCurrentNetAddr); - } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */ - struct vnt_cts *buf = pvCTS; - /* Get SignalField, ServiceField & Length */ - vnt_get_phy_field(pDevice, uCTSFrameLen, - pDevice->byTopCCKBasicRate, - PK_TYPE_11B, &buf->b); - - /* Get CTSDuration_ba */ - buf->duration_ba = - s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, - cbFrameLength, byPktType, - wCurrentRate, bNeedAck, - byFBOption); - - /* Get CTS Frame body */ - buf->data.duration = buf->duration_ba; - - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_CTS); - - buf->reserved2 = 0x0; - ether_addr_copy(buf->data.ra, - pDevice->abyCurrentNetAddr); - } - } -} - -/* - * - * Description: - * Generate FIFO control for MAC & Baseband controller - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * pTxDataHead - Transmit Data Buffer - * pTxBufHead - pTxBufHead - * pvRrvTime - pvRrvTime - * pvRTS - RTS Buffer - * pCTS - CTS Buffer - * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS) - * bNeedACK - If need ACK - * uDescIdx - Desc Index - * Out: - * none - * - * Return Value: none - * - - - * unsigned int cbFrameSize, Hdr+Payload+FCS - */ -static -void -s_vGenerateTxParameter( - struct vnt_private *pDevice, - unsigned char byPktType, - struct vnt_tx_fifo_head *tx_buffer_head, - void *pvRrvTime, - void *pvRTS, - void *pvCTS, - unsigned int cbFrameSize, - bool bNeedACK, - unsigned int uDMAIdx, - void *psEthHeader, - unsigned short wCurrentRate -) -{ - u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl); - bool bDisCRC = false; - unsigned char byFBOption = AUTO_FB_NONE; - - tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate); - - if (fifo_ctl & FIFOCTL_CRCDIS) - bDisCRC = true; - - if (fifo_ctl & FIFOCTL_AUTO_FB_0) - byFBOption = AUTO_FB_0; - else if (fifo_ctl & FIFOCTL_AUTO_FB_1) - byFBOption = AUTO_FB_1; - - if (!pvRrvTime) - return; - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - if (pvRTS) { /* RTS_need */ - /* Fill RsvTime */ - struct vnt_rrv_time_rts *buf = pvRrvTime; - - buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate); - buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate); - buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate); - buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK); - buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK); - - s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); - } else {/* RTS_needless, PCF mode */ - struct vnt_rrv_time_cts *buf = pvRrvTime; - - buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK); - buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK); - buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate); - - /* Fill CTS */ - s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption); - } - } else if (byPktType == PK_TYPE_11A) { - if (pvRTS) {/* RTS_need, non PCF mode */ - struct vnt_rrv_time_ab *buf = pvRrvTime; - - buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate); - buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK); - - /* Fill RTS */ - s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); - } else if (!pvRTS) {/* RTS_needless, non PCF mode */ - struct vnt_rrv_time_ab *buf = pvRrvTime; - - buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK); - } - } else if (byPktType == PK_TYPE_11B) { - if (pvRTS) {/* RTS_need, non PCF mode */ - struct vnt_rrv_time_ab *buf = pvRrvTime; - - buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate); - buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK); - - /* Fill RTS */ - s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption); - } else { /* RTS_needless, non PCF mode */ - struct vnt_rrv_time_ab *buf = pvRrvTime; - - buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK); - } - } -} - -static unsigned int -s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, - unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD, - unsigned int is_pspoll) -{ - struct vnt_td_info *td_info = pHeadTD->td_info; - struct sk_buff *skb = td_info->skb; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct vnt_tx_fifo_head *tx_buffer_head = - (struct vnt_tx_fifo_head *)td_info->buf; - u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl); - unsigned int cbFrameSize; - __le16 uDuration; - unsigned char *pbyBuffer; - unsigned int uLength = 0; - unsigned int cbMICHDR = 0; - unsigned int uMACfragNum = 1; - unsigned int uPadding = 0; - unsigned int cbReqCount = 0; - bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK); - bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS); - struct vnt_tx_desc *ptdCurr; - unsigned int cbHeaderLength = 0; - void *pvRrvTime = NULL; - struct vnt_mic_hdr *pMICHDR = NULL; - void *pvRTS = NULL; - void *pvCTS = NULL; - void *pvTxDataHd = NULL; - unsigned short wTxBufSize; /* FFinfo size */ - unsigned char byFBOption = AUTO_FB_NONE; - - cbFrameSize = skb->len + 4; - - if (info->control.hw_key) { - switch (info->control.hw_key->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - cbMICHDR = sizeof(struct vnt_mic_hdr); - break; - default: - break; - } - - cbFrameSize += info->control.hw_key->icv_len; - - if (pDevice->local_id > REV_ID_VT3253_A1) { - /* MAC Header should be padding 0 to DW alignment. */ - uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4); - uPadding %= 4; - } - } - - /* - * Use for AUTO FALL BACK - */ - if (fifo_ctl & FIFOCTL_AUTO_FB_0) - byFBOption = AUTO_FB_0; - else if (fifo_ctl & FIFOCTL_AUTO_FB_1) - byFBOption = AUTO_FB_1; - - /* Set RrvTime/RTS/CTS Buffer */ - wTxBufSize = sizeof(struct vnt_tx_fifo_head); - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */ - - if (byFBOption == AUTO_FB_NONE) { - if (bRTS) {/* RTS_need */ - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts)); - pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + - cbMICHDR + sizeof(struct vnt_rts_g)); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) + - cbMICHDR + sizeof(struct vnt_rts_g) + - sizeof(struct vnt_tx_datahead_g); - } else { /* RTS_needless */ - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts)); - pvRTS = NULL; - pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts)); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g); - } - } else { - /* Auto Fall Back */ - if (bRTS) {/* RTS_need */ - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts)); - pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + - cbMICHDR + sizeof(struct vnt_rts_g_fb)); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) + - cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb); - } else { /* RTS_needless */ - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts)); - pvRTS = NULL; - pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts_fb)); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb); - } - } /* Auto Fall Back */ - } else {/* 802.11a/b packet */ - - if (byFBOption == AUTO_FB_NONE) { - if (bRTS) { - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab)); - pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab)); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab); - } else { /* RTS_needless, need MICHDR */ - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_tx_datahead_ab); - } - } else { - /* Auto Fall Back */ - if (bRTS) { /* RTS_need */ - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab)); - pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR); - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb)); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb); - } else { /* RTS_needless */ - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR); - cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb); - } - } /* Auto Fall Back */ - } - - td_info->mic_hdr = pMICHDR; - - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); - - /* Fill FIFO,RrvTime,RTS,and CTS */ - s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate); - /* Fill DataHead */ - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, - 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll); - - hdr->duration_id = uDuration; - - cbReqCount = cbHeaderLength + uPadding + skb->len; - pbyBuffer = (unsigned char *)pHeadTD->td_info->buf; - uLength = cbHeaderLength + uPadding; - - /* Copy the Packet into a tx Buffer */ - memcpy((pbyBuffer + uLength), skb->data, skb->len); - - ptdCurr = pHeadTD; - - ptdCurr->td_info->req_count = (u16)cbReqCount; - - return cbHeaderLength; -} - -static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer, - struct ieee80211_key_conf *tx_key, - struct sk_buff *skb, u16 payload_len, - struct vnt_mic_hdr *mic_hdr) -{ - u64 pn64; - u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); - - /* strip header and icv len from payload */ - payload_len -= ieee80211_get_hdrlen_from_skb(skb); - payload_len -= tx_key->icv_len; - - switch (tx_key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - memcpy(key_buffer, iv, 3); - memcpy(key_buffer + 3, tx_key->key, tx_key->keylen); - - if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { - memcpy(key_buffer + 8, iv, 3); - memcpy(key_buffer + 11, - tx_key->key, WLAN_KEY_LEN_WEP40); - } - - break; - case WLAN_CIPHER_SUITE_TKIP: - ieee80211_get_tkip_p2k(tx_key, skb, key_buffer); - - break; - case WLAN_CIPHER_SUITE_CCMP: - - if (!mic_hdr) - return; - - mic_hdr->id = 0x59; - mic_hdr->payload_len = cpu_to_be16(payload_len); - ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2); - - pn64 = atomic64_read(&tx_key->tx_pn); - mic_hdr->ccmp_pn[5] = pn64; - mic_hdr->ccmp_pn[4] = pn64 >> 8; - mic_hdr->ccmp_pn[3] = pn64 >> 16; - mic_hdr->ccmp_pn[2] = pn64 >> 24; - mic_hdr->ccmp_pn[1] = pn64 >> 32; - mic_hdr->ccmp_pn[0] = pn64 >> 40; - - if (ieee80211_has_a4(hdr->frame_control)) - mic_hdr->hlen = cpu_to_be16(28); - else - mic_hdr->hlen = cpu_to_be16(22); - - ether_addr_copy(mic_hdr->addr1, hdr->addr1); - ether_addr_copy(mic_hdr->addr2, hdr->addr2); - ether_addr_copy(mic_hdr->addr3, hdr->addr3); - - mic_hdr->frame_control = cpu_to_le16( - le16_to_cpu(hdr->frame_control) & 0xc78f); - mic_hdr->seq_ctrl = cpu_to_le16( - le16_to_cpu(hdr->seq_ctrl) & 0xf); - - if (ieee80211_has_a4(hdr->frame_control)) - ether_addr_copy(mic_hdr->addr4, hdr->addr4); - - memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP); - - break; - default: - break; - } -} - -int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx, - struct vnt_tx_desc *head_td, struct sk_buff *skb) -{ - struct vnt_td_info *td_info = head_td->td_info; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_tx_rate *tx_rate = &info->control.rates[0]; - struct ieee80211_rate *rate; - struct ieee80211_key_conf *tx_key; - struct ieee80211_hdr *hdr; - struct vnt_tx_fifo_head *tx_buffer_head = - (struct vnt_tx_fifo_head *)td_info->buf; - u16 tx_body_size = skb->len, current_rate; - u8 pkt_type; - bool is_pspoll = false; - - memset(tx_buffer_head, 0, sizeof(*tx_buffer_head)); - - hdr = (struct ieee80211_hdr *)(skb->data); - - rate = ieee80211_get_tx_rate(priv->hw, info); - - current_rate = rate->hw_value; - if (priv->wCurrentRate != current_rate && - !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { - priv->wCurrentRate = current_rate; - - RFbSetPower(priv, priv->wCurrentRate, - priv->hw->conf.chandef.chan->hw_value); - } - - if (current_rate > RATE_11M) { - if (info->band == NL80211_BAND_5GHZ) { - pkt_type = PK_TYPE_11A; - } else { - if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) - pkt_type = PK_TYPE_11GB; - else - pkt_type = PK_TYPE_11GA; - } - } else { - pkt_type = PK_TYPE_11B; - } - - /*Set fifo controls */ - if (pkt_type == PK_TYPE_11A) - tx_buffer_head->fifo_ctl = 0; - else if (pkt_type == PK_TYPE_11B) - tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B); - else if (pkt_type == PK_TYPE_11GB) - tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB); - else if (pkt_type == PK_TYPE_11GA) - tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA); - - /* generate interrupt */ - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); - - if (!ieee80211_is_data(hdr->frame_control)) { - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN); - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0); - tx_buffer_head->time_stamp = - cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - } else { - tx_buffer_head->time_stamp = - cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); - } - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); - - if (ieee80211_has_retry(hdr->frame_control)) - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY); - - if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - priv->preamble_type = PREAMBLE_SHORT; - else - priv->preamble_type = PREAMBLE_LONG; - - if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS); - - if (ieee80211_has_a4(hdr->frame_control)) { - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD); - priv->bLongHeader = true; - } - - if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) - is_pspoll = true; - - tx_buffer_head->frag_ctl = - cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10); - - if (info->control.hw_key) { - switch (info->control.hw_key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); - break; - case WLAN_CIPHER_SUITE_TKIP: - tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); - break; - case WLAN_CIPHER_SUITE_CCMP: - tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES); - break; - default: - break; - } - } - - tx_buffer_head->current_rate = cpu_to_le16(current_rate); - - /* legacy rates TODO use ieee80211_tx_rate */ - if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) { - if (priv->byAutoFBCtrl == AUTO_FB_0) - tx_buffer_head->fifo_ctl |= - cpu_to_le16(FIFOCTL_AUTO_FB_0); - else if (priv->byAutoFBCtrl == AUTO_FB_1) - tx_buffer_head->fifo_ctl |= - cpu_to_le16(FIFOCTL_AUTO_FB_1); - } - - tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); - - s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head, - dma_idx, head_td, is_pspoll); - - if (info->control.hw_key) { - tx_key = info->control.hw_key; - if (tx_key->keylen > 0) - vnt_fill_txkey(hdr, tx_buffer_head->tx_key, - tx_key, skb, tx_body_size, - td_info->mic_hdr); - } - - return 0; -} - -static int vnt_beacon_xmit(struct vnt_private *priv, - struct sk_buff *skb) -{ - struct vnt_tx_short_buf_head *short_head = - (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs; - struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *) - (priv->tx_beacon_bufs + sizeof(*short_head)); - struct ieee80211_tx_info *info; - u32 frame_size = skb->len + 4; - u16 current_rate; - - memset(priv->tx_beacon_bufs, 0, sizeof(*short_head)); - - if (priv->byBBType == BB_TYPE_11A) { - current_rate = RATE_6M; - - /* Get SignalField,ServiceField,Length */ - vnt_get_phy_field(priv, frame_size, current_rate, - PK_TYPE_11A, &short_head->ab); - - /* Get Duration and TimeStampOff */ - short_head->duration = - cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, - frame_size, PK_TYPE_11A, current_rate, - false, 0, 0, 1, AUTO_FB_NONE)); - - short_head->time_stamp_off = - vnt_time_stamp_off(priv, current_rate); - } else { - current_rate = RATE_1M; - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); - - /* Get SignalField,ServiceField,Length */ - vnt_get_phy_field(priv, frame_size, current_rate, - PK_TYPE_11B, &short_head->ab); - - /* Get Duration and TimeStampOff */ - short_head->duration = - cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, - frame_size, PK_TYPE_11B, current_rate, - false, 0, 0, 1, AUTO_FB_NONE)); - - short_head->time_stamp_off = - vnt_time_stamp_off(priv, current_rate); - } - - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); - - /* Copy Beacon */ - memcpy(mgmt_hdr, skb->data, skb->len); - - /* time stamp always 0 */ - mgmt_hdr->u.beacon.timestamp = 0; - - info = IEEE80211_SKB_CB(skb); - if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; - - hdr->duration_id = 0; - hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4); - } - - priv->wSeqCounter++; - if (priv->wSeqCounter > 0x0fff) - priv->wSeqCounter = 0; - - priv->wBCNBufLen = sizeof(*short_head) + skb->len; - - iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR); - - iowrite16(priv->wBCNBufLen, priv->port_offset + MAC_REG_BCNDMACTL + 2); - /* Set auto Transmit on */ - vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX); - /* Poll Transmit the adapter */ - iowrite8(BEACON_READY, priv->port_offset + MAC_REG_BCNDMACTL); - - return 0; -} - -int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) -{ - struct sk_buff *beacon; - - beacon = ieee80211_beacon_get(priv->hw, vif, 0); - if (!beacon) - return -ENOMEM; - - if (vnt_beacon_xmit(priv, beacon)) { - ieee80211_free_txskb(priv->hw, beacon); - return -ENODEV; - } - - return 0; -} - -int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, - struct ieee80211_bss_conf *conf) -{ - iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL); - - iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL); - - CARDvSetFirstNextTBTT(priv, conf->beacon_int); - - card_set_beacon_period(priv, conf->beacon_int); - - return vnt_beacon_make(priv, vif); -} diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h deleted file mode 100644 index be1e5180d57b8c6b7462f2c9a12a8901927303e2..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/rxtx.h +++ /dev/null @@ -1,184 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: - * - * Author: Jerry Chen - * - * Date: Jun. 27, 2002 - * - */ - -#ifndef __RXTX_H__ -#define __RXTX_H__ - -#include "device.h" - -#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */ -#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ - -/*--------------------- Export Definitions -------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* MIC HDR data header */ -struct vnt_mic_hdr { - u8 id; - u8 tx_priority; - u8 mic_addr2[ETH_ALEN]; - u8 ccmp_pn[IEEE80211_CCMP_PN_LEN]; - __be16 payload_len; - __be16 hlen; - __le16 frame_control; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctrl; - u8 addr4[ETH_ALEN]; - u16 packing; /* packing to 48 bytes */ -} __packed; - -/* RsvTime buffer header */ -struct vnt_rrv_time_rts { - __le16 rts_rrv_time_ba; - __le16 rts_rrv_time_aa; - __le16 rts_rrv_time_bb; - u16 reserved; - __le16 rrv_time_b; - __le16 rrv_time_a; -} __packed; - -struct vnt_rrv_time_cts { - __le16 cts_rrv_time_ba; - u16 reserved; - __le16 rrv_time_b; - __le16 rrv_time_a; -} __packed; - -struct vnt_rrv_time_ab { - __le16 rts_rrv_time; - __le16 rrv_time; -} __packed; - -/* TX data header */ -struct vnt_tx_datahead_g { - struct vnt_phy_field b; - struct vnt_phy_field a; - __le16 duration_b; - __le16 duration_a; - __le16 time_stamp_off_b; - __le16 time_stamp_off_a; -} __packed; - -struct vnt_tx_datahead_g_fb { - struct vnt_phy_field b; - struct vnt_phy_field a; - __le16 duration_b; - __le16 duration_a; - __le16 duration_a_f0; - __le16 duration_a_f1; - __le16 time_stamp_off_b; - __le16 time_stamp_off_a; -} __packed; - -struct vnt_tx_datahead_ab { - struct vnt_phy_field ab; - __le16 duration; - __le16 time_stamp_off; -} __packed; - -struct vnt_tx_datahead_a_fb { - struct vnt_phy_field a; - __le16 duration; - __le16 time_stamp_off; - __le16 duration_f0; - __le16 duration_f1; -} __packed; - -/* RTS buffer header */ -struct vnt_rts_g { - struct vnt_phy_field b; - struct vnt_phy_field a; - __le16 duration_ba; - __le16 duration_aa; - __le16 duration_bb; - u16 reserved; - struct ieee80211_rts data; -} __packed __aligned(2); - -struct vnt_rts_g_fb { - struct vnt_phy_field b; - struct vnt_phy_field a; - __le16 duration_ba; - __le16 duration_aa; - __le16 duration_bb; - u16 wReserved; - __le16 rts_duration_ba_f0; - __le16 rts_duration_aa_f0; - __le16 rts_duration_ba_f1; - __le16 rts_duration_aa_f1; - struct ieee80211_rts data; -} __packed __aligned(2); - -struct vnt_rts_ab { - struct vnt_phy_field ab; - __le16 duration; - u16 reserved; - struct ieee80211_rts data; -} __packed __aligned(2); - -struct vnt_rts_a_fb { - struct vnt_phy_field a; - __le16 duration; - u16 reserved; - __le16 rts_duration_f0; - __le16 rts_duration_f1; - struct ieee80211_rts data; -} __packed __aligned(2); - -/* CTS buffer header */ -struct vnt_cts { - struct vnt_phy_field b; - __le16 duration_ba; - u16 reserved; - struct ieee80211_cts data; - u16 reserved2; -} __packed __aligned(2); - -struct vnt_cts_fb { - struct vnt_phy_field b; - __le16 duration_ba; - u16 reserved; - __le16 cts_duration_ba_f0; - __le16 cts_duration_ba_f1; - struct ieee80211_cts data; - u16 reserved2; -} __packed __aligned(2); - -struct vnt_tx_fifo_head { - u8 tx_key[WLAN_KEY_LEN_CCMP]; - __le16 fifo_ctl; - __le16 time_stamp; - __le16 frag_ctl; - __le16 current_rate; -} __packed; - -struct vnt_tx_short_buf_head { - __le16 fifo_ctl; - u16 time_stamp; - struct vnt_phy_field ab; - __le16 duration; - __le16 time_stamp_off; -} __packed; - -int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx, - struct vnt_tx_desc *head_td, struct sk_buff *skb); -int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif); -int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, - struct ieee80211_bss_conf *conf); - -#endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c deleted file mode 100644 index e80556509c58dde01addf6750044405fd3c960d8..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/srom.c +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose:Implement functions to access eeprom - * - * Author: Jerry Chen - * - * Date: Jan 29, 2003 - * - * Functions: - * SROMbyReadEmbedded - Embedded read eeprom via MAC - * SROMbWriteEmbedded - Embedded write eeprom via MAC - * SROMvRegBitsOn - Set Bits On in eeprom - * SROMvRegBitsOff - Clear Bits Off in eeprom - * SROMbIsRegBitsOn - Test if Bits On in eeprom - * SROMbIsRegBitsOff - Test if Bits Off in eeprom - * SROMvReadAllContents - Read all contents in eeprom - * SROMvWriteAllContents - Write all contents in eeprom - * SROMvReadEtherAddress - Read Ethernet Address in eeprom - * SROMvWriteEtherAddress - Write Ethernet Address in eeprom - * SROMvReadSubSysVenId - Read Sub_VID and Sub_SysId in eeprom - * SROMbAutoLoad - Auto Load eeprom to MAC register - * - * Revision History: - * - */ - -#include "device.h" -#include "mac.h" -#include "srom.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: Read a byte from EEPROM, by MAC I2C - * - * Parameters: - * In: - * iobase - I/O base address - * contnt_offset - address of EEPROM - * Out: - * none - * - * Return Value: data read - * - */ -unsigned char SROMbyReadEmbedded(void __iomem *iobase, - unsigned char contnt_offset) -{ - unsigned short wDelay, wNoACK; - unsigned char byWait; - unsigned char byData; - unsigned char byOrg; - - byOrg = ioread8(iobase + MAC_REG_I2MCFG); - /* turn off hardware retry for getting NACK */ - iowrite8(byOrg & (~I2MCFG_NORETRY), iobase + MAC_REG_I2MCFG); - for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { - iowrite8(EEP_I2C_DEV_ID, iobase + MAC_REG_I2MTGID); - iowrite8(contnt_offset, iobase + MAC_REG_I2MTGAD); - - /* issue read command */ - iowrite8(I2MCSR_EEMR, iobase + MAC_REG_I2MCSR); - /* wait DONE be set */ - for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { - byWait = ioread8(iobase + MAC_REG_I2MCSR); - if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) - break; - udelay(CB_DELAY_LOOP_WAIT); - } - if ((wDelay < W_MAX_TIMEOUT) && - (!(byWait & I2MCSR_NACK))) { - break; - } - } - byData = ioread8(iobase + MAC_REG_I2MDIPT); - iowrite8(byOrg, iobase + MAC_REG_I2MCFG); - return byData; -} - -/* - * Description: Read all contents of eeprom to buffer - * - * Parameters: - * In: - * iobase - I/O base address - * Out: - * pbyEepromRegs - EEPROM content Buffer - * - * Return Value: none - * - */ -void SROMvReadAllContents(void __iomem *iobase, unsigned char *pbyEepromRegs) -{ - int ii; - - /* ii = Rom Address */ - for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { - *pbyEepromRegs = SROMbyReadEmbedded(iobase, - (unsigned char)ii); - pbyEepromRegs++; - } -} - -/* - * Description: Read Ethernet Address from eeprom to buffer - * - * Parameters: - * In: - * iobase - I/O base address - * Out: - * pbyEtherAddress - Ethernet Address buffer - * - * Return Value: none - * - */ -void SROMvReadEtherAddress(void __iomem *iobase, - unsigned char *pbyEtherAddress) -{ - unsigned char ii; - - /* ii = Rom Address */ - for (ii = 0; ii < ETH_ALEN; ii++) { - *pbyEtherAddress = SROMbyReadEmbedded(iobase, ii); - pbyEtherAddress++; - } -} diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h deleted file mode 100644 index b03073ffa18a2e07776b127ef91f2f1e94d64e56..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/srom.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions to access eeprom - * - * Author: Jerry Chen - * - * Date: Jan 29, 2003 - */ - -#ifndef __SROM_H__ -#define __SROM_H__ - -/*--------------------- Export Definitions -------------------------*/ - -#define EEP_MAX_CONTEXT_SIZE 256 - -#define CB_EEPROM_READBYTE_WAIT 900 /* us */ - -#define W_MAX_I2CRETRY 0x0fff - -/* Contents in the EEPROM */ -#define EEP_OFS_PAR 0x00 /* physical address */ -#define EEP_OFS_ANTENNA 0x16 -#define EEP_OFS_RADIOCTL 0x17 -#define EEP_OFS_RFTYPE 0x1B /* for select RF */ -#define EEP_OFS_MINCHANNEL 0x1C /* Min Channel # */ -#define EEP_OFS_MAXCHANNEL 0x1D /* Max Channel # */ -#define EEP_OFS_SIGNATURE 0x1E -#define EEP_OFS_ZONETYPE 0x1F -#define EEP_OFS_RFTABLE 0x20 /* RF POWER TABLE */ -#define EEP_OFS_PWR_CCK 0x20 -#define EEP_OFS_SETPT_CCK 0x21 -#define EEP_OFS_PWR_OFDMG 0x23 -#define EEP_OFS_SETPT_OFDMG 0x24 -#define EEP_OFS_PWR_FORMULA_OST 0x26 -#define EEP_OFS_MAJOR_VER 0x2E -#define EEP_OFS_MINOR_VER 0x2F -#define EEP_OFS_CCK_PWR_TBL 0x30 -#define EEP_OFS_CCK_PWR_dBm 0x3F -#define EEP_OFS_OFDM_PWR_TBL 0x40 -#define EEP_OFS_OFDM_PWR_dBm 0x4F -/*{{ RobertYu: 20041124 */ -#define EEP_OFS_SETPT_OFDMA 0x4E -#define EEP_OFS_OFDMA_PWR_TBL 0x50 -/*}}*/ -#define EEP_OFS_OFDMA_PWR_dBm 0xD2 - -/*----------need to remove --------------------*/ -#define EEP_OFS_BBTAB_LEN 0x70 /* BB Table Length */ -#define EEP_OFS_BBTAB_ADR 0x71 /* BB Table Offset */ -#define EEP_OFS_CHECKSUM 0xFF /* reserved area for baseband 28h~78h */ - -#define EEP_I2C_DEV_ID 0x50 /* EEPROM device address on I2C bus */ - -/* Bits in EEP_OFS_ANTENNA */ -#define EEP_ANTENNA_MAIN 0x01 -#define EEP_ANTENNA_AUX 0x02 -#define EEP_ANTINV 0x04 - -/* Bits in EEP_OFS_RADIOCTL */ -#define EEP_RADIOCTL_ENABLE 0x80 -#define EEP_RADIOCTL_INV 0x01 - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -unsigned char SROMbyReadEmbedded(void __iomem *iobase, - unsigned char byContntOffset); - -void SROMvReadAllContents(void __iomem *iobase, unsigned char *pbyEepromRegs); - -void SROMvReadEtherAddress(void __iomem *iobase, - unsigned char *pbyEtherAddress); - -#endif /* __EEPROM_H__*/ diff --git a/drivers/staging/vt6655/test b/drivers/staging/vt6655/test deleted file mode 100644 index ba6dec774478e9d57321d07983ad1884bb29078e..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6655/test +++ /dev/null @@ -1,9 +0,0 @@ -KSP := /lib/modules/$(shell uname -r)/build \ - /usr/src/linux-$(shell uname -r) \ - /usr/src/linux-$(shell uname -r | sed 's/-.*//') \ -# /usr/src/kernel-headers-$(shell uname -r) \ -# /usr/src/kernel-source-$(shell uname -r) \ -# /usr/src/linux-$(shell uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \ -# /usr/src/linux /home/plice -test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir)) -KSP := $(foreach dir, $(KSP), $(test_dir)) diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig deleted file mode 100644 index f52a3f1d9a2ee294cb5a511b788bbf58d6117ca9..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config VT6656 - tristate "VIA Technologies VT6656 support" - depends on MAC80211 && USB && WLAN && m - select FW_LOADER - help - This is a vendor-written driver for VIA VT6656. diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile deleted file mode 100644 index f696a9d7a143d42dfa4821c42d6b6bfff523e1f7..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -vt6656_stage-y += main_usb.o \ - card.o \ - mac.o \ - baseband.o \ - wcmd.o\ - rxtx.o \ - power.o \ - key.o \ - rf.o \ - usbpipe.o \ - channel.o - -obj-$(CONFIG_VT6656) += vt6656_stage.o diff --git a/drivers/staging/vt6656/TODO b/drivers/staging/vt6656/TODO deleted file mode 100644 index cca78d2d3cfeb5bbf46ffb548336b51c89175639..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/TODO +++ /dev/null @@ -1,17 +0,0 @@ -TODO: -- remove __cplusplus ifdefs -- done -- remove kernel version compatibility wrappers -- remove support for older wireless extensions -- prepare for merge with vt6655 driver: - - remove PRINT_K() macro - - split rf.c - - abstract VT3184 chipset specific code -- add common vt665x infrastructure -- kill ttype.h -- done -- switch to use MAC80211 -- use kernel coding style -- sparse fixes -- integrate with drivers/net/wireless - -Please send any patches to Greg Kroah-Hartman -and Forest Bond . diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c deleted file mode 100644 index ad7b963f0d981afd6a6926089f567feb16392ca4..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/baseband.c +++ /dev/null @@ -1,455 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions to access baseband - * - * Author: Jerry Chen - * - * Date: Jun. 5, 2002 - * - * Functions: - * vnt_get_frame_time - Calculate data frame transmitting time - * vnt_get_phy_field - Calculate PhyLength, PhyService and Phy - * Signal parameter for baseband Tx - * vnt_vt3184_init - VIA VT3184 baseband chip init code - * - * Revision History: - * - * - */ - -#include -#include -#include -#include "device.h" -#include "mac.h" -#include "baseband.h" -#include "rf.h" -#include "usbpipe.h" - -static const u8 vnt_vt3184_agc[] = { - 0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06, - 0x08, 0x08, 0x0a, 0x0a, 0x0c, 0x0c, 0x0e, 0x0e, /* 0x0f */ - 0x10, 0x10, 0x12, 0x12, 0x14, 0x14, 0x16, 0x16, - 0x18, 0x18, 0x1a, 0x1a, 0x1c, 0x1c, 0x1e, 0x1e, /* 0x1f */ - 0x20, 0x20, 0x22, 0x22, 0x24, 0x24, 0x26, 0x26, - 0x28, 0x28, 0x2a, 0x2a, 0x2c, 0x2c, 0x2e, 0x2e, /* 0x2f */ - 0x30, 0x30, 0x32, 0x32, 0x34, 0x34, 0x36, 0x36, - 0x38, 0x38, 0x3a, 0x3a, 0x3c, 0x3c, 0x3e, 0x3e /* 0x3f */ -}; - -static u8 vnt_vt3184_al2230[] = { - 0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, - 0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */ - 0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, - 0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */ - 0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */ - 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */ - 0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */ - 0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x18, /* 0xaf */ - 0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2, - 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */ - 0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x0e, 0x0a, - 0x0e, 0x00, 0x82, 0xa7, 0x3c, 0x10, 0x30, 0x05, /* 0xcf */ - 0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */ - 0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x12, - 0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x05, /* 0xef */ - 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0xff */ -}; - -/* {{RobertYu:20060515, new BB setting for VT3226D0 */ -static const u8 vnt_vt3184_vt3226d0[] = { - 0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, - 0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */ - 0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, - 0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */ - 0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */ - 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */ - 0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */ - 0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0xaf */ - 0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2, - 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */ - 0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x10, 0x0a, - 0x0e, 0x00, 0x84, 0xa7, 0x3c, 0x10, 0x24, 0x05, /* 0xcf */ - 0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */ - 0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, - 0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x08, /* 0xef */ - 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0xff */ -}; - -struct vnt_threshold { - u8 bb_pre_ed_rssi; - u8 cr_201; - u8 cr_206; -}; - -static const struct vnt_threshold al2230_vnt_threshold[] = { - {0, 0x00, 0x30}, /* Max sensitivity */ - {68, 0x00, 0x36}, - {67, 0x00, 0x43}, - {66, 0x00, 0x51}, - {65, 0x00, 0x62}, - {64, 0x00, 0x79}, - {63, 0x00, 0x93}, - {62, 0x00, 0xb9}, - {61, 0x00, 0xe3}, - {60, 0x01, 0x18}, - {59, 0x01, 0x54}, - {58, 0x01, 0xa0}, - {57, 0x02, 0x20}, - {56, 0x02, 0xa0}, - {55, 0x03, 0x00}, - {53, 0x06, 0x00}, - {51, 0x09, 0x00}, - {49, 0x0e, 0x00}, - {47, 0x15, 0x00}, - {46, 0x1a, 0x00}, - {45, 0xff, 0x00} -}; - -static const struct vnt_threshold vt3226_vnt_threshold[] = { - {0, 0x00, 0x24}, /* Max sensitivity */ - {68, 0x00, 0x2d}, - {67, 0x00, 0x36}, - {66, 0x00, 0x43}, - {65, 0x00, 0x52}, - {64, 0x00, 0x68}, - {63, 0x00, 0x80}, - {62, 0x00, 0x9c}, - {61, 0x00, 0xc0}, - {60, 0x00, 0xea}, - {59, 0x01, 0x30}, - {58, 0x01, 0x70}, - {57, 0x01, 0xb0}, - {56, 0x02, 0x30}, - {55, 0x02, 0xc0}, - {53, 0x04, 0x00}, - {51, 0x07, 0x00}, - {49, 0x0a, 0x00}, - {47, 0x11, 0x00}, - {45, 0x18, 0x00}, - {43, 0x26, 0x00}, - {42, 0x36, 0x00}, - {41, 0xff, 0x00} -}; - -/* - * Description: Set Antenna mode - * - * Parameters: - * In: - * priv - Device Structure - * antenna_mode - Antenna Mode - * Out: - * none - * - * Return Value: none - * - */ -int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode) -{ - switch (antenna_mode) { - case ANT_TXA: - case ANT_TXB: - break; - case ANT_RXA: - priv->bb_rx_conf &= 0xFC; - break; - case ANT_RXB: - priv->bb_rx_conf &= 0xFE; - priv->bb_rx_conf |= 0x02; - break; - } - - return vnt_control_out(priv, MESSAGE_TYPE_SET_ANTMD, - (u16)antenna_mode, 0, 0, NULL); -} - -/* - * Description: Set Antenna mode - * - * Parameters: - * In: - * pDevice - Device Structure - * byAntennaMode - Antenna Mode - * Out: - * none - * - * Return Value: none - * - */ - -int vnt_vt3184_init(struct vnt_private *priv) -{ - int ret; - u16 length; - u8 *addr = NULL; - const u8 *c_addr; - u8 data; - - ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, MESSAGE_REQUEST_EEPROM, - EEP_MAX_CONTEXT_SIZE, priv->eeprom); - if (ret) - goto end; - - priv->rf_type = priv->eeprom[EEP_OFS_RFTYPE]; - - dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type); - - if ((priv->rf_type == RF_AL2230) || - (priv->rf_type == RF_AL2230S)) { - priv->bb_rx_conf = vnt_vt3184_al2230[10]; - length = sizeof(vnt_vt3184_al2230); - addr = vnt_vt3184_al2230; - - priv->bb_vga[0] = 0x1c; - priv->bb_vga[1] = 0x10; - priv->bb_vga[2] = 0x0; - priv->bb_vga[3] = 0x0; - - } else if ((priv->rf_type == RF_VT3226) || - (priv->rf_type == RF_VT3226D0)) { - priv->bb_rx_conf = vnt_vt3184_vt3226d0[10]; - length = sizeof(vnt_vt3184_vt3226d0); - c_addr = vnt_vt3184_vt3226d0; - - priv->bb_vga[0] = 0x20; - priv->bb_vga[1] = 0x10; - priv->bb_vga[2] = 0x0; - priv->bb_vga[3] = 0x0; - - /* Fix VT3226 DFC system timing issue */ - ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2, - SOFTPWRCTL_RFLEOPT); - if (ret) - goto end; - } else { - goto end; - } - - if (addr) - c_addr = addr; - - ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, - MESSAGE_REQUEST_BBREG, length, c_addr); - if (ret) - goto end; - - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0, - MESSAGE_REQUEST_BBAGC, - sizeof(vnt_vt3184_agc), vnt_vt3184_agc); - if (ret) - goto end; - - if ((priv->rf_type == RF_VT3226) || - (priv->rf_type == RF_VT3226D0)) { - data = (priv->rf_type == RF_VT3226D0) ? 0x11 : 0x23; - - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, - MAC_REG_ITRTMSET, data); - if (ret) - goto end; - - ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0)); - if (ret) - goto end; - } - - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x04, 0x7f); - if (ret) - goto end; - - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01); - if (ret) - goto end; - - ret = vnt_rf_table_download(priv); - if (ret) - goto end; - - /* Fix for TX USB resets from vendors driver */ - ret = vnt_control_in(priv, MESSAGE_TYPE_READ, USB_REG4, - MESSAGE_REQUEST_MEM, sizeof(data), &data); - if (ret) - goto end; - - data |= 0x2; - - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, USB_REG4, - MESSAGE_REQUEST_MEM, sizeof(data), &data); - -end: - return ret; -} - -/* - * Description: Set ShortSlotTime mode - * - * Parameters: - * In: - * priv - Device Structure - * Out: - * none - * - * Return Value: none - * - */ -int vnt_set_short_slot_time(struct vnt_private *priv) -{ - int ret = 0; - u8 bb_vga = 0; - - if (priv->short_slot_time) - priv->bb_rx_conf &= 0xdf; - else - priv->bb_rx_conf |= 0x20; - - ret = vnt_control_in_u8(priv, MESSAGE_REQUEST_BBREG, 0xe7, &bb_vga); - if (ret) - return ret; - - if (bb_vga == priv->bb_vga[0]) - priv->bb_rx_conf |= 0x20; - - return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, - priv->bb_rx_conf); -} - -int vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data) -{ - int ret; - - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data); - if (ret) - return ret; - - /* patch for 3253B0 Baseband with Cardbus module */ - if (priv->short_slot_time) - priv->bb_rx_conf &= 0xdf; /* 1101 1111 */ - else - priv->bb_rx_conf |= 0x20; /* 0010 0000 */ - - return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, - priv->bb_rx_conf); -} - -/* - * Description: vnt_set_deep_sleep - * - * Parameters: - * In: - * priv - Device Structure - * Out: - * none - * - * Return Value: none - * - */ -int vnt_set_deep_sleep(struct vnt_private *priv) -{ - int ret = 0; - - /* CR12 */ - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x17); - if (ret) - return ret; - - /* CR13 */ - return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0xB9); -} - -int vnt_exit_deep_sleep(struct vnt_private *priv) -{ - int ret = 0; - - /* CR12 */ - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x00); - if (ret) - return ret; - - /* CR13 */ - return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01); -} - -int vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning) -{ - const struct vnt_threshold *threshold = NULL; - u8 length; - u8 cr_201, cr_206; - u8 ed_inx; - int ret; - - switch (priv->rf_type) { - case RF_AL2230: - case RF_AL2230S: - threshold = al2230_vnt_threshold; - length = ARRAY_SIZE(al2230_vnt_threshold); - break; - - case RF_VT3226: - case RF_VT3226D0: - threshold = vt3226_vnt_threshold; - length = ARRAY_SIZE(vt3226_vnt_threshold); - break; - } - - if (!threshold) - return -EINVAL; - - for (ed_inx = scanning ? 0 : length - 1; ed_inx > 0; ed_inx--) { - if (priv->bb_pre_ed_rssi <= threshold[ed_inx].bb_pre_ed_rssi) - break; - } - - cr_201 = threshold[ed_inx].cr_201; - cr_206 = threshold[ed_inx].cr_206; - - if (ed_inx == priv->bb_pre_ed_index && !scanning) - return 0; - - priv->bb_pre_ed_index = ed_inx; - - dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n", - __func__, priv->bb_pre_ed_rssi); - - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201); - if (ret) - return ret; - - return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206); -} - diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h deleted file mode 100644 index dce50a311f24387409ebc7178042a4d31a7861d4..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/baseband.h +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions to access baseband - * - * Author: Jerry Chen - * - * Date: Jun. 5, 2002 - * - * Revision History: - * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. - * 08-26-2003 Kyle Hsu : Add defines of packet type and TX rate. - */ - -#ifndef __BASEBAND_H__ -#define __BASEBAND_H__ - -#include "device.h" - -#define PREAMBLE_LONG 0 -#define PREAMBLE_SHORT 1 - -/* - * Registers in the BASEBAND - */ -#define BB_MAX_CONTEXT_SIZE 256 - -#define C_SIFS_A 16 /* usec */ -#define C_SIFS_BG 10 - -#define C_EIFS 80 /* usec */ - -#define C_SLOT_SHORT 9 /* usec */ -#define C_SLOT_LONG 20 - -#define C_CWMIN_A 15 /* slot time */ -#define C_CWMIN_B 31 - -#define C_CWMAX 1023 /* slot time */ - -/* 0:11A 1:11B 2:11G */ -#define BB_TYPE_11A 0 -#define BB_TYPE_11B 1 -#define BB_TYPE_11G 2 - -/* 0:11a, 1:11b, 2:11gb (only CCK in BasicRate), 3:11ga (OFDM in BasicRate) */ -#define PK_TYPE_11A 0 -#define PK_TYPE_11B 1 -#define PK_TYPE_11GB 2 -#define PK_TYPE_11GA 3 - -#define TOP_RATE_54M 0x80000000 -#define TOP_RATE_48M 0x40000000 -#define TOP_RATE_36M 0x20000000 -#define TOP_RATE_24M 0x10000000 -#define TOP_RATE_18M 0x08000000 -#define TOP_RATE_12M 0x04000000 -#define TOP_RATE_11M 0x02000000 -#define TOP_RATE_9M 0x01000000 -#define TOP_RATE_6M 0x00800000 -#define TOP_RATE_55M 0x00400000 -#define TOP_RATE_2M 0x00200000 -#define TOP_RATE_1M 0x00100000 - -int vnt_set_short_slot_time(struct vnt_private *priv); -int vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data); -int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode); -int vnt_vt3184_init(struct vnt_private *priv); -int vnt_set_deep_sleep(struct vnt_private *priv); -int vnt_exit_deep_sleep(struct vnt_private *priv); -int vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning); - -#endif /* __BASEBAND_H__ */ diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c deleted file mode 100644 index b9dc0d13c00c85234302ffb231c522883872f9e4..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/card.c +++ /dev/null @@ -1,456 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Provide functions to setup NIC operation mode - * Functions: - * vnt_set_rspinf - Set RSPINF - * vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS - * vnt_update_top_rates - Update BasicTopRate - * vnt_add_basic_rate - Add to BasicRateSet - * vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet - * vnt_get_tsf_offset - Calculate TSFOffset - * vnt_get_next_tbtt - Calculate Next Beacon TSF counter - * vnt_reset_next_tbtt - Set NIC Beacon time - * vnt_update_next_tbtt - Sync. NIC Beacon time - * vnt_radio_power_off - Turn Off NIC Radio Power - * vnt_radio_power_on - Turn On NIC Radio Power - * - * Revision History: - * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. - * 08-26-2003 Kyle Hsu: Modify the definition type of dwIoBase. - * 09-01-2003 Bryan YC Fan: Add vnt_update_ifs(). - * - */ - -#include -#include -#include "device.h" -#include "card.h" -#include "baseband.h" -#include "mac.h" -#include "desc.h" -#include "rf.h" -#include "power.h" -#include "key.h" -#include "usbpipe.h" - -/* const u16 cw_rxbcntsf_off[MAX_RATE] = - * {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; - */ - -static const u16 cw_rxbcntsf_off[MAX_RATE] = { - 192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3 -}; - -int vnt_set_channel(struct vnt_private *priv, u32 connection_channel) -{ - int ret; - - if (connection_channel > CB_MAX_CHANNEL || !connection_channel) - return -EINVAL; - - /* clear NAV */ - vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV); - - /* Set Channel[7] = 0 to tell H/W channel is changing now. */ - vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, - (BIT(7) | BIT(5) | BIT(4))); - - ret = vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL, - connection_channel, 0, 0, NULL); - if (ret) - return ret; - - return vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL, - (u8)(connection_channel | 0x80)); -} - -static const u8 vnt_rspinf_b_short_table[] = { - 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x09, 0x00, - 0x15, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x80 -}; - -static const u8 vnt_rspinf_b_long_table[] = { - 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, - 0x15, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x80 -}; - -static const u8 vnt_rspinf_a_table[] = { - 0x9b, 0x18, 0x9f, 0x10, 0x9a, 0x0a, 0x9e, 0x08, 0x99, - 0x08, 0x9d, 0x04, 0x98, 0x04, 0x9c, 0x04, 0x9c, 0x04 -}; - -static const u8 vnt_rspinf_gb_table[] = { - 0x8b, 0x1e, 0x8f, 0x16, 0x8a, 0x12, 0x8e, 0x0e, 0x89, - 0x0e, 0x8d, 0x0a, 0x88, 0x0a, 0x8c, 0x0a, 0x8c, 0x0a -}; - -int vnt_set_rspinf(struct vnt_private *priv, u8 bb_type) -{ - const u8 *data; - u16 len; - int ret; - - if (priv->preamble_type) { - data = vnt_rspinf_b_short_table; - len = ARRAY_SIZE(vnt_rspinf_b_short_table); - } else { - data = vnt_rspinf_b_long_table; - len = ARRAY_SIZE(vnt_rspinf_b_long_table); - } - - /* RSPINF_b_1 to RSPINF_b_11 */ - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1, - MESSAGE_REQUEST_MACREG, len, data); - if (ret) - return ret; - - if (bb_type == BB_TYPE_11A) { - data = vnt_rspinf_a_table; - len = ARRAY_SIZE(vnt_rspinf_a_table); - } else { - data = vnt_rspinf_gb_table; - len = ARRAY_SIZE(vnt_rspinf_gb_table); - } - - /* RSPINF_a_6 to RSPINF_a_72 */ - return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_A_6, - MESSAGE_REQUEST_MACREG, len, data); -} - -int vnt_update_ifs(struct vnt_private *priv) -{ - u8 max_min = 0; - u8 data[4]; - int ret; - - if (priv->packet_type == PK_TYPE_11A) { - priv->slot = C_SLOT_SHORT; - priv->sifs = C_SIFS_A; - priv->difs = C_SIFS_A + 2 * C_SLOT_SHORT; - max_min = 4; - } else { - priv->sifs = C_SIFS_BG; - - if (priv->short_slot_time) { - priv->slot = C_SLOT_SHORT; - max_min = 4; - } else { - priv->slot = C_SLOT_LONG; - max_min = 5; - } - - priv->difs = C_SIFS_BG + 2 * priv->slot; - } - - priv->eifs = C_EIFS; - - data[0] = (u8)priv->sifs; - data[1] = (u8)priv->difs; - data[2] = (u8)priv->eifs; - data[3] = (u8)priv->slot; - - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS, - MESSAGE_REQUEST_MACREG, 4, &data[0]); - if (ret) - return ret; - - max_min |= 0xa0; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0, - MESSAGE_REQUEST_MACREG, 1, &max_min); -} - -void vnt_update_top_rates(struct vnt_private *priv) -{ - int pos; - - pos = fls(priv->basic_rates & GENMASK(RATE_54M, RATE_6M)); - priv->top_ofdm_basic_rate = pos ? (pos - 1) : RATE_24M; - - pos = fls(priv->basic_rates & GENMASK(RATE_11M, RATE_1M)); - priv->top_cck_basic_rate = pos ? (pos - 1) : RATE_1M; -} - -bool vnt_ofdm_min_rate(struct vnt_private *priv) -{ - return priv->basic_rates & GENMASK(RATE_54M, RATE_6M) ? true : false; -} - -u8 vnt_get_pkt_type(struct vnt_private *priv) -{ - if (priv->bb_type == BB_TYPE_11A || priv->bb_type == BB_TYPE_11B) - return (u8)priv->bb_type; - else if (vnt_ofdm_min_rate(priv)) - return PK_TYPE_11GA; - return PK_TYPE_11GB; -} - -/* - * Description: Calculate TSF offset of two TSF input - * Get TSF Offset from RxBCN's TSF and local TSF - * - * Parameters: - * In: - * rx_rate - rx rate. - * tsf1 - Rx BCN's TSF - * tsf2 - Local TSF - * Out: - * none - * - * Return Value: TSF Offset value - * - */ -u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2) -{ - return tsf1 - tsf2 - (u64)cw_rxbcntsf_off[rx_rate % MAX_RATE]; -} - -int vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, - u64 time_stamp, u64 local_tsf) -{ - u64 tsf_offset = 0; - u8 data[8]; - - tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf); - - data[0] = (u8)tsf_offset; - data[1] = (u8)(tsf_offset >> 8); - data[2] = (u8)(tsf_offset >> 16); - data[3] = (u8)(tsf_offset >> 24); - data[4] = (u8)(tsf_offset >> 32); - data[5] = (u8)(tsf_offset >> 40); - data[6] = (u8)(tsf_offset >> 48); - data[7] = (u8)(tsf_offset >> 56); - - return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, - MESSAGE_REQUEST_TSF, 0, 8, data); -} - -/* - * Description: Clear NIC TSF counter - * Clear local TSF counter - * - * Parameters: - * In: - * priv - The adapter to be read - * - * Return Value: true if success; otherwise false - * - */ -bool vnt_clear_current_tsf(struct vnt_private *priv) -{ - vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - - priv->current_tsf = 0; - - return true; -} - -/* - * Description: Read NIC TSF counter - * Get NEXTTBTT from adjusted TSF and Beacon Interval - * - * Parameters: - * In: - * tsf - Current TSF counter - * beacon_interval - Beacon Interval - * Out: - * tsf - Current TSF counter - * - * Return Value: TSF value of next Beacon - * - */ -u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval) -{ - u32 beacon_int; - - beacon_int = beacon_interval * 1024; - - /* Next TBTT = - * ((local_current_TSF / beacon_interval) + 1) * beacon_interval - */ - if (beacon_int) { - do_div(tsf, beacon_int); - tsf += 1; - tsf *= beacon_int; - } - - return tsf; -} - -int vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval) -{ - u64 next_tbtt = 0; - u8 data[8]; - - vnt_clear_current_tsf(priv); - - next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval); - - data[0] = (u8)next_tbtt; - data[1] = (u8)(next_tbtt >> 8); - data[2] = (u8)(next_tbtt >> 16); - data[3] = (u8)(next_tbtt >> 24); - data[4] = (u8)(next_tbtt >> 32); - data[5] = (u8)(next_tbtt >> 40); - data[6] = (u8)(next_tbtt >> 48); - data[7] = (u8)(next_tbtt >> 56); - - return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, - MESSAGE_REQUEST_TBTT, 0, 8, data); -} - -int vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, - u16 beacon_interval) -{ - u8 data[8]; - int ret; - - tsf = vnt_get_next_tbtt(tsf, beacon_interval); - - data[0] = (u8)tsf; - data[1] = (u8)(tsf >> 8); - data[2] = (u8)(tsf >> 16); - data[3] = (u8)(tsf >> 24); - data[4] = (u8)(tsf >> 32); - data[5] = (u8)(tsf >> 40); - data[6] = (u8)(tsf >> 48); - data[7] = (u8)(tsf >> 56); - - ret = vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, - MESSAGE_REQUEST_TBTT, 0, 8, data); - if (ret) - return ret; - - dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf); - return 0; -} - -/* - * Description: Turn off Radio power - * - * Parameters: - * In: - * priv - The adapter to be turned off - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -int vnt_radio_power_off(struct vnt_private *priv) -{ - int ret = 0; - - switch (priv->rf_type) { - case RF_AL2230: - case RF_AL2230S: - case RF_VT3226: - case RF_VT3226D0: - ret = vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL, - (SOFTPWRCTL_SWPE2 | - SOFTPWRCTL_SWPE3)); - break; - } - - if (ret) - goto end; - - ret = vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON); - if (ret) - goto end; - - ret = vnt_set_deep_sleep(priv); - if (ret) - goto end; - - ret = vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); - -end: - return ret; -} - -/* - * Description: Turn on Radio power - * - * Parameters: - * In: - * priv - The adapter to be turned on - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -int vnt_radio_power_on(struct vnt_private *priv) -{ - int ret = 0; - - ret = vnt_exit_deep_sleep(priv); - if (ret) - return ret; - - ret = vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON); - if (ret) - return ret; - - switch (priv->rf_type) { - case RF_AL2230: - case RF_AL2230S: - case RF_VT3226: - case RF_VT3226D0: - ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL, - (SOFTPWRCTL_SWPE2 | - SOFTPWRCTL_SWPE3)); - if (ret) - return ret; - } - - return vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); -} - -int vnt_set_bss_mode(struct vnt_private *priv) -{ - int ret; - unsigned char type = priv->bb_type; - unsigned char data = 0; - unsigned char bb_vga_2_3 = 0x00; - - ret = vnt_mac_set_bb_type(priv, type); - if (ret) - return ret; - - priv->packet_type = vnt_get_pkt_type(priv); - - if (priv->bb_type == BB_TYPE_11A) { - data = 0x03; - bb_vga_2_3 = 0x10; - } else if (priv->bb_type == BB_TYPE_11B) { - data = 0x02; - } else if (priv->bb_type == BB_TYPE_11G) { - data = 0x08; - } - - if (data) { - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, - 0x88, data); - if (ret) - return ret; - } - - ret = vnt_update_ifs(priv); - if (ret) - return ret; - - ret = vnt_set_rspinf(priv, priv->bb_type); - if (ret) - return ret; - - priv->bb_vga[2] = bb_vga_2_3; - priv->bb_vga[3] = bb_vga_2_3; - - return vnt_set_vga_gain_offset(priv, priv->bb_vga[0]); -} diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h deleted file mode 100644 index eb01f7cc871f40076d46ce64b58e3762eb1b53f2..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/card.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Provide functions to setup NIC operation mode - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __CARD_H__ -#define __CARD_H__ -#include "device.h" - -/* init card type */ - -#define CB_MAX_CHANNEL_24G 14 -#define CB_MAX_CHANNEL_5G 42 /* add channel9(5045MHz), 41==>42 */ -#define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G + CB_MAX_CHANNEL_5G) - -struct vnt_private; - -int vnt_set_channel(struct vnt_private *priv, u32 connection_channel); -int vnt_set_rspinf(struct vnt_private *priv, u8 bb_type); -int vnt_update_ifs(struct vnt_private *priv); -void vnt_update_top_rates(struct vnt_private *priv); -bool vnt_ofdm_min_rate(struct vnt_private *priv); -int vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, - u64 time_stamp, u64 local_tsf); -bool vnt_clear_current_tsf(struct vnt_private *priv); -int vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval); -int vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, - u16 beacon_interval); -u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval); -u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2); -int vnt_radio_power_off(struct vnt_private *priv); -int vnt_radio_power_on(struct vnt_private *priv); -u8 vnt_get_pkt_type(struct vnt_private *priv); -int vnt_set_bss_mode(struct vnt_private *priv); - -#endif /* __CARD_H__ */ diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c deleted file mode 100644 index 413e2fc4a50dcacedbdd37a25ced88f14c8bf2aa..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/channel.c +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Channel number mapping - * - * Author: Lucas Lin - * - * Date: Dec 24, 2004 - * - * - * - * Revision History: - * 01-18-2005 RobertYu: remove the for loop searching in - * ChannelValid, change ChannelRuleTab - * to lookup-type, reorder table items. - * - * - */ - -#include "device.h" -#include "channel.h" -#include "rf.h" - -static struct ieee80211_rate vnt_rates_bg[] = { - { .bitrate = 10, .hw_value = RATE_1M }, - { .bitrate = 20, .hw_value = RATE_2M }, - { .bitrate = 55, .hw_value = RATE_5M }, - { .bitrate = 110, .hw_value = RATE_11M }, - { .bitrate = 60, .hw_value = RATE_6M }, - { .bitrate = 90, .hw_value = RATE_9M }, - { .bitrate = 120, .hw_value = RATE_12M }, - { .bitrate = 180, .hw_value = RATE_18M }, - { .bitrate = 240, .hw_value = RATE_24M }, - { .bitrate = 360, .hw_value = RATE_36M }, - { .bitrate = 480, .hw_value = RATE_48M }, - { .bitrate = 540, .hw_value = RATE_54M }, -}; - -static struct ieee80211_channel vnt_channels_2ghz[] = { - { .center_freq = 2412, .hw_value = 1 }, - { .center_freq = 2417, .hw_value = 2 }, - { .center_freq = 2422, .hw_value = 3 }, - { .center_freq = 2427, .hw_value = 4 }, - { .center_freq = 2432, .hw_value = 5 }, - { .center_freq = 2437, .hw_value = 6 }, - { .center_freq = 2442, .hw_value = 7 }, - { .center_freq = 2447, .hw_value = 8 }, - { .center_freq = 2452, .hw_value = 9 }, - { .center_freq = 2457, .hw_value = 10 }, - { .center_freq = 2462, .hw_value = 11 }, - { .center_freq = 2467, .hw_value = 12 }, - { .center_freq = 2472, .hw_value = 13 }, - { .center_freq = 2484, .hw_value = 14 } -}; - -static struct ieee80211_supported_band vnt_supported_2ghz_band = { - .channels = vnt_channels_2ghz, - .n_channels = ARRAY_SIZE(vnt_channels_2ghz), - .bitrates = vnt_rates_bg, - .n_bitrates = ARRAY_SIZE(vnt_rates_bg), -}; - -void vnt_init_bands(struct vnt_private *priv) -{ - struct ieee80211_channel *ch; - int i; - - ch = vnt_channels_2ghz; - for (i = 0; i < ARRAY_SIZE(vnt_channels_2ghz); i++) { - ch[i].max_power = VNT_RF_MAX_POWER; - ch[i].flags = IEEE80211_CHAN_NO_HT40; - } - priv->hw->wiphy->bands[NL80211_BAND_2GHZ] = - &vnt_supported_2ghz_band; -} diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h deleted file mode 100644 index 723660e40310a60f5d80261897b1c956d7ed0818..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/channel.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Country Regulation Rules header file - * - * Author: Lucas Lin - * - * Date: Dec 23, 2004 - * - */ - -#ifndef _CHANNEL_H_ -#define _CHANNEL_H_ - -#include "device.h" - -void vnt_init_bands(struct vnt_private *priv); - -#endif /* _CHANNEL_H_ */ diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h deleted file mode 100644 index c13561e528db37b3fa0aa40da48100039dce8c92..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/desc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose:The header file of descriptor - * - * Revision History: - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __DESC_H__ -#define __DESC_H__ - -#include -#include -#include - -/* max transmit or receive buffer size */ -#define CB_MAX_BUF_SIZE 2900U /* NOTE: must be multiple of 4 */ - -#define MAX_TOTAL_SIZE_WITH_ALL_HEADERS CB_MAX_BUF_SIZE - -#define MAX_INTERRUPT_SIZE 32 - -#define CB_MAX_RX_DESC 128 /* max # of descriptors */ -#define CB_MIN_RX_DESC 16 /* min # of RX descriptors */ -#define CB_MAX_TX_DESC 128 /* max # of descriptors */ -#define CB_MIN_TX_DESC 16 /* min # of TX descriptors */ - -/* - * bits in the RSR register - */ -#define RSR_ADDRBROAD BIT(7) -#define RSR_ADDRMULTI BIT(6) -#define RSR_ADDRUNI 0x00 -#define RSR_IVLDTYP BIT(5) /* invalid packet type */ -#define RSR_IVLDLEN BIT(4) /* invalid len (> 2312 byte) */ -#define RSR_BSSIDOK BIT(3) -#define RSR_CRCOK BIT(2) -#define RSR_BCNSSIDOK BIT(1) -#define RSR_ADDROK BIT(0) - -/* - * bits in the new RSR register - */ -#define NEWRSR_DECRYPTOK BIT(4) -#define NEWRSR_CFPIND BIT(3) -#define NEWRSR_HWUTSF BIT(2) -#define NEWRSR_BCNHITAID BIT(1) -#define NEWRSR_BCNHITAID0 BIT(0) - -/* - * bits in the TSR register - */ -#define TSR_RETRYTMO BIT(3) -#define TSR_TMO BIT(2) -#define TSR_ACKDATA BIT(1) -#define TSR_VALID BIT(0) - -#define FIFOCTL_AUTO_FB_1 0x1000 -#define FIFOCTL_AUTO_FB_0 0x0800 -#define FIFOCTL_GRPACK 0x0400 -#define FIFOCTL_11GA 0x0300 -#define FIFOCTL_11GB 0x0200 -#define FIFOCTL_11B 0x0100 -#define FIFOCTL_11A 0x0000 -#define FIFOCTL_RTS 0x0080 -#define FIFOCTL_ISDMA0 0x0040 -#define FIFOCTL_GENINT 0x0020 -#define FIFOCTL_TMOEN 0x0010 -#define FIFOCTL_LRETRY 0x0008 -#define FIFOCTL_CRCDIS 0x0004 -#define FIFOCTL_NEEDACK 0x0002 -#define FIFOCTL_LHEAD 0x0001 - -/* WMAC definition Frag Control */ -#define FRAGCTL_AES 0x0300 -#define FRAGCTL_TKIP 0x0200 -#define FRAGCTL_LEGACY 0x0100 -#define FRAGCTL_NONENCRYPT 0x0000 -#define FRAGCTL_ENDFRAG 0x0003 -#define FRAGCTL_MIDFRAG 0x0002 -#define FRAGCTL_STAFRAG 0x0001 -#define FRAGCTL_NONFRAG 0x0000 - -#endif /* __DESC_H__ */ diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h deleted file mode 100644 index ca974d61d3f443dc17215523920d56fe8487febd..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/device.h +++ /dev/null @@ -1,386 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: MAC Data structure - * - * Author: Tevin Chen - * - * Date: Mar 17, 1997 - * - */ - -#ifndef __DEVICE_H__ -#define __DEVICE_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef SIOCETHTOOL -#define DEVICE_ETHTOOL_IOCTL_SUPPORT -#include -#else -#undef DEVICE_ETHTOOL_IOCTL_SUPPORT -#endif - -#define RATE_1M 0 -#define RATE_2M 1 -#define RATE_5M 2 -#define RATE_11M 3 -#define RATE_6M 4 -#define RATE_9M 5 -#define RATE_12M 6 -#define RATE_18M 7 -#define RATE_24M 8 -#define RATE_36M 9 -#define RATE_48M 10 -#define RATE_54M 11 -#define RATE_AUTO 12 - -#define MAX_RATE 12 -#define VNT_B_RATES (BIT(RATE_1M) | BIT(RATE_2M) |\ - BIT(RATE_5M) | BIT(RATE_11M)) - -/* - * device specific - */ - -#include "wcmd.h" -#include "desc.h" -#include "key.h" -#include "card.h" - -#define VNT_USB_VENDOR_ID 0x160a -#define VNT_USB_PRODUCT_ID 0x3184 - -#define DEVICE_NAME "vt6656" -#define DEVICE_FULL_DRV_NAM "VIA Networking Wireless LAN USB Driver" - -#define DEVICE_VERSION "mac80211" - -#define FIRMWARE_VERSION 0x133 /* version 1.51 */ -#define FIRMWARE_NAME "vntwusb.fw" -#define FIRMWARE_CHUNK_SIZE 0x400 - -#define MAX_UINTS 8 -#define OPTION_DEFAULT { [0 ... MAX_UINTS - 1] = -1} - -#define DUPLICATE_RX_CACHE_LENGTH 5 - -#define AUTO_FB_NONE 0 -#define AUTO_FB_0 1 -#define AUTO_FB_1 2 - -#define FB_RATE0 0 -#define FB_RATE1 1 - -/* Antenna Mode */ -#define ANT_A 0 -#define ANT_B 1 -#define ANT_DIVERSITY 2 -#define ANT_RXD_TXA 3 -#define ANT_RXD_TXB 4 -#define ANT_UNKNOWN 0xFF -#define ANT_TXA 0 -#define ANT_TXB 1 -#define ANT_RXA 2 -#define ANT_RXB 3 - -#define BB_VGA_LEVEL 4 -#define BB_VGA_CHANGE_THRESHOLD 3 - -#define EEP_MAX_CONTEXT_SIZE 256 - -/* Contents in the EEPROM */ -#define EEP_OFS_PAR 0x0 -#define EEP_OFS_ANTENNA 0x17 -#define EEP_OFS_RADIOCTL 0x18 -#define EEP_OFS_RFTYPE 0x1b -#define EEP_OFS_MINCHANNEL 0x1c -#define EEP_OFS_MAXCHANNEL 0x1d -#define EEP_OFS_SIGNATURE 0x1e -#define EEP_OFS_ZONETYPE 0x1f -#define EEP_OFS_RFTABLE 0x20 -#define EEP_OFS_PWR_CCK 0x20 -#define EEP_OFS_SETPT_CCK 0x21 -#define EEP_OFS_PWR_OFDMG 0x23 - -#define EEP_OFS_CALIB_TX_IQ 0x24 -#define EEP_OFS_CALIB_TX_DC 0x25 -#define EEP_OFS_CALIB_RX_IQ 0x26 - -#define EEP_OFS_MAJOR_VER 0x2e -#define EEP_OFS_MINOR_VER 0x2f - -#define EEP_OFS_CCK_PWR_TBL 0x30 -#define EEP_OFS_OFDM_PWR_TBL 0x40 -#define EEP_OFS_OFDMA_PWR_TBL 0x50 - -/* Bits in EEP_OFS_ANTENNA */ -#define EEP_ANTENNA_MAIN BIT(0) -#define EEP_ANTENNA_AUX BIT(1) -#define EEP_ANTINV BIT(2) - -/* Bits in EEP_OFS_RADIOCTL */ -#define EEP_RADIOCTL_ENABLE BIT(7) - -/* control commands */ -#define MESSAGE_TYPE_READ 0x1 -#define MESSAGE_TYPE_WRITE 0x0 -#define MESSAGE_TYPE_LOCK_OR 0x2 -#define MESSAGE_TYPE_LOCK_AND 0x3 -#define MESSAGE_TYPE_WRITE_MASK 0x4 -#define MESSAGE_TYPE_CARDINIT 0x5 -#define MESSAGE_TYPE_INIT_RSP 0x6 -#define MESSAGE_TYPE_MACSHUTDOWN 0x7 -#define MESSAGE_TYPE_SETKEY 0x8 -#define MESSAGE_TYPE_CLRKEYENTRY 0x9 -#define MESSAGE_TYPE_WRITE_MISCFF 0xa -#define MESSAGE_TYPE_SET_ANTMD 0xb -#define MESSAGE_TYPE_SELECT_CHANNEL 0xc -#define MESSAGE_TYPE_SET_TSFTBTT 0xd -#define MESSAGE_TYPE_SET_SSTIFS 0xe -#define MESSAGE_TYPE_CHANGE_BBTYPE 0xf -#define MESSAGE_TYPE_DISABLE_PS 0x10 -#define MESSAGE_TYPE_WRITE_IFRF 0x11 - -/* command read/write(index) */ -#define MESSAGE_REQUEST_MEM 0x1 -#define MESSAGE_REQUEST_BBREG 0x2 -#define MESSAGE_REQUEST_MACREG 0x3 -#define MESSAGE_REQUEST_EEPROM 0x4 -#define MESSAGE_REQUEST_TSF 0x5 -#define MESSAGE_REQUEST_TBTT 0x6 -#define MESSAGE_REQUEST_BBAGC 0x7 -#define MESSAGE_REQUEST_VERSION 0x8 -#define MESSAGE_REQUEST_RF_INIT 0x9 -#define MESSAGE_REQUEST_RF_INIT2 0xa -#define MESSAGE_REQUEST_RF_CH0 0xb -#define MESSAGE_REQUEST_RF_CH1 0xc -#define MESSAGE_REQUEST_RF_CH2 0xd - -/* USB registers */ -#define USB_REG4 0x604 - -#define DEVICE_INIT_COLD 0x0 /* cold init */ -#define DEVICE_INIT_RESET 0x1 /* reset init or Dx to D0 power remain */ -#define DEVICE_INIT_DXPL 0x2 /* Dx to D0 power lost init */ - -/* Device init */ -struct vnt_cmd_card_init { - u8 init_class; - u8 exist_sw_net_addr; - u8 sw_net_addr[6]; - u8 short_retry_limit; - u8 long_retry_limit; -}; - -struct vnt_rsp_card_init { - u8 status; - u8 net_addr[6]; - u8 rf_type; - u8 min_channel; - u8 max_channel; -}; - -/* USB */ - -/* - * Enum of context types for SendPacket - */ -enum { - CONTEXT_DATA_PACKET = 0, - CONTEXT_BEACON_PACKET -}; - -struct vnt_rx_header { - u32 wbk_status; - u8 rx_sts; - u8 rx_rate; - u16 pay_load_len; -} __packed; - -struct vnt_rx_tail { - __le64 tsf_time; - u8 sq; - u8 new_rsr; - u8 rssi; - u8 rsr; - u8 sq_3; -} __packed; - -/* RCB (Receive Control Block) */ -struct vnt_rcb { - void *priv; - struct urb *urb; - struct sk_buff *skb; -}; - -/* used to track bulk out irps */ -struct vnt_usb_send_context { - void *priv; - struct sk_buff *skb; - void *tx_buffer; - u32 frame_len; - u16 tx_hdr_size; - u16 tx_rate; - u8 type; - u8 pkt_no; - u8 pkt_type; - bool in_use; -}; - -/* - * Structure to keep track of USB interrupt packets - */ -struct vnt_interrupt_buffer { - u8 *data_buf; -}; - -/* flags for options */ -#define DEVICE_FLAGS_UNPLUG 0 -#define DEVICE_FLAGS_DISCONNECTED 1 - -struct vnt_private { - /* mac80211 */ - struct ieee80211_hw *hw; - struct ieee80211_vif *vif; - u8 mac_hw; - /* netdev */ - struct usb_device *usb; - struct usb_interface *intf; - - u64 tsf_time; - - u32 rx_buf_sz; - int mc_list_count; - - spinlock_t lock; /* prepare tx USB URB */ - struct mutex usb_lock; /* USB control messages */ - - unsigned long flags; - - /* USB */ - struct urb *interrupt_urb; - u32 int_interval; - - /* Variables to track resources for the BULK In Pipe */ - struct vnt_rcb *rcb[CB_MAX_RX_DESC]; - u32 num_rcb; - - /* Variables to track resources for the BULK Out Pipe */ - struct vnt_usb_send_context *tx_context[CB_MAX_TX_DESC]; - struct usb_anchor tx_submitted; - u32 num_tx_context; - - /* Variables to track resources for the Interrupt In Pipe */ - struct vnt_interrupt_buffer int_buf; - - /* Version control */ - u16 firmware_version; - u8 local_id; - u8 rf_type; - u8 bb_rx_conf; - - struct vnt_cmd_card_init init_command; - struct vnt_rsp_card_init init_response; - u8 current_net_addr[ETH_ALEN] __aligned(2); - u8 permanent_net_addr[ETH_ALEN] __aligned(2); - - u8 exist_sw_net_addr; - - u64 current_tsf; - - /* 802.11 MAC specific */ - u32 current_rssi; - - /* Antenna Diversity */ - int tx_rx_ant_inv; - u32 rx_antenna_sel; - u8 rx_antenna_mode; - u8 tx_antenna_mode; - u8 radio_ctl; - - /* IFS & Cw */ - u32 sifs; /* Current SIFS */ - u32 difs; /* Current DIFS */ - u32 eifs; /* Current EIFS */ - u32 slot; /* Current SlotTime */ - - /* Rate */ - u8 bb_type; /* 0: 11A, 1:11B, 2:11G */ - u8 packet_type; /* 0:11a 1:11b 2:11gb 3:11ga */ - u32 basic_rates; - u8 top_ofdm_basic_rate; - u8 top_cck_basic_rate; - - u8 eeprom[EEP_MAX_CONTEXT_SIZE]; /*u32 alignment */ - - u8 preamble_type; - - /* For RF Power table */ - u8 cck_pwr; - u8 ofdm_pwr_g; - u8 ofdm_pwr_a; - u8 power; - u8 cck_pwr_tbl[14]; - u8 ofdm_pwr_tbl[14]; - u8 ofdm_a_pwr_tbl[42]; - - u16 tx_rate_fb0; - u16 tx_rate_fb1; - - enum nl80211_iftype op_mode; - - int short_slot_time; - - /* Power save */ - u16 current_aid; - - /* Beacon related */ - u16 seq_counter; - - enum vnt_cmd_state command_state; - - enum vnt_cmd command; - - /* 802.11 counter */ - - enum vnt_cmd cmd_queue[CMD_Q_SIZE]; - u32 cmd_dequeue_idx; - u32 cmd_enqueue_idx; - u32 free_cmd_queue; - int cmd_running; - - unsigned long key_entry_inuse; - - u8 auto_fb_ctrl; - - /* For Update BaseBand VGA Gain Offset */ - u8 bb_vga[BB_VGA_LEVEL]; - - u8 bb_pre_ed_rssi; - u8 bb_pre_ed_index; - - /* command timer */ - struct delayed_work run_command_work; - - struct ieee80211_low_level_stats low_stats; -}; - -int vnt_init(struct vnt_private *priv); - -#endif diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c deleted file mode 100644 index bdc5f30c4f9d2951a6f80feaa9fac54c5a7c3f65..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/key.c +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions for 802.11i Key management - * - * Author: Jerry Chen - * - * Date: May 29, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "mac.h" -#include "key.h" -#include "usbpipe.h" - -int vnt_key_init_table(struct vnt_private *priv) -{ - u8 i; - u8 data[MAX_KEY_TABLE]; - - for (i = 0; i < MAX_KEY_TABLE; i++) - data[i] = i; - - return vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, - 0, 0, ARRAY_SIZE(data), data); -} - -static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, - struct ieee80211_key_conf *key, u32 key_type, - u32 mode) -{ - struct vnt_private *priv = hw->priv; - u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u16 key_mode = 0; - u32 entry = 0; - u8 *bssid; - u8 key_inx = key->keyidx; - u8 i; - - if (mac_addr) - bssid = mac_addr; - else - bssid = &broadcast[0]; - - if (key_type != VNT_KEY_DEFAULTKEY) { - for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { - if (!test_bit(i, &priv->key_entry_inuse)) { - set_bit(i, &priv->key_entry_inuse); - - key->hw_key_idx = i; - entry = key->hw_key_idx; - break; - } - } - } - - switch (key_type) { - case VNT_KEY_DEFAULTKEY: - /* default key last entry */ - entry = MAX_KEY_TABLE - 1; - key->hw_key_idx = entry; - fallthrough; - case VNT_KEY_GROUP_ADDRESS: - key_mode = mode | (mode << 4); - break; - case VNT_KEY_GROUP: - key_mode = mode << 4; - break; - case VNT_KEY_PAIRWISE: - key_mode |= mode; - key_inx = 4; - break; - default: - return -EINVAL; - } - - key_mode |= key_type; - - if (mode == KEY_CTL_WEP) { - if (key->keylen == WLAN_KEY_LEN_WEP40) - key->key[15] &= 0x7f; - if (key->keylen == WLAN_KEY_LEN_WEP104) - key->key[15] |= 0x80; - } - - return vnt_mac_set_keyentry(priv, key_mode, entry, - key_inx, bssid, key->key); -} - -int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - struct ieee80211_vif *vif, struct ieee80211_key_conf *key) -{ - struct vnt_private *priv = hw->priv; - u8 *mac_addr = NULL; - u8 key_dec_mode = 0; - - if (sta) - mac_addr = &sta->addr[0]; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY, - KEY_CTL_WEP); - - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - - return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY, - KEY_CTL_WEP); - - case WLAN_CIPHER_SUITE_TKIP: - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - - key_dec_mode = KEY_CTL_TKIP; - - break; - case WLAN_CIPHER_SUITE_CCMP: - if (priv->local_id <= MAC_REVISION_A1) - return -EOPNOTSUPP; - - key_dec_mode = KEY_CTL_CCMP; - - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - break; - default: - return -EOPNOTSUPP; - } - - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) - return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE, - key_dec_mode); - - return vnt_set_keymode(hw, mac_addr, key, - VNT_KEY_GROUP_ADDRESS, key_dec_mode); -} diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h deleted file mode 100644 index 6f1d5b4f6da7894d82e01c6aa293db35c8248eb7..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/key.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Implement functions for 802.11i Key management - * - * Author: Jerry Chen - * - * Date: May 29, 2003 - * - */ - -#ifndef __KEY_H__ -#define __KEY_H__ - -#include "device.h" - -#define MAX_KEY_TABLE 11 - -#define KEY_CTL_WEP 0x00 -#define KEY_CTL_NONE 0x01 -#define KEY_CTL_TKIP 0x02 -#define KEY_CTL_CCMP 0x03 - -#define VNT_KEY_ONFLY_ALL 0x4000 -#define VNT_KEY_ONFLY 0x8000 -#define VNT_KEY_ALLGROUP 0x04 -#define VNT_KEY_GROUP 0x40 -#define VNT_KEY_PAIRWISE VNT_KEY_ONFLY -#define VNT_KEY_GROUP_ADDRESS (VNT_KEY_ALLGROUP | VNT_KEY_GROUP) -#define VNT_KEY_DEFAULTKEY (VNT_KEY_GROUP_ADDRESS | VNT_KEY_ONFLY |\ - VNT_KEY_ONFLY_ALL) - -int vnt_key_init_table(struct vnt_private *priv); - -int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - struct ieee80211_vif *vif, struct ieee80211_key_conf *key); - -#endif /* __KEY_H__ */ diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c deleted file mode 100644 index 49430c0a99b8dd7b1abd3bb38cfb15d1b9e5f579..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/mac.c +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: MAC routines - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Functions: - * - * Revision History: - */ - -#include - -#include "desc.h" -#include "mac.h" -#include "usbpipe.h" - -int vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter) -{ - __le64 le_mc = cpu_to_le64(mc_filter); - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0, - MESSAGE_REQUEST_MACREG, sizeof(le_mc), - (u8 *)&le_mc); -} - -int vnt_mac_shutdown(struct vnt_private *priv) -{ - return vnt_control_out(priv, MESSAGE_TYPE_MACSHUTDOWN, 0, 0, 0, NULL); -} - -int vnt_mac_set_bb_type(struct vnt_private *priv, u8 type) -{ - u8 data[2]; - - data[0] = type; - data[1] = EN_CFG_BB_TYPE_MASK; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), - data); -} - -int vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx) -{ - return vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0, - sizeof(entry_idx), &entry_idx); -} - -int vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, - u32 key_idx, u8 *addr, u8 *key) -{ - struct vnt_mac_set_key set_key; - u16 offset; - - offset = MISCFIFO_KEYETRY0; - offset += entry_idx * MISCFIFO_KEYENTRYSIZE; - - set_key.u.write.key_ctl = cpu_to_le16(key_ctl); - ether_addr_copy(set_key.u.write.addr, addr); - - /* swap over swap[0] and swap[1] to get correct write order */ - swap(set_key.u.swap[0], set_key.u.swap[1]); - - memcpy(set_key.key, key, WLAN_KEY_LEN_CCMP); - - dev_dbg(&priv->usb->dev, "offset %d key ctl %d set key %24ph\n", - offset, key_ctl, (u8 *)&set_key); - - return vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset, - (u16)key_idx, sizeof(struct vnt_mac_set_key), - (u8 *)&set_key); -} - -int vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits) -{ - u8 data[2]; - - data[0] = 0; - data[1] = bits; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, reg_ofs, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits) -{ - u8 data[2]; - - data[0] = bits; - data[1] = bits; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, reg_ofs, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word) -{ - u8 data[2]; - - data[0] = (u8)(word & 0xff); - data[1] = (u8)(word >> 8); - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE, reg_ofs, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr) -{ - return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0, - MESSAGE_REQUEST_MACREG, ETH_ALEN, addr); -} - -int vnt_mac_enable_protect_mode(struct vnt_private *priv) -{ - u8 data[2]; - - data[0] = EN_CFG_PROTECT_MD; - data[1] = EN_CFG_PROTECT_MD; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_disable_protect_mode(struct vnt_private *priv) -{ - u8 data[2]; - - data[0] = 0; - data[1] = EN_CFG_PROTECT_MD; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv) -{ - u8 data[2]; - - data[0] = EN_CFG_BARKER_PREAM; - data[1] = EN_CFG_BARKER_PREAM; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv) -{ - u8 data[2]; - - data[0] = 0; - data[1] = EN_CFG_BARKER_PREAM; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval) -{ - u8 data[2]; - - data[0] = (u8)(interval & 0xff); - data[1] = (u8)(interval >> 8); - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BI, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} - -int vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led) -{ - u8 data[2]; - - data[0] = led; - data[1] = state; - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_PAPEDELAY, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); -} diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h deleted file mode 100644 index 0ac845bd3c5ad832a9b881ac433de9ae4bd2260e..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/mac.h +++ /dev/null @@ -1,373 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: MAC routines - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Revision History: - * 07-01-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. - * 08-25-2003 Kyle Hsu: Porting MAC functions from sim53. - * 09-03-2003 Bryan YC Fan: Add MACvDisableProtectMD & MACvEnableProtectMD - */ - -#ifndef __MAC_H__ -#define __MAC_H__ - -#include -#include "device.h" - -#define REV_ID_VT3253_A0 0x00 -#define REV_ID_VT3253_A1 0x01 -#define REV_ID_VT3253_B0 0x08 -#define REV_ID_VT3253_B1 0x09 - -/* Registers in the MAC */ -#define MAC_REG_BISTCMD 0x04 -#define MAC_REG_BISTSR0 0x05 -#define MAC_REG_BISTSR1 0x06 -#define MAC_REG_BISTSR2 0x07 -#define MAC_REG_I2MCSR 0x08 -#define MAC_REG_I2MTGID 0x09 -#define MAC_REG_I2MTGAD 0x0a -#define MAC_REG_I2MCFG 0x0b -#define MAC_REG_I2MDIPT 0x0c -#define MAC_REG_I2MDOPT 0x0e -#define MAC_REG_USBSUS 0x0f - -#define MAC_REG_LOCALID 0x14 -#define MAC_REG_TESTCFG 0x15 -#define MAC_REG_JUMPER0 0x16 -#define MAC_REG_JUMPER1 0x17 -#define MAC_REG_TMCTL 0x18 -#define MAC_REG_TMDATA0 0x1c -#define MAC_REG_TMDATA1 0x1d -#define MAC_REG_TMDATA2 0x1e -#define MAC_REG_TMDATA3 0x1f - -/* MAC Parameter related */ -#define MAC_REG_LRT 0x20 -#define MAC_REG_SRT 0x21 -#define MAC_REG_SIFS 0x22 -#define MAC_REG_DIFS 0x23 -#define MAC_REG_EIFS 0x24 -#define MAC_REG_SLOT 0x25 -#define MAC_REG_BI 0x26 -#define MAC_REG_CWMAXMIN0 0x28 -#define MAC_REG_LINKOFFTOTM 0x2a -#define MAC_REG_SWTMOT 0x2b -#define MAC_REG_RTSOKCNT 0x2c -#define MAC_REG_RTSFAILCNT 0x2d -#define MAC_REG_ACKFAILCNT 0x2e -#define MAC_REG_FCSERRCNT 0x2f - -/* TSF Related */ -#define MAC_REG_TSFCNTR 0x30 -#define MAC_REG_NEXTTBTT 0x38 -#define MAC_REG_TSFOFST 0x40 -#define MAC_REG_TFTCTL 0x48 - -/* WMAC Control/Status Related */ -#define MAC_REG_ENCFG0 0x4c -#define MAC_REG_ENCFG1 0x4d -#define MAC_REG_ENCFG2 0x4e - -#define MAC_REG_CFG 0x50 -#define MAC_REG_TEST 0x52 -#define MAC_REG_HOSTCR 0x54 -#define MAC_REG_MACCR 0x55 -#define MAC_REG_RCR 0x56 -#define MAC_REG_TCR 0x57 -#define MAC_REG_IMR 0x58 -#define MAC_REG_ISR 0x5c -#define MAC_REG_ISR1 0x5d - -/* Power Saving Related */ -#define MAC_REG_PSCFG 0x60 -#define MAC_REG_PSCTL 0x61 -#define MAC_REG_PSPWRSIG 0x62 -#define MAC_REG_BBCR13 0x63 -#define MAC_REG_AIDATIM 0x64 -#define MAC_REG_PWBT 0x66 -#define MAC_REG_WAKEOKTMR 0x68 -#define MAC_REG_CALTMR 0x69 -#define MAC_REG_SYNSPACCNT 0x6a -#define MAC_REG_WAKSYNOPT 0x6b - -/* Baseband/IF Control Group */ -#define MAC_REG_BBREGCTL 0x6c -#define MAC_REG_CHANNEL 0x6d -#define MAC_REG_BBREGADR 0x6e -#define MAC_REG_BBREGDATA 0x6f -#define MAC_REG_IFREGCTL 0x70 -#define MAC_REG_IFDATA 0x71 -#define MAC_REG_ITRTMSET 0x74 -#define MAC_REG_PAPEDELAY 0x77 -#define MAC_REG_SOFTPWRCTL 0x78 -#define MAC_REG_SOFTPWRCTL2 0x79 -#define MAC_REG_GPIOCTL0 0x7a -#define MAC_REG_GPIOCTL1 0x7b - -/* MiscFF PIO related */ -#define MAC_REG_MISCFFNDEX 0xbc -#define MAC_REG_MISCFFCTL 0xbe -#define MAC_REG_MISCFFDATA 0xc0 - -/* MAC Configuration Group */ -#define MAC_REG_PAR0 0xc4 -#define MAC_REG_PAR4 0xc8 -#define MAC_REG_BSSID0 0xcc -#define MAC_REG_BSSID4 0xd0 -#define MAC_REG_MAR0 0xd4 -#define MAC_REG_MAR4 0xd8 - -/* MAC RSPPKT INFO Group */ -#define MAC_REG_RSPINF_B_1 0xdC -#define MAC_REG_RSPINF_B_2 0xe0 -#define MAC_REG_RSPINF_B_5 0xe4 -#define MAC_REG_RSPINF_B_11 0xe8 -#define MAC_REG_RSPINF_A_6 0xec -#define MAC_REG_RSPINF_A_9 0xee -#define MAC_REG_RSPINF_A_12 0xf0 -#define MAC_REG_RSPINF_A_18 0xf2 -#define MAC_REG_RSPINF_A_24 0xf4 -#define MAC_REG_RSPINF_A_36 0xf6 -#define MAC_REG_RSPINF_A_48 0xf8 -#define MAC_REG_RSPINF_A_54 0xfa -#define MAC_REG_RSPINF_A_72 0xfc - -/* Bits in the I2MCFG EEPROM register */ -#define I2MCFG_BOUNDCTL BIT(7) -#define I2MCFG_WAITCTL BIT(5) -#define I2MCFG_SCLOECTL BIT(4) -#define I2MCFG_WBUSYCTL BIT(3) -#define I2MCFG_NORETRY BIT(2) -#define I2MCFG_I2MLDSEQ BIT(1) -#define I2MCFG_I2CMFAST BIT(0) - -/* Bits in the I2MCSR EEPROM register */ -#define I2MCSR_EEMW BIT(7) -#define I2MCSR_EEMR BIT(6) -#define I2MCSR_AUTOLD BIT(3) -#define I2MCSR_NACK BIT(1) -#define I2MCSR_DONE BIT(0) - -/* Bits in the TMCTL register */ -#define TMCTL_TSUSP BIT(2) -#define TMCTL_TMD BIT(1) -#define TMCTL_TE BIT(0) - -/* Bits in the TFTCTL register */ -#define TFTCTL_HWUTSF BIT(7) -#define TFTCTL_TBTTSYNC BIT(6) -#define TFTCTL_HWUTSFEN BIT(5) -#define TFTCTL_TSFCNTRRD BIT(4) -#define TFTCTL_TBTTSYNCEN BIT(3) -#define TFTCTL_TSFSYNCEN BIT(2) -#define TFTCTL_TSFCNTRST BIT(1) -#define TFTCTL_TSFCNTREN BIT(0) - -/* Bits in the EnhanceCFG_0 register */ -#define EN_CFG_BB_TYPE_A 0x00 -#define EN_CFG_BB_TYPE_B BIT(0) -#define EN_CFG_BB_TYPE_G BIT(1) -#define EN_CFG_BB_TYPE_MASK (EN_CFG_BB_TYPE_B | EN_CFG_BB_TYPE_G) -#define EN_CFG_PROTECT_MD BIT(5) - -/* Bits in the EnhanceCFG_1 register */ -#define EN_CFG_BCN_SUS_IND BIT(0) -#define EN_CFG_BCN_SUS_CLR BIT(1) - -/* Bits in the EnhanceCFG_2 register */ -#define EN_CFG_NXTBTTCFPSTR BIT(0) -#define EN_CFG_BARKER_PREAM BIT(1) -#define EN_CFG_PKT_BURST_MD BIT(2) - -/* Bits in the CFG register */ -#define CFG_TKIPOPT BIT(7) -#define CFG_RXDMAOPT BIT(6) -#define CFG_TMOT_SW BIT(5) -#define CFG_TMOT_HWLONG BIT(4) -#define CFG_TMOT_HW 0x00 -#define CFG_CFPENDOPT BIT(3) -#define CFG_BCNSUSEN BIT(2) -#define CFG_NOTXTIMEOUT BIT(1) -#define CFG_NOBUFOPT BIT(0) - -/* Bits in the TEST register */ -#define TEST_LBEXT BIT(7) -#define TEST_LBINT BIT(6) -#define TEST_LBNONE 0x00 -#define TEST_SOFTINT BIT(5) -#define TEST_CONTTX BIT(4) -#define TEST_TXPE BIT(3) -#define TEST_NAVDIS BIT(2) -#define TEST_NOCTS BIT(1) -#define TEST_NOACK BIT(0) - -/* Bits in the HOSTCR register */ -#define HOSTCR_TXONST BIT(7) -#define HOSTCR_RXONST BIT(6) -#define HOSTCR_ADHOC BIT(5) -#define HOSTCR_AP BIT(4) -#define HOSTCR_TXON BIT(3) -#define HOSTCR_RXON BIT(2) -#define HOSTCR_MACEN BIT(1) -#define HOSTCR_SOFTRST BIT(0) - -/* Bits in the MACCR register */ -#define MACCR_SYNCFLUSHOK BIT(2) -#define MACCR_SYNCFLUSH BIT(1) -#define MACCR_CLRNAV BIT(0) - -/* Bits in the RCR register */ -#define RCR_SSID BIT(7) -#define RCR_RXALLTYPE BIT(6) -#define RCR_UNICAST BIT(5) -#define RCR_BROADCAST BIT(4) -#define RCR_MULTICAST BIT(3) -#define RCR_WPAERR BIT(2) -#define RCR_ERRCRC BIT(1) -#define RCR_BSSID BIT(0) - -/* Bits in the TCR register */ -#define TCR_SYNCDCFOPT BIT(1) -#define TCR_AUTOBCNTX BIT(0) - -/* ISR1 */ -#define ISR_GPIO3 BIT(6) -#define ISR_RXNOBUF BIT(3) -#define ISR_MIBNEARFULL BIT(2) -#define ISR_SOFTINT BIT(1) -#define ISR_FETALERR BIT(0) - -#define LEDSTS_STS 0x06 -#define LEDSTS_TMLEN 0x78 -#define LEDSTS_OFF 0x00 -#define LEDSTS_ON 0x02 -#define LEDSTS_SLOW 0x04 -#define LEDSTS_INTER 0x06 - -/* ISR0 */ -#define ISR_WATCHDOG BIT(7) -#define ISR_SOFTTIMER BIT(6) -#define ISR_GPIO0 BIT(5) -#define ISR_TBTT BIT(4) -#define ISR_RXDMA0 BIT(3) -#define ISR_BNTX BIT(2) -#define ISR_ACTX BIT(0) - -/* Bits in the PSCFG register */ -#define PSCFG_PHILIPMD BIT(6) -#define PSCFG_WAKECALEN BIT(5) -#define PSCFG_WAKETMREN BIT(4) -#define PSCFG_BBPSPROG BIT(3) -#define PSCFG_WAKESYN BIT(2) -#define PSCFG_SLEEPSYN BIT(1) -#define PSCFG_AUTOSLEEP BIT(0) - -/* Bits in the PSCTL register */ -#define PSCTL_WAKEDONE BIT(5) -#define PSCTL_PS BIT(4) -#define PSCTL_GO2DOZE BIT(3) -#define PSCTL_LNBCN BIT(2) -#define PSCTL_ALBCN BIT(1) -#define PSCTL_PSEN BIT(0) - -/* Bits in the PSPWSIG register */ -#define PSSIG_WPE3 BIT(7) -#define PSSIG_WPE2 BIT(6) -#define PSSIG_WPE1 BIT(5) -#define PSSIG_WRADIOPE BIT(4) -#define PSSIG_SPE3 BIT(3) -#define PSSIG_SPE2 BIT(2) -#define PSSIG_SPE1 BIT(1) -#define PSSIG_SRADIOPE BIT(0) - -/* Bits in the BBREGCTL register */ -#define BBREGCTL_DONE BIT(2) -#define BBREGCTL_REGR BIT(1) -#define BBREGCTL_REGW BIT(0) - -/* Bits in the IFREGCTL register */ -#define IFREGCTL_DONE BIT(2) -#define IFREGCTL_IFRF BIT(1) -#define IFREGCTL_REGW BIT(0) - -/* Bits in the SOFTPWRCTL register */ -#define SOFTPWRCTL_RFLEOPT BIT(3) -#define SOFTPWRCTL_TXPEINV BIT(1) -#define SOFTPWRCTL_SWPECTI BIT(0) -#define SOFTPWRCTL_SWPAPE BIT(5) -#define SOFTPWRCTL_SWCALEN BIT(4) -#define SOFTPWRCTL_SWRADIO_PE BIT(3) -#define SOFTPWRCTL_SWPE2 BIT(2) -#define SOFTPWRCTL_SWPE1 BIT(1) -#define SOFTPWRCTL_SWPE3 BIT(0) - -/* Bits in the GPIOCTL1 register */ -#define GPIO3_MD BIT(5) -#define GPIO3_DATA BIT(6) -#define GPIO3_INTMD BIT(7) - -/* Bits in the MISCFFCTL register */ -#define MISCFFCTL_WRITE BIT(0) - -/* Loopback mode */ -#define MAC_LB_EXT BIT(1) -#define MAC_LB_INTERNAL BIT(0) -#define MAC_LB_NONE 0x00 - -/* Ethernet address filter type */ -#define PKT_TYPE_NONE 0x00 /* turn off receiver */ -#define PKT_TYPE_ALL_MULTICAST BIT(7) -#define PKT_TYPE_PROMISCUOUS BIT(6) -#define PKT_TYPE_DIRECTED BIT(5) /* obselete */ -#define PKT_TYPE_BROADCAST BIT(4) -#define PKT_TYPE_MULTICAST BIT(3) -#define PKT_TYPE_ERROR_WPA BIT(2) -#define PKT_TYPE_ERROR_CRC BIT(1) -#define PKT_TYPE_BSSID BIT(0) - -#define DEFAULT_BI 0x200 - -/* MiscFIFO Offset */ -#define MISCFIFO_KEYETRY0 32 -#define MISCFIFO_KEYENTRYSIZE 22 - -#define MAC_REVISION_A0 0x00 -#define MAC_REVISION_A1 0x01 - -struct vnt_mac_set_key { - union { - struct { - u8 addr[ETH_ALEN]; - __le16 key_ctl; - } write __packed; - u32 swap[2]; - } u; - u8 key[WLAN_KEY_LEN_CCMP]; -} __packed; - -int vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter); -int vnt_mac_shutdown(struct vnt_private *priv); -int vnt_mac_set_bb_type(struct vnt_private *priv, u8 type); -int vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx); -int vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, - u32 key_idx, u8 *addr, u8 *key); -int vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits); -int vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits); -int vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word); -int vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr); -int vnt_mac_enable_protect_mode(struct vnt_private *priv); -int vnt_mac_disable_protect_mode(struct vnt_private *priv); -int vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv); -int vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv); -int vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval); -int vnt_mac_set_led(struct vnt_private *privpriv, u8 state, u8 led); - -#endif /* __MAC_H__ */ diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c deleted file mode 100644 index 4f09e733e7a81e19b5d7a6d99d8cc68fe5041a1d..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/main_usb.c +++ /dev/null @@ -1,1121 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: driver entry for initial, open, close, tx and rx. - * - * Author: Lyndon Chen - * - * Date: Dec 8, 2005 - * - * Functions: - * - * vt6656_probe - module initial (insmod) driver entry - * vnt_free_tx_bufs - free tx buffer function - * vnt_init_registers- initial MAC & BBP & RF internal registers. - * - * Revision History: - */ -#undef __NO_VERSION__ - -#include -#include -#include -#include -#include "device.h" -#include "card.h" -#include "baseband.h" -#include "mac.h" -#include "power.h" -#include "wcmd.h" -#include "rxtx.h" -#include "rf.h" -#include "usbpipe.h" -#include "channel.h" - -/* - * define module options - */ - -/* version information */ -#define DRIVER_AUTHOR \ - "VIA Networking Technologies, Inc., " -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM); - -#define RX_DESC_DEF0 64 -static int vnt_rx_buffers = RX_DESC_DEF0; -module_param_named(rx_buffers, vnt_rx_buffers, int, 0644); -MODULE_PARM_DESC(rx_buffers, "Number of receive usb rx buffers"); - -#define TX_DESC_DEF0 64 -static int vnt_tx_buffers = TX_DESC_DEF0; -module_param_named(tx_buffers, vnt_tx_buffers, int, 0644); -MODULE_PARM_DESC(tx_buffers, "Number of receive usb tx buffers"); - -#define RTS_THRESH_DEF 2347 -#define FRAG_THRESH_DEF 2346 - -/* BasebandType[] baseband type selected - * 0: indicate 802.11a type - * 1: indicate 802.11b type - * 2: indicate 802.11g type - */ - -#define BBP_TYPE_DEF 2 - -/* - * Static vars definitions - */ - -static const struct usb_device_id vt6656_table[] = { - {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, - {} -}; - -static void vnt_set_options(struct vnt_private *priv) -{ - /* Set number of TX buffers */ - if (vnt_tx_buffers < CB_MIN_TX_DESC || vnt_tx_buffers > CB_MAX_TX_DESC) - priv->num_tx_context = TX_DESC_DEF0; - else - priv->num_tx_context = vnt_tx_buffers; - - /* Set number of RX buffers */ - if (vnt_rx_buffers < CB_MIN_RX_DESC || vnt_rx_buffers > CB_MAX_RX_DESC) - priv->num_rcb = RX_DESC_DEF0; - else - priv->num_rcb = vnt_rx_buffers; - - priv->op_mode = NL80211_IFTYPE_UNSPECIFIED; - priv->bb_type = BBP_TYPE_DEF; - priv->packet_type = priv->bb_type; - priv->preamble_type = PREAMBLE_LONG; - priv->exist_sw_net_addr = false; -} - -static int vnt_download_firmware(struct vnt_private *priv) -{ - struct device *dev = &priv->usb->dev; - const struct firmware *fw; - u16 length; - int ii; - int ret = 0; - - dev_dbg(dev, "---->Download firmware\n"); - - ret = request_firmware(&fw, FIRMWARE_NAME, dev); - if (ret) { - dev_err(dev, "firmware file %s request failed (%d)\n", - FIRMWARE_NAME, ret); - goto end; - } - - for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) { - length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE); - - ret = vnt_control_out(priv, 0, 0x1200 + ii, 0x0000, length, - fw->data + ii); - if (ret) - goto free_fw; - - dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size); - } - -free_fw: - release_firmware(fw); -end: - return ret; -} - -static int vnt_firmware_branch_to_sram(struct vnt_private *priv) -{ - dev_dbg(&priv->usb->dev, "---->Branch to Sram\n"); - - return vnt_control_out(priv, 1, 0x1200, 0x0000, 0, NULL); -} - -static int vnt_check_firmware_version(struct vnt_private *priv) -{ - int ret = 0; - - ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, - MESSAGE_REQUEST_VERSION, 2, - (u8 *)&priv->firmware_version); - if (ret) { - dev_dbg(&priv->usb->dev, - "Could not get firmware version: %d.\n", ret); - goto end; - } - - dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n", - priv->firmware_version); - - if (priv->firmware_version == 0xFFFF) { - dev_dbg(&priv->usb->dev, "In Loader.\n"); - ret = -EINVAL; - goto end; - } - - if (priv->firmware_version < FIRMWARE_VERSION) { - /* branch to loader for download new firmware */ - ret = vnt_firmware_branch_to_sram(priv); - if (ret) { - dev_dbg(&priv->usb->dev, - "Could not branch to SRAM: %d.\n", ret); - } else { - ret = -EINVAL; - } - } - -end: - return ret; -} - -/* - * initialization of MAC & BBP registers - */ -static int vnt_init_registers(struct vnt_private *priv) -{ - int ret; - struct vnt_cmd_card_init *init_cmd = &priv->init_command; - struct vnt_rsp_card_init *init_rsp = &priv->init_response; - u8 antenna; - int ii; - u8 tmp; - u8 calib_tx_iq = 0, calib_tx_dc = 0, calib_rx_iq = 0; - - dev_dbg(&priv->usb->dev, "---->INIbInitAdapter. [%d][%d]\n", - DEVICE_INIT_COLD, priv->packet_type); - - ret = vnt_check_firmware_version(priv); - if (ret) { - ret = vnt_download_firmware(priv); - if (ret) { - dev_dbg(&priv->usb->dev, - "Could not download firmware: %d.\n", ret); - goto end; - } - - ret = vnt_firmware_branch_to_sram(priv); - if (ret) { - dev_dbg(&priv->usb->dev, - "Could not branch to SRAM: %d.\n", ret); - goto end; - } - } - - ret = vnt_vt3184_init(priv); - if (ret) { - dev_dbg(&priv->usb->dev, "vnt_vt3184_init fail\n"); - goto end; - } - - init_cmd->init_class = DEVICE_INIT_COLD; - init_cmd->exist_sw_net_addr = priv->exist_sw_net_addr; - for (ii = 0; ii < ARRAY_SIZE(init_cmd->sw_net_addr); ii++) - init_cmd->sw_net_addr[ii] = priv->current_net_addr[ii]; - init_cmd->short_retry_limit = priv->hw->wiphy->retry_short; - init_cmd->long_retry_limit = priv->hw->wiphy->retry_long; - - /* issue card_init command to device */ - ret = vnt_control_out(priv, MESSAGE_TYPE_CARDINIT, 0, 0, - sizeof(struct vnt_cmd_card_init), - (u8 *)init_cmd); - if (ret) { - dev_dbg(&priv->usb->dev, "Issue Card init fail\n"); - goto end; - } - - ret = vnt_control_in(priv, MESSAGE_TYPE_INIT_RSP, 0, 0, - sizeof(struct vnt_rsp_card_init), - (u8 *)init_rsp); - if (ret) { - dev_dbg(&priv->usb->dev, "Cardinit request in status fail!\n"); - goto end; - } - - /* local ID for AES functions */ - ret = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_LOCALID, - MESSAGE_REQUEST_MACREG, 1, &priv->local_id); - if (ret) - goto end; - - /* do MACbSoftwareReset in MACvInitialize */ - - priv->top_ofdm_basic_rate = RATE_24M; - priv->top_cck_basic_rate = RATE_1M; - - /* target to IF pin while programming to RF chip */ - priv->power = 0xFF; - - priv->cck_pwr = priv->eeprom[EEP_OFS_PWR_CCK]; - priv->ofdm_pwr_g = priv->eeprom[EEP_OFS_PWR_OFDMG]; - /* load power table */ - for (ii = 0; ii < ARRAY_SIZE(priv->cck_pwr_tbl); ii++) { - priv->cck_pwr_tbl[ii] = - priv->eeprom[ii + EEP_OFS_CCK_PWR_TBL]; - if (priv->cck_pwr_tbl[ii] == 0) - priv->cck_pwr_tbl[ii] = priv->cck_pwr; - - priv->ofdm_pwr_tbl[ii] = - priv->eeprom[ii + EEP_OFS_OFDM_PWR_TBL]; - if (priv->ofdm_pwr_tbl[ii] == 0) - priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_g; - } - - /* - * original zonetype is USA, but custom zonetype is Europe, - * then need to recover 12, 13, 14 channels with 11 channel - */ - for (ii = 11; ii < ARRAY_SIZE(priv->cck_pwr_tbl); ii++) { - priv->cck_pwr_tbl[ii] = priv->cck_pwr_tbl[10]; - priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_tbl[10]; - } - - priv->ofdm_pwr_a = 0x34; /* same as RFbMA2829SelectChannel */ - - /* load OFDM A power table */ - for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { - priv->ofdm_a_pwr_tbl[ii] = - priv->eeprom[ii + EEP_OFS_OFDMA_PWR_TBL]; - - if (priv->ofdm_a_pwr_tbl[ii] == 0) - priv->ofdm_a_pwr_tbl[ii] = priv->ofdm_pwr_a; - } - - antenna = priv->eeprom[EEP_OFS_ANTENNA]; - - if (antenna & EEP_ANTINV) - priv->tx_rx_ant_inv = true; - else - priv->tx_rx_ant_inv = false; - - antenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); - - if (antenna == 0) /* if not set default is both */ - antenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); - - if (antenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { - priv->tx_antenna_mode = ANT_B; - priv->rx_antenna_sel = 1; - - if (priv->tx_rx_ant_inv) - priv->rx_antenna_mode = ANT_A; - else - priv->rx_antenna_mode = ANT_B; - } else { - priv->rx_antenna_sel = 0; - - if (antenna & EEP_ANTENNA_AUX) { - priv->tx_antenna_mode = ANT_A; - - if (priv->tx_rx_ant_inv) - priv->rx_antenna_mode = ANT_B; - else - priv->rx_antenna_mode = ANT_A; - } else { - priv->tx_antenna_mode = ANT_B; - - if (priv->tx_rx_ant_inv) - priv->rx_antenna_mode = ANT_A; - else - priv->rx_antenna_mode = ANT_B; - } - } - - /* Set initial antenna mode */ - ret = vnt_set_antenna_mode(priv, priv->rx_antenna_mode); - if (ret) - goto end; - - /* default Auto Mode */ - priv->bb_type = BB_TYPE_11G; - - /* get RFType */ - priv->rf_type = init_rsp->rf_type; - - /* load vt3266 calibration parameters in EEPROM */ - if (priv->rf_type == RF_VT3226D0) { - if ((priv->eeprom[EEP_OFS_MAJOR_VER] == 0x1) && - (priv->eeprom[EEP_OFS_MINOR_VER] >= 0x4)) { - calib_tx_iq = priv->eeprom[EEP_OFS_CALIB_TX_IQ]; - calib_tx_dc = priv->eeprom[EEP_OFS_CALIB_TX_DC]; - calib_rx_iq = priv->eeprom[EEP_OFS_CALIB_RX_IQ]; - if (calib_tx_iq || calib_tx_dc || calib_rx_iq) { - /* CR255, enable TX/RX IQ and - * DC compensation mode - */ - ret = vnt_control_out_u8(priv, - MESSAGE_REQUEST_BBREG, - 0xff, 0x03); - if (ret) - goto end; - - /* CR251, TX I/Q Imbalance Calibration */ - ret = vnt_control_out_u8(priv, - MESSAGE_REQUEST_BBREG, - 0xfb, calib_tx_iq); - if (ret) - goto end; - - /* CR252, TX DC-Offset Calibration */ - ret = vnt_control_out_u8(priv, - MESSAGE_REQUEST_BBREG, - 0xfC, calib_tx_dc); - if (ret) - goto end; - - /* CR253, RX I/Q Imbalance Calibration */ - ret = vnt_control_out_u8(priv, - MESSAGE_REQUEST_BBREG, - 0xfd, calib_rx_iq); - if (ret) - goto end; - } else { - /* CR255, turn off - * BB Calibration compensation - */ - ret = vnt_control_out_u8(priv, - MESSAGE_REQUEST_BBREG, - 0xff, 0x0); - if (ret) - goto end; - } - } - } - - /* get permanent network address */ - memcpy(priv->permanent_net_addr, init_rsp->net_addr, 6); - ether_addr_copy(priv->current_net_addr, priv->permanent_net_addr); - - /* if exist SW network address, use it */ - dev_dbg(&priv->usb->dev, "Network address = %pM\n", - priv->current_net_addr); - - priv->radio_ctl = priv->eeprom[EEP_OFS_RADIOCTL]; - - if ((priv->radio_ctl & EEP_RADIOCTL_ENABLE) != 0) { - ret = vnt_control_in(priv, MESSAGE_TYPE_READ, - MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, - 1, &tmp); - if (ret) - goto end; - - if ((tmp & GPIO3_DATA) == 0) { - ret = vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, - GPIO3_INTMD); - } else { - ret = vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, - GPIO3_INTMD); - } - - if (ret) - goto end; - } - - ret = vnt_mac_set_led(priv, LEDSTS_TMLEN, 0x38); - if (ret) - goto end; - - ret = vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW); - if (ret) - goto end; - - ret = vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL0, BIT(0)); - if (ret) - goto end; - - ret = vnt_radio_power_on(priv); - if (ret) - goto end; - - dev_dbg(&priv->usb->dev, "<----INIbInitAdapter Exit\n"); - -end: - return ret; -} - -static void vnt_free_tx_bufs(struct vnt_private *priv) -{ - struct vnt_usb_send_context *tx_context; - int ii; - - usb_kill_anchored_urbs(&priv->tx_submitted); - - for (ii = 0; ii < priv->num_tx_context; ii++) { - tx_context = priv->tx_context[ii]; - if (!tx_context) - continue; - - kfree(tx_context); - } -} - -static void vnt_free_rx_bufs(struct vnt_private *priv) -{ - struct vnt_rcb *rcb; - int ii; - - for (ii = 0; ii < priv->num_rcb; ii++) { - rcb = priv->rcb[ii]; - if (!rcb) - continue; - - /* deallocate URBs */ - if (rcb->urb) { - usb_kill_urb(rcb->urb); - usb_free_urb(rcb->urb); - } - - /* deallocate skb */ - if (rcb->skb) - dev_kfree_skb(rcb->skb); - - kfree(rcb); - } -} - -static void vnt_free_int_bufs(struct vnt_private *priv) -{ - kfree(priv->int_buf.data_buf); -} - -static int vnt_alloc_bufs(struct vnt_private *priv) -{ - int ret; - struct vnt_usb_send_context *tx_context; - struct vnt_rcb *rcb; - int ii; - - init_usb_anchor(&priv->tx_submitted); - - for (ii = 0; ii < priv->num_tx_context; ii++) { - tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL); - if (!tx_context) { - ret = -ENOMEM; - goto free_tx; - } - - priv->tx_context[ii] = tx_context; - tx_context->priv = priv; - tx_context->pkt_no = ii; - tx_context->in_use = false; - } - - for (ii = 0; ii < priv->num_rcb; ii++) { - priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL); - if (!priv->rcb[ii]) { - ret = -ENOMEM; - goto free_rx_tx; - } - - rcb = priv->rcb[ii]; - - rcb->priv = priv; - - /* allocate URBs */ - rcb->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rcb->urb) { - ret = -ENOMEM; - goto free_rx_tx; - } - - rcb->skb = dev_alloc_skb(priv->rx_buf_sz); - if (!rcb->skb) { - ret = -ENOMEM; - goto free_rx_tx; - } - /* submit rx urb */ - ret = vnt_submit_rx_urb(priv, rcb); - if (ret) - goto free_rx_tx; - } - - priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->interrupt_urb) { - ret = -ENOMEM; - goto free_rx_tx; - } - - priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL); - if (!priv->int_buf.data_buf) { - ret = -ENOMEM; - goto free_rx_tx_urb; - } - - return 0; - -free_rx_tx_urb: - usb_free_urb(priv->interrupt_urb); -free_rx_tx: - vnt_free_rx_bufs(priv); -free_tx: - vnt_free_tx_bufs(priv); - return ret; -} - -static void vnt_tx_80211(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct vnt_private *priv = hw->priv; - - if (vnt_tx_packet(priv, skb)) - ieee80211_free_txskb(hw, skb); -} - -static int vnt_start(struct ieee80211_hw *hw) -{ - int ret; - struct vnt_private *priv = hw->priv; - - priv->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS; - - ret = vnt_alloc_bufs(priv); - if (ret) { - dev_dbg(&priv->usb->dev, "vnt_alloc_bufs fail...\n"); - goto err; - } - - clear_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags); - - ret = vnt_init_registers(priv); - if (ret) { - dev_dbg(&priv->usb->dev, " init register fail\n"); - goto free_all; - } - - ret = vnt_key_init_table(priv); - if (ret) - goto free_all; - - priv->int_interval = 1; /* bInterval is set to 1 */ - - ret = vnt_start_interrupt_urb(priv); - if (ret) - goto free_all; - - ieee80211_wake_queues(hw); - - return 0; - -free_all: - vnt_free_rx_bufs(priv); - vnt_free_tx_bufs(priv); - vnt_free_int_bufs(priv); - - usb_kill_urb(priv->interrupt_urb); - usb_free_urb(priv->interrupt_urb); -err: - return ret; -} - -static void vnt_stop(struct ieee80211_hw *hw, bool suspend) -{ - struct vnt_private *priv = hw->priv; - int i; - - if (!priv) - return; - - for (i = 0; i < MAX_KEY_TABLE; i++) - vnt_mac_disable_keyentry(priv, i); - - /* clear all keys */ - priv->key_entry_inuse = 0; - - if (!test_bit(DEVICE_FLAGS_UNPLUG, &priv->flags)) - vnt_mac_shutdown(priv); - - ieee80211_stop_queues(hw); - - set_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags); - - cancel_delayed_work_sync(&priv->run_command_work); - - priv->cmd_running = false; - - vnt_free_tx_bufs(priv); - vnt_free_rx_bufs(priv); - vnt_free_int_bufs(priv); - - usb_kill_urb(priv->interrupt_urb); - usb_free_urb(priv->interrupt_urb); -} - -static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - priv->vif = vif; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_ADHOC: - vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST); - - vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC); - - break; - case NL80211_IFTYPE_AP: - vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST); - - vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_AP); - - break; - default: - return -EOPNOTSUPP; - } - - priv->op_mode = vif->type; - - /* LED blink on TX */ - vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_INTER); - - return 0; -} - -static void vnt_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_ADHOC: - vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); - vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC); - break; - case NL80211_IFTYPE_AP: - vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); - vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_AP); - break; - default: - break; - } - - vnt_radio_power_off(priv); - - priv->op_mode = NL80211_IFTYPE_UNSPECIFIED; - - /* LED slow blink */ - vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW); -} - -static int vnt_config(struct ieee80211_hw *hw, u32 changed) -{ - struct vnt_private *priv = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (changed & IEEE80211_CONF_CHANGE_PS) { - if (conf->flags & IEEE80211_CONF_PS) - vnt_enable_power_saving(priv, conf->listen_interval); - else - vnt_disable_power_saving(priv); - } - - if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || - (conf->flags & IEEE80211_CONF_OFFCHANNEL)) { - vnt_set_channel(priv, conf->chandef.chan->hw_value); - - if (conf->chandef.chan->band == NL80211_BAND_5GHZ) - priv->bb_type = BB_TYPE_11A; - else - priv->bb_type = BB_TYPE_11G; - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) - vnt_rf_setpower(priv, conf->chandef.chan); - - if (conf->flags & (IEEE80211_CONF_OFFCHANNEL | IEEE80211_CONF_IDLE)) - /* Set max sensitivity*/ - vnt_update_pre_ed_threshold(priv, true); - else - vnt_update_pre_ed_threshold(priv, false); - - return 0; -} - -static void vnt_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *conf, u64 changed) -{ - struct vnt_private *priv = hw->priv; - - priv->current_aid = vif->cfg.aid; - - if (changed & BSS_CHANGED_BSSID && conf->bssid) - vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid); - - if (changed & BSS_CHANGED_BASIC_RATES) { - priv->basic_rates = conf->basic_rates; - - vnt_update_top_rates(priv); - - dev_dbg(&priv->usb->dev, "basic rates %x\n", conf->basic_rates); - } - - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - if (conf->use_short_preamble) { - vnt_mac_enable_barker_preamble_mode(priv); - priv->preamble_type = PREAMBLE_SHORT; - } else { - vnt_mac_disable_barker_preamble_mode(priv); - priv->preamble_type = PREAMBLE_LONG; - } - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - if (conf->use_cts_prot) - vnt_mac_enable_protect_mode(priv); - else - vnt_mac_disable_protect_mode(priv); - } - - if (changed & BSS_CHANGED_ERP_SLOT) { - if (conf->use_short_slot) - priv->short_slot_time = true; - else - priv->short_slot_time = false; - - vnt_set_short_slot_time(priv); - vnt_set_vga_gain_offset(priv, priv->bb_vga[0]); - } - - if (changed & (BSS_CHANGED_BASIC_RATES | BSS_CHANGED_ERP_PREAMBLE | - BSS_CHANGED_ERP_SLOT)) - vnt_set_bss_mode(priv); - - if (changed & (BSS_CHANGED_TXPOWER | BSS_CHANGED_BANDWIDTH)) - vnt_rf_setpower(priv, conf->chanreq.oper.chan); - - if (changed & BSS_CHANGED_BEACON_ENABLED) { - dev_dbg(&priv->usb->dev, - "Beacon enable %d\n", conf->enable_beacon); - - if (conf->enable_beacon) { - vnt_beacon_enable(priv, vif, conf); - - vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX); - } else { - vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); - } - } - - if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) && - priv->op_mode != NL80211_IFTYPE_AP) { - if (vif->cfg.assoc && conf->beacon_rate) { - u16 ps_beacon_int = conf->beacon_int; - - if (conf->dtim_period) - ps_beacon_int *= conf->dtim_period; - else if (hw->conf.listen_interval) - ps_beacon_int *= hw->conf.listen_interval; - - vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, - TFTCTL_TSFCNTREN); - - vnt_mac_set_beacon_interval(priv, ps_beacon_int); - - vnt_reset_next_tbtt(priv, conf->beacon_int); - - vnt_adjust_tsf(priv, conf->beacon_rate->hw_value, - conf->sync_tsf, priv->current_tsf); - - vnt_update_next_tbtt(priv, - conf->sync_tsf, ps_beacon_int); - } else { - vnt_clear_current_tsf(priv); - - vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, - TFTCTL_TSFCNTREN); - } - } -} - -static u64 vnt_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - struct vnt_private *priv = hw->priv; - struct netdev_hw_addr *ha; - u64 mc_filter = 0; - u32 bit_nr; - - netdev_hw_addr_list_for_each(ha, mc_list) { - bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; - mc_filter |= BIT_ULL(bit_nr); - } - - priv->mc_list_count = mc_list->count; - - return mc_filter; -} - -static void vnt_configure(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast) -{ - struct vnt_private *priv = hw->priv; - u8 rx_mode = 0; - - *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC; - - vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR, - MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode); - - dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode); - - if (changed_flags & FIF_ALLMULTI) { - if (*total_flags & FIF_ALLMULTI) { - if (priv->mc_list_count > 2) - vnt_mac_set_filter(priv, ~0); - else - vnt_mac_set_filter(priv, multicast); - - rx_mode |= RCR_MULTICAST | RCR_BROADCAST; - } else { - rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST); - } - } - - if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) { - if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) - rx_mode &= ~RCR_BSSID; - else - rx_mode |= RCR_BSSID; - } - - vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, rx_mode); - - dev_dbg(&priv->usb->dev, "rx mode out= %x\n", rx_mode); -} - -static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct vnt_private *priv = hw->priv; - - switch (cmd) { - case SET_KEY: - return vnt_set_keys(hw, sta, vif, key); - case DISABLE_KEY: - if (test_bit(key->hw_key_idx, &priv->key_entry_inuse)) { - clear_bit(key->hw_key_idx, &priv->key_entry_inuse); - - vnt_mac_disable_keyentry(priv, key->hw_key_idx); - } - break; - - default: - break; - } - - return 0; -} - -static int vnt_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct vnt_private *priv = hw->priv; - - memcpy(stats, &priv->low_stats, sizeof(*stats)); - - return 0; -} - -static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - return priv->current_tsf; -} - -static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u64 tsf) -{ - struct vnt_private *priv = hw->priv; - - vnt_update_next_tbtt(priv, tsf, vif->bss_conf.beacon_int); -} - -static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - vnt_clear_current_tsf(priv); -} - -static const struct ieee80211_ops vnt_mac_ops = { - .add_chanctx = ieee80211_emulate_add_chanctx, - .remove_chanctx = ieee80211_emulate_remove_chanctx, - .change_chanctx = ieee80211_emulate_change_chanctx, - .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, - .tx = vnt_tx_80211, - .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = vnt_start, - .stop = vnt_stop, - .add_interface = vnt_add_interface, - .remove_interface = vnt_remove_interface, - .config = vnt_config, - .bss_info_changed = vnt_bss_info_changed, - .prepare_multicast = vnt_prepare_multicast, - .configure_filter = vnt_configure, - .set_key = vnt_set_key, - .get_stats = vnt_get_stats, - .get_tsf = vnt_get_tsf, - .set_tsf = vnt_set_tsf, - .reset_tsf = vnt_reset_tsf, -}; - -int vnt_init(struct vnt_private *priv) -{ - if (vnt_init_registers(priv)) - return -EAGAIN; - - SET_IEEE80211_PERM_ADDR(priv->hw, priv->permanent_net_addr); - - vnt_init_bands(priv); - - if (ieee80211_register_hw(priv->hw)) - return -ENODEV; - - priv->mac_hw = true; - - vnt_radio_power_off(priv); - - return 0; -} - -static int -vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *udev; - struct vnt_private *priv; - struct ieee80211_hw *hw; - struct wiphy *wiphy; - int rc; - - udev = usb_get_dev(interface_to_usbdev(intf)); - - dev_notice(&udev->dev, "%s Ver. %s\n", - DEVICE_FULL_DRV_NAM, DEVICE_VERSION); - dev_notice(&udev->dev, - "Copyright (c) 2004 VIA Networking Technologies, Inc.\n"); - - hw = ieee80211_alloc_hw(sizeof(struct vnt_private), &vnt_mac_ops); - if (!hw) { - dev_err(&udev->dev, "could not register ieee80211_hw\n"); - rc = -ENOMEM; - goto err_nomem; - } - - priv = hw->priv; - priv->hw = hw; - priv->usb = udev; - priv->intf = intf; - - vnt_set_options(priv); - - spin_lock_init(&priv->lock); - mutex_init(&priv->usb_lock); - - INIT_DELAYED_WORK(&priv->run_command_work, vnt_run_command); - - usb_set_intfdata(intf, priv); - - wiphy = priv->hw->wiphy; - - wiphy->frag_threshold = FRAG_THRESH_DEF; - wiphy->rts_threshold = RTS_THRESH_DEF; - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); - - ieee80211_hw_set(priv->hw, TIMING_BEACON_ONLY); - ieee80211_hw_set(priv->hw, SIGNAL_DBM); - ieee80211_hw_set(priv->hw, RX_INCLUDES_FCS); - ieee80211_hw_set(priv->hw, REPORTS_TX_ACK_STATUS); - ieee80211_hw_set(priv->hw, SUPPORTS_PS); - ieee80211_hw_set(priv->hw, PS_NULLFUNC_STACK); - - priv->hw->extra_tx_headroom = - sizeof(struct vnt_tx_buffer) + sizeof(struct vnt_tx_usb_header); - priv->hw->max_signal = 100; - - SET_IEEE80211_DEV(priv->hw, &intf->dev); - - rc = usb_reset_device(priv->usb); - if (rc) - dev_warn(&priv->usb->dev, - "%s reset fail status=%d\n", __func__, rc); - - clear_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags); - vnt_reset_command_timer(priv); - - vnt_schedule_command(priv, WLAN_CMD_INIT_MAC80211); - - return 0; - -err_nomem: - usb_put_dev(udev); - - return rc; -} - -static void vt6656_disconnect(struct usb_interface *intf) -{ - struct vnt_private *priv = usb_get_intfdata(intf); - - if (!priv) - return; - - if (priv->mac_hw) - ieee80211_unregister_hw(priv->hw); - - usb_set_intfdata(intf, NULL); - usb_put_dev(interface_to_usbdev(intf)); - - set_bit(DEVICE_FLAGS_UNPLUG, &priv->flags); - - ieee80211_free_hw(priv->hw); -} - -#ifdef CONFIG_PM - -static int vt6656_suspend(struct usb_interface *intf, pm_message_t message) -{ - return 0; -} - -static int vt6656_resume(struct usb_interface *intf) -{ - return 0; -} - -#endif /* CONFIG_PM */ - -MODULE_DEVICE_TABLE(usb, vt6656_table); - -static struct usb_driver vt6656_driver = { - .name = DEVICE_NAME, - .probe = vt6656_probe, - .disconnect = vt6656_disconnect, - .id_table = vt6656_table, -#ifdef CONFIG_PM - .suspend = vt6656_suspend, - .resume = vt6656_resume, -#endif /* CONFIG_PM */ -}; - -module_usb_driver(vt6656_driver); - -MODULE_FIRMWARE(FIRMWARE_NAME); diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c deleted file mode 100644 index e5411f6284c765fc997eb71615a393206ae41edf..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/power.c +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Handles 802.11 power management functions - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - * Functions: - * vnt_enable_power_saving - Enable Power Saving Mode - * PSvDiasblePowerSaving - Disable Power Saving Mode - * vnt_next_tbtt_wakeup - Decide if we need to wake up at next Beacon - * - * Revision History: - * - */ - -#include "mac.h" -#include "device.h" -#include "power.h" -#include "wcmd.h" -#include "rxtx.h" -#include "card.h" -#include "usbpipe.h" - -/* - * - * Routine Description: - * Enable hw power saving functions - * - * Return Value: - * None. - * - */ - -void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval) -{ - u16 aid = priv->current_aid | BIT(14) | BIT(15); - - /* set period of power up before TBTT */ - vnt_mac_write_word(priv, MAC_REG_PWBT, C_PWBT); - - if (priv->op_mode != NL80211_IFTYPE_ADHOC) - /* set AID */ - vnt_mac_write_word(priv, MAC_REG_AIDATIM, aid); - - /* Warren:06-18-2004,the sequence must follow - * PSEN->AUTOSLEEP->GO2DOZE - */ - /* enable power saving hw function */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_PSEN); - - /* Set AutoSleep */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - - /* Warren:MUST turn on this once before turn on AUTOSLEEP ,or the - * AUTOSLEEP doesn't work - */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE); - - /* always listen beacon */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); - - dev_dbg(&priv->usb->dev, "PS:Power Saving Mode Enable...\n"); -} - -int vnt_disable_power_saving(struct vnt_private *priv) -{ - int ret; - - /* disable power saving hw function */ - ret = vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0, - 0, 0, NULL); - if (ret) - return ret; - - /* clear AutoSleep */ - vnt_mac_reg_bits_off(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - - /* set always listen beacon */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); - - return 0; -} - -/* - * - * Routine Description: - * Check if Next TBTT must wake up - * - * Return Value: - * None. - * - */ - -int vnt_next_tbtt_wakeup(struct vnt_private *priv) -{ - struct ieee80211_hw *hw = priv->hw; - struct ieee80211_conf *conf = &hw->conf; - int wake_up = false; - - if (conf->listen_interval > 1) { - /* Turn on wake up to listen next beacon */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN); - wake_up = true; - } - - return wake_up; -} diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h deleted file mode 100644 index 9f9c7007293345b33eda3f41e632b001399ac498..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/power.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Handles 802.11 power management functions - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - */ - -#ifndef __POWER_H__ -#define __POWER_H__ - -#define C_PWBT 1000 /* micro sec. power up before TBTT */ - -int vnt_disable_power_saving(struct vnt_private *priv); -void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval); -int vnt_next_tbtt_wakeup(struct vnt_private *priv); - -#endif /* __POWER_H__ */ diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c deleted file mode 100644 index 464602c747270d6a308dc915f9cbf970067e7303..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/rf.c +++ /dev/null @@ -1,443 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: rf function code - * - * Author: Jerry Chen - * - * Date: Feb. 19, 2004 - * - * Functions: - * vnt_rf_write_embedded - Embedded write RF register via MAC - * - * Revision History: - * RF_VT3226: RobertYu:20051111, VT3226C0 and before - * RF_VT3226D0: RobertYu:20051228 - * RF_VT3342A0: RobertYu:20060609 - * - */ - -#include -#include "mac.h" -#include "rf.h" -#include "baseband.h" -#include "usbpipe.h" - -#define CB_AL2230_INIT_SEQ 15 -#define CB_AL7230_INIT_SEQ 16 -#define CB_VT3226_INIT_SEQ 11 -#define CB_VT3342_INIT_SEQ 13 - -static u8 al2230_init_table[CB_AL2230_INIT_SEQ][3] = { - {0x03, 0xf7, 0x90}, - {0x03, 0x33, 0x31}, - {0x01, 0xb8, 0x02}, - {0x00, 0xff, 0xf3}, - {0x00, 0x05, 0xa4}, - {0x0f, 0x4d, 0xc5}, - {0x08, 0x05, 0xb6}, - {0x01, 0x47, 0xc7}, - {0x00, 0x06, 0x88}, - {0x04, 0x03, 0xb9}, - {0x00, 0xdb, 0xba}, - {0x00, 0x09, 0x9b}, - {0x0b, 0xdf, 0xfc}, - {0x00, 0x00, 0x0d}, - {0x00, 0x58, 0x0f} -}; - -static u8 al2230_channel_table0[CB_MAX_CHANNEL_24G][3] = { - {0x03, 0xf7, 0x90}, - {0x03, 0xf7, 0x90}, - {0x03, 0xe7, 0x90}, - {0x03, 0xe7, 0x90}, - {0x03, 0xf7, 0xa0}, - {0x03, 0xf7, 0xa0}, - {0x03, 0xe7, 0xa0}, - {0x03, 0xe7, 0xa0}, - {0x03, 0xf7, 0xb0}, - {0x03, 0xf7, 0xb0}, - {0x03, 0xe7, 0xb0}, - {0x03, 0xe7, 0xb0}, - {0x03, 0xf7, 0xc0}, - {0x03, 0xe7, 0xc0} -}; - -static u8 al2230_channel_table1[CB_MAX_CHANNEL_24G][3] = { - {0x03, 0x33, 0x31}, - {0x0b, 0x33, 0x31}, - {0x03, 0x33, 0x31}, - {0x0b, 0x33, 0x31}, - {0x03, 0x33, 0x31}, - {0x0b, 0x33, 0x31}, - {0x03, 0x33, 0x31}, - {0x0b, 0x33, 0x31}, - {0x03, 0x33, 0x31}, - {0x0b, 0x33, 0x31}, - {0x03, 0x33, 0x31}, - {0x0b, 0x33, 0x31}, - {0x03, 0x33, 0x31}, - {0x06, 0x66, 0x61} -}; - -static u8 vt3226_init_table[CB_VT3226_INIT_SEQ][3] = { - {0x03, 0xff, 0x80}, - {0x02, 0x82, 0xa1}, - {0x03, 0xc6, 0xa2}, - {0x01, 0x97, 0x93}, - {0x03, 0x66, 0x64}, - {0x00, 0x61, 0xa5}, - {0x01, 0x7b, 0xd6}, - {0x00, 0x80, 0x17}, - {0x03, 0xf8, 0x08}, - {0x00, 0x02, 0x39}, - {0x02, 0x00, 0x2a} -}; - -static u8 vt3226d0_init_table[CB_VT3226_INIT_SEQ][3] = { - {0x03, 0xff, 0x80}, - {0x03, 0x02, 0x21}, - {0x03, 0xc6, 0xa2}, - {0x01, 0x97, 0x93}, - {0x03, 0x66, 0x64}, - {0x00, 0x71, 0xa5}, - {0x01, 0x15, 0xc6}, - {0x01, 0x2e, 0x07}, - {0x00, 0x58, 0x08}, - {0x00, 0x02, 0x79}, - {0x02, 0x01, 0xaa} -}; - -static u8 vt3226_channel_table0[CB_MAX_CHANNEL_24G][3] = { - {0x01, 0x97, 0x83}, - {0x01, 0x97, 0x83}, - {0x01, 0x97, 0x93}, - {0x01, 0x97, 0x93}, - {0x01, 0x97, 0x93}, - {0x01, 0x97, 0x93}, - {0x01, 0x97, 0xa3}, - {0x01, 0x97, 0xa3}, - {0x01, 0x97, 0xa3}, - {0x01, 0x97, 0xa3}, - {0x01, 0x97, 0xb3}, - {0x01, 0x97, 0xb3}, - {0x01, 0x97, 0xb3}, - {0x03, 0x37, 0xc3} -}; - -static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = { - {0x02, 0x66, 0x64}, - {0x03, 0x66, 0x64}, - {0x00, 0x66, 0x64}, - {0x01, 0x66, 0x64}, - {0x02, 0x66, 0x64}, - {0x03, 0x66, 0x64}, - {0x00, 0x66, 0x64}, - {0x01, 0x66, 0x64}, - {0x02, 0x66, 0x64}, - {0x03, 0x66, 0x64}, - {0x00, 0x66, 0x64}, - {0x01, 0x66, 0x64}, - {0x02, 0x66, 0x64}, - {0x00, 0xcc, 0xc4} -}; - -static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = { - 0x0135c600, - 0x0135c600, - 0x0235c600, - 0x0235c600, - 0x0235c600, - 0x0335c600, - 0x0335c600, - 0x0335c600, - 0x0335c600, - 0x0335c600, - 0x0335c600, - 0x0335c600, - 0x0335c600, - 0x0135c600 -}; - -enum { - VNT_TABLE_INIT = 0, - VNT_TABLE_INIT_2 = 0, - VNT_TABLE_0 = 1, - VNT_TABLE_1 = 2, - VNT_TABLE_2 = 1 -}; - -struct vnt_table_info { - u8 *addr; - int length; -}; - -static const struct vnt_table_info vnt_table_seq[][3] = { - { /* RF_AL2230, RF_AL2230S init table, channel table 0 and 1 */ - {&al2230_init_table[0][0], CB_AL2230_INIT_SEQ * 3}, - {&al2230_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3}, - {&al2230_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3} - }, { /* RF_VT3226 init table, channel table 0 and 1 */ - {&vt3226_init_table[0][0], CB_VT3226_INIT_SEQ * 3}, - {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3}, - {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3} - }, { /* RF_VT3226D0 init table, channel table 0 and 1 */ - {&vt3226d0_init_table[0][0], CB_VT3226_INIT_SEQ * 3}, - {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3}, - {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3} - } -}; - -/* - * Description: Write to IF/RF, by embedded programming - */ -int vnt_rf_write_embedded(struct vnt_private *priv, u32 data) -{ - u8 reg_data[4]; - - data |= (VNT_RF_REG_LEN << 3) | IFREGCTL_REGW; - - reg_data[0] = (u8)data; - reg_data[1] = (u8)(data >> 8); - reg_data[2] = (u8)(data >> 16); - reg_data[3] = (u8)(data >> 24); - - return vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, 0, 0, - ARRAY_SIZE(reg_data), reg_data); -} - -static u8 vnt_rf_addpower(struct vnt_private *priv) -{ - int base; - s32 rssi = -priv->current_rssi; - - if (!rssi) - return 7; - - if (priv->rf_type == RF_VT3226D0) - base = -60; - else - base = -70; - - if (rssi < base) - return ((rssi - base + 1) / -5) * 2 + 5; - - return 0; -} - -/* Set Tx power by power level and rate */ -static int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, - struct ieee80211_channel *ch) -{ - u32 power_setting = 0; - int ret = 0; - - power += vnt_rf_addpower(priv); - if (power > VNT_RF_MAX_POWER) - power = VNT_RF_MAX_POWER; - - if (priv->power == power) - return 0; - - priv->power = power; - - switch (priv->rf_type) { - case RF_AL2230: - power_setting = 0x0404090 | (power << 12); - - ret = vnt_rf_write_embedded(priv, power_setting); - if (ret) - return ret; - - if (ch->flags & IEEE80211_CHAN_NO_OFDM) - ret = vnt_rf_write_embedded(priv, 0x0001b400); - else - ret = vnt_rf_write_embedded(priv, 0x0005a400); - - break; - case RF_AL2230S: - power_setting = 0x0404090 | (power << 12); - - ret = vnt_rf_write_embedded(priv, power_setting); - if (ret) - return ret; - - if (ch->flags & IEEE80211_CHAN_NO_OFDM) { - ret = vnt_rf_write_embedded(priv, 0x040c1400); - if (ret) - return ret; - - ret = vnt_rf_write_embedded(priv, 0x00299b00); - } else { - ret = vnt_rf_write_embedded(priv, 0x0005a400); - if (ret) - return ret; - - ret = vnt_rf_write_embedded(priv, 0x00099b00); - } - - break; - - case RF_VT3226: - power_setting = ((0x3f - power) << 20) | (0x17 << 8); - - ret = vnt_rf_write_embedded(priv, power_setting); - break; - case RF_VT3226D0: - if (ch->flags & IEEE80211_CHAN_NO_OFDM) { - u16 hw_value = ch->hw_value; - - power_setting = ((0x3f - power) << 20) | (0xe07 << 8); - - ret = vnt_rf_write_embedded(priv, power_setting); - if (ret) - return ret; - - ret = vnt_rf_write_embedded(priv, 0x03c6a200); - if (ret) - return ret; - - dev_dbg(&priv->usb->dev, - "%s 11b channel [%d]\n", __func__, hw_value); - - hw_value--; - - if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table)) { - ret = vnt_rf_write_embedded(priv, - vt3226d0_lo_current_table[hw_value]); - if (ret) - return ret; - } - - ret = vnt_rf_write_embedded(priv, 0x015C0800); - } else { - dev_dbg(&priv->usb->dev, - "@@@@ %s> 11G mode\n", __func__); - - power_setting = ((0x3f - power) << 20) | (0x7 << 8); - - ret = vnt_rf_write_embedded(priv, power_setting); - if (ret) - return ret; - - ret = vnt_rf_write_embedded(priv, 0x00C6A200); - if (ret) - return ret; - - ret = vnt_rf_write_embedded(priv, 0x016BC600); - if (ret) - return ret; - - ret = vnt_rf_write_embedded(priv, 0x00900800); - } - - break; - - default: - break; - } - return ret; -} - -/* Set Tx power by channel number type */ -int vnt_rf_setpower(struct vnt_private *priv, - struct ieee80211_channel *ch) -{ - u16 channel; - u8 power = priv->cck_pwr; - - if (!ch) - return -EINVAL; - - /* set channel number to array number */ - channel = ch->hw_value - 1; - - if (ch->flags & IEEE80211_CHAN_NO_OFDM) { - if (channel < ARRAY_SIZE(priv->cck_pwr_tbl)) - power = priv->cck_pwr_tbl[channel]; - } else if (ch->band == NL80211_BAND_5GHZ) { - /* remove 14 channels to array size */ - channel -= 14; - - if (channel < ARRAY_SIZE(priv->ofdm_a_pwr_tbl)) - power = priv->ofdm_a_pwr_tbl[channel]; - } else { - if (channel < ARRAY_SIZE(priv->ofdm_pwr_tbl)) - power = priv->ofdm_pwr_tbl[channel]; - } - - return vnt_rf_set_txpower(priv, power, ch); -} - -/* Convert rssi to dbm */ -void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm) -{ - u8 idx = ((rssi & 0xc0) >> 6) & 0x03; - long b = rssi & 0x3f; - long a = 0; - u8 airoharf[4] = {0, 18, 0, 40}; - - switch (priv->rf_type) { - case RF_AL2230: - case RF_AL2230S: - case RF_VT3226: - case RF_VT3226D0: - a = airoharf[idx]; - break; - default: - break; - } - - *dbm = -1 * (a + b * 2); -} - -int vnt_rf_table_download(struct vnt_private *priv) -{ - int ret; - int idx = -1; - const struct vnt_table_info *table_seq; - - switch (priv->rf_type) { - case RF_AL2230: - case RF_AL2230S: - idx = 0; - break; - case RF_VT3226: - idx = 1; - break; - case RF_VT3226D0: - idx = 2; - break; - } - - if (idx < 0) - return 0; - - table_seq = &vnt_table_seq[idx][0]; - - /* Init Table */ - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0, - MESSAGE_REQUEST_RF_INIT, - table_seq[VNT_TABLE_INIT].length, - table_seq[VNT_TABLE_INIT].addr); - if (ret) - return ret; - - /* Channel Table 0 */ - ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, - MESSAGE_REQUEST_RF_CH0, - table_seq[VNT_TABLE_0].length, - table_seq[VNT_TABLE_0].addr); - if (ret) - return ret; - - /* Channel Table 1 */ - ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, - MESSAGE_REQUEST_RF_CH1, - table_seq[VNT_TABLE_1].length, - table_seq[VNT_TABLE_1].addr); - - return ret; -} diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h deleted file mode 100644 index b47e149875d1db68c887a3e54f85115a6ab9aba5..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/rf.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: - * - * Author: Jerry Chen - * - * Date: Feb. 19, 2004 - * - */ - -#ifndef __RF_H__ -#define __RF_H__ - -#include "device.h" - -/* Baseband RF pair definition in eeprom (Bits 6..0) */ -#define RF_RFMD2959 0x01 -#define RF_MAXIMAG 0x02 -#define RF_AL2230 0x03 -#define RF_GCT5103 0x04 -#define RF_UW2451 0x05 -#define RF_MAXIMG 0x06 -#define RF_MAXIM2829 0x07 -#define RF_UW2452 0x08 -#define RF_VT3226 0x09 -#define RF_AIROHA7230 0x0a -#define RF_UW2453 0x0b -#define RF_VT3226D0 0x0c /* RobertYu:20051114 */ -#define RF_VT3342A0 0x0d /* RobertYu:20060609 */ -#define RF_AL2230S 0x0e - -#define RF_EMU 0x80 -#define RF_MASK 0x7F - -#define VNT_RF_MAX_POWER 0x3f -#define VNT_RF_REG_LEN 0x17 /* 24 bit length */ - -int vnt_rf_write_embedded(struct vnt_private *priv, u32 data); -int vnt_rf_setpower(struct vnt_private *priv, struct ieee80211_channel *ch); -void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm); -int vnt_rf_table_download(struct vnt_private *priv); - -#endif /* __RF_H__ */ diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c deleted file mode 100644 index cd99091c6c28fc8ade305bebd3413546decf1110..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/rxtx.c +++ /dev/null @@ -1,730 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: handle WMAC/802.3/802.11 rx & tx functions - * - * Author: Lyndon Chen - * - * Date: May 20, 2003 - * - * Functions: - * vnt_generate_tx_parameter - Generate tx dma required parameter. - * vnt_get_rsvtime- get frame reserved time - * vnt_fill_cts_head- fulfill CTS ctl header - * - * Revision History: - * - */ - -#include -#include "device.h" -#include "rxtx.h" -#include "card.h" -#include "mac.h" -#include "rf.h" -#include "usbpipe.h" - -static const u16 vnt_time_stampoff[2][MAX_RATE] = { - /* Long Preamble */ - {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, - - /* Short Preamble */ - {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, -}; - -#define DATADUR_B 10 -#define DATADUR_A 11 - -static const u8 vnt_phy_signal[] = { - 0x00, /* RATE_1M */ - 0x01, /* RATE_2M */ - 0x02, /* RATE_5M */ - 0x03, /* RATE_11M */ - 0x8b, /* RATE_6M */ - 0x8f, /* RATE_9M */ - 0x8a, /* RATE_12M */ - 0x8e, /* RATE_18M */ - 0x89, /* RATE_24M */ - 0x8d, /* RATE_36M */ - 0x88, /* RATE_48M */ - 0x8c /* RATE_54M */ -}; - -static struct vnt_usb_send_context - *vnt_get_free_context(struct vnt_private *priv) -{ - struct vnt_usb_send_context *context = NULL; - int ii; - - for (ii = 0; ii < priv->num_tx_context; ii++) { - if (!priv->tx_context[ii]) - return NULL; - - context = priv->tx_context[ii]; - if (!context->in_use) { - context->in_use = true; - return context; - } - } - - if (ii == priv->num_tx_context) { - dev_dbg(&priv->usb->dev, "%s No Free Tx Context\n", __func__); - - ieee80211_stop_queues(priv->hw); - } - - return NULL; -} - -/* Get Length, Service, and Signal fields of Phy for Tx */ -static void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, - u16 tx_rate, u8 pkt_type, - struct vnt_phy_field *phy) -{ - u32 bit_count; - u32 count = 0; - u32 tmp; - int ext_bit; - int i; - u8 mask = 0; - u8 preamble_type = priv->preamble_type; - - bit_count = frame_length * 8; - ext_bit = false; - - switch (tx_rate) { - case RATE_1M: - count = bit_count; - break; - case RATE_2M: - count = bit_count / 2; - break; - case RATE_5M: - count = DIV_ROUND_UP(bit_count * 10, 55); - break; - case RATE_11M: - count = bit_count / 11; - tmp = count * 11; - - if (tmp != bit_count) { - count++; - - if ((bit_count - tmp) <= 3) - ext_bit = true; - } - - break; - } - - if (tx_rate > RATE_11M) { - if (pkt_type == PK_TYPE_11A) - mask = BIT(4); - } else if (tx_rate > RATE_1M) { - if (preamble_type == PREAMBLE_SHORT) - mask = BIT(3); - } - - i = tx_rate > RATE_54M ? RATE_54M : tx_rate; - phy->signal = vnt_phy_signal[i] | mask; - phy->service = 0x00; - - if (pkt_type == PK_TYPE_11B) { - if (ext_bit) - phy->service |= 0x80; - phy->len = cpu_to_le16((u16)count); - } else { - phy->len = cpu_to_le16((u16)frame_length); - } -} - -static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) -{ - return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2] - [rate % MAX_RATE]); -} - -static __le16 vnt_rxtx_rsvtime_le16(struct vnt_usb_send_context *context) -{ - struct vnt_private *priv = context->priv; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); - struct ieee80211_rate *rate = ieee80211_get_tx_rate(priv->hw, info); - - return ieee80211_generic_frame_duration(priv->hw, - info->control.vif, info->band, - context->frame_len, - rate); -} - -static __le16 vnt_get_rts_duration(struct vnt_usb_send_context *context) -{ - struct vnt_private *priv = context->priv; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); - - return ieee80211_rts_duration(priv->hw, priv->vif, - context->frame_len, info); -} - -static __le16 vnt_get_cts_duration(struct vnt_usb_send_context *context) -{ - struct vnt_private *priv = context->priv; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); - - return ieee80211_ctstoself_duration(priv->hw, priv->vif, - context->frame_len, info); -} - -static void vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context, - struct vnt_tx_datahead_g *buf) -{ - struct vnt_private *priv = tx_context->priv; - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *)tx_context->skb->data; - u32 frame_len = tx_context->frame_len; - u16 rate = tx_context->tx_rate; - - /* Get SignalField,ServiceField,Length */ - vnt_get_phy_field(priv, frame_len, rate, tx_context->pkt_type, &buf->a); - vnt_get_phy_field(priv, frame_len, priv->top_cck_basic_rate, - PK_TYPE_11B, &buf->b); - - /* Get Duration and TimeStamp */ - buf->duration_a = hdr->duration_id; - buf->duration_b = hdr->duration_id; - buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate); - buf->time_stamp_off_b = vnt_time_stamp_off(priv, - priv->top_cck_basic_rate); -} - -static void vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context, - struct vnt_tx_datahead_ab *buf) -{ - struct vnt_private *priv = tx_context->priv; - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *)tx_context->skb->data; - u32 frame_len = tx_context->frame_len; - u16 rate = tx_context->tx_rate; - - /* Get SignalField,ServiceField,Length */ - vnt_get_phy_field(priv, frame_len, rate, - tx_context->pkt_type, &buf->ab); - - /* Get Duration and TimeStampOff */ - buf->duration = hdr->duration_id; - buf->time_stamp_off = vnt_time_stamp_off(priv, rate); -} - -static void vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context, - struct ieee80211_rts *rts, __le16 duration) -{ - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *)tx_context->skb->data; - - rts->duration = duration; - rts->frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - ether_addr_copy(rts->ra, hdr->addr1); - ether_addr_copy(rts->ta, hdr->addr2); -} - -static void vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context, - struct vnt_rts_g *buf) -{ - struct vnt_private *priv = tx_context->priv; - u16 rts_frame_len = 20; - - vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate, - PK_TYPE_11B, &buf->b); - vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, - tx_context->pkt_type, &buf->a); - - buf->duration_bb = vnt_get_rts_duration(tx_context); - buf->duration_aa = buf->duration_bb; - buf->duration_ba = buf->duration_bb; - - vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa); - - vnt_rxtx_datahead_g(tx_context, &buf->data_head); -} - -static void vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context, - struct vnt_rts_ab *buf) -{ - struct vnt_private *priv = tx_context->priv; - u16 rts_frame_len = 20; - - vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, - tx_context->pkt_type, &buf->ab); - - buf->duration = vnt_get_rts_duration(tx_context); - - vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration); - - vnt_rxtx_datahead_ab(tx_context, &buf->data_head); -} - -static void vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, - union vnt_tx_data_head *head) -{ - struct vnt_private *priv = tx_context->priv; - struct vnt_cts *buf = &head->cts_g; - u32 cts_frame_len = 14; - - /* Get SignalField,ServiceField,Length */ - vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate, - PK_TYPE_11B, &buf->b); - /* Get CTSDuration_ba */ - buf->duration_ba = vnt_get_cts_duration(tx_context); - /*Get CTS Frame body*/ - buf->data.duration = buf->duration_ba; - buf->data.frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); - - ether_addr_copy(buf->data.ra, priv->current_net_addr); - - vnt_rxtx_datahead_g(tx_context, &buf->data_head); -} - -/* returns true if mic_hdr is needed */ -static bool vnt_fill_txkey(struct vnt_tx_buffer *tx_buffer, struct sk_buff *skb) -{ - struct vnt_tx_fifo_head *fifo = &tx_buffer->fifo_head; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_key_conf *tx_key = info->control.hw_key; - struct vnt_mic_hdr *mic_hdr; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u64 pn64; - u16 payload_len = skb->len; - u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); - - /* strip header and icv len from payload */ - payload_len -= ieee80211_get_hdrlen_from_skb(skb); - payload_len -= tx_key->icv_len; - - switch (tx_key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - memcpy(fifo->tx_key, iv, 3); - memcpy(fifo->tx_key + 3, tx_key->key, tx_key->keylen); - - if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { - memcpy(fifo->tx_key + 8, iv, 3); - memcpy(fifo->tx_key + 11, - tx_key->key, WLAN_KEY_LEN_WEP40); - } - - fifo->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); - break; - case WLAN_CIPHER_SUITE_TKIP: - ieee80211_get_tkip_p2k(tx_key, skb, fifo->tx_key); - - fifo->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); - break; - case WLAN_CIPHER_SUITE_CCMP: - if (info->control.use_cts_prot) { - if (info->control.use_rts) - mic_hdr = &tx_buffer->tx_head.tx_rts.tx.mic.hdr; - else - mic_hdr = &tx_buffer->tx_head.tx_cts.tx.mic.hdr; - } else { - mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr; - } - - mic_hdr->id = 0x59; - mic_hdr->payload_len = cpu_to_be16(payload_len); - ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2); - - pn64 = atomic64_read(&tx_key->tx_pn); - mic_hdr->ccmp_pn[5] = pn64; - mic_hdr->ccmp_pn[4] = pn64 >> 8; - mic_hdr->ccmp_pn[3] = pn64 >> 16; - mic_hdr->ccmp_pn[2] = pn64 >> 24; - mic_hdr->ccmp_pn[1] = pn64 >> 32; - mic_hdr->ccmp_pn[0] = pn64 >> 40; - - if (ieee80211_has_a4(hdr->frame_control)) - mic_hdr->hlen = cpu_to_be16(28); - else - mic_hdr->hlen = cpu_to_be16(22); - - ether_addr_copy(mic_hdr->addr1, hdr->addr1); - ether_addr_copy(mic_hdr->addr2, hdr->addr2); - ether_addr_copy(mic_hdr->addr3, hdr->addr3); - - mic_hdr->frame_control = cpu_to_le16(le16_to_cpu(hdr->frame_control) & 0xc78f); - mic_hdr->seq_ctrl = cpu_to_le16(le16_to_cpu(hdr->seq_ctrl) & 0xf); - - if (ieee80211_has_a4(hdr->frame_control)) - ether_addr_copy(mic_hdr->addr4, hdr->addr4); - - memcpy(fifo->tx_key, tx_key->key, WLAN_KEY_LEN_CCMP); - - fifo->frag_ctl |= cpu_to_le16(FRAGCTL_AES); - return true; - default: - break; - } - - return false; -} - -static void vnt_rxtx_rts(struct vnt_usb_send_context *tx_context) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); - struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; - union vnt_tx_head *tx_head = &tx_buffer->tx_head; - struct vnt_rrv_time_rts *buf = &tx_head->tx_rts.rts; - union vnt_tx_data_head *head = &tx_head->tx_rts.tx.head; - - buf->rts_rrv_time_aa = vnt_get_rts_duration(tx_context); - buf->rts_rrv_time_ba = buf->rts_rrv_time_aa; - buf->rts_rrv_time_bb = buf->rts_rrv_time_aa; - - buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context); - buf->rrv_time_b = buf->rrv_time_a; - - if (info->control.hw_key) { - if (vnt_fill_txkey(tx_buffer, tx_context->skb)) - head = &tx_head->tx_rts.tx.mic.head; - } - - vnt_rxtx_rts_g_head(tx_context, &head->rts_g); -} - -static void vnt_rxtx_cts(struct vnt_usb_send_context *tx_context) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); - struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; - union vnt_tx_head *tx_head = &tx_buffer->tx_head; - struct vnt_rrv_time_cts *buf = &tx_head->tx_cts.cts; - union vnt_tx_data_head *head = &tx_head->tx_cts.tx.head; - - buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context); - buf->rrv_time_b = buf->rrv_time_a; - - buf->cts_rrv_time_ba = vnt_get_cts_duration(tx_context); - - if (info->control.hw_key) { - if (vnt_fill_txkey(tx_buffer, tx_context->skb)) - head = &tx_head->tx_cts.tx.mic.head; - } - - vnt_fill_cts_head(tx_context, head); -} - -static void vnt_rxtx_ab(struct vnt_usb_send_context *tx_context) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); - struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; - union vnt_tx_head *tx_head = &tx_buffer->tx_head; - struct vnt_rrv_time_ab *buf = &tx_head->tx_ab.ab; - union vnt_tx_data_head *head = &tx_head->tx_ab.tx.head; - - buf->rrv_time = vnt_rxtx_rsvtime_le16(tx_context); - - if (info->control.hw_key) { - if (vnt_fill_txkey(tx_buffer, tx_context->skb)) - head = &tx_head->tx_ab.tx.mic.head; - } - - if (info->control.use_rts) { - buf->rts_rrv_time = vnt_get_rts_duration(tx_context); - - vnt_rxtx_rts_ab_head(tx_context, &head->rts_ab); - - return; - } - - vnt_rxtx_datahead_ab(tx_context, &head->data_head_ab); -} - -static void vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); - - if (info->control.use_cts_prot) { - if (info->control.use_rts) { - vnt_rxtx_rts(tx_context); - - return; - } - - vnt_rxtx_cts(tx_context); - - return; - } - - vnt_rxtx_ab(tx_context); -} - -static u16 vnt_get_hdr_size(struct ieee80211_tx_info *info) -{ - u16 size = sizeof(struct vnt_tx_datahead_ab); - - if (info->control.use_cts_prot) { - if (info->control.use_rts) - size = sizeof(struct vnt_rts_g); - else - size = sizeof(struct vnt_cts); - } else if (info->control.use_rts) { - size = sizeof(struct vnt_rts_ab); - } - - if (info->control.hw_key) { - if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP) - size += sizeof(struct vnt_mic_hdr); - } - - /* Get rrv_time header */ - if (info->control.use_cts_prot) { - if (info->control.use_rts) - size += sizeof(struct vnt_rrv_time_rts); - else - size += sizeof(struct vnt_rrv_time_cts); - } else { - size += sizeof(struct vnt_rrv_time_ab); - } - - size += sizeof(struct vnt_tx_fifo_head); - - return size; -} - -int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_tx_rate *tx_rate = &info->control.rates[0]; - struct ieee80211_rate *rate; - struct ieee80211_hdr *hdr; - struct vnt_tx_buffer *tx_buffer; - struct vnt_tx_fifo_head *tx_buffer_head; - struct vnt_usb_send_context *tx_context; - unsigned long flags; - u8 pkt_type; - - hdr = (struct ieee80211_hdr *)(skb->data); - - rate = ieee80211_get_tx_rate(priv->hw, info); - - if (rate->hw_value > RATE_11M) { - if (info->band == NL80211_BAND_5GHZ) { - pkt_type = PK_TYPE_11A; - } else { - if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - if (priv->basic_rates & VNT_B_RATES) - pkt_type = PK_TYPE_11GB; - else - pkt_type = PK_TYPE_11GA; - } else { - pkt_type = PK_TYPE_11A; - } - } - } else { - pkt_type = PK_TYPE_11B; - } - - spin_lock_irqsave(&priv->lock, flags); - - tx_context = vnt_get_free_context(priv); - if (!tx_context) { - dev_dbg(&priv->usb->dev, "%s No free context\n", __func__); - spin_unlock_irqrestore(&priv->lock, flags); - return -ENOMEM; - } - - tx_context->pkt_type = pkt_type; - tx_context->frame_len = skb->len + 4; - tx_context->tx_rate = rate->hw_value; - - spin_unlock_irqrestore(&priv->lock, flags); - - tx_context->skb = skb_clone(skb, GFP_ATOMIC); - if (!tx_context->skb) { - tx_context->in_use = false; - return -ENOMEM; - } - - tx_buffer = skb_push(skb, vnt_get_hdr_size(info)); - tx_context->tx_buffer = tx_buffer; - tx_buffer_head = &tx_buffer->fifo_head; - - tx_context->type = CONTEXT_DATA_PACKET; - - /*Set fifo controls */ - if (pkt_type == PK_TYPE_11A) - tx_buffer_head->fifo_ctl = 0; - else if (pkt_type == PK_TYPE_11B) - tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B); - else if (pkt_type == PK_TYPE_11GB) - tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB); - else if (pkt_type == PK_TYPE_11GA) - tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA); - - if (!ieee80211_is_data(hdr->frame_control)) { - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT | - FIFOCTL_ISDMA0); - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN); - - tx_buffer_head->time_stamp = - cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - } else { - tx_buffer_head->time_stamp = - cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); - } - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); - - if (ieee80211_has_retry(hdr->frame_control)) - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY); - - if (info->control.use_rts) - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS); - - if (ieee80211_has_a4(hdr->frame_control)) - tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD); - - tx_buffer_head->frag_ctl = - cpu_to_le16(ieee80211_hdrlen(hdr->frame_control) << 10); - - if (info->control.hw_key) - tx_context->frame_len += info->control.hw_key->icv_len; - - tx_buffer_head->current_rate = cpu_to_le16(rate->hw_value); - - vnt_generate_tx_parameter(tx_context); - - tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); - - priv->seq_counter = (le16_to_cpu(hdr->seq_ctrl) & - IEEE80211_SCTL_SEQ) >> 4; - - spin_lock_irqsave(&priv->lock, flags); - - if (vnt_tx_context(priv, tx_context, skb)) { - dev_kfree_skb(tx_context->skb); - spin_unlock_irqrestore(&priv->lock, flags); - return -EIO; - } - - dev_kfree_skb(skb); - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) -{ - struct vnt_tx_short_buf_head *short_head; - struct ieee80211_tx_info *info; - struct vnt_usb_send_context *context; - struct ieee80211_mgmt *mgmt_hdr; - unsigned long flags; - u32 frame_size = skb->len + 4; - u16 current_rate; - - spin_lock_irqsave(&priv->lock, flags); - - context = vnt_get_free_context(priv); - if (!context) { - dev_dbg(&priv->usb->dev, "%s No free context!\n", __func__); - spin_unlock_irqrestore(&priv->lock, flags); - return -ENOMEM; - } - - context->skb = skb; - - spin_unlock_irqrestore(&priv->lock, flags); - - mgmt_hdr = (struct ieee80211_mgmt *)skb->data; - short_head = skb_push(skb, sizeof(*short_head)); - - if (priv->bb_type == BB_TYPE_11A) { - current_rate = RATE_6M; - - /* Get SignalField,ServiceField,Length */ - vnt_get_phy_field(priv, frame_size, current_rate, - PK_TYPE_11A, &short_head->ab); - - /* Get TimeStampOff */ - short_head->time_stamp_off = - vnt_time_stamp_off(priv, current_rate); - } else { - current_rate = RATE_1M; - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); - - /* Get SignalField,ServiceField,Length */ - vnt_get_phy_field(priv, frame_size, current_rate, - PK_TYPE_11B, &short_head->ab); - - /* Get TimeStampOff */ - short_head->time_stamp_off = - vnt_time_stamp_off(priv, current_rate); - } - - /* Get Duration */ - short_head->duration = mgmt_hdr->duration; - - /* time stamp always 0 */ - mgmt_hdr->u.beacon.timestamp = 0; - - info = IEEE80211_SKB_CB(skb); - if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; - - hdr->duration_id = 0; - hdr->seq_ctrl = cpu_to_le16(priv->seq_counter << 4); - } - - priv->seq_counter++; - if (priv->seq_counter > 0x0fff) - priv->seq_counter = 0; - - context->type = CONTEXT_BEACON_PACKET; - - spin_lock_irqsave(&priv->lock, flags); - - if (vnt_tx_context(priv, context, skb)) - ieee80211_free_txskb(priv->hw, context->skb); - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) -{ - struct sk_buff *beacon; - - beacon = ieee80211_beacon_get(priv->hw, vif, 0); - if (!beacon) - return -ENOMEM; - - if (vnt_beacon_xmit(priv, beacon)) { - ieee80211_free_txskb(priv->hw, beacon); - return -ENODEV; - } - - return 0; -} - -int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, - struct ieee80211_bss_conf *conf) -{ - vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); - - vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - vnt_mac_set_beacon_interval(priv, conf->beacon_int); - - vnt_clear_current_tsf(priv); - - vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - vnt_reset_next_tbtt(priv, conf->beacon_int); - - return vnt_beacon_make(priv, vif); -} diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h deleted file mode 100644 index b9df0854b4b01153fd30947d1f79593a008a2f0a..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/rxtx.h +++ /dev/null @@ -1,178 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: - * - * Author: Jerry Chen - * - * Date: Jun. 27, 2002 - * - */ - -#ifndef __RXTX_H__ -#define __RXTX_H__ - -#include "device.h" -#include "wcmd.h" -#include "baseband.h" - -#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ -#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 - -/* Length, Service, and Signal fields of Phy for Tx */ -struct vnt_phy_field { - u8 signal; - u8 service; - __le16 len; -} __packed; - -/* MIC HDR data header */ -struct vnt_mic_hdr { - u8 id; - u8 tx_priority; - u8 mic_addr2[6]; - u8 ccmp_pn[IEEE80211_CCMP_PN_LEN]; - __be16 payload_len; - __be16 hlen; - __le16 frame_control; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - __le16 seq_ctrl; - u8 addr4[6]; - u16 packing; /* packing to 48 bytes */ -} __packed; - -/* RsvTime buffer header */ -struct vnt_rrv_time_rts { - __le16 rts_rrv_time_ba; - __le16 rts_rrv_time_aa; - __le16 rts_rrv_time_bb; - u16 wReserved; - __le16 rrv_time_b; - __le16 rrv_time_a; -} __packed; - -struct vnt_rrv_time_cts { - __le16 cts_rrv_time_ba; - u16 wReserved; - __le16 rrv_time_b; - __le16 rrv_time_a; -} __packed; - -struct vnt_rrv_time_ab { - __le16 rts_rrv_time; - __le16 rrv_time; -} __packed; - -/* TX data header */ -struct vnt_tx_datahead_g { - struct vnt_phy_field b; - struct vnt_phy_field a; - __le16 duration_b; - __le16 duration_a; - __le16 time_stamp_off_b; - __le16 time_stamp_off_a; -} __packed; - -struct vnt_tx_datahead_ab { - struct vnt_phy_field ab; - __le16 duration; - __le16 time_stamp_off; -} __packed; - -/* RTS buffer header */ -struct vnt_rts_g { - struct vnt_phy_field b; - struct vnt_phy_field a; - __le16 duration_ba; - __le16 duration_aa; - __le16 duration_bb; - u16 wReserved; - struct ieee80211_rts data; - struct vnt_tx_datahead_g data_head; -} __packed __aligned(2); - -struct vnt_rts_ab { - struct vnt_phy_field ab; - __le16 duration; - u16 wReserved; - struct ieee80211_rts data; - struct vnt_tx_datahead_ab data_head; -} __packed __aligned(2); - -/* CTS buffer header */ -struct vnt_cts { - struct vnt_phy_field b; - __le16 duration_ba; - u16 wReserved; - struct ieee80211_cts data; - u16 reserved2; - struct vnt_tx_datahead_g data_head; -} __packed __aligned(2); - -union vnt_tx_data_head { - /* rts g */ - struct vnt_rts_g rts_g; - /* rts a/b */ - struct vnt_rts_ab rts_ab; - /* cts g */ - struct vnt_cts cts_g; - /* no rts/cts */ - struct vnt_tx_datahead_ab data_head_ab; -}; - -struct vnt_tx_mic_hdr { - struct vnt_mic_hdr hdr; - union vnt_tx_data_head head; -} __packed; - -union vnt_tx { - struct vnt_tx_mic_hdr mic; - union vnt_tx_data_head head; -}; - -union vnt_tx_head { - struct { - struct vnt_rrv_time_rts rts; - union vnt_tx tx; - } __packed tx_rts; - struct { - struct vnt_rrv_time_cts cts; - union vnt_tx tx; - } __packed tx_cts; - struct { - struct vnt_rrv_time_ab ab; - union vnt_tx tx; - } __packed tx_ab; -}; - -struct vnt_tx_fifo_head { - u8 tx_key[WLAN_KEY_LEN_CCMP]; - __le16 fifo_ctl; - __le16 time_stamp; - __le16 frag_ctl; - __le16 current_rate; -} __packed; - -struct vnt_tx_buffer { - struct vnt_tx_fifo_head fifo_head; - union vnt_tx_head tx_head; -} __packed; - -struct vnt_tx_short_buf_head { - __le16 fifo_ctl; - u16 time_stamp; - struct vnt_phy_field ab; - __le16 duration; - __le16 time_stamp_off; -} __packed; - -int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb); -int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif); -int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, - struct ieee80211_bss_conf *conf); - -#endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c deleted file mode 100644 index d505b4b69ba4933699ac212681c9dea1e1a8a1df..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/usbpipe.c +++ /dev/null @@ -1,506 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Handle USB control endpoint - * - * Author: Warren Hsu - * - * Date: Mar. 29, 2005 - * - * Functions: - * vnt_control_out - Write variable length bytes to MEM/BB/MAC/EEPROM - * vnt_control_in - Read variable length bytes from MEM/BB/MAC/EEPROM - * vnt_control_out_u8 - Write one byte to MEM/BB/MAC/EEPROM - * vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM - * - * Revision History: - * 04-05-2004 Jerry Chen: Initial release - * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte, - * ControlvMaskByte - * - */ - -#include "rxtx.h" -#include "desc.h" -#include "device.h" -#include "usbpipe.h" -#include "mac.h" -#include "rf.h" - -#define USB_CTL_WAIT 500 /* ms */ - -int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, const u8 *buffer) -{ - int ret = 0; - u8 *usb_buffer; - - if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) { - ret = -EINVAL; - goto end; - } - - mutex_lock(&priv->usb_lock); - - usb_buffer = kmemdup(buffer, length, GFP_KERNEL); - if (!usb_buffer) { - ret = -ENOMEM; - goto end_unlock; - } - - ret = usb_control_msg(priv->usb, - usb_sndctrlpipe(priv->usb, 0), - request, 0x40, value, - index, usb_buffer, length, USB_CTL_WAIT); - - kfree(usb_buffer); - - if (ret == (int)length) - ret = 0; - else - ret = -EIO; - -end_unlock: - mutex_unlock(&priv->usb_lock); -end: - return ret; -} - -int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) -{ - return vnt_control_out(priv, MESSAGE_TYPE_WRITE, - reg_off, reg, sizeof(u8), &data); -} - -int vnt_control_out_blocks(struct vnt_private *priv, - u16 block, u8 reg, u16 length, const u8 *data) -{ - int ret = 0, i; - - for (i = 0; i < length; i += block) { - u16 len = min_t(int, length - i, block); - - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, - i, reg, len, data + i); - if (ret) - goto end; - } -end: - return ret; -} - -int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer) -{ - int ret = 0; - u8 *usb_buffer; - - if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) { - ret = -EINVAL; - goto end; - } - - mutex_lock(&priv->usb_lock); - - usb_buffer = kmalloc(length, GFP_KERNEL); - if (!usb_buffer) { - ret = -ENOMEM; - goto end_unlock; - } - - ret = usb_control_msg(priv->usb, - usb_rcvctrlpipe(priv->usb, 0), - request, 0xc0, value, - index, usb_buffer, length, USB_CTL_WAIT); - - if (ret == length) - memcpy(buffer, usb_buffer, length); - - kfree(usb_buffer); - - if (ret == (int)length) - ret = 0; - else - ret = -EIO; - -end_unlock: - mutex_unlock(&priv->usb_lock); -end: - return ret; -} - -int vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data) -{ - return vnt_control_in(priv, MESSAGE_TYPE_READ, - reg_off, reg, sizeof(u8), data); -} - -static int vnt_int_report_rate(struct vnt_private *priv, u8 pkt_no, u8 tsr) -{ - struct vnt_usb_send_context *context; - struct ieee80211_tx_info *info; - u8 tx_retry = (tsr & 0xf0) >> 4; - s8 idx; - - if (pkt_no >= priv->num_tx_context) - return -EINVAL; - - context = priv->tx_context[pkt_no]; - - if (!context->skb) - return -EINVAL; - - info = IEEE80211_SKB_CB(context->skb); - idx = info->control.rates[0].idx; - - ieee80211_tx_info_clear_status(info); - - info->status.rates[0].count = tx_retry; - - if (!(tsr & TSR_TMO)) { - info->status.rates[0].idx = idx; - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - info->flags |= IEEE80211_TX_STAT_ACK; - } - - ieee80211_tx_status_irqsafe(priv->hw, context->skb); - - context->in_use = false; - - return 0; -} - -static void vnt_int_process_data(struct vnt_private *priv) -{ - struct vnt_interrupt_data *int_data; - struct ieee80211_low_level_stats *low_stats = &priv->low_stats; - - dev_dbg(&priv->usb->dev, "---->s_nsInterruptProcessData\n"); - - int_data = (struct vnt_interrupt_data *)priv->int_buf.data_buf; - - if (int_data->tsr0 & TSR_VALID) - vnt_int_report_rate(priv, int_data->pkt0, int_data->tsr0); - - if (int_data->tsr1 & TSR_VALID) - vnt_int_report_rate(priv, int_data->pkt1, int_data->tsr1); - - if (int_data->tsr2 & TSR_VALID) - vnt_int_report_rate(priv, int_data->pkt2, int_data->tsr2); - - if (int_data->tsr3 & TSR_VALID) - vnt_int_report_rate(priv, int_data->pkt3, int_data->tsr3); - - if (!int_data->isr0) - return; - - if (int_data->isr0 & ISR_BNTX && priv->op_mode == NL80211_IFTYPE_AP) - vnt_schedule_command(priv, WLAN_CMD_BECON_SEND); - - priv->current_tsf = le64_to_cpu(int_data->tsf); - - low_stats->dot11RTSSuccessCount += int_data->rts_success; - low_stats->dot11RTSFailureCount += int_data->rts_fail; - low_stats->dot11ACKFailureCount += int_data->ack_fail; - low_stats->dot11FCSErrorCount += int_data->fcs_err; -} - -static void vnt_start_interrupt_urb_complete(struct urb *urb) -{ - struct vnt_private *priv = urb->context; - int status = urb->status; - - switch (status) { - case 0: - case -ETIMEDOUT: - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - return; - default: - break; - } - - if (status) - dev_dbg(&priv->usb->dev, "%s status = %d\n", __func__, status); - else - vnt_int_process_data(priv); - - if (!test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) - status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC); - - if (status) - dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); -} - -int vnt_start_interrupt_urb(struct vnt_private *priv) -{ - int ret = 0; - - dev_dbg(&priv->usb->dev, "---->Interrupt Polling Thread\n"); - - usb_fill_int_urb(priv->interrupt_urb, - priv->usb, - usb_rcvintpipe(priv->usb, 1), - priv->int_buf.data_buf, - MAX_INTERRUPT_SIZE, - vnt_start_interrupt_urb_complete, - priv, - priv->int_interval); - - ret = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC); - if (ret) - dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", ret); - - return ret; -} - -static int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb, - unsigned long bytes_received) -{ - struct ieee80211_hw *hw = priv->hw; - struct ieee80211_supported_band *sband; - struct sk_buff *skb; - struct ieee80211_rx_status *rx_status; - struct vnt_rx_header *head; - struct vnt_rx_tail *tail; - u32 frame_size; - int ii; - u16 rx_bitrate, pay_load_with_padding; - u8 rate_idx = 0; - long rx_dbm; - - skb = ptr_rcb->skb; - rx_status = IEEE80211_SKB_RXCB(skb); - - /* [31:16]RcvByteCount ( not include 4-byte Status ) */ - head = (struct vnt_rx_header *)skb->data; - frame_size = head->wbk_status >> 16; - frame_size += 4; - - if (bytes_received != frame_size) { - dev_dbg(&priv->usb->dev, "------- WRONG Length 1\n"); - return false; - } - - if ((bytes_received > 2372) || (bytes_received <= 40)) { - /* Frame Size error drop this packet.*/ - dev_dbg(&priv->usb->dev, "------ WRONG Length 2\n"); - return false; - } - - /* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */ - /* -8TSF - 4RSR - 4SQ3 - ?Padding */ - - /* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */ - - /*Fix hardware bug => PLCP_Length error */ - if (((bytes_received - head->pay_load_len) > 27) || - ((bytes_received - head->pay_load_len) < 24) || - (bytes_received < head->pay_load_len)) { - dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n", - head->pay_load_len); - return false; - } - - sband = hw->wiphy->bands[hw->conf.chandef.chan->band]; - rx_bitrate = head->rx_rate * 5; /* rx_rate * 5 */ - - for (ii = 0; ii < sband->n_bitrates; ii++) { - if (sband->bitrates[ii].bitrate == rx_bitrate) { - rate_idx = ii; - break; - } - } - - if (ii == sband->n_bitrates) { - dev_dbg(&priv->usb->dev, "Wrong Rx Bit Rate %d\n", rx_bitrate); - return false; - } - - pay_load_with_padding = ((head->pay_load_len / 4) + - ((head->pay_load_len % 4) ? 1 : 0)) * 4; - - tail = (struct vnt_rx_tail *)(skb->data + - sizeof(*head) + pay_load_with_padding); - priv->tsf_time = le64_to_cpu(tail->tsf_time); - - if (tail->rsr & (RSR_IVLDTYP | RSR_IVLDLEN)) - return false; - - vnt_rf_rssi_to_dbm(priv, tail->rssi, &rx_dbm); - - priv->bb_pre_ed_rssi = (u8)-rx_dbm + 1; - priv->current_rssi = priv->bb_pre_ed_rssi; - - skb_pull(skb, sizeof(*head)); - skb_trim(skb, head->pay_load_len); - - rx_status->mactime = priv->tsf_time; - rx_status->band = hw->conf.chandef.chan->band; - rx_status->signal = rx_dbm; - rx_status->flag = 0; - rx_status->freq = hw->conf.chandef.chan->center_freq; - - if (!(tail->rsr & RSR_CRCOK)) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - - rx_status->rate_idx = rate_idx; - - if (tail->new_rsr & NEWRSR_DECRYPTOK) - rx_status->flag |= RX_FLAG_DECRYPTED; - - ieee80211_rx_irqsafe(priv->hw, skb); - - return true; -} - -static void vnt_submit_rx_urb_complete(struct urb *urb) -{ - struct vnt_rcb *rcb = urb->context; - struct vnt_private *priv = rcb->priv; - - switch (urb->status) { - case 0: - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - return; - case -ETIMEDOUT: - default: - dev_dbg(&priv->usb->dev, "BULK In failed %d\n", urb->status); - break; - } - - if (urb->actual_length) { - if (vnt_rx_data(priv, rcb, urb->actual_length)) { - rcb->skb = dev_alloc_skb(priv->rx_buf_sz); - if (!rcb->skb) - return; - } else { - skb_push(rcb->skb, skb_headroom(rcb->skb)); - skb_trim(rcb->skb, 0); - } - - urb->transfer_buffer = skb_put(rcb->skb, - skb_tailroom(rcb->skb)); - } - - if (usb_submit_urb(urb, GFP_ATOMIC)) - dev_dbg(&priv->usb->dev, "Failed to re submit rx skb\n"); -} - -int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb) -{ - int ret = 0; - struct urb *urb = rcb->urb; - - if (!rcb->skb) { - dev_dbg(&priv->usb->dev, "rcb->skb is null\n"); - ret = -EINVAL; - goto end; - } - - usb_fill_bulk_urb(urb, - priv->usb, - usb_rcvbulkpipe(priv->usb, 2), - skb_put(rcb->skb, skb_tailroom(rcb->skb)), - MAX_TOTAL_SIZE_WITH_ALL_HEADERS, - vnt_submit_rx_urb_complete, - rcb); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) - dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", ret); -end: - return ret; -} - -static void vnt_tx_context_complete(struct urb *urb) -{ - struct vnt_usb_send_context *context = urb->context; - struct vnt_private *priv = context->priv; - - switch (urb->status) { - case 0: - dev_dbg(&priv->usb->dev, - "Write %d bytes\n", urb->actual_length); - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - context->in_use = false; - return; - case -ETIMEDOUT: - default: - dev_dbg(&priv->usb->dev, "BULK Out failed %d\n", urb->status); - break; - } - - if (context->type == CONTEXT_DATA_PACKET) - ieee80211_wake_queues(priv->hw); - - if (urb->status || context->type == CONTEXT_BEACON_PACKET) { - if (context->skb) - ieee80211_free_txskb(priv->hw, context->skb); - - context->in_use = false; - } -} - -int vnt_tx_context(struct vnt_private *priv, - struct vnt_usb_send_context *context, - struct sk_buff *skb) -{ - struct vnt_tx_usb_header *usb; - struct urb *urb; - int status; - u16 count = skb->len; - - usb = skb_push(skb, sizeof(*usb)); - usb->tx_byte_count = cpu_to_le16(count); - usb->pkt_no = context->pkt_no; - usb->type = context->type; - - if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) { - context->in_use = false; - return -ENODEV; - } - - if (skb->len > MAX_TOTAL_SIZE_WITH_ALL_HEADERS) { - context->in_use = false; - return -E2BIG; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - context->in_use = false; - return -ENOMEM; - } - - usb_fill_bulk_urb(urb, - priv->usb, - usb_sndbulkpipe(priv->usb, 3), - skb->data, - skb->len, - vnt_tx_context_complete, - context); - - usb_anchor_urb(urb, &priv->tx_submitted); - - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status); - usb_unanchor_urb(urb); - context->in_use = false; - } - - usb_free_urb(urb); - - return status; -} diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h deleted file mode 100644 index 922312e299bf64ff2446011a9c358215fbe5388e..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/usbpipe.h +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: - * - * Author: Warren Hsu - * - * Date: Mar. 30, 2005 - * - */ - -#ifndef __USBPIPE_H__ -#define __USBPIPE_H__ - -#include "device.h" - -struct vnt_interrupt_data { - u8 tsr0; - u8 pkt0; - u16 time0; - u8 tsr1; - u8 pkt1; - u16 time1; - u8 tsr2; - u8 pkt2; - u16 time2; - u8 tsr3; - u8 pkt3; - u16 time3; - __le64 tsf; - u8 isr0; - u8 isr1; - u8 rts_success; - u8 rts_fail; - u8 ack_fail; - u8 fcs_err; - u8 sw[2]; -} __packed; - -struct vnt_tx_usb_header { - u8 type; - u8 pkt_no; - __le16 tx_byte_count; -} __packed; - -#define VNT_REG_BLOCK_SIZE 64 - -int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, const u8 *buffer); -int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer); - -int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 ref_off, u8 data); -int vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data); - -int vnt_control_out_blocks(struct vnt_private *priv, - u16 block, u8 reg, u16 len, const u8 *data); - -int vnt_start_interrupt_urb(struct vnt_private *priv); -int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb); -int vnt_tx_context(struct vnt_private *priv, - struct vnt_usb_send_context *context, - struct sk_buff *skb); - -#endif /* __USBPIPE_H__ */ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c deleted file mode 100644 index 14b8aa58711906358d3231444e527bd457f94694..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/wcmd.c +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Handles the management command interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2003 - * - * Functions: - * vnt_cmd_complete - Command Complete function - * vnt_schedule_command - Push Command and wait Command Scheduler to do - * vnt_cmd_timer_wait- Call back timer - * - * Revision History: - * - */ - -#include "device.h" -#include "mac.h" -#include "wcmd.h" -#include "power.h" -#include "usbpipe.h" -#include "rxtx.h" -#include "rf.h" - -static void vnt_cmd_timer_wait(struct vnt_private *priv, unsigned long msecs) -{ - schedule_delayed_work(&priv->run_command_work, msecs_to_jiffies(msecs)); -} - -static u32 add_one_with_wrap_around(u32 var, u8 modulo) -{ - if (var >= (modulo - 1)) - var = 0; - else - var++; - return var; -} - -static int vnt_cmd_complete(struct vnt_private *priv) -{ - priv->command_state = WLAN_CMD_IDLE; - if (priv->free_cmd_queue == CMD_Q_SIZE) { - /* Command Queue Empty */ - priv->cmd_running = false; - return true; - } - - priv->command = priv->cmd_queue[priv->cmd_dequeue_idx]; - - priv->cmd_dequeue_idx = add_one_with_wrap_around(priv->cmd_dequeue_idx, CMD_Q_SIZE); - priv->free_cmd_queue++; - priv->cmd_running = true; - - switch (priv->command) { - case WLAN_CMD_INIT_MAC80211: - priv->command_state = WLAN_CMD_INIT_MAC80211_START; - break; - - case WLAN_CMD_TBTT_WAKEUP: - priv->command_state = WLAN_CMD_TBTT_WAKEUP_START; - break; - - case WLAN_CMD_BECON_SEND: - priv->command_state = WLAN_CMD_BECON_SEND_START; - break; - - case WLAN_CMD_SETPOWER: - priv->command_state = WLAN_CMD_SETPOWER_START; - break; - - case WLAN_CMD_CHANGE_ANTENNA: - priv->command_state = WLAN_CMD_CHANGE_ANTENNA_START; - break; - - default: - break; - } - - vnt_cmd_timer_wait(priv, 0); - - return true; -} - -void vnt_run_command(struct work_struct *work) -{ - struct vnt_private *priv = - container_of(work, struct vnt_private, run_command_work.work); - - if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) - return; - - if (!priv->cmd_running) - return; - - switch (priv->command_state) { - case WLAN_CMD_INIT_MAC80211_START: - if (priv->mac_hw) - break; - - dev_info(&priv->usb->dev, "Starting mac80211\n"); - - if (vnt_init(priv)) { - /* If fail all ends TODO retry */ - dev_err(&priv->usb->dev, "failed to start\n"); - usb_set_intfdata(priv->intf, NULL); - ieee80211_free_hw(priv->hw); - return; - } - - break; - - case WLAN_CMD_TBTT_WAKEUP_START: - vnt_next_tbtt_wakeup(priv); - break; - - case WLAN_CMD_BECON_SEND_START: - if (!priv->vif) - break; - - vnt_beacon_make(priv, priv->vif); - - vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX); - - break; - - case WLAN_CMD_SETPOWER_START: - - vnt_rf_setpower(priv, priv->hw->conf.chandef.chan); - - break; - - case WLAN_CMD_CHANGE_ANTENNA_START: - dev_dbg(&priv->usb->dev, "Change from Antenna%d to", - priv->rx_antenna_sel); - - if (priv->rx_antenna_sel == 0) { - priv->rx_antenna_sel = 1; - if (priv->tx_rx_ant_inv) - vnt_set_antenna_mode(priv, ANT_RXA); - else - vnt_set_antenna_mode(priv, ANT_RXB); - } else { - priv->rx_antenna_sel = 0; - if (priv->tx_rx_ant_inv) - vnt_set_antenna_mode(priv, ANT_RXB); - else - vnt_set_antenna_mode(priv, ANT_RXA); - } - break; - - default: - break; - } - - vnt_cmd_complete(priv); -} - -int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd command) -{ - if (priv->free_cmd_queue == 0) - return false; - - priv->cmd_queue[priv->cmd_enqueue_idx] = command; - - priv->cmd_enqueue_idx = add_one_with_wrap_around(priv->cmd_enqueue_idx, CMD_Q_SIZE); - priv->free_cmd_queue--; - - if (!priv->cmd_running) - vnt_cmd_complete(priv); - - return true; -} - -void vnt_reset_command_timer(struct vnt_private *priv) -{ - priv->free_cmd_queue = CMD_Q_SIZE; - priv->cmd_dequeue_idx = 0; - priv->cmd_enqueue_idx = 0; - priv->command_state = WLAN_CMD_IDLE; - priv->cmd_running = false; -} diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h deleted file mode 100644 index a62924671b17e6a483696873f5cb21a954bac01c..0000000000000000000000000000000000000000 --- a/drivers/staging/vt6656/wcmd.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * Purpose: Handles the management command interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __WCMD_H__ -#define __WCMD_H__ - -#include "device.h" - -/* Command code */ -enum vnt_cmd { - WLAN_CMD_INIT_MAC80211, - WLAN_CMD_SETPOWER, - WLAN_CMD_TBTT_WAKEUP, - WLAN_CMD_BECON_SEND, - WLAN_CMD_CHANGE_ANTENNA -}; - -#define CMD_Q_SIZE 32 - -/* Command state */ -enum vnt_cmd_state { - WLAN_CMD_INIT_MAC80211_START, - WLAN_CMD_SETPOWER_START, - WLAN_CMD_TBTT_WAKEUP_START, - WLAN_CMD_BECON_SEND_START, - WLAN_CMD_CHANGE_ANTENNA_START, - WLAN_CMD_IDLE -}; - -struct vnt_private; - -void vnt_reset_command_timer(struct vnt_private *priv); - -int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd); - -void vnt_run_command(struct work_struct *work); - -#endif /* __WCMD_H__ */ diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index e9456e3e74ccaa75bce46cb591d3d0cb9fccaf3e..3e33cf2af73bbfed28cf61757deef294e65db416 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1817,7 +1817,7 @@ MODULE_DEVICE_TABLE(of, optee_dt_match); static struct platform_driver optee_driver = { .probe = optee_probe, - .remove_new = optee_smc_remove, + .remove = optee_smc_remove, .shutdown = optee_shutdown, .driver = { .name = "optee", diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index 7c46dd6bee731eaec4659a179a59681cfd7a91d3..c868d8b7bd1cbf5cf3aaae6e169272691d543055 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -454,8 +454,8 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device * } EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove); -MODULE_IMPORT_NS(INTEL_TCC); -MODULE_IMPORT_NS(INT340X_THERMAL); +MODULE_IMPORT_NS("INTEL_TCC"); +MODULE_IMPORT_NS("INT340X_THERMAL"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c index ba5d36d36fc404c9e69279a961d3b63383f53903..145d471546d50cecf2fa8934a5e1286d686d8744 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -510,7 +510,7 @@ static struct pci_driver proc_thermal_pci_driver = { module_pci_driver(proc_thermal_pci_driver); -MODULE_IMPORT_NS(INT340X_THERMAL); +MODULE_IMPORT_NS("INT340X_THERMAL"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c index af2ec0beb7a1109508f0ca6a02670319d4c0d33e..b1d531ef440f1db0e36a84c671741f47fcd6e954 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c @@ -94,7 +94,7 @@ int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp return ret; } -EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_read_cmd, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_read_cmd, "INT340X_THERMAL"); int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data) { @@ -106,7 +106,7 @@ int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data return ret; } -EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd, "INT340X_THERMAL"); #define MBOX_CAMARILLO_RD_INTR_CONFIG 0x1E #define MBOX_CAMARILLO_WR_INTR_CONFIG 0x1F @@ -153,7 +153,7 @@ unlock: return ret; } -EXPORT_SYMBOL_NS_GPL(processor_thermal_mbox_interrupt_config, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(processor_thermal_mbox_interrupt_config, "INT340X_THERMAL"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Processor Thermal Mail Box Interface"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_power_floor.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_power_floor.c index d6b787ca2741ee4c3ee2d04ac537378db8a68c40..25cdbb6d91a6a738a594c974e5905d9f9c765a68 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_power_floor.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_power_floor.c @@ -42,7 +42,7 @@ int proc_thermal_read_power_floor_status(struct proc_thermal_device *proc_priv) status = readq(proc_priv->mmio_base + SOC_WT_RES_INT_STATUS_OFFSET); return (status & SOC_POWER_FLOOR_STATUS) >> SOC_POWER_FLOOR_SHIFT; } -EXPORT_SYMBOL_NS_GPL(proc_thermal_read_power_floor_status, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_read_power_floor_status, "INT340X_THERMAL"); static bool enable_state; static DEFINE_MUTEX(pf_lock); @@ -69,13 +69,13 @@ pf_unlock: return ret; } -EXPORT_SYMBOL_NS_GPL(proc_thermal_power_floor_set_state, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_power_floor_set_state, "INT340X_THERMAL"); bool proc_thermal_power_floor_get_state(struct proc_thermal_device *proc_priv) { return enable_state; } -EXPORT_SYMBOL_NS_GPL(proc_thermal_power_floor_get_state, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_power_floor_get_state, "INT340X_THERMAL"); /** * proc_thermal_check_power_floor_intr() - Check power floor interrupt. @@ -94,7 +94,7 @@ bool proc_thermal_check_power_floor_intr(struct proc_thermal_device *proc_priv) int_status = readq(proc_priv->mmio_base + SOC_WT_RES_INT_STATUS_OFFSET); return !!(int_status & SOC_POWER_FLOOR_INT_ACTIVE); } -EXPORT_SYMBOL_NS_GPL(proc_thermal_check_power_floor_intr, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_check_power_floor_intr, "INT340X_THERMAL"); /** * proc_thermal_power_floor_intr_callback() - Process power floor notification @@ -120,8 +120,8 @@ void proc_thermal_power_floor_intr_callback(struct pci_dev *pdev, sysfs_notify(&pdev->dev.kobj, "power_limits", "power_floor_status"); } -EXPORT_SYMBOL_NS_GPL(proc_thermal_power_floor_intr_callback, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_power_floor_intr_callback, "INT340X_THERMAL"); -MODULE_IMPORT_NS(INT340X_THERMAL); +MODULE_IMPORT_NS("INT340X_THERMAL"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Processor Thermal power floor notification Interface"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c index 0e2dc1426282da29dbcdd6951768cdd73a05a8c7..dad63f2d5f90fc2f695e223a706c8b2b3bc1de72 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c @@ -9,7 +9,7 @@ #include #include "processor_thermal_device.h" -MODULE_IMPORT_NS(INT340X_THERMAL); +MODULE_IMPORT_NS("INT340X_THERMAL"); struct mmio_reg { int read_only; diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c index e947d84f4977fce91b69dc2e15d07955974cf48e..68e8391af8f4e1ac34dedb1b9ee0fb1434cebdcf 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c @@ -204,7 +204,7 @@ bool proc_thermal_check_wt_intr(struct proc_thermal_device *proc_priv) return false; } -EXPORT_SYMBOL_NS_GPL(proc_thermal_check_wt_intr, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_check_wt_intr, "INT340X_THERMAL"); /* Callback to notify user space */ void proc_thermal_wt_intr_callback(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) @@ -217,7 +217,7 @@ void proc_thermal_wt_intr_callback(struct pci_dev *pdev, struct proc_thermal_dev sysfs_notify(&pdev->dev.kobj, "workload_hint", "workload_type_index"); } -EXPORT_SYMBOL_NS_GPL(proc_thermal_wt_intr_callback, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_wt_intr_callback, "INT340X_THERMAL"); static bool workload_hint_created; @@ -233,7 +233,7 @@ int proc_thermal_wt_hint_add(struct pci_dev *pdev, struct proc_thermal_device *p return 0; } -EXPORT_SYMBOL_NS_GPL(proc_thermal_wt_hint_add, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_wt_hint_add, "INT340X_THERMAL"); void proc_thermal_wt_hint_remove(struct pci_dev *pdev) { @@ -249,8 +249,8 @@ void proc_thermal_wt_hint_remove(struct pci_dev *pdev) workload_hint_created = false; } -EXPORT_SYMBOL_NS_GPL(proc_thermal_wt_hint_remove, INT340X_THERMAL); +EXPORT_SYMBOL_NS_GPL(proc_thermal_wt_hint_remove, "INT340X_THERMAL"); -MODULE_IMPORT_NS(INT340X_THERMAL); +MODULE_IMPORT_NS("INT340X_THERMAL"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Processor Thermal Work Load type hint Interface"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c index f298e7442662a156664d02e1baa72fad719f1eca..b95810f4a0118a16729d81421c5178b8ffbd3bd6 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c @@ -132,6 +132,6 @@ void proc_thermal_wt_req_remove(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(proc_thermal_wt_req_remove); -MODULE_IMPORT_NS(INT340X_THERMAL); +MODULE_IMPORT_NS("INT340X_THERMAL"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Processor Thermal Work Load type request Interface"); diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c index 4ba649370aa1a7f8a687c476c4470178541b8baf..96a24df79686ca0d489d53c3debdf01c7711410e 100644 --- a/drivers/thermal/intel/intel_powerclamp.c +++ b/drivers/thermal/intel/intel_powerclamp.c @@ -809,7 +809,7 @@ static void __exit powerclamp_exit(void) } module_exit(powerclamp_exit); -MODULE_IMPORT_NS(IDLE_INJECT); +MODULE_IMPORT_NS("IDLE_INJECT"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Arjan van de Ven "); diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.c b/drivers/thermal/intel/intel_soc_dts_iosf.c index 43a29551ba17ebc057269db0b31c5acdab72a158..ea87439fe7a99bbbe1c87ed8f8f71557bc79d95a 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.c +++ b/drivers/thermal/intel/intel_soc_dts_iosf.c @@ -388,6 +388,6 @@ void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors) } EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_exit); -MODULE_IMPORT_NS(INTEL_TCC); +MODULE_IMPORT_NS("INTEL_TCC"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("SoC DTS driver using side band interface"); diff --git a/drivers/thermal/intel/intel_tcc.c b/drivers/thermal/intel/intel_tcc.c index c86654f28aa5b2efe8629d8aa731def62a774167..817421508d5c92465dc403c5bb814d9fab80f227 100644 --- a/drivers/thermal/intel/intel_tcc.c +++ b/drivers/thermal/intel/intel_tcc.c @@ -150,7 +150,7 @@ u32 intel_tcc_get_offset_mask(void) { return intel_tcc_temp_masks.tcc_offset; } -EXPORT_SYMBOL_NS(intel_tcc_get_offset_mask, INTEL_TCC); +EXPORT_SYMBOL_NS(intel_tcc_get_offset_mask, "INTEL_TCC"); /** * get_temp_mask() - Returns the model-specific bitmask for temperature @@ -195,7 +195,7 @@ int intel_tcc_get_tjmax(int cpu) return val ? val : -ENODATA; } -EXPORT_SYMBOL_NS_GPL(intel_tcc_get_tjmax, INTEL_TCC); +EXPORT_SYMBOL_NS_GPL(intel_tcc_get_tjmax, "INTEL_TCC"); /** * intel_tcc_get_offset() - returns the TCC Offset value to Tjmax @@ -220,7 +220,7 @@ int intel_tcc_get_offset(int cpu) return (low >> 24) & intel_tcc_temp_masks.tcc_offset; } -EXPORT_SYMBOL_NS_GPL(intel_tcc_get_offset, INTEL_TCC); +EXPORT_SYMBOL_NS_GPL(intel_tcc_get_offset, "INTEL_TCC"); /** * intel_tcc_set_offset() - set the TCC offset value to Tjmax @@ -263,7 +263,7 @@ int intel_tcc_set_offset(int cpu, int offset) else return wrmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, low, high); } -EXPORT_SYMBOL_NS_GPL(intel_tcc_set_offset, INTEL_TCC); +EXPORT_SYMBOL_NS_GPL(intel_tcc_set_offset, "INTEL_TCC"); /** * intel_tcc_get_temp() - returns the current temperature @@ -303,4 +303,4 @@ int intel_tcc_get_temp(int cpu, int *temp, bool pkg) return 0; } -EXPORT_SYMBOL_NS_GPL(intel_tcc_get_temp, INTEL_TCC); +EXPORT_SYMBOL_NS_GPL(intel_tcc_get_temp, "INTEL_TCC"); diff --git a/drivers/thermal/intel/intel_tcc_cooling.c b/drivers/thermal/intel/intel_tcc_cooling.c index 17110ffa80bb05424e0c13461bbbc55b4ad6d2d1..9ff0ebdde0ef2ca9860bfb067b0586c86071a980 100644 --- a/drivers/thermal/intel/intel_tcc_cooling.c +++ b/drivers/thermal/intel/intel_tcc_cooling.c @@ -118,7 +118,7 @@ static void __exit tcc_cooling_exit(void) module_exit(tcc_cooling_exit) -MODULE_IMPORT_NS(INTEL_TCC); +MODULE_IMPORT_NS("INTEL_TCC"); MODULE_DESCRIPTION("TCC offset cooling device Driver"); MODULE_AUTHOR("Zhang Rui "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index 65b33b56a9be5e170cf268835307792238250bd7..496abf8e55e0d53492efc57e02fa5c3955172f49 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -524,7 +524,7 @@ static void __exit pkg_temp_thermal_exit(void) } module_exit(pkg_temp_thermal_exit) -MODULE_IMPORT_NS(INTEL_TCC); +MODULE_IMPORT_NS("INTEL_TCC"); MODULE_DESCRIPTION("X86 PKG TEMP Thermal Driver"); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index 37da7a8ea948c148d4386ddcb567882bfc8f8d4a..0ecccd4d8556c4960748ba9292d49e0380b7df0d 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -284,4 +284,4 @@ int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device } EXPORT_SYMBOL_GPL(devm_thermal_add_hwmon_sysfs); -MODULE_IMPORT_NS(HWMON_THERMAL); +MODULE_IMPORT_NS("HWMON_THERMAL"); diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 350310bd0feea70656f6c18f28906c59c5acfea7..a1d0d8a33f208a23cabe54ec84d481e794e09bdd 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -7,6 +7,7 @@ * Mika Westerberg */ +#include #include #include #include @@ -43,6 +44,24 @@ #define MAX_DWELL_TIME 500 /* ms */ #define DWELL_SAMPLE_INTERVAL 10 +enum usb4_margin_cap_voltage_indp { + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_MIN, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_BOTH, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_MIN, + USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_BOTH, + USB4_MARGIN_CAP_VOLTAGE_INDP_UNKNOWN, +}; + +enum usb4_margin_cap_time_indp { + USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_MIN, + USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR, + USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_BOTH, + USB4_MARGIN_CAP_TIME_INDP_GEN_4_MIN, + USB4_MARGIN_CAP_TIME_INDP_GEN_4_BOTH, + USB4_MARGIN_CAP_TIME_INDP_UNKNOWN, +}; + /* Sideband registers and their sizes as defined in the USB4 spec */ struct sb_reg { unsigned int reg; @@ -395,6 +414,8 @@ out: * @target: Sideband target * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER * @dev: Pointer to the device that is the target (USB4 port or retimer) + * @gen: Link generation + * @asym_rx: %true% if @port supports asymmetric link with 3 Rx * @caps: Port lane margining capabilities * @results: Last lane margining results * @lanes: %0, %1 or %7 (all) @@ -416,15 +437,19 @@ out: * @time: %true if time margining is used instead of voltage * @right_high: %false if left/low margin test is performed, %true if * right/high + * @upper_eye: %false if the lower PAM3 eye is used, %true if the upper + * eye is used */ struct tb_margining { struct tb_port *port; enum usb4_sb_target target; u8 index; struct device *dev; - u32 caps[2]; - u32 results[2]; - unsigned int lanes; + unsigned int gen; + bool asym_rx; + u32 caps[3]; + u32 results[3]; + enum usb4_margining_lane lanes; unsigned int min_ber_level; unsigned int max_ber_level; unsigned int ber_level; @@ -441,6 +466,7 @@ struct tb_margining { bool software; bool time; bool right_high; + bool upper_eye; }; static int margining_modify_error_counter(struct tb_margining *margining, @@ -463,35 +489,75 @@ static int margining_modify_error_counter(struct tb_margining *margining, static bool supports_software(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW; + if (margining->gen < 4) + return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_SW; + return margining->caps[2] & USB4_MARGIN_CAP_2_MODES_SW; } static bool supports_hardware(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW; + if (margining->gen < 4) + return margining->caps[0] & USB4_MARGIN_CAP_0_MODES_HW; + return margining->caps[2] & USB4_MARGIN_CAP_2_MODES_HW; } -static bool both_lanes(const struct tb_margining *margining) +static bool all_lanes(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_2_LANES; + return margining->caps[0] & USB4_MARGIN_CAP_0_ALL_LANES; } -static unsigned int +static enum usb4_margin_cap_voltage_indp independent_voltage_margins(const struct tb_margining *margining) { - return FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK, margining->caps[0]); + if (margining->gen < 4) { + switch (FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK, margining->caps[0])) { + case USB4_MARGIN_CAP_0_VOLTAGE_MIN: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_MIN; + case USB4_MARGIN_CAP_0_VOLTAGE_HL: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL; + case USB4_MARGIN_CAP_1_TIME_BOTH: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_BOTH; + } + } else { + switch (FIELD_GET(USB4_MARGIN_CAP_2_VOLTAGE_INDP_MASK, margining->caps[2])) { + case USB4_MARGIN_CAP_2_VOLTAGE_MIN: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_MIN; + case USB4_MARGIN_CAP_2_VOLTAGE_BOTH: + return USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_BOTH; + } + } + return USB4_MARGIN_CAP_VOLTAGE_INDP_UNKNOWN; } static bool supports_time(const struct tb_margining *margining) { - return margining->caps[0] & USB4_MARGIN_CAP_0_TIME; + if (margining->gen < 4) + return margining->caps[0] & USB4_MARGIN_CAP_0_TIME; + return margining->caps[2] & USB4_MARGIN_CAP_2_TIME; } /* Only applicable if supports_time() returns true */ -static unsigned int +static enum usb4_margin_cap_time_indp independent_time_margins(const struct tb_margining *margining) { - return FIELD_GET(USB4_MARGIN_CAP_1_TIME_INDP_MASK, margining->caps[1]); + if (margining->gen < 4) { + switch (FIELD_GET(USB4_MARGIN_CAP_1_TIME_INDP_MASK, margining->caps[1])) { + case USB4_MARGIN_CAP_1_TIME_MIN: + return USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_MIN; + case USB4_MARGIN_CAP_1_TIME_LR: + return USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR; + case USB4_MARGIN_CAP_1_TIME_BOTH: + return USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_BOTH; + } + } else { + switch (FIELD_GET(USB4_MARGIN_CAP_2_TIME_INDP_MASK, margining->caps[2])) { + case USB4_MARGIN_CAP_2_TIME_MIN: + return USB4_MARGIN_CAP_TIME_INDP_GEN_4_MIN; + case USB4_MARGIN_CAP_2_TIME_BOTH: + return USB4_MARGIN_CAP_TIME_INDP_GEN_4_BOTH; + } + } + return USB4_MARGIN_CAP_TIME_INDP_UNKNOWN; } static bool @@ -570,16 +636,14 @@ static int margining_caps_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; struct tb *tb = margining->port->sw->tb; - u32 cap0, cap1; + int ret = 0; if (mutex_lock_interruptible(&tb->lock)) return -ERESTARTSYS; /* Dump the raw caps first */ - cap0 = margining->caps[0]; - seq_printf(s, "0x%08x\n", cap0); - cap1 = margining->caps[1]; - seq_printf(s, "0x%08x\n", cap1); + for (int i = 0; i < ARRAY_SIZE(margining->caps); i++) + seq_printf(s, "0x%08x\n", margining->caps[i]); seq_printf(s, "# software margining: %s\n", supports_software(margining) ? "yes" : "no"); @@ -593,8 +657,8 @@ static int margining_caps_show(struct seq_file *s, void *not_used) seq_puts(s, "# hardware margining: no\n"); } - seq_printf(s, "# both lanes simultaneously: %s\n", - both_lanes(margining) ? "yes" : "no"); + seq_printf(s, "# all lanes simultaneously: %s\n", + str_yes_no(all_lanes(margining))); seq_printf(s, "# voltage margin steps: %u\n", margining->voltage_steps); seq_printf(s, "# maximum voltage offset: %u mV\n", @@ -609,32 +673,54 @@ static int margining_caps_show(struct seq_file *s, void *not_used) } switch (independent_voltage_margins(margining)) { - case USB4_MARGIN_CAP_0_VOLTAGE_MIN: + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_MIN: seq_puts(s, "# returns minimum between high and low voltage margins\n"); break; - case USB4_MARGIN_CAP_0_VOLTAGE_HL: + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL: seq_puts(s, "# returns high or low voltage margin\n"); break; - case USB4_MARGIN_CAP_0_VOLTAGE_BOTH: + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_BOTH: seq_puts(s, "# returns both high and low margins\n"); break; + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_MIN: + seq_puts(s, "# returns minimum between high and low voltage margins in both lower and upper eye\n"); + break; + case USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_4_BOTH: + seq_puts(s, "# returns both high and low margins of both upper and lower eye\n"); + break; + case USB4_MARGIN_CAP_VOLTAGE_INDP_UNKNOWN: + tb_port_warn(margining->port, + "failed to parse independent voltage margining capabilities\n"); + ret = -EIO; + goto out; } if (supports_time(margining)) { seq_puts(s, "# time margining: yes\n"); seq_printf(s, "# time margining is destructive: %s\n", - cap1 & USB4_MARGIN_CAP_1_TIME_DESTR ? "yes" : "no"); + str_yes_no(margining->caps[1] & USB4_MARGIN_CAP_1_TIME_DESTR)); switch (independent_time_margins(margining)) { - case USB4_MARGIN_CAP_1_TIME_MIN: + case USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_MIN: seq_puts(s, "# returns minimum between left and right time margins\n"); break; - case USB4_MARGIN_CAP_1_TIME_LR: + case USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR: seq_puts(s, "# returns left or right margin\n"); break; - case USB4_MARGIN_CAP_1_TIME_BOTH: + case USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_BOTH: seq_puts(s, "# returns both left and right margins\n"); break; + case USB4_MARGIN_CAP_TIME_INDP_GEN_4_MIN: + seq_puts(s, "# returns minimum between left and right time margins in both lower and upper eye\n"); + break; + case USB4_MARGIN_CAP_TIME_INDP_GEN_4_BOTH: + seq_puts(s, "# returns both left and right margins of both upper and lower eye\n"); + break; + case USB4_MARGIN_CAP_TIME_INDP_UNKNOWN: + tb_port_warn(margining->port, + "failed to parse independent time margining capabilities\n"); + ret = -EIO; + goto out; } seq_printf(s, "# time margin steps: %u\n", @@ -645,19 +731,43 @@ static int margining_caps_show(struct seq_file *s, void *not_used) seq_puts(s, "# time margining: no\n"); } +out: mutex_unlock(&tb->lock); - return 0; + return ret; } DEBUGFS_ATTR_RO(margining_caps); +static const struct { + enum usb4_margining_lane lane; + const char *name; +} lane_names[] = { + { + .lane = USB4_MARGINING_LANE_RX0, + .name = "0", + }, + { + .lane = USB4_MARGINING_LANE_RX1, + .name = "1", + }, + { + .lane = USB4_MARGINING_LANE_RX2, + .name = "2", + }, + { + .lane = USB4_MARGINING_LANE_ALL, + .name = "all", + }, +}; + static ssize_t margining_lanes_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct seq_file *s = file->private_data; struct tb_margining *margining = s->private; - struct tb *tb = margining->port->sw->tb; - int ret = 0; + struct tb_port *port = margining->port; + struct tb *tb = port->sw->tb; + int lane = -1; char *buf; buf = validate_and_copy_from_user(user_buf, &count); @@ -666,57 +776,60 @@ margining_lanes_write(struct file *file, const char __user *user_buf, buf[count - 1] = '\0'; - if (mutex_lock_interruptible(&tb->lock)) { - ret = -ERESTARTSYS; - goto out_free; + for (int i = 0; i < ARRAY_SIZE(lane_names); i++) { + if (!strcmp(buf, lane_names[i].name)) { + lane = lane_names[i].lane; + break; + } } - if (!strcmp(buf, "0")) { - margining->lanes = 0; - } else if (!strcmp(buf, "1")) { - margining->lanes = 1; - } else if (!strcmp(buf, "all")) { - /* Needs to be supported */ - if (both_lanes(margining)) - margining->lanes = 7; - else - ret = -EINVAL; - } else { - ret = -EINVAL; - } + free_page((unsigned long)buf); - mutex_unlock(&tb->lock); + if (lane == -1) + return -EINVAL; -out_free: - free_page((unsigned long)buf); - return ret < 0 ? ret : count; + scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) { + if (lane == USB4_MARGINING_LANE_ALL && !all_lanes(margining)) + return -EINVAL; + /* + * Enabling on RX2 requires that it is supported by the + * USB4 port. + */ + if (lane == USB4_MARGINING_LANE_RX2 && !margining->asym_rx) + return -EINVAL; + + margining->lanes = lane; + } + + return count; } static int margining_lanes_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; - struct tb *tb = margining->port->sw->tb; - unsigned int lanes; - - if (mutex_lock_interruptible(&tb->lock)) - return -ERESTARTSYS; + struct tb_port *port = margining->port; + struct tb *tb = port->sw->tb; - lanes = margining->lanes; - if (both_lanes(margining)) { - if (!lanes) - seq_puts(s, "[0] 1 all\n"); - else if (lanes == 1) - seq_puts(s, "0 [1] all\n"); - else - seq_puts(s, "0 1 [all]\n"); - } else { - if (!lanes) - seq_puts(s, "[0] 1\n"); - else - seq_puts(s, "0 [1]\n"); + scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &tb->lock) { + for (int i = 0; i < ARRAY_SIZE(lane_names); i++) { + if (lane_names[i].lane == USB4_MARGINING_LANE_ALL && + !all_lanes(margining)) + continue; + if (lane_names[i].lane == USB4_MARGINING_LANE_RX2 && + !margining->asym_rx) + continue; + + if (i != 0) + seq_putc(s, ' '); + + if (lane_names[i].lane == margining->lanes) + seq_printf(s, "[%s]", lane_names[i].name); + else + seq_printf(s, "%s", lane_names[i].name); + } + seq_puts(s, "\n"); } - mutex_unlock(&tb->lock); return 0; } DEBUGFS_ATTR_RW(margining_lanes); @@ -1004,13 +1117,16 @@ static int margining_run_sw(struct tb_margining *margining, if (ret) break; - if (margining->lanes == USB4_MARGIN_SW_LANE_0) + if (margining->lanes == USB4_MARGINING_LANE_RX0) errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK, margining->results[1]); - else if (margining->lanes == USB4_MARGIN_SW_LANE_1) + else if (margining->lanes == USB4_MARGINING_LANE_RX1) errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK, margining->results[1]); - else if (margining->lanes == USB4_MARGIN_SW_ALL_LANES) + else if (margining->lanes == USB4_MARGINING_LANE_RX2) + errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_2_MASK, + margining->results[1]); + else if (margining->lanes == USB4_MARGINING_LANE_ALL) errors = margining->results[1]; /* Any errors stop the test */ @@ -1030,6 +1146,31 @@ out_stop: return ret; } +static int validate_margining(struct tb_margining *margining) +{ + /* + * For running on RX2 the link must be asymmetric with 3 + * receivers. Because this is can change dynamically, check it + * here before we start the margining and report back error if + * expectations are not met. + */ + if (margining->lanes == USB4_MARGINING_LANE_RX2) { + int ret; + + ret = tb_port_get_link_width(margining->port); + if (ret < 0) + return ret; + if (ret != TB_LINK_WIDTH_ASYM_RX) { + tb_port_warn(margining->port, "link is %s expected %s", + tb_width_name(ret), + tb_width_name(TB_LINK_WIDTH_ASYM_RX)); + return -EINVAL; + } + } + + return 0; +} + static int margining_run_write(void *data, u64 val) { struct tb_margining *margining = data; @@ -1050,6 +1191,10 @@ static int margining_run_write(void *data, u64 val) goto out_rpm_put; } + ret = validate_margining(margining); + if (ret) + goto out_unlock; + if (tb_is_upstream_port(port)) down_sw = sw; else if (port->remote) @@ -1080,6 +1225,7 @@ static int margining_run_write(void *data, u64 val) .time = margining->time, .voltage_time_offset = margining->voltage_time_offset, .right_high = margining->right_high, + .upper_eye = margining->upper_eye, .optional_voltage_offset_range = margining->optional_voltage_offset_range, }; @@ -1095,6 +1241,7 @@ static int margining_run_write(void *data, u64 val) .lanes = margining->lanes, .time = margining->time, .right_high = margining->right_high, + .upper_eye = margining->upper_eye, .optional_voltage_offset_range = margining->optional_voltage_offset_range, }; @@ -1104,7 +1251,7 @@ static int margining_run_write(void *data, u64 val) margining->lanes); ret = usb4_port_hw_margin(port, margining->target, margining->index, ¶ms, - margining->results); + margining->results, ARRAY_SIZE(margining->results)); } if (down_sw) @@ -1132,13 +1279,12 @@ static ssize_t margining_results_write(struct file *file, return -ERESTARTSYS; /* Just clear the results */ - margining->results[0] = 0; - margining->results[1] = 0; + memset(margining->results, 0, sizeof(margining->results)); if (margining->software) { /* Clear the error counters */ margining_modify_error_counter(margining, - USB4_MARGIN_SW_ALL_LANES, + USB4_MARGINING_LANE_ALL, USB4_MARGIN_SW_ERROR_COUNTER_CLEAR); } @@ -1151,10 +1297,10 @@ static void voltage_margin_show(struct seq_file *s, { unsigned int tmp, voltage; - tmp = FIELD_GET(USB4_MARGIN_HW_RES_1_MARGIN_MASK, val); + tmp = FIELD_GET(USB4_MARGIN_HW_RES_MARGIN_MASK, val); voltage = tmp * margining->max_voltage_offset / margining->voltage_steps; seq_printf(s, "%u mV (%u)", voltage, tmp); - if (val & USB4_MARGIN_HW_RES_1_EXCEEDS) + if (val & USB4_MARGIN_HW_RES_EXCEEDS) seq_puts(s, " exceeds maximum"); seq_puts(s, "\n"); if (margining->optional_voltage_offset_range) @@ -1166,14 +1312,55 @@ static void time_margin_show(struct seq_file *s, { unsigned int tmp, interval; - tmp = FIELD_GET(USB4_MARGIN_HW_RES_1_MARGIN_MASK, val); + tmp = FIELD_GET(USB4_MARGIN_HW_RES_MARGIN_MASK, val); interval = tmp * margining->max_time_offset / margining->time_steps; seq_printf(s, "%u mUI (%u)", interval, tmp); - if (val & USB4_MARGIN_HW_RES_1_EXCEEDS) + if (val & USB4_MARGIN_HW_RES_EXCEEDS) seq_puts(s, " exceeds maximum"); seq_puts(s, "\n"); } +static u8 margining_hw_result_val(const u32 *results, + enum usb4_margining_lane lane, + bool right_high) +{ + u32 val; + + if (lane == USB4_MARGINING_LANE_RX0) + val = results[1]; + else if (lane == USB4_MARGINING_LANE_RX1) + val = results[1] >> USB4_MARGIN_HW_RES_LANE_SHIFT; + else if (lane == USB4_MARGINING_LANE_RX2) + val = results[2]; + else + val = 0; + + return right_high ? val : val >> USB4_MARGIN_HW_RES_LL_SHIFT; +} + +static void margining_hw_result_format(struct seq_file *s, + const struct tb_margining *margining, + enum usb4_margining_lane lane) +{ + u8 val; + + if (margining->time) { + val = margining_hw_result_val(margining->results, lane, true); + seq_printf(s, "# lane %u right time margin: ", lane); + time_margin_show(s, margining, val); + val = margining_hw_result_val(margining->results, lane, false); + seq_printf(s, "# lane %u left time margin: ", lane); + time_margin_show(s, margining, val); + } else { + val = margining_hw_result_val(margining->results, lane, true); + seq_printf(s, "# lane %u high voltage margin: ", lane); + voltage_margin_show(s, margining, val); + val = margining_hw_result_val(margining->results, lane, false); + seq_printf(s, "# lane %u low voltage margin: ", lane); + voltage_margin_show(s, margining, val); + } +} + static int margining_results_show(struct seq_file *s, void *not_used) { struct tb_margining *margining = s->private; @@ -1186,69 +1373,46 @@ static int margining_results_show(struct seq_file *s, void *not_used) seq_printf(s, "0x%08x\n", margining->results[0]); /* Only the hardware margining has two result dwords */ if (!margining->software) { - unsigned int val; - - seq_printf(s, "0x%08x\n", margining->results[1]); - - if (margining->time) { - if (!margining->lanes || margining->lanes == 7) { - val = margining->results[1]; - seq_puts(s, "# lane 0 right time margin: "); - time_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 0 left time margin: "); - time_margin_show(s, margining, val); - } - if (margining->lanes == 1 || margining->lanes == 7) { - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT; - seq_puts(s, "# lane 1 right time margin: "); - time_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 1 left time margin: "); - time_margin_show(s, margining, val); - } + for (int i = 1; i < ARRAY_SIZE(margining->results); i++) + seq_printf(s, "0x%08x\n", margining->results[i]); + + if (margining->lanes == USB4_MARGINING_LANE_ALL) { + margining_hw_result_format(s, margining, + USB4_MARGINING_LANE_RX0); + margining_hw_result_format(s, margining, + USB4_MARGINING_LANE_RX1); + if (margining->asym_rx) + margining_hw_result_format(s, margining, + USB4_MARGINING_LANE_RX2); } else { - if (!margining->lanes || margining->lanes == 7) { - val = margining->results[1]; - seq_puts(s, "# lane 0 high voltage margin: "); - voltage_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 0 low voltage margin: "); - voltage_margin_show(s, margining, val); - } - if (margining->lanes == 1 || margining->lanes == 7) { - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT; - seq_puts(s, "# lane 1 high voltage margin: "); - voltage_margin_show(s, margining, val); - val = margining->results[1] >> - USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT; - seq_puts(s, "# lane 1 low voltage margin: "); - voltage_margin_show(s, margining, val); - } + margining_hw_result_format(s, margining, + margining->lanes); } } else { u32 lane_errors, result; seq_printf(s, "0x%08x\n", margining->results[1]); - result = FIELD_GET(USB4_MARGIN_SW_LANES_MASK, margining->results[0]); - if (result == USB4_MARGIN_SW_LANE_0 || - result == USB4_MARGIN_SW_ALL_LANES) { + result = FIELD_GET(USB4_MARGIN_SW_LANES_MASK, margining->results[0]); + if (result == USB4_MARGINING_LANE_RX0 || + result == USB4_MARGINING_LANE_ALL) { lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK, margining->results[1]); seq_printf(s, "# lane 0 errors: %u\n", lane_errors); } - if (result == USB4_MARGIN_SW_LANE_1 || - result == USB4_MARGIN_SW_ALL_LANES) { + if (result == USB4_MARGINING_LANE_RX1 || + result == USB4_MARGINING_LANE_ALL) { lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK, margining->results[1]); seq_printf(s, "# lane 1 errors: %u\n", lane_errors); } + if (margining->asym_rx && + (result == USB4_MARGINING_LANE_RX2 || + result == USB4_MARGINING_LANE_ALL)) { + lane_errors = FIELD_GET(USB4_MARGIN_SW_ERR_COUNTER_LANE_2_MASK, + margining->results[1]); + seq_printf(s, "# lane 2 errors: %u\n", lane_errors); + } } mutex_unlock(&tb->lock); @@ -1382,6 +1546,55 @@ static int margining_margin_show(struct seq_file *s, void *not_used) } DEBUGFS_ATTR_RW(margining_margin); +static ssize_t margining_eye_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct tb_port *port = s->private; + struct usb4_port *usb4 = port->usb4; + struct tb *tb = port->sw->tb; + int ret = 0; + char *buf; + + buf = validate_and_copy_from_user(user_buf, &count); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + buf[count - 1] = '\0'; + + scoped_cond_guard(mutex_intr, ret = -ERESTARTSYS, &tb->lock) { + if (!strcmp(buf, "lower")) + usb4->margining->upper_eye = false; + else if (!strcmp(buf, "upper")) + usb4->margining->upper_eye = true; + else + ret = -EINVAL; + } + + free_page((unsigned long)buf); + return ret ? ret : count; +} + +static int margining_eye_show(struct seq_file *s, void *not_used) +{ + struct tb_port *port = s->private; + struct usb4_port *usb4 = port->usb4; + struct tb *tb = port->sw->tb; + + scoped_guard(mutex_intr, &tb->lock) { + if (usb4->margining->upper_eye) + seq_puts(s, "lower [upper]\n"); + else + seq_puts(s, "[lower] upper\n"); + + return 0; + } + + return -ERESTARTSYS; +} +DEBUGFS_ATTR_RW(margining_eye); + static struct tb_margining *margining_alloc(struct tb_port *port, struct device *dev, enum usb4_sb_target target, @@ -1392,6 +1605,12 @@ static struct tb_margining *margining_alloc(struct tb_port *port, unsigned int val; int ret; + ret = tb_port_get_link_generation(port); + if (ret < 0) { + tb_port_warn(port, "failed to read link generation\n"); + return NULL; + } + margining = kzalloc(sizeof(*margining), GFP_KERNEL); if (!margining) return NULL; @@ -1400,8 +1619,11 @@ static struct tb_margining *margining_alloc(struct tb_port *port, margining->target = target; margining->index = index; margining->dev = dev; + margining->gen = ret; + margining->asym_rx = tb_port_width_supported(port, TB_LINK_WIDTH_ASYM_RX); - ret = usb4_port_margining_caps(port, target, index, margining->caps); + ret = usb4_port_margining_caps(port, target, index, margining->caps, + ARRAY_SIZE(margining->caps)); if (ret) { kfree(margining); return NULL; @@ -1411,10 +1633,17 @@ static struct tb_margining *margining_alloc(struct tb_port *port, if (supports_software(margining)) margining->software = true; - val = FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_STEPS_MASK, margining->caps[0]); - margining->voltage_steps = val; - val = FIELD_GET(USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_MASK, margining->caps[0]); - margining->max_voltage_offset = 74 + val * 2; + if (margining->gen < 4) { + val = FIELD_GET(USB4_MARGIN_CAP_0_VOLTAGE_STEPS_MASK, margining->caps[0]); + margining->voltage_steps = val; + val = FIELD_GET(USB4_MARGIN_CAP_0_MAX_VOLTAGE_OFFSET_MASK, margining->caps[0]); + margining->max_voltage_offset = 74 + val * 2; + } else { + val = FIELD_GET(USB4_MARGIN_CAP_2_VOLTAGE_STEPS_MASK, margining->caps[2]); + margining->voltage_steps = val; + val = FIELD_GET(USB4_MARGIN_CAP_2_MAX_VOLTAGE_OFFSET_MASK, margining->caps[2]); + margining->max_voltage_offset = 74 + val * 2; + } if (supports_optional_voltage_offset_range(margining)) { val = FIELD_GET(USB4_MARGIN_CAP_0_VOLT_STEPS_OPT_MASK, @@ -1456,11 +1685,10 @@ static struct tb_margining *margining_alloc(struct tb_port *port, debugfs_create_file("results", 0600, dir, margining, &margining_results_fops); debugfs_create_file("test", 0600, dir, margining, &margining_test_fops); - if (independent_voltage_margins(margining) == USB4_MARGIN_CAP_0_VOLTAGE_HL || + if (independent_voltage_margins(margining) == USB4_MARGIN_CAP_VOLTAGE_INDP_GEN_2_3_HL || (supports_time(margining) && - independent_time_margins(margining) == USB4_MARGIN_CAP_1_TIME_LR)) - debugfs_create_file("margin", 0600, dir, margining, - &margining_margin_fops); + independent_time_margins(margining) == USB4_MARGIN_CAP_TIME_INDP_GEN_2_3_LR)) + debugfs_create_file("margin", 0600, dir, margining, &margining_margin_fops); margining->error_counter = USB4_MARGIN_SW_ERROR_COUNTER_CLEAR; margining->dwell_time = MIN_DWELL_TIME; @@ -1477,6 +1705,10 @@ static struct tb_margining *margining_alloc(struct tb_port *port, debugfs_create_file("dwell_time", DEBUGFS_MODE, dir, margining, &margining_dwell_time_fops); } + + if (margining->gen >= 4) + debugfs_create_file("eye", 0600, dir, port, &margining_eye_fops); + return margining; } diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 7af2642b97cb8133f1e4d49854cb41f323c2c8ed..1257dd3ce7e6a3b759576af8c9c5401cbefdadb4 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -1340,18 +1340,18 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (res) return dev_err_probe(dev, res, "cannot enable PCI device, aborting\n"); - res = pcim_iomap_regions(pdev, 1 << 0, "thunderbolt"); - if (res) - return dev_err_probe(dev, res, "cannot obtain PCI resources, aborting\n"); - nhi = devm_kzalloc(&pdev->dev, sizeof(*nhi), GFP_KERNEL); if (!nhi) return -ENOMEM; nhi->pdev = pdev; nhi->ops = (const struct tb_nhi_ops *)id->driver_data; - /* cannot fail - table is allocated in pcim_iomap_regions */ - nhi->iobase = pcim_iomap_table(pdev)[0]; + + nhi->iobase = pcim_iomap_region(pdev, 0, "thunderbolt"); + res = PTR_ERR_OR_ZERO(nhi->iobase); + if (res) + return dev_err_probe(dev, res, "cannot obtain PCI resources, aborting\n"); + nhi->hop_count = ioread32(nhi->iobase + REG_CAPS) & 0x3ff; dev_dbg(dev, "total paths: %d\n", nhi->hop_count); diff --git a/drivers/thunderbolt/sb_regs.h b/drivers/thunderbolt/sb_regs.h index dbcad25ead50f1687b253499b8ed0693c3f0a90a..5391502a4b8736f4d426594a6121ee3e7c0fd758 100644 --- a/drivers/thunderbolt/sb_regs.h +++ b/drivers/thunderbolt/sb_regs.h @@ -49,7 +49,7 @@ enum usb4_sb_opcode { /* USB4_SB_OPCODE_READ_LANE_MARGINING_CAP */ #define USB4_MARGIN_CAP_0_MODES_HW BIT(0) #define USB4_MARGIN_CAP_0_MODES_SW BIT(1) -#define USB4_MARGIN_CAP_0_2_LANES BIT(2) +#define USB4_MARGIN_CAP_0_ALL_LANES BIT(2) #define USB4_MARGIN_CAP_0_VOLTAGE_INDP_MASK GENMASK(4, 3) #define USB4_MARGIN_CAP_0_VOLTAGE_MIN 0x0 #define USB4_MARGIN_CAP_0_VOLTAGE_HL 0x1 @@ -69,34 +69,44 @@ enum usb4_sb_opcode { #define USB4_MARGIN_CAP_1_TIME_OFFSET_MASK GENMASK(20, 16) #define USB4_MARGIN_CAP_1_MIN_BER_MASK GENMASK(25, 21) #define USB4_MARGIN_CAP_1_MAX_BER_MASK GENMASK(30, 26) +#define USB4_MARGIN_CAP_2_MODES_HW BIT(0) +#define USB4_MARGIN_CAP_2_MODES_SW BIT(1) +#define USB4_MARGIN_CAP_2_TIME BIT(2) +#define USB4_MARGIN_CAP_2_MAX_VOLTAGE_OFFSET_MASK GENMASK(8, 3) +#define USB4_MARGIN_CAP_2_VOLTAGE_STEPS_MASK GENMASK(15, 9) +#define USB4_MARGIN_CAP_2_VOLTAGE_INDP_MASK GENMASK(17, 16) +#define USB4_MARGIN_CAP_2_VOLTAGE_MIN 0x0 +#define USB4_MARGIN_CAP_2_VOLTAGE_BOTH 0x1 +#define USB4_MARGIN_CAP_2_TIME_INDP_MASK GENMASK(19, 18) +#define USB4_MARGIN_CAP_2_TIME_MIN 0x0 +#define USB4_MARGIN_CAP_2_TIME_BOTH 0x1 /* USB4_SB_OPCODE_RUN_HW_LANE_MARGINING */ #define USB4_MARGIN_HW_TIME BIT(3) -#define USB4_MARGIN_HW_RH BIT(4) +#define USB4_MARGIN_HW_RHU BIT(4) #define USB4_MARGIN_HW_BER_MASK GENMASK(9, 5) #define USB4_MARGIN_HW_BER_SHIFT 5 #define USB4_MARGIN_HW_OPT_VOLTAGE BIT(10) /* Applicable to all margin values */ -#define USB4_MARGIN_HW_RES_1_MARGIN_MASK GENMASK(6, 0) -#define USB4_MARGIN_HW_RES_1_EXCEEDS BIT(7) -/* Different lane margin shifts */ -#define USB4_MARGIN_HW_RES_1_L0_LL_MARGIN_SHIFT 8 -#define USB4_MARGIN_HW_RES_1_L1_RH_MARGIN_SHIFT 16 -#define USB4_MARGIN_HW_RES_1_L1_LL_MARGIN_SHIFT 24 +#define USB4_MARGIN_HW_RES_MARGIN_MASK GENMASK(6, 0) +#define USB4_MARGIN_HW_RES_EXCEEDS BIT(7) + +/* Shifts for parsing the lane results */ +#define USB4_MARGIN_HW_RES_LANE_SHIFT 16 +#define USB4_MARGIN_HW_RES_LL_SHIFT 8 /* USB4_SB_OPCODE_RUN_SW_LANE_MARGINING */ #define USB4_MARGIN_SW_LANES_MASK GENMASK(2, 0) -#define USB4_MARGIN_SW_LANE_0 0x0 -#define USB4_MARGIN_SW_LANE_1 0x1 -#define USB4_MARGIN_SW_ALL_LANES 0x7 #define USB4_MARGIN_SW_TIME BIT(3) #define USB4_MARGIN_SW_RH BIT(4) #define USB4_MARGIN_SW_OPT_VOLTAGE BIT(5) #define USB4_MARGIN_SW_VT_MASK GENMASK(12, 6) #define USB4_MARGIN_SW_COUNTER_MASK GENMASK(14, 13) +#define USB4_MARGIN_SW_UPPER_EYE BIT(15) #define USB4_MARGIN_SW_ERR_COUNTER_LANE_0_MASK GENMASK(3, 0) #define USB4_MARGIN_SW_ERR_COUNTER_LANE_1_MASK GENMASK(7, 4) +#define USB4_MARGIN_SW_ERR_COUNTER_LANE_2_MASK GENMASK(11, 8) #endif diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 6737188f25815748118a0316e74092531e855343..ddbf0cd7837763c13dc0201ef8fb9288761e49d0 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1367,11 +1367,18 @@ enum usb4_margin_sw_error_counter { USB4_MARGIN_SW_ERROR_COUNTER_STOP, }; +enum usb4_margining_lane { + USB4_MARGINING_LANE_RX0 = 0, + USB4_MARGINING_LANE_RX1 = 1, + USB4_MARGINING_LANE_RX2 = 2, + USB4_MARGINING_LANE_ALL = 7, +}; + /** * struct usb4_port_margining_params - USB4 margining parameters * @error_counter: Error counter operation for software margining * @ber_level: Current BER level contour value - * @lanes: %0, %1 or %7 (all) + * @lanes: Lanes to enable for the margining operation * @voltage_time_offset: Offset for voltage / time for software margining * @optional_voltage_offset_range: Enable optional extended voltage range * @right_high: %false if left/low margin test is performed, %true if right/high @@ -1380,18 +1387,19 @@ enum usb4_margin_sw_error_counter { struct usb4_port_margining_params { enum usb4_margin_sw_error_counter error_counter; u32 ber_level; - u32 lanes; + enum usb4_margining_lane lanes; u32 voltage_time_offset; bool optional_voltage_offset_range; bool right_high; + bool upper_eye; bool time; }; int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, - u8 index, u32 *caps); + u8 index, u32 *caps, size_t ncaps); int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, u8 index, const struct usb4_port_margining_params *params, - u32 *results); + u32 *results, size_t nresults); int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target, u8 index, const struct usb4_port_margining_params *params, u32 *results); diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 402fdf8b1cdecaa49bcc39449437e588a0ddd5b4..e51d01671d8e7cb79494df458b7ecade04d3fce6 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1631,11 +1631,12 @@ int usb4_port_asym_start(struct tb_port *port) * @target: Sideband target * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER * @caps: Array with at least two elements to hold the results + * @ncaps: Number of elements in the caps array * * Reads the USB4 port lane margining capabilities into @caps. */ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, - u8 index, u32 *caps) + u8 index, u32 *caps, size_t ncaps) { int ret; @@ -1645,7 +1646,7 @@ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, return ret; return usb4_port_sb_read(port, target, index, USB4_SB_DATA, caps, - sizeof(*caps) * 2); + sizeof(*caps) * ncaps); } /** @@ -1654,14 +1655,15 @@ int usb4_port_margining_caps(struct tb_port *port, enum usb4_sb_target target, * @target: Sideband target * @index: Retimer index if taget is %USB4_SB_TARGET_RETIMER * @params: Parameters for USB4 hardware margining - * @results: Array with at least two elements to hold the results + * @results: Array to hold the results + * @nresults: Number of elements in the results array * * Runs hardware lane margining on USB4 port and returns the result in * @results. */ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, u8 index, const struct usb4_port_margining_params *params, - u32 *results) + u32 *results, size_t nresults) { u32 val; int ret; @@ -1672,8 +1674,8 @@ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, val = params->lanes; if (params->time) val |= USB4_MARGIN_HW_TIME; - if (params->right_high) - val |= USB4_MARGIN_HW_RH; + if (params->right_high || params->upper_eye) + val |= USB4_MARGIN_HW_RHU; if (params->ber_level) val |= FIELD_PREP(USB4_MARGIN_HW_BER_MASK, params->ber_level); if (params->optional_voltage_offset_range) @@ -1690,7 +1692,7 @@ int usb4_port_hw_margin(struct tb_port *port, enum usb4_sb_target target, return ret; return usb4_port_sb_read(port, target, index, USB4_SB_DATA, results, - sizeof(*results) * 2); + sizeof(*results) * nresults); } /** @@ -1722,6 +1724,8 @@ int usb4_port_sw_margin(struct tb_port *port, enum usb4_sb_target target, val |= USB4_MARGIN_SW_OPT_VOLTAGE; if (params->right_high) val |= USB4_MARGIN_SW_RH; + if (params->upper_eye) + val |= USB4_MARGIN_SW_UPPER_EYE; val |= FIELD_PREP(USB4_MARGIN_SW_COUNTER_MASK, params->error_counter); val |= FIELD_PREP(USB4_MARGIN_SW_VT_MASK, params->voltage_time_offset); diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 37164289277bf870adb112b9750a5857233c6d56..5af46442a792d4fb1e1fbf5d9db6ea106e02cb1a 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1585,7 +1585,7 @@ static void __exit amiga_serial_remove(struct platform_device *pdev) * triggering a section mismatch warning. */ static struct platform_driver amiga_serial_driver __refdata = { - .remove_new = __exit_p(amiga_serial_remove), + .remove = __exit_p(amiga_serial_remove), .driver = { .name = "amiga-serial", }, diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index c60745f8e621625a3d4ee2afdb653a3d5a74955c..3a958202900531b2860bd97f48e435b9a0e073a7 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -461,7 +461,7 @@ MODULE_DEVICE_TABLE(of, goldfish_tty_of_match); static struct platform_driver goldfish_tty_platform_driver = { .probe = goldfish_tty_probe, - .remove_new = goldfish_tty_remove, + .remove = goldfish_tty_remove, .driver = { .name = "goldfish_tty", .of_match_table = goldfish_tty_of_match, diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 095c33ad10f83cb14c87aeeeef33503674d5682e..b2ec1f6efa0a8a92b73c2bacc2bc5eb78c1955cf 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -247,7 +247,7 @@ static void hvc_opal_remove(struct platform_device *dev) static struct platform_driver hvc_opal_driver = { .probe = hvc_opal_probe, - .remove_new = hvc_opal_remove, + .remove = hvc_opal_remove, .driver = { .name = hvc_opal_name, .of_match_table = hvc_opal_match, diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 25c201cfb91e17fe95a432bcc4a96f0071478131..e5da9ce26006db4462c3d56b6d113c445a7413d5 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -569,7 +569,7 @@ static struct platform_driver aspeed_vuart_driver = { .of_match_table = aspeed_vuart_table, }, .probe = aspeed_vuart_probe, - .remove_new = aspeed_vuart_remove, + .remove = aspeed_vuart_remove, }; module_platform_driver(aspeed_vuart_driver); diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c index d7a0f271263a9325f707991e40514d61bff66b95..fdb53b54e99e60a00aab02d0785bb0e31beeee6b 100644 --- a/drivers/tty/serial/8250/8250_bcm2835aux.c +++ b/drivers/tty/serial/8250/8250_bcm2835aux.c @@ -267,7 +267,7 @@ static struct platform_driver bcm2835aux_serial_driver = { .pm = pm_ptr(&bcm2835aux_dev_pm_ops), }, .probe = bcm2835aux_serial_probe, - .remove_new = bcm2835aux_serial_remove, + .remove = bcm2835aux_serial_remove, }; module_platform_driver(bcm2835aux_serial_driver); diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index 2569ca69223f3ccf4441ec81684929384cb3a62c..d0b18358859e11f353d5b838cae18a390afe8c6e 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -812,7 +812,7 @@ static int brcmuart_handle_irq(struct uart_port *p) /* * if Receive Data Interrupt is enabled and * we're uing hardware flow control, deassert - * RTS and wait for any chars in the pipline to + * RTS and wait for any chars in the pipeline to * arrive and then check for DR again. */ if ((ier & UART_IER_RDI) && (up->mcr & UART_MCR_AFE)) { @@ -1204,7 +1204,7 @@ static struct platform_driver brcmuart_platform_driver = { .of_match_table = brcmuart_dt_ids, }, .probe = brcmuart_probe, - .remove_new = brcmuart_remove, + .remove = brcmuart_remove, }; static int __init brcmuart_init(void) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index ab9e7f20426025432d98632809552eef9b896cee..6afcf27db3b8880e75362941ac613dd7bc58c414 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -750,7 +750,7 @@ static const struct dw8250_platform_data dw8250_renesas_rzn1_data = { .quirks = DW_UART_QUIRK_CPR_VALUE | DW_UART_QUIRK_IS_DMA_FC, }; -static const struct dw8250_platform_data dw8250_starfive_jh7100_data = { +static const struct dw8250_platform_data dw8250_skip_set_rate_data = { .usr_reg = DW_UART_USR, .quirks = DW_UART_QUIRK_SKIP_SET_RATE, }; @@ -760,7 +760,8 @@ static const struct of_device_id dw8250_of_match[] = { { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data }, { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data }, { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data }, - { .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data }, + { .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data }, + { .compatible = "starfive,jh7100-uart", .data = &dw8250_skip_set_rate_data }, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, dw8250_of_match); @@ -796,7 +797,7 @@ static struct platform_driver dw8250_platform_driver = { .acpi_match_table = dw8250_acpi_match, }, .probe = dw8250_probe, - .remove_new = dw8250_remove, + .remove = dw8250_remove, }; module_platform_driver(dw8250_platform_driver); diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c index a754755100ffe1f11ca7ebfdb90d915e6c3a2187..35094f884492c7638327d9417ffc918f2a39910d 100644 --- a/drivers/tty/serial/8250/8250_em.c +++ b/drivers/tty/serial/8250/8250_em.c @@ -219,7 +219,7 @@ static struct platform_driver serial8250_em_platform_driver = { .of_match_table = serial8250_em_dt_ids, }, .probe = serial8250_em_probe, - .remove_new = serial8250_em_remove, + .remove = serial8250_em_remove, }; module_platform_driver(serial8250_em_platform_driver); diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index b7a75db15249a7c4f54eaa4ccef09a4c3c7f11d3..04a0cbab02c253938c0bd392a5630166defa676b 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -135,8 +136,6 @@ #define UART_EXAR_REGB_EECS BIT(5) #define UART_EXAR_REGB_EEDI BIT(6) #define UART_EXAR_REGB_EEDO BIT(7) -#define UART_EXAR_REGB_EE_ADDR_SIZE 6 -#define UART_EXAR_REGB_EE_DATA_SIZE 16 #define UART_EXAR_XR17C15X_PORT_OFFSET 0x200 #define UART_EXAR_XR17V25X_PORT_OFFSET 0x200 @@ -179,18 +178,19 @@ /* CTI EEPROM offsets */ #define CTI_EE_OFF_XR17C15X_OSC_FREQ 0x04 /* 2 words */ -#define CTI_EE_OFF_XR17V25X_OSC_FREQ 0x08 /* 2 words */ #define CTI_EE_OFF_XR17C15X_PART_NUM 0x0A /* 4 words */ -#define CTI_EE_OFF_XR17V25X_PART_NUM 0x0E /* 4 words */ #define CTI_EE_OFF_XR17C15X_SERIAL_NUM 0x0E /* 1 word */ + +#define CTI_EE_OFF_XR17V25X_OSC_FREQ 0x08 /* 2 words */ +#define CTI_EE_OFF_XR17V25X_PART_NUM 0x0E /* 4 words */ #define CTI_EE_OFF_XR17V25X_SERIAL_NUM 0x12 /* 1 word */ + #define CTI_EE_OFF_XR17V35X_SERIAL_NUM 0x11 /* 2 word */ #define CTI_EE_OFF_XR17V35X_BRD_FLAGS 0x13 /* 1 word */ #define CTI_EE_OFF_XR17V35X_PORT_FLAGS 0x14 /* 1 word */ #define CTI_EE_MASK_PORT_FLAGS_TYPE GENMASK(7, 0) -#define CTI_EE_MASK_OSC_FREQ_LOWER GENMASK(15, 0) -#define CTI_EE_MASK_OSC_FREQ_UPPER GENMASK(31, 16) +#define CTI_EE_MASK_OSC_FREQ GENMASK(31, 0) #define CTI_FPGA_RS485_IO_REG 0x2008 #define CTI_FPGA_CFG_INT_EN_REG 0x48 @@ -252,6 +252,7 @@ struct exar8250 { unsigned int nr; unsigned int osc_freq; struct exar8250_board *board; + struct eeprom_93cx6 eeprom; void __iomem *virt; int line[]; }; @@ -267,92 +268,37 @@ static inline u8 exar_read_reg(struct exar8250 *priv, unsigned int reg) return readb(priv->virt + reg); } -static inline void exar_ee_select(struct exar8250 *priv) -{ - // Set chip select pin high to enable EEPROM reads/writes - exar_write_reg(priv, UART_EXAR_REGB, UART_EXAR_REGB_EECS); - // Min ~500ns delay needed between CS assert and EEPROM access - udelay(1); -} - -static inline void exar_ee_deselect(struct exar8250 *priv) -{ - exar_write_reg(priv, UART_EXAR_REGB, 0x00); -} - -static inline void exar_ee_write_bit(struct exar8250 *priv, u8 bit) +static void exar_eeprom_93cx6_reg_read(struct eeprom_93cx6 *eeprom) { - u8 value = UART_EXAR_REGB_EECS; + struct exar8250 *priv = eeprom->data; + u8 regb = exar_read_reg(priv, UART_EXAR_REGB); - if (bit) - value |= UART_EXAR_REGB_EEDI; - - // Clock out the bit on the EEPROM interface - exar_write_reg(priv, UART_EXAR_REGB, value); - // 2us delay = ~500khz clock speed - udelay(2); - - value |= UART_EXAR_REGB_EECK; - - exar_write_reg(priv, UART_EXAR_REGB, value); - udelay(2); + /* EECK and EECS always read 0 from REGB so only set EEDO */ + eeprom->reg_data_out = regb & UART_EXAR_REGB_EEDO; } -static inline u8 exar_ee_read_bit(struct exar8250 *priv) +static void exar_eeprom_93cx6_reg_write(struct eeprom_93cx6 *eeprom) { - u8 regb; - u8 value = UART_EXAR_REGB_EECS; - - // Clock in the bit on the EEPROM interface - exar_write_reg(priv, UART_EXAR_REGB, value); - // 2us delay = ~500khz clock speed - udelay(2); + struct exar8250 *priv = eeprom->data; + u8 regb = 0; - value |= UART_EXAR_REGB_EECK; + if (eeprom->reg_data_in) + regb |= UART_EXAR_REGB_EEDI; + if (eeprom->reg_data_clock) + regb |= UART_EXAR_REGB_EECK; + if (eeprom->reg_chip_select) + regb |= UART_EXAR_REGB_EECS; - exar_write_reg(priv, UART_EXAR_REGB, value); - udelay(2); - - regb = exar_read_reg(priv, UART_EXAR_REGB); - - return (regb & UART_EXAR_REGB_EEDO ? 1 : 0); + exar_write_reg(priv, UART_EXAR_REGB, regb); } -/** - * exar_ee_read() - Read a word from the EEPROM - * @priv: Device's private structure - * @ee_addr: Offset of EEPROM to read word from - * - * Read a single 16bit word from an Exar UART's EEPROM. - * The type of the EEPROM is AT93C46D. - * - * Return: EEPROM word - */ -static u16 exar_ee_read(struct exar8250 *priv, u8 ee_addr) +static void exar_eeprom_init(struct exar8250 *priv) { - int i; - u16 data = 0; - - exar_ee_select(priv); - - // Send read command (opcode 110) - exar_ee_write_bit(priv, 1); - exar_ee_write_bit(priv, 1); - exar_ee_write_bit(priv, 0); - - // Send address to read from - for (i = UART_EXAR_REGB_EE_ADDR_SIZE - 1; i >= 0; i--) - exar_ee_write_bit(priv, ee_addr & BIT(i)); - - // Read data 1 bit at a time starting with a dummy bit - for (i = UART_EXAR_REGB_EE_DATA_SIZE; i >= 0; i--) { - if (exar_ee_read_bit(priv)) - data |= BIT(i); - } - - exar_ee_deselect(priv); - - return data; + priv->eeprom.data = priv; + priv->eeprom.register_read = exar_eeprom_93cx6_reg_read; + priv->eeprom.register_write = exar_eeprom_93cx6_reg_write; + priv->eeprom.width = PCI_EEPROM_WIDTH_93C46; + priv->eeprom.quirks |= PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE; } /** @@ -360,7 +306,7 @@ static u16 exar_ee_read(struct exar8250 *priv, u8 ee_addr) * @priv: Device's private structure * @mpio_num: MPIO number/offset to configure * - * Configure a single MPIO as an output and disable tristate. It is reccomended + * Configure a single MPIO as an output and disable tristate. It is recommended * to set the level with exar_mpio_set_high()/exar_mpio_set_low() prior to * calling this function to ensure default MPIO pin state. * @@ -516,7 +462,7 @@ static int xr17v35x_startup(struct uart_port *port) serial_port_out(port, UART_XR_EFR, UART_EFR_ECB); /* - * Make sure all interrups are masked until initialization is + * Make sure all interrupts are masked until initialization is * complete and the FIFOs are cleared * * Synchronize UART_IER access against the console. @@ -696,20 +642,16 @@ static int cti_plx_int_enable(struct exar8250 *priv) */ static int cti_read_osc_freq(struct exar8250 *priv, u8 eeprom_offset) { - u16 lower_word; - u16 upper_word; + __le16 ee_words[2]; + u32 osc_freq; - lower_word = exar_ee_read(priv, eeprom_offset); - // Check if EEPROM word was blank - if (lower_word == 0xFFFF) - return -EIO; + eeprom_93cx6_multiread(&priv->eeprom, eeprom_offset, ee_words, ARRAY_SIZE(ee_words)); - upper_word = exar_ee_read(priv, (eeprom_offset + 1)); - if (upper_word == 0xFFFF) + osc_freq = le16_to_cpu(ee_words[0]) | (le16_to_cpu(ee_words[1]) << 16); + if (osc_freq == CTI_EE_MASK_OSC_FREQ) return -EIO; - return FIELD_PREP(CTI_EE_MASK_OSC_FREQ_LOWER, lower_word) | - FIELD_PREP(CTI_EE_MASK_OSC_FREQ_UPPER, upper_word); + return osc_freq; } /** @@ -833,7 +775,7 @@ static enum cti_port_type cti_get_port_type_xr17v35x(struct exar8250 *priv, u8 offset; offset = CTI_EE_OFF_XR17V35X_PORT_FLAGS + port_num; - port_flags = exar_ee_read(priv, offset); + eeprom_93cx6_read(&priv->eeprom, offset, &port_flags); port_type = FIELD_GET(CTI_EE_MASK_PORT_FLAGS_TYPE, port_flags); if (CTI_PORT_TYPE_VALID(port_type)) @@ -1551,6 +1493,8 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) if (rc) return rc; + exar_eeprom_init(priv); + for (i = 0; i < nr_ports && i < maxnr; i++) { rc = board->setup(priv, pcidev, &uart, i); if (rc) { @@ -1786,7 +1730,7 @@ static struct pci_driver exar_pci_driver = { }; module_pci_driver(exar_pci_driver); -MODULE_IMPORT_NS(SERIAL_8250_PCI); +MODULE_IMPORT_NS("SERIAL_8250_PCI"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Exar Serial Driver"); MODULE_AUTHOR("Sudip Mukherjee "); diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index e2aa2a1a02ddf53997fb7425a216a7df3d8f517e..b4461a89b8d0caa56939dd85fc1947d2fba43988 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c @@ -21,6 +21,7 @@ #define CHIP_ID_F81866 0x1010 #define CHIP_ID_F81966 0x0215 #define CHIP_ID_F81216AD 0x1602 +#define CHIP_ID_F81216E 0x1617 #define CHIP_ID_F81216H 0x0501 #define CHIP_ID_F81216 0x0802 #define VENDOR_ID1 0x23 @@ -125,7 +126,7 @@ static int fintek_8250_enter_key(u16 base_port, u8 key) if (!request_muxed_region(base_port, 2, "8250_fintek")) return -EBUSY; - /* Force to deactive all SuperIO in this base_port */ + /* Force to deactivate all SuperIO in this base_port */ outb(EXIT_KEY, base_port + ADDR_PORT); outb(key, base_port + ADDR_PORT); @@ -158,6 +159,7 @@ static int fintek_8250_check_id(struct fintek_8250 *pdata) case CHIP_ID_F81866: case CHIP_ID_F81966: case CHIP_ID_F81216AD: + case CHIP_ID_F81216E: case CHIP_ID_F81216H: case CHIP_ID_F81216: break; @@ -181,6 +183,7 @@ static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min, return 0; case CHIP_ID_F81216AD: + case CHIP_ID_F81216E: case CHIP_ID_F81216H: case CHIP_ID_F81216: *min = F81216_LDN_LOW; @@ -250,6 +253,7 @@ static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level) break; case CHIP_ID_F81216AD: + case CHIP_ID_F81216E: case CHIP_ID_F81216H: case CHIP_ID_F81216: sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE, @@ -263,7 +267,8 @@ static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level) static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata) { switch (pdata->pid) { - case CHIP_ID_F81216H: /* 128Bytes FIFO */ + case CHIP_ID_F81216E: /* 128Bytes FIFO */ + case CHIP_ID_F81216H: case CHIP_ID_F81966: case CHIP_ID_F81866: sio_write_mask_reg(pdata, FIFO_CTRL, @@ -297,6 +302,7 @@ static void fintek_8250_set_termios(struct uart_port *port, goto exit; switch (pdata->pid) { + case CHIP_ID_F81216E: case CHIP_ID_F81216H: reg = RS485; break; @@ -346,6 +352,7 @@ static void fintek_8250_set_termios_handler(struct uart_8250_port *uart) struct fintek_8250 *pdata = uart->port.private_data; switch (pdata->pid) { + case CHIP_ID_F81216E: case CHIP_ID_F81216H: case CHIP_ID_F81966: case CHIP_ID_F81866: @@ -438,6 +445,11 @@ static void fintek_8250_set_rs485_handler(struct uart_8250_port *uart) uart->port.rs485_supported = fintek_8250_rs485_supported; break; + case CHIP_ID_F81216E: /* F81216E does not support RS485 delays */ + uart->port.rs485_config = fintek_8250_rs485_config; + uart->port.rs485_supported = fintek_8250_rs485_supported; + break; + default: /* No RS485 Auto direction functional */ break; } diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index b4ed442082a8521b61ec6d87cc01864a3e9a475e..1b7bd55619c660a1e8137b267267435b8e7a69a9 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -179,7 +179,7 @@ static struct platform_driver fsl8250_platform_driver = { .acpi_match_table = ACPI_PTR(fsl_8250_acpi_id), }, .probe = fsl8250_acpi_probe, - .remove_new = fsl8250_acpi_remove, + .remove = fsl8250_acpi_remove, }; module_platform_driver(fsl8250_platform_driver); diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index a2783e38a2e31641c50667df086ecfad27df34bf..a73dd3773640484757e15e9c3fa372afbd8c0384 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -361,7 +361,7 @@ static struct platform_driver ingenic_uart_platform_driver = { .of_match_table = of_match, }, .probe = ingenic_uart_probe, - .remove_new = ingenic_uart_remove, + .remove = ingenic_uart_remove, }; module_platform_driver(ingenic_uart_platform_driver); diff --git a/drivers/tty/serial/8250/8250_ioc3.c b/drivers/tty/serial/8250/8250_ioc3.c index 50c77c3dacf2c809dd1785e54a363c5381d605b9..499e80aa4cf96b4e059c30db46780db086f39799 100644 --- a/drivers/tty/serial/8250/8250_ioc3.c +++ b/drivers/tty/serial/8250/8250_ioc3.c @@ -84,7 +84,7 @@ static void serial8250_ioc3_remove(struct platform_device *pdev) static struct platform_driver serial8250_ioc3_driver = { .probe = serial8250_ioc3_probe, - .remove_new = serial8250_ioc3_remove, + .remove = serial8250_ioc3_remove, .driver = { .name = "ioc3-serial8250", } diff --git a/drivers/tty/serial/8250/8250_lpc18xx.c b/drivers/tty/serial/8250/8250_lpc18xx.c index 47e1a056a60c34b49f37dc4aa0f0c3963bf78bef..d52445948da0b85ddf9af97d92b5bb8c0d90f206 100644 --- a/drivers/tty/serial/8250/8250_lpc18xx.c +++ b/drivers/tty/serial/8250/8250_lpc18xx.c @@ -195,7 +195,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_serial_match); static struct platform_driver lpc18xx_serial_driver = { .probe = lpc18xx_serial_probe, - .remove_new = lpc18xx_serial_remove, + .remove = lpc18xx_serial_remove, .driver = { .name = "lpc18xx-uart", .of_match_table = lpc18xx_serial_match, diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index dc9e093b1cb31183bd925db0ec7fa1ef0314b7b1..a78ef35c81877e17f6166c770a6593b350f0fe60 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -271,4 +271,4 @@ MODULE_AUTHOR("Michael Moese private_data; + pm_runtime_get_sync(port->dev); + flush_work(&priv->qos_work); if (up->dma) omap_8250_rx_dma_flush(up); - pm_runtime_get_sync(port->dev); - serial_out(up, UART_OMAP_WER, 0); if (priv->habit & UART_HAS_EFR2) serial_out(up, UART_OMAP_EFR2, 0x0); @@ -1304,7 +1304,7 @@ static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, /* * This is mostly serial8250_handle_irq(). We have a slightly different DMA - * hoook for RX/TX and need different logic for them in the ISR. Therefore we + * hook for RX/TX and need different logic for them in the ISR. Therefore we * use the default routine in the non-DMA case and this one for with DMA. */ static int omap_8250_dma_handle_irq(struct uart_port *port) @@ -1338,7 +1338,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) serial8250_tx_chars(up); } else { /* - * try again due to an earlier failer which + * try again due to an earlier failure which * might have been resolved by now. */ if (omap_8250_tx_dma(up)) @@ -1867,7 +1867,7 @@ static struct platform_driver omap8250_platform_driver = { .of_match_table = omap8250_dt_ids, }, .probe = omap8250_probe, - .remove_new = omap8250_remove, + .remove = omap8250_remove, }; module_platform_driver(omap8250_platform_driver); diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 7d7a6d62c09ceabcf4094d539c565ed09c153561..3c3f7c926afb87419bad5dd8d0249b1ed5a02c66 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -6180,4 +6180,4 @@ module_pci_driver(serial_pci_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); MODULE_DEVICE_TABLE(pci, serial_pci_tbl); -MODULE_IMPORT_NS(SERIAL_8250_PCI); +MODULE_IMPORT_NS("SERIAL_8250_PCI"); diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c b/drivers/tty/serial/8250/8250_pci1xxxx.c index d3930bf32fe4c4caf6ec8e16dc3628df498250e2..838f181f929bf0f72dd3077938c93a28835eb755 100644 --- a/drivers/tty/serial/8250/8250_pci1xxxx.c +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c @@ -812,7 +812,7 @@ module_pci_driver(pci1xxxx_pci_driver); static_assert((ARRAY_SIZE(logical_to_physical_port_idx) == PCI_SUBDEVICE_ID_EFAR_PCI1XXXX_1p3 + 1)); -MODULE_IMPORT_NS(SERIAL_8250_PCI); +MODULE_IMPORT_NS("SERIAL_8250_PCI"); MODULE_DESCRIPTION("Microchip Technology Inc. PCIe to UART module"); MODULE_AUTHOR("Kumaravel Thiagarajan "); MODULE_AUTHOR("Tharun Kumar P "); diff --git a/drivers/tty/serial/8250/8250_pcilib.c b/drivers/tty/serial/8250/8250_pcilib.c index 3bdccf76f71d6a7de5a66e388fe2b9d88349086d..d8d0ae0d72387c210b1ac80427ddaa20e037e91d 100644 --- a/drivers/tty/serial/8250/8250_pcilib.c +++ b/drivers/tty/serial/8250/8250_pcilib.c @@ -19,7 +19,7 @@ int serial_8250_warn_need_ioport(struct pci_dev *dev) return -ENXIO; } -EXPORT_SYMBOL_NS_GPL(serial_8250_warn_need_ioport, SERIAL_8250_PCI); +EXPORT_SYMBOL_NS_GPL(serial_8250_warn_need_ioport, "SERIAL_8250_PCI"); int serial8250_pci_setup_port(struct pci_dev *dev, struct uart_8250_port *port, u8 bar, unsigned int offset, int regshift) @@ -47,6 +47,6 @@ int serial8250_pci_setup_port(struct pci_dev *dev, struct uart_8250_port *port, } return 0; } -EXPORT_SYMBOL_NS_GPL(serial8250_pci_setup_port, SERIAL_8250_PCI); +EXPORT_SYMBOL_NS_GPL(serial8250_pci_setup_port, "SERIAL_8250_PCI"); MODULE_DESCRIPTION("8250 PCI library"); MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/8250/8250_platform.c b/drivers/tty/serial/8250/8250_platform.c index be7ff07cbdd009514c5283ec4a025d7d56b361d8..8bdc1879d952be58dfd0095a85a25d9d17ae9602 100644 --- a/drivers/tty/serial/8250/8250_platform.c +++ b/drivers/tty/serial/8250/8250_platform.c @@ -285,7 +285,7 @@ MODULE_DEVICE_TABLE(acpi, acpi_platform_serial_table); static struct platform_driver serial8250_isa_driver = { .probe = serial8250_probe, - .remove_new = serial8250_remove, + .remove = serial8250_remove, .suspend = serial8250_suspend, .resume = serial8250_resume, .driver = { diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c index 96dd6126296c6d328e363d772ee4849fc0fd9243..6dd0190b4843b42fbafb925381e8c3f6d4e695ae 100644 --- a/drivers/tty/serial/8250/8250_pxa.c +++ b/drivers/tty/serial/8250/8250_pxa.c @@ -154,7 +154,7 @@ static void serial_pxa_remove(struct platform_device *pdev) static struct platform_driver serial_pxa_driver = { .probe = serial_pxa_probe, - .remove_new = serial_pxa_remove, + .remove = serial_pxa_remove, .driver = { .name = "pxa2xx-uart", diff --git a/drivers/tty/serial/8250/8250_tegra.c b/drivers/tty/serial/8250/8250_tegra.c index 60a80d00d2519b600dfb4fb635f2f1e33551adad..2f3b0075763f28db4fe7e997230f78688d1f2988 100644 --- a/drivers/tty/serial/8250/8250_tegra.c +++ b/drivers/tty/serial/8250/8250_tegra.c @@ -182,7 +182,7 @@ static struct platform_driver tegra_uart_driver = { .acpi_match_table = ACPI_PTR(tegra_uart_acpi_match), }, .probe = tegra_uart_probe, - .remove_new = tegra_uart_remove, + .remove = tegra_uart_remove, }; module_platform_driver(tegra_uart_driver); diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index 670d2ca0f7572948384c67a49855cd96464447c1..4874a9632db391e48f47326fdbeff93442259302 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c @@ -282,7 +282,7 @@ MODULE_DEVICE_TABLE(of, uniphier_uart_match); static struct platform_driver uniphier_uart_platform_driver = { .probe = uniphier_uart_probe, - .remove_new = uniphier_uart_remove, + .remove = uniphier_uart_remove, .driver = { .name = "uniphier-uart", .of_match_table = uniphier_uart_match, diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 1eb20350fcf432d41cb416bed3be72ed8ab129bb..55d26d16df9b94ae577ee3705567e444ad10f3a5 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -150,6 +150,7 @@ config SERIAL_8250_EXAR tristate "8250/16550 Exar/Commtech PCI/PCIe device support" depends on SERIAL_8250 && PCI select SERIAL_8250_PCILIB + select EEPROM_93CX6 default SERIAL_8250 help This builds support for XR17C1xx, XR17V3xx and some Commtech diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index effcba71ea775ab0d5f0f6d48576b0110844a7db..b9c3c3bed0c170cddadc13916224331d5d7be40b 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -175,8 +175,8 @@ static int altera_jtaguart_startup(struct uart_port *port) ret = request_irq(port->irq, altera_jtaguart_interrupt, 0, DRV_NAME, port); if (ret) { - pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d " - "interrupt vector=%d\n", port->line, port->irq); + dev_err(port->dev, "unable to attach Altera JTAG UART %d interrupt vector=%d\n", + port->line, port->irq); return ret; } @@ -449,7 +449,7 @@ MODULE_DEVICE_TABLE(of, altera_jtaguart_match); static struct platform_driver altera_jtaguart_platform_driver = { .probe = altera_jtaguart_probe, - .remove_new = altera_jtaguart_remove, + .remove = altera_jtaguart_remove, .driver = { .name = DRV_NAME, .of_match_table = of_match_ptr(altera_jtaguart_match), diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 897f0995b2fe77b0827be4a2221c7abec6f57f06..c94655453c3353955f929afc0277f090dbb51254 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -307,8 +307,8 @@ static int altera_uart_startup(struct uart_port *port) ret = request_irq(port->irq, altera_uart_interrupt, 0, dev_name(port->dev), port); if (ret) { - pr_err(DRV_NAME ": unable to attach Altera UART %d " - "interrupt vector=%d\n", port->line, port->irq); + dev_err(port->dev, "unable to attach Altera UART %d interrupt vector=%d\n", + port->line, port->irq); return ret; } } @@ -617,7 +617,7 @@ MODULE_DEVICE_TABLE(of, altera_uart_match); static struct platform_driver altera_uart_platform_driver = { .probe = altera_uart_probe, - .remove_new = altera_uart_remove, + .remove = altera_uart_remove, .driver = { .name = DRV_NAME, .of_match_table = of_match_ptr(altera_uart_match), diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 1c60850030b14b57276077e0140381eb37cc8825..69b7a3e1e418e200944b0b0429b6341d71ecff26 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1819,6 +1819,13 @@ static void pl011_unthrottle_rx(struct uart_port *port) pl011_write(uap->im, uap, REG_IMSC); +#ifdef CONFIG_DMA_ENGINE + if (uap->using_rx_dma) { + uap->dmacr |= UART011_RXDMAE; + pl011_write(uap->dmacr, uap, REG_DMACR); + } +#endif + uart_port_unlock_irqrestore(&uap->port, flags); } @@ -2937,7 +2944,7 @@ MODULE_DEVICE_TABLE(acpi, sbsa_uart_acpi_match); static struct platform_driver arm_sbsa_uart_platform_driver = { .probe = sbsa_uart_probe, - .remove_new = sbsa_uart_remove, + .remove = sbsa_uart_remove, .driver = { .name = "sbsa-uart", .pm = &pl011_dev_pm_ops, diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 47889a557119885690ee055e2bdcb616b0bcc930..8bb33556b31208a1707ca7a48db0aa2ca81452bd 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -832,7 +832,7 @@ MODULE_DEVICE_TABLE(of, ar933x_uart_of_ids); static struct platform_driver ar933x_uart_platform_driver = { .probe = ar933x_uart_probe, - .remove_new = ar933x_uart_remove, + .remove = ar933x_uart_remove, .driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(ar933x_uart_of_ids), diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 09b246c9e389ecf791c818b180e216f99df7de26..0cf05ac189938306f0374bb650ca8d3d45d4913d 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1166,7 +1166,7 @@ static void atmel_rx_from_dma(struct uart_port *port) port->icount.rx += count; } - /* USART retreives ownership of RX DMA buffer */ + /* USART retrieves ownership of RX DMA buffer */ dma_sync_single_for_device(port->dev, atmel_port->rx_phys, ATMEL_SERIAL_RX_SIZE, DMA_FROM_DEVICE); @@ -2419,17 +2419,11 @@ static void atmel_release_port(struct uart_port *port) static int atmel_request_port(struct uart_port *port) { struct platform_device *mpdev = to_platform_device(port->dev->parent); - int size = resource_size(mpdev->resource); - - if (!request_mem_region(port->mapbase, size, "atmel_serial")) - return -EBUSY; if (port->flags & UPF_IOREMAP) { - port->membase = ioremap(port->mapbase, size); - if (port->membase == NULL) { - release_mem_region(port->mapbase, size); - return -ENOMEM; - } + port->membase = devm_platform_ioremap_resource(mpdev, 0); + if (IS_ERR(port->membase)) + return PTR_ERR(port->membase); } return 0; @@ -3017,7 +3011,7 @@ static SIMPLE_DEV_PM_OPS(atmel_serial_pm_ops, atmel_serial_suspend, static struct platform_driver atmel_serial_driver = { .probe = atmel_serial_probe, - .remove_new = atmel_serial_remove, + .remove = atmel_serial_remove, .driver = { .name = "atmel_usart_serial", .of_match_table = of_match_ptr(atmel_serial_dt_ids), diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index b88cc28c94e33711be426201157f7e905b9e09ff..51df9d2d8bfc5470b21762e920587b8a5b17ac68 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -884,7 +884,7 @@ MODULE_DEVICE_TABLE(of, bcm63xx_of_match); */ static struct platform_driver bcm_uart_platform_driver = { .probe = bcm_uart_probe, - .remove_new = bcm_uart_remove, + .remove = bcm_uart_remove, .driver = { .name = "bcm63xx_uart", .of_match_table = bcm63xx_of_match, diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 30425a3d19fbe04e3b544a5bdb2b3a216fd84ad2..83186bf50002722d8d448679ad1dfee883fac5bb 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -529,7 +529,7 @@ static struct platform_driver clps711x_uart_platform = { .of_match_table = of_match_ptr(clps711x_uart_dt_ids), }, .probe = uart_clps711x_probe, - .remove_new = uart_clps711x_remove, + .remove = uart_clps711x_remove, }; static int __init uart_clps711x_init(void) diff --git a/drivers/tty/serial/cpm_uart.c b/drivers/tty/serial/cpm_uart.c index 6eb8625de435ebae78d54420cfc34353276efeef..b778a20ec9b13db69bb46cd9199a772a87d7595a 100644 --- a/drivers/tty/serial/cpm_uart.c +++ b/drivers/tty/serial/cpm_uart.c @@ -1573,7 +1573,7 @@ static struct platform_driver cpm_uart_driver = { .of_match_table = cpm_uart_match, }, .probe = cpm_uart_probe, - .remove_new = cpm_uart_remove, + .remove = cpm_uart_remove, }; static int __init cpm_uart_init(void) diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index 2ccd13cc0a899f589bd5b80cc70081c3d053ff62..d2482df5cb9b469c5c85df399ecb18049ee0297c 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c @@ -522,7 +522,7 @@ static struct platform_driver digicolor_uart_platform = { .of_match_table = of_match_ptr(digicolor_uart_dt_ids), }, .probe = digicolor_uart_probe, - .remove_new = digicolor_uart_remove, + .remove = digicolor_uart_remove, }; static int __init digicolor_uart_init(void) diff --git a/drivers/tty/serial/esp32_acm.c b/drivers/tty/serial/esp32_acm.c index 85eb0392e3793525eda2d62864703369e3c761ac..bb7cc65427f0b756ecc535a7cfd468aab472e867 100644 --- a/drivers/tty/serial/esp32_acm.c +++ b/drivers/tty/serial/esp32_acm.c @@ -423,7 +423,7 @@ static void esp32s3_acm_remove(struct platform_device *pdev) static struct platform_driver esp32s3_acm_driver = { .probe = esp32s3_acm_probe, - .remove_new = esp32s3_acm_remove, + .remove = esp32s3_acm_remove, .driver = { .name = DRIVER_NAME, .of_match_table = esp32s3_acm_dt_ids, diff --git a/drivers/tty/serial/esp32_uart.c b/drivers/tty/serial/esp32_uart.c index 8c86cf9cb7630cbc884f87ed595f7aea54d6fdb8..667c2198a03a51e9b88fa760868a123601994897 100644 --- a/drivers/tty/serial/esp32_uart.c +++ b/drivers/tty/serial/esp32_uart.c @@ -743,7 +743,7 @@ static void esp32_uart_remove(struct platform_device *pdev) static struct platform_driver esp32_uart_driver = { .probe = esp32_uart_probe, - .remove_new = esp32_uart_remove, + .remove = esp32_uart_remove, .driver = { .name = DRIVER_NAME, .of_match_table = esp32_uart_dt_ids, diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c index e972df4b188d3b061606f42cbbeb9cdc1ec36ca9..e70a56de1fcedb2f53d4503d2236934a580df8aa 100644 --- a/drivers/tty/serial/fsl_linflexuart.c +++ b/drivers/tty/serial/fsl_linflexuart.c @@ -882,7 +882,7 @@ static SIMPLE_DEV_PM_OPS(linflex_pm_ops, linflex_suspend, linflex_resume); static struct platform_driver linflex_driver = { .probe = linflex_probe, - .remove_new = linflex_remove, + .remove = linflex_remove, .driver = { .name = DRIVER_NAME, .of_match_table = linflex_dt_ids, diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 77efa7ee6eda29aa9a1d92740430327ffe416eb8..57b0632a3db6fbf31c8ae07682a89c9d31f7eb8d 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -184,6 +184,7 @@ #define UARTCTRL_SBK 0x00010000 #define UARTCTRL_MA1IE 0x00008000 #define UARTCTRL_MA2IE 0x00004000 +#define UARTCTRL_M7 0x00000800 #define UARTCTRL_IDLECFG GENMASK(10, 8) #define UARTCTRL_LOOPS 0x00000080 #define UARTCTRL_DOZEEN 0x00000040 @@ -2222,8 +2223,9 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, modem = lpuart32_read(&sport->port, UARTMODIR); sport->is_cs7 = false; /* - * only support CS8 and CS7, and for CS7 must enable PE. + * only support CS8 and CS7 * supported mode: + * - (7,n,1) (imx only) * - (7,e/o,1) * - (8,n,1) * - (8,m/s,1) @@ -2238,7 +2240,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & CSIZE) == CS8 || (termios->c_cflag & CSIZE) == CS7) - ctrl = old_ctrl & ~UARTCTRL_M; + ctrl = old_ctrl & ~(UARTCTRL_M | UARTCTRL_M7); if (termios->c_cflag & CMSPAR) { if ((termios->c_cflag & CSIZE) != CS8) { @@ -2265,9 +2267,18 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, else bd &= ~UARTBAUD_SBNS; - /* parity must be enabled when CS7 to match 8-bits format */ - if ((termios->c_cflag & CSIZE) == CS7) - termios->c_cflag |= PARENB; + /* + * imx support 7-bits format, no limitation on parity when CS7 + * for layerscape, parity must be enabled when CS7 to match 8-bits format + */ + if ((termios->c_cflag & CSIZE) == CS7 && !(termios->c_cflag & PARENB)) { + if (is_imx7ulp_lpuart(sport) || + is_imx8ulp_lpuart(sport) || + is_imx8qxp_lpuart(sport)) + ctrl |= UARTCTRL_M7; + else + termios->c_cflag |= PARENB; + } if ((termios->c_cflag & PARENB)) { if (termios->c_cflag & CMSPAR) { @@ -3206,7 +3217,7 @@ static const struct dev_pm_ops lpuart_pm_ops = { static struct platform_driver lpuart_driver = { .probe = lpuart_probe, - .remove_new = lpuart_remove, + .remove = lpuart_remove, .driver = { .name = "fsl-lpuart", .of_match_table = lpuart_dt_ids, diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 90974d338f3c0bfd6b1ed8459540aab205046c89..17f70e4bee4358a64f17c6e4bf375798f3689ca2 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -230,6 +230,8 @@ struct imx_port { unsigned int saved_reg[10]; bool context_saved; + bool last_putchar_was_newline; + enum imx_tx_state tx_state; struct hrtimer trigger_start_tx; struct hrtimer trigger_stop_tx; @@ -370,6 +372,7 @@ static void imx_uart_soft_reset(struct imx_port *sport) sport->idle_counter = 0; } +/* called with port.lock taken and irqs off */ static void imx_uart_disable_loopback_rs485(struct imx_port *sport) { unsigned int uts; @@ -470,6 +473,7 @@ static void imx_uart_stop_tx(struct uart_port *port) } } +/* called with port.lock taken and irqs off */ static void imx_uart_stop_rx_with_loopback_ctrl(struct uart_port *port, bool loopback) { struct imx_port *sport = to_imx_port(port); @@ -818,6 +822,8 @@ static irqreturn_t imx_uart_txint(int irq, void *dev_id) * issuing soft reset to the UART (just stop/start of RX does not help). Note * that what we do here is sending isolated start bit about 2.4 times shorter * than it is to be on UART configured baud rate. + * + * Called with port.lock taken and irqs off. */ static void imx_uart_check_flood(struct imx_port *sport, u32 usr2) { @@ -853,6 +859,7 @@ static void imx_uart_check_flood(struct imx_port *sport, u32 usr2) } } +/* called with port.lock taken and irqs off */ static irqreturn_t __imx_uart_rxint(int irq, void *dev_id) { struct imx_port *sport = dev_id; @@ -931,6 +938,7 @@ static void imx_uart_clear_rx_errors(struct imx_port *sport); /* * We have a modem side uart, so the meanings of RTS and CTS are inverted. */ +/* called with port.lock taken and irqs off */ static unsigned int imx_uart_get_hwmctrl(struct imx_port *sport) { unsigned int tmp = TIOCM_DSR; @@ -953,6 +961,8 @@ static unsigned int imx_uart_get_hwmctrl(struct imx_port *sport) /* * Handle any change of modem status signal since we were last called. + * + * Called with port.lock taken and irqs off. */ static void imx_uart_mctrl_check(struct imx_port *sport) { @@ -1292,6 +1302,7 @@ static int imx_uart_start_rx_dma(struct imx_port *sport) return 0; } +/* called with port.lock taken and irqs off */ static void imx_uart_clear_rx_errors(struct imx_port *sport) { struct tty_port *port = &sport->port.state->port; @@ -1422,6 +1433,7 @@ err: return ret; } +/* called with port.lock taken and irqs off */ static void imx_uart_enable_dma(struct imx_port *sport) { u32 ucr1; @@ -2069,26 +2081,34 @@ static void imx_uart_console_putchar(struct uart_port *port, unsigned char ch) barrier(); imx_uart_writel(sport, ch, URTX0); + + sport->last_putchar_was_newline = (ch == '\n'); } -/* - * Interrupts are disabled on entering - */ -static void -imx_uart_console_write(struct console *co, const char *s, unsigned int count) +static void imx_uart_console_device_lock(struct console *co, unsigned long *flags) +{ + struct uart_port *up = &imx_uart_ports[co->index]->port; + + return __uart_port_lock_irqsave(up, flags); +} + +static void imx_uart_console_device_unlock(struct console *co, unsigned long flags) +{ + struct uart_port *up = &imx_uart_ports[co->index]->port; + + return __uart_port_unlock_irqrestore(up, flags); +} + +static void imx_uart_console_write_atomic(struct console *co, + struct nbcon_write_context *wctxt) { struct imx_port *sport = imx_uart_ports[co->index]; + struct uart_port *port = &sport->port; struct imx_port_ucrs old_ucr; - unsigned long flags; unsigned int ucr1, usr2; - int locked = 1; - if (sport->port.sysrq) - locked = 0; - else if (oops_in_progress) - locked = uart_port_trylock_irqsave(&sport->port, &flags); - else - uart_port_lock_irqsave(&sport->port, &flags); + if (!nbcon_enter_unsafe(wctxt)) + return; /* * First, save UCR1/2/3 and then disable interrupts @@ -2102,10 +2122,12 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN); imx_uart_writel(sport, ucr1, UCR1); - imx_uart_writel(sport, old_ucr.ucr2 | UCR2_TXEN, UCR2); - uart_console_write(&sport->port, s, count, imx_uart_console_putchar); + if (!sport->last_putchar_was_newline) + uart_console_write(port, "\n", 1, imx_uart_console_putchar); + uart_console_write(port, wctxt->outbuf, wctxt->len, + imx_uart_console_putchar); /* * Finally, wait for transmitter to become empty @@ -2115,8 +2137,73 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) 0, USEC_PER_SEC, false, sport, USR2); imx_uart_ucrs_restore(sport, &old_ucr); - if (locked) - uart_port_unlock_irqrestore(&sport->port, flags); + nbcon_exit_unsafe(wctxt); +} + +static void imx_uart_console_write_thread(struct console *co, + struct nbcon_write_context *wctxt) +{ + struct imx_port *sport = imx_uart_ports[co->index]; + struct uart_port *port = &sport->port; + struct imx_port_ucrs old_ucr; + unsigned int ucr1, usr2; + + if (!nbcon_enter_unsafe(wctxt)) + return; + + /* + * First, save UCR1/2/3 and then disable interrupts + */ + imx_uart_ucrs_save(sport, &old_ucr); + ucr1 = old_ucr.ucr1; + + if (imx_uart_is_imx1(sport)) + ucr1 |= IMX1_UCR1_UARTCLKEN; + ucr1 |= UCR1_UARTEN; + ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN); + + imx_uart_writel(sport, ucr1, UCR1); + imx_uart_writel(sport, old_ucr.ucr2 | UCR2_TXEN, UCR2); + + if (nbcon_exit_unsafe(wctxt)) { + int len = READ_ONCE(wctxt->len); + int i; + + /* + * Write out the message. Toggle unsafe for each byte in order + * to give another (higher priority) context the opportunity + * for a friendly takeover. If such a takeover occurs, this + * context must reacquire ownership in order to perform final + * actions (such as re-enabling the interrupts). + * + * IMPORTANT: wctxt->outbuf and wctxt->len are no longer valid + * after a reacquire so writing the message must be + * aborted. + */ + for (i = 0; i < len; i++) { + if (!nbcon_enter_unsafe(wctxt)) + break; + + uart_console_write(port, wctxt->outbuf + i, 1, + imx_uart_console_putchar); + + if (!nbcon_exit_unsafe(wctxt)) + break; + } + } + + while (!nbcon_enter_unsafe(wctxt)) + nbcon_reacquire_nobuf(wctxt); + + /* + * Finally, wait for transmitter to become empty + * and restore UCR1/2/3 + */ + read_poll_timeout(imx_uart_readl, usr2, usr2 & USR2_TXDC, + 0, USEC_PER_SEC, false, sport, USR2); + imx_uart_ucrs_restore(sport, &old_ucr); + + nbcon_exit_unsafe(wctxt); } /* @@ -2208,6 +2295,8 @@ imx_uart_console_setup(struct console *co, char *options) if (retval) goto error_console; + sport->last_putchar_was_newline = true; + if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else @@ -2244,11 +2333,14 @@ imx_uart_console_exit(struct console *co) static struct uart_driver imx_uart_uart_driver; static struct console imx_uart_console = { .name = DEV_NAME, - .write = imx_uart_console_write, + .write_atomic = imx_uart_console_write_atomic, + .write_thread = imx_uart_console_write_thread, + .device_lock = imx_uart_console_device_lock, + .device_unlock = imx_uart_console_device_unlock, + .flags = CON_PRINTBUFFER | CON_NBCON, .device = uart_console_device, .setup = imx_uart_console_setup, .exit = imx_uart_console_exit, - .flags = CON_PRINTBUFFER, .index = -1, .data = &imx_uart_uart_driver, }; @@ -2595,10 +2687,13 @@ static void imx_uart_save_context(struct imx_port *sport) uart_port_unlock_irqrestore(&sport->port, flags); } +/* called with irq off */ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) { u32 ucr3; + uart_port_lock(&sport->port); + ucr3 = imx_uart_readl(sport, UCR3); if (on) { imx_uart_writel(sport, USR1_AWAKE, USR1); @@ -2618,6 +2713,8 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) } imx_uart_writel(sport, ucr1, UCR1); } + + uart_port_unlock(&sport->port); } static int imx_uart_suspend_noirq(struct device *dev) @@ -2717,7 +2814,7 @@ static const struct dev_pm_ops imx_uart_pm_ops = { static struct platform_driver imx_uart_platform_driver = { .probe = imx_uart_probe, - .remove_new = imx_uart_remove, + .remove = imx_uart_remove, .driver = { .name = "imx-uart", diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index a0731773ce75c5affaafd7e8dd69a173583fb035..58a3ab030d6706315923622c49b3e9d7ab5cc516 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -915,7 +915,7 @@ MODULE_DEVICE_TABLE(of, ltq_asc_match); static struct platform_driver lqasc_driver = { .probe = lqasc_probe, - .remove_new = lqasc_remove, + .remove = lqasc_remove, .driver = { .name = DRVNAME, .of_match_table = ltq_asc_match, diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c index 3ce369f76349835a1c9bd0ac90dbcabf4d049105..6c13cf1ab646fbb0e3e8bbb35bd18c95193f2b79 100644 --- a/drivers/tty/serial/liteuart.c +++ b/drivers/tty/serial/liteuart.c @@ -353,7 +353,7 @@ MODULE_DEVICE_TABLE(of, liteuart_of_match); static struct platform_driver liteuart_platform_driver = { .probe = liteuart_probe, - .remove_new = liteuart_remove, + .remove = liteuart_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = liteuart_of_match, diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index 3e4ac46de1bc3786173c72754e0240965aec183c..42c5f9bc18b7c3abd7d5b4c4e6107dc6d48fe446 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -695,7 +695,7 @@ MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids); static struct platform_driver serial_hs_lpc32xx_driver = { .probe = serial_hs_lpc32xx_probe, - .remove_new = serial_hs_lpc32xx_remove, + .remove = serial_hs_lpc32xx_remove, .suspend = serial_hs_lpc32xx_suspend, .resume = serial_hs_lpc32xx_resume, .driver = { diff --git a/drivers/tty/serial/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c index 3b4206e815fe9d7feb4ebf7720197c16cbe82501..8dcad52eedfd1c1cc0a293533e12d9afa4592d9a 100644 --- a/drivers/tty/serial/ma35d1_serial.c +++ b/drivers/tty/serial/ma35d1_serial.c @@ -794,7 +794,7 @@ static int ma35d1serial_resume(struct platform_device *dev) static struct platform_driver ma35d1serial_driver = { .probe = ma35d1serial_probe, - .remove_new = ma35d1serial_remove, + .remove = ma35d1serial_remove, .suspend = ma35d1serial_suspend, .resume = ma35d1serial_resume, .driver = { diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index 58858dd352c59bfd44ea6922b9ae01b103d588d0..93e7dda4d39acd23daf8c0d4c29ac8d666f263c5 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -616,7 +616,7 @@ static void mcf_remove(struct platform_device *pdev) static struct platform_driver mcf_platform_driver = { .probe = mcf_probe, - .remove_new = mcf_remove, + .remove = mcf_remove, .driver = { .name = "mcfuart", }, diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 4bff422bb1bc36fb4faf5ec8dd4b38db91f34507..9cc15449b673c4486e023fec8291336dbcf1f0b0 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -920,4 +920,4 @@ MODULE_AUTHOR("Johannes Thumshirn "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MEN 16z135 High Speed UART"); MODULE_ALIAS("mcb:16z135"); -MODULE_IMPORT_NS(MCB); +MODULE_IMPORT_NS("MCB"); diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 8eb586ac3b0da0646316f2c5f13715e8e35a9cb3..a6cb2a535f9dcca48b9784432352341e81cd253d 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -842,7 +842,7 @@ MODULE_DEVICE_TABLE(of, meson_uart_dt_match); static struct platform_driver meson_uart_platform_driver = { .probe = meson_uart_probe, - .remove_new = meson_uart_remove, + .remove = meson_uart_remove, .driver = { .name = "meson_uart", .of_match_table = meson_uart_dt_match, diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c index fb082ee73d5b25c80a714d92b23d9bf94b2cefaa..059bea18dbab569a610cb96a1f153a01ca9d362c 100644 --- a/drivers/tty/serial/milbeaut_usio.c +++ b/drivers/tty/serial/milbeaut_usio.c @@ -570,7 +570,7 @@ MODULE_DEVICE_TABLE(of, mlb_usio_dt_ids); static struct platform_driver mlb_usio_driver = { .probe = mlb_usio_probe, - .remove_new = mlb_usio_remove, + .remove = mlb_usio_remove, .driver = { .name = USIO_NAME, .of_match_table = mlb_usio_dt_ids, diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 95dae5e27b28685e744ccf137988adce998de515..f55aa353aed9ee6273d10bce15eefbee45a76c0f 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1843,7 +1843,7 @@ MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); static struct platform_driver mpc52xx_uart_of_driver = { .probe = mpc52xx_uart_of_probe, - .remove_new = mpc52xx_uart_of_remove, + .remove = mpc52xx_uart_of_remove, #ifdef CONFIG_PM .suspend = mpc52xx_uart_of_suspend, .resume = mpc52xx_uart_of_resume, diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 0a9c5219df88bf30ee9c48ef95cc487a038fab01..1b137e06844425584afe5d3f647e9537c6e2d658 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1894,7 +1894,7 @@ static const struct dev_pm_ops msm_serial_dev_pm_ops = { }; static struct platform_driver msm_platform_driver = { - .remove_new = msm_serial_remove, + .remove = msm_serial_remove, .probe = msm_serial_probe, .driver = { .name = "msm_serial", diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index a1c76565c3991f917dcf3c0efd7277c796e0952b..cc65c9fb6446c240d50ac2d12890ffa4f23aa65f 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -1704,7 +1704,7 @@ static void mxs_auart_remove(struct platform_device *pdev) static struct platform_driver mxs_auart_driver = { .probe = mxs_auart_probe, - .remove_new = mxs_auart_remove, + .remove = mxs_auart_remove, .driver = { .name = "mxs-auart", .of_match_table = mxs_auart_dt_ids, diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d7e172eeaab153d8a62b8ea9bd25724fed7cb788..0b85f47ff19e041f9e10202a07bd9f9e640ce0af 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1802,7 +1802,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match); static struct platform_driver serial_omap_driver = { .probe = serial_omap_probe, - .remove_new = serial_omap_remove, + .remove = serial_omap_remove, .driver = { .name = OMAP_SERIAL_DRIVER_NAME, .pm = &serial_omap_dev_pm_ops, diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index ecec483d4d59df5ac6baf9ff118031f5a542c8b4..0542882cfbbe452eb08d02acd8eda37746b20b21 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -730,7 +730,7 @@ static void owl_uart_remove(struct platform_device *pdev) static struct platform_driver owl_uart_platform_driver = { .probe = owl_uart_probe, - .remove_new = owl_uart_remove, + .remove = owl_uart_remove, .driver = { .name = "owl-uart", .of_match_table = owl_uart_dt_matches, diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index 261c8115a700ccce7c4472bfc36ccc1792c1c503..14d50bd7f1bd3575e60e51783bf5b2d821f9168d 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -956,7 +956,7 @@ MODULE_DEVICE_TABLE(of, pic32_serial_dt_ids); static struct platform_driver pic32_uart_platform_driver = { .probe = pic32_uart_probe, - .remove_new = pic32_uart_remove, + .remove = pic32_uart_remove, .driver = { .name = PIC32_DEV_NAME, .of_match_table = of_match_ptr(pic32_serial_dt_ids), diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 8969b11cc0a9a98aae3ee41f965dbc1f617d243f..e3a919328695454633934e118f78490020c8e556 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1776,7 +1776,7 @@ static struct macio_driver pmz_driver = { static struct platform_driver pmz_driver = { .probe = pmz_attach, - .remove_new = pmz_detach, + .remove = pmz_detach, .driver = { .name = "scc", }, diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 5dfe4e599ad68df1a10de0722f69035460fa51de..a80ce7aaf309d1754cbae6469259291b79854c2a 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1839,7 +1839,7 @@ static const struct of_device_id qcom_geni_serial_match_table[] = { MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table); static struct platform_driver qcom_geni_serial_platform_driver = { - .remove_new = qcom_geni_serial_remove, + .remove = qcom_geni_serial_remove, .probe = qcom_geni_serial_probe, .driver = { .name = "qcom_geni_serial", diff --git a/drivers/tty/serial/rda-uart.c b/drivers/tty/serial/rda-uart.c index 663e35e424bdb08b73d85a9ddebadf9b84ff0c6e..87fa30d68687848a1c9d0d6304bcab09f6a77e65 100644 --- a/drivers/tty/serial/rda-uart.c +++ b/drivers/tty/serial/rda-uart.c @@ -777,7 +777,7 @@ static void rda_uart_remove(struct platform_device *pdev) static struct platform_driver rda_uart_platform_driver = { .probe = rda_uart_probe, - .remove_new = rda_uart_remove, + .remove = rda_uart_remove, .driver = { .name = "rda-uart", .of_match_table = rda_uart_dt_matches, diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 79c794fa654512ae6a912c900cbbd87ef9671fe2..3c34027687d21c669eea10f169ece8b1ab7c4467 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -880,7 +880,7 @@ static void sa1100_serial_remove(struct platform_device *pdev) static struct platform_driver sa11x0_serial_driver = { .probe = sa1100_serial_probe, - .remove_new = sa1100_serial_remove, + .remove = sa1100_serial_remove, .suspend = sa1100_serial_suspend, .resume = sa1100_serial_resume, .driver = { diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 0d184ee2f9cec0156dd3ef11e489118711c9f37a..210fff7164c138e315d20ccaa4a29ce6a7bb2dfe 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -2498,6 +2498,12 @@ static const struct s3c24xx_serial_drv_data exynos850_serial_drv_data = { .fifosize = { 256, 64, 64, 64 }, }; +static const struct s3c24xx_serial_drv_data exynos8895_serial_drv_data = { + EXYNOS_COMMON_SERIAL_DRV_DATA, + /* samsung,uart-fifosize must be specified in the device tree. */ + .fifosize = { 0 }, +}; + static const struct s3c24xx_serial_drv_data gs101_serial_drv_data = { .info = { .name = "Google GS101 UART", @@ -2528,12 +2534,14 @@ static const struct s3c24xx_serial_drv_data gs101_serial_drv_data = { #define EXYNOS4210_SERIAL_DRV_DATA (&exynos4210_serial_drv_data) #define EXYNOS5433_SERIAL_DRV_DATA (&exynos5433_serial_drv_data) #define EXYNOS850_SERIAL_DRV_DATA (&exynos850_serial_drv_data) +#define EXYNOS8895_SERIAL_DRV_DATA (&exynos8895_serial_drv_data) #define GS101_SERIAL_DRV_DATA (&gs101_serial_drv_data) #else #define EXYNOS4210_SERIAL_DRV_DATA NULL #define EXYNOS5433_SERIAL_DRV_DATA NULL #define EXYNOS850_SERIAL_DRV_DATA NULL +#define EXYNOS8895_SERIAL_DRV_DATA NULL #define GS101_SERIAL_DRV_DATA NULL #endif @@ -2623,6 +2631,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = { }, { .name = "gs101-uart", .driver_data = (kernel_ulong_t)GS101_SERIAL_DRV_DATA, + }, { + .name = "exynos8895-uart", + .driver_data = (kernel_ulong_t)EXYNOS8895_SERIAL_DRV_DATA, }, { }, }; @@ -2646,6 +2657,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { .data = ARTPEC8_SERIAL_DRV_DATA }, { .compatible = "google,gs101-uart", .data = GS101_SERIAL_DRV_DATA }, + { .compatible = "samsung,exynos8895-uart", + .data = EXYNOS8895_SERIAL_DRV_DATA }, {}, }; MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); @@ -2653,7 +2666,7 @@ MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); static struct platform_driver samsung_serial_driver = { .probe = s3c24xx_serial_probe, - .remove_new = s3c24xx_serial_remove, + .remove = s3c24xx_serial_remove, .id_table = s3c24xx_serial_driver_ids, .driver = { .name = "samsung-uart", diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index ad88a33a504f53f0fecaa51469b6276a84445a64..a3093e09309ffe6999eeee8be97e5adbe74c18b5 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -8,7 +8,7 @@ */ #undef DEFAULT_SYMBOL_NAMESPACE -#define DEFAULT_SYMBOL_NAMESPACE SERIAL_NXP_SC16IS7XX +#define DEFAULT_SYMBOL_NAMESPACE "SERIAL_NXP_SC16IS7XX" #include #include @@ -1473,7 +1473,7 @@ static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s, } static const struct serial_rs485 sc16is7xx_rs485_supported = { - .flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND, .delay_rts_before_send = 1, .delay_rts_after_send = 1, /* Not supported but keep returning -EINVAL */ }; diff --git a/drivers/tty/serial/sc16is7xx_i2c.c b/drivers/tty/serial/sc16is7xx_i2c.c index 3ed47c306d855711ddf1bcede4786b23bd45501a..cd7de9e057b851f250eb234389df0838909baf1b 100644 --- a/drivers/tty/serial/sc16is7xx_i2c.c +++ b/drivers/tty/serial/sc16is7xx_i2c.c @@ -64,4 +64,4 @@ module_i2c_driver(sc16is7xx_i2c_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SC16IS7xx I2C interface driver"); -MODULE_IMPORT_NS(SERIAL_NXP_SC16IS7XX); +MODULE_IMPORT_NS("SERIAL_NXP_SC16IS7XX"); diff --git a/drivers/tty/serial/sc16is7xx_spi.c b/drivers/tty/serial/sc16is7xx_spi.c index 73df36f8a7fd8604d12704fd60827288b0e0b356..20d736b657b17ac1a66bf080920ff924b6d464a8 100644 --- a/drivers/tty/serial/sc16is7xx_spi.c +++ b/drivers/tty/serial/sc16is7xx_spi.c @@ -87,4 +87,4 @@ module_spi_driver(sc16is7xx_spi_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SC16IS7xx SPI interface driver"); -MODULE_IMPORT_NS(SERIAL_NXP_SC16IS7XX); +MODULE_IMPORT_NS("SERIAL_NXP_SC16IS7XX"); diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index 6d1d142fd2161f4ab79a51be9125907f76461858..4c851dae6624f87afb4d86d62e3ec2d38c4c8ee7 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -1052,7 +1052,7 @@ static struct platform_driver sccnxp_uart_driver = { .name = SCCNXP_NAME, }, .probe = sccnxp_probe, - .remove_new = sccnxp_remove, + .remove = sccnxp_remove, .id_table = sccnxp_id_table, }; module_platform_driver(sccnxp_uart_driver); diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 1183ca54ab9217559a88ee075a5f3c7bf94b101c..8004fc00fb9cd57796d7f3512e24d7737efd44d8 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -1648,7 +1648,7 @@ static const struct dev_pm_ops tegra_uart_pm_ops = { static struct platform_driver tegra_uart_platform_driver = { .probe = tegra_uart_probe, - .remove_new = tegra_uart_remove, + .remove = tegra_uart_remove, .driver = { .name = "serial-tegra", .of_match_table = tegra_uart_of_match, diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index abba397229581851d05cd09ab393865f4509204d..436a559234dfe7539da2b4793578af642ce08f82 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -1097,7 +1097,7 @@ static int serial_txx9_resume(struct platform_device *dev) static struct platform_driver serial_txx9_plat_driver = { .probe = serial_txx9_probe, - .remove_new = serial_txx9_remove, + .remove = serial_txx9_remove, #ifdef CONFIG_PM .suspend = serial_txx9_suspend, .resume = serial_txx9_resume, diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index b80e9a528e17ff8b07c39d1688316dd3de1a8c87..df523c74442308360c1b411b27fea32f74c48f77 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3505,7 +3505,7 @@ static SIMPLE_DEV_PM_OPS(sci_dev_pm_ops, sci_suspend, sci_resume); static struct platform_driver sci_driver = { .probe = sci_probe, - .remove_new = sci_remove, + .remove = sci_remove, .driver = { .name = "sh-sci", .pm = &sci_dev_pm_ops, diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index cbfce65c9d221abb1dd589f40e4b6658867803c6..5904a2d4cefa71d371c3d6a07c66cae9140d0353 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -1040,7 +1040,7 @@ MODULE_DEVICE_TABLE(of, sifive_serial_of_match); static struct platform_driver sifive_serial_platform_driver = { .probe = sifive_serial_probe, - .remove_new = sifive_serial_remove, + .remove = sifive_serial_remove, .driver = { .name = SIFIVE_SERIAL_NAME, .pm = pm_sleep_ptr(&sifive_uart_pm_ops), diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 3fc54cc02a1fc5242d06f8f9392966dd847208f8..8c9366321f8e734fa65d09e0448f24855759d5de 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -53,10 +53,12 @@ #define SPRD_IEN_TX_EMPTY BIT(1) #define SPRD_IEN_BREAK_DETECT BIT(7) #define SPRD_IEN_TIMEOUT BIT(13) +#define SPRD_IEN_DATA_TIMEOUT BIT(17) /* interrupt clear register */ #define SPRD_ICLR 0x0014 #define SPRD_ICLR_TIMEOUT BIT(13) +#define SPRD_ICLR_DATA_TIMEOUT BIT(17) /* line control register */ #define SPRD_LCR 0x0018 @@ -102,6 +104,7 @@ #define SPRD_IMSR_TX_FIFO_EMPTY BIT(1) #define SPRD_IMSR_BREAK_DETECT BIT(7) #define SPRD_IMSR_TIMEOUT BIT(13) +#define SPRD_IMSR_DATA_TIMEOUT BIT(17) #define SPRD_DEFAULT_SOURCE_CLK 26000000 #define SPRD_RX_DMA_STEP 1 @@ -118,6 +121,12 @@ struct sprd_uart_dma { bool enable; }; +struct sprd_uart_data { + unsigned int timeout_ien; + unsigned int timeout_iclr; + unsigned int timeout_imsr; +}; + struct sprd_uart_port { struct uart_port port; char name[16]; @@ -126,6 +135,7 @@ struct sprd_uart_port { struct sprd_uart_dma rx_dma; dma_addr_t pos; unsigned char *rx_buf_tail; + const struct sprd_uart_data *pdata; }; static struct sprd_uart_port *sprd_port[UART_NR_MAX]; @@ -134,6 +144,18 @@ static int sprd_ports_num; static int sprd_start_dma_rx(struct uart_port *port); static int sprd_tx_dma_config(struct uart_port *port); +static const struct sprd_uart_data sc9836_data = { + .timeout_ien = SPRD_IEN_TIMEOUT, + .timeout_iclr = SPRD_ICLR_TIMEOUT, + .timeout_imsr = SPRD_IMSR_TIMEOUT, +}; + +static const struct sprd_uart_data sc9632_data = { + .timeout_ien = SPRD_IEN_DATA_TIMEOUT, + .timeout_iclr = SPRD_ICLR_DATA_TIMEOUT, + .timeout_imsr = SPRD_IMSR_DATA_TIMEOUT, +}; + static inline unsigned int serial_in(struct uart_port *port, unsigned int offset) { @@ -637,6 +659,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) { struct uart_port *port = dev_id; unsigned int ims; + struct sprd_uart_port *sp = + container_of(port, struct sprd_uart_port, port); uart_port_lock(port); @@ -647,14 +671,14 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) return IRQ_NONE; } - if (ims & SPRD_IMSR_TIMEOUT) - serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT); + if (ims & sp->pdata->timeout_imsr) + serial_out(port, SPRD_ICLR, sp->pdata->timeout_iclr); if (ims & SPRD_IMSR_BREAK_DETECT) serial_out(port, SPRD_ICLR, SPRD_IMSR_BREAK_DETECT); if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT | - SPRD_IMSR_TIMEOUT)) + sp->pdata->timeout_imsr)) sprd_rx(port); if (ims & SPRD_IMSR_TX_FIFO_EMPTY) @@ -729,7 +753,7 @@ static int sprd_startup(struct uart_port *port) /* enable interrupt */ uart_port_lock_irqsave(port, &flags); ien = serial_in(port, SPRD_IEN); - ien |= SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT; + ien |= SPRD_IEN_BREAK_DETECT | sp->pdata->timeout_ien; if (!sp->rx_dma.enable) ien |= SPRD_IEN_RX_FULL; serial_out(port, SPRD_IEN, ien); @@ -1184,6 +1208,12 @@ static int sprd_probe(struct platform_device *pdev) up->mapbase = res->start; + sport->pdata = of_device_get_match_data(&pdev->dev); + if (!sport->pdata) { + dev_err(&pdev->dev, "get match data failed!\n"); + return -EINVAL; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -1248,14 +1278,15 @@ static int sprd_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume); static const struct of_device_id serial_ids[] = { - {.compatible = "sprd,sc9836-uart",}, + {.compatible = "sprd,sc9836-uart", .data = &sc9836_data}, + {.compatible = "sprd,sc9632-uart", .data = &sc9632_data}, {} }; MODULE_DEVICE_TABLE(of, serial_ids); static struct platform_driver sprd_platform_driver = { .probe = sprd_probe, - .remove_new = sprd_remove, + .remove = sprd_remove, .driver = { .name = "sprd_serial", .of_match_table = serial_ids, diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 8aea59f8ca13dac6fd7ee927dea1c59a66d19abe..6ed9a327702bb5a7c3830f29db61429c80e8bf07 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -934,7 +934,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(asc_serial_pm_ops, asc_serial_suspend, static struct platform_driver asc_serial_driver = { .probe = asc_serial_probe, - .remove_new = asc_serial_remove, + .remove = asc_serial_remove, .driver = { .name = DRIVER_NAME, .pm = pm_sleep_ptr(&asc_serial_pm_ops), diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index e1e7bc04c579208dbb989c4209db6c7ed0ad8851..7dc254546075120c72d561775283ace6c57eec42 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -2188,7 +2188,7 @@ static const struct dev_pm_ops stm32_serial_pm_ops = { static struct platform_driver stm32_serial_driver = { .probe = stm32_usart_serial_probe, - .remove_new = stm32_usart_serial_remove, + .remove = stm32_usart_serial_remove, .driver = { .name = DRIVER_NAME, .pm = &stm32_serial_pm_ops, diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 7f60679fdde1971b3af905dc72237a076e7f63ab..2b3ec65d595d8f8d6b30cfd2b1cc43c0a43b975d 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -633,7 +633,7 @@ static struct platform_driver hv_driver = { .of_match_table = hv_match, }, .probe = hv_probe, - .remove_new = hv_remove, + .remove = hv_remove, }; static int __init sunhv_init(void) diff --git a/drivers/tty/serial/sunplus-uart.c b/drivers/tty/serial/sunplus-uart.c index abf7c449308d9f32b7106fd2bc276550578179a7..38deee571b0d08e356dfce92e57b7d3ed9a475f2 100644 --- a/drivers/tty/serial/sunplus-uart.c +++ b/drivers/tty/serial/sunplus-uart.c @@ -697,7 +697,7 @@ MODULE_DEVICE_TABLE(of, sp_uart_of_match); static struct platform_driver sunplus_uart_platform_driver = { .probe = sunplus_uart_probe, - .remove_new = sunplus_uart_remove, + .remove = sunplus_uart_remove, .driver = { .name = "sunplus_uart", .of_match_table = sp_uart_of_match, diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 1acbe2fba746f948c6d913799bd631c00e8919f7..df906ccf2e8a4f39c2f4dea8c3696eb632a060ca 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -1100,7 +1100,7 @@ static struct platform_driver sab_driver = { .of_match_table = sab_match, }, .probe = sab_probe, - .remove_new = sab_remove, + .remove = sab_remove, }; static int __init sunsab_init(void) diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 0f463da5e7ce6830c32e047a529c1a475ace0bae..7f0fef07e141d092bfe49a7b9243ec468a476cb1 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -1549,7 +1549,7 @@ static struct platform_driver su_driver = { .of_match_table = su_match, }, .probe = su_probe, - .remove_new = su_remove, + .remove = su_remove, }; static int __init sunsu_init(void) diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 71758ad4241c17681c144f45fbc02e1e1959412f..0551c24c06f5faa019421d9e154a273e61737e61 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -1538,7 +1538,7 @@ static struct platform_driver zs_driver = { .of_match_table = zs_match, }, .probe = zs_probe, - .remove_new = zs_remove, + .remove = zs_remove, }; static int __init sunzilog_init(void) diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c index 21ca5fcadf4997c8fce7e952ba0260755c3dbb41..7033dbfe8ba1ec841f773d7063a3d0934b085aca 100644 --- a/drivers/tty/serial/tegra-tcu.c +++ b/drivers/tty/serial/tegra-tcu.c @@ -293,7 +293,7 @@ static struct platform_driver tegra_tcu_driver = { .of_match_table = tegra_tcu_match, }, .probe = tegra_tcu_probe, - .remove_new = tegra_tcu_remove, + .remove = tegra_tcu_remove, }; module_platform_driver(tegra_tcu_driver); diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 43fa0938b5e33e3b544e88564d60583431e2909b..6fa93c3872a727e014bba6b945889e6018345880 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -485,7 +485,7 @@ static struct platform_driver timbuart_platform_driver = { .name = "timb-uart", }, .probe = timbuart_probe, - .remove_new = timbuart_remove, + .remove = timbuart_remove, }; module_platform_driver(timbuart_platform_driver); diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 68357ac8ffe3ca58e1aaba0eb7f509ebb8baeaef..a41e7fc373b7c61f4617d466a7db2024521023ce 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -915,7 +915,7 @@ MODULE_ALIAS("platform:uartlite"); static struct platform_driver ulite_platform_driver = { .probe = ulite_probe, - .remove_new = ulite_remove, + .remove = ulite_remove, .driver = { .name = "uartlite", .of_match_table = of_match_ptr(ulite_of_match), diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 4eed909468ff6dfe0e24dab2d8217bac2c543e5c..0613f8c11ab111abd630fb5d127db71df1e9f71e 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1484,7 +1484,7 @@ static struct platform_driver ucc_uart_of_driver = { .of_match_table = ucc_uart_match, }, .probe = ucc_uart_probe, - .remove_new = ucc_uart_remove, + .remove = ucc_uart_remove, }; static int __init ucc_uart_init(void) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 777392914819d77d03b08a50010d4fb54cf3583c..beb151be4d328731aa37589288803cafbaf761db 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1903,7 +1903,7 @@ static void cdns_uart_remove(struct platform_device *pdev) static struct platform_driver cdns_uart_platform_driver = { .probe = cdns_uart_probe, - .remove_new = cdns_uart_remove, + .remove = cdns_uart_remove, .driver = { .name = CDNS_UART_NAME, .of_match_table = cdns_uart_of_match, diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 9771072da177cb4ee1a486e6c156735fce6bbbec..dcb1769c3625cd0f7d1555260adfe6051139a305 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3631,7 +3631,7 @@ static struct ctl_table tty_table[] = { .data = &tty_ldisc_autoload, .maxlen = sizeof(tty_ldisc_autoload), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, }, diff --git a/drivers/ufs/host/cdns-pltfrm.c b/drivers/ufs/host/cdns-pltfrm.c index 66811d8d1929c135aa43d5cda482464cf37854b4..c80f770a6285437d9ceec2b0fe7571b8b6cf5c8c 100644 --- a/drivers/ufs/host/cdns-pltfrm.c +++ b/drivers/ufs/host/cdns-pltfrm.c @@ -321,7 +321,7 @@ static const struct dev_pm_ops cdns_ufs_dev_pm_ops = { static struct platform_driver cdns_ufs_pltfrm_driver = { .probe = cdns_ufs_pltfrm_probe, - .remove_new = cdns_ufs_pltfrm_remove, + .remove = cdns_ufs_pltfrm_remove, .driver = { .name = "cdns-ufshcd", .pm = &cdns_ufs_dev_pm_ops, diff --git a/drivers/ufs/host/tc-dwc-g210-pltfrm.c b/drivers/ufs/host/tc-dwc-g210-pltfrm.c index a3877592604d5d659add23f18f1c93c22ef99341..9bfaa36cc898675df7a1f026282af4ffb034ace9 100644 --- a/drivers/ufs/host/tc-dwc-g210-pltfrm.c +++ b/drivers/ufs/host/tc-dwc-g210-pltfrm.c @@ -89,7 +89,7 @@ static const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = { static struct platform_driver tc_dwc_g210_pltfm_driver = { .probe = tc_dwc_g210_pltfm_probe, - .remove_new = tc_dwc_g210_pltfm_remove, + .remove = tc_dwc_g210_pltfm_remove, .driver = { .name = "tc-dwc-g210-pltfm", .pm = &tc_dwc_g210_pltfm_pm_ops, diff --git a/drivers/ufs/host/ti-j721e-ufs.c b/drivers/ufs/host/ti-j721e-ufs.c index 250c22df000d534632dd0b5924bade6d5467ee1b..21214e5d5896447431b251d7f5783585532a835a 100644 --- a/drivers/ufs/host/ti-j721e-ufs.c +++ b/drivers/ufs/host/ti-j721e-ufs.c @@ -83,7 +83,7 @@ MODULE_DEVICE_TABLE(of, ti_j721e_ufs_of_match); static struct platform_driver ti_j721e_ufs_driver = { .probe = ti_j721e_ufs_probe, - .remove_new = ti_j721e_ufs_remove, + .remove = ti_j721e_ufs_remove, .driver = { .name = "ti-j721e-ufs", .of_match_table = ti_j721e_ufs_of_match, diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index 6548f7a8562fb83b822087fd60373ec533f087ad..c4098011c4b47eb03e90f9eea733570c3021a683 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -2166,7 +2166,7 @@ static const struct dev_pm_ops exynos_ufs_pm_ops = { static struct platform_driver exynos_ufs_pltform = { .probe = exynos_ufs_probe, - .remove_new = exynos_ufs_remove, + .remove = exynos_ufs_remove, .driver = { .name = "exynos-ufshc", .pm = &exynos_ufs_pm_ops, diff --git a/drivers/ufs/host/ufs-hisi.c b/drivers/ufs/host/ufs-hisi.c index 5ee73ff052512b3468adc707ed26e99cd8c3b1ec..494f593702a34d8ebbfd5d1c2a1f2296b34de687 100644 --- a/drivers/ufs/host/ufs-hisi.c +++ b/drivers/ufs/host/ufs-hisi.c @@ -590,7 +590,7 @@ static const struct dev_pm_ops ufs_hisi_pm_ops = { static struct platform_driver ufs_hisi_pltform = { .probe = ufs_hisi_probe, - .remove_new = ufs_hisi_remove, + .remove = ufs_hisi_remove, .driver = { .name = "ufshcd-hisi", .pm = &ufs_hisi_pm_ops, diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c index 06ab1e5e8b6fbc2dd67d18cd7832f5e4d6c87b29..6fc848d0ada8bcf13aaf9f095ad9e4e43876c743 100644 --- a/drivers/ufs/host/ufs-mediatek.c +++ b/drivers/ufs/host/ufs-mediatek.c @@ -1962,7 +1962,7 @@ static const struct dev_pm_ops ufs_mtk_pm_ops = { static struct platform_driver ufs_mtk_pltform = { .probe = ufs_mtk_probe, - .remove_new = ufs_mtk_remove, + .remove = ufs_mtk_remove, .driver = { .name = "ufshcd-mtk", .pm = &ufs_mtk_pm_ops, diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 3b592492e15209f6ad715bed636d550a4a07de2a..d2b8d97b480eb14e7fc22a16f9e6f7ca779cd6e1 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -1897,7 +1897,7 @@ static const struct dev_pm_ops ufs_qcom_pm_ops = { static struct platform_driver ufs_qcom_pltform = { .probe = ufs_qcom_probe, - .remove_new = ufs_qcom_remove, + .remove = ufs_qcom_remove, .driver = { .name = "ufshcd-qcom", .pm = &ufs_qcom_pm_ops, diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c index 3ff97112e1f6d085b59972643a78c3ebc061c24e..f404019dc5d960fc55a706a8103f18b5aed4e6a8 100644 --- a/drivers/ufs/host/ufs-renesas.c +++ b/drivers/ufs/host/ufs-renesas.c @@ -404,7 +404,7 @@ static void ufs_renesas_remove(struct platform_device *pdev) static struct platform_driver ufs_renesas_platform = { .probe = ufs_renesas_probe, - .remove_new = ufs_renesas_remove, + .remove = ufs_renesas_remove, .driver = { .name = "ufshcd-renesas", .of_match_table = of_match_ptr(ufs_renesas_of_match), diff --git a/drivers/ufs/host/ufs-sprd.c b/drivers/ufs/host/ufs-sprd.c index d8b165908809d69a7ca6bdd82f07ffc87db9def4..b1ffb9b05fa75fe2e6f90ac318ea468e9273264a 100644 --- a/drivers/ufs/host/ufs-sprd.c +++ b/drivers/ufs/host/ufs-sprd.c @@ -442,7 +442,7 @@ static const struct dev_pm_ops ufs_sprd_pm_ops = { static struct platform_driver ufs_sprd_pltform = { .probe = ufs_sprd_probe, - .remove_new = ufs_sprd_remove, + .remove = ufs_sprd_remove, .driver = { .name = "ufshcd-sprd", .pm = &ufs_sprd_pm_ops, diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index 13cc35ab5d29a7ddc079883b8a853387fcdad63e..c70dd81bfc61fd26851335f67eb356d066aaa97d 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -210,8 +210,6 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) } if (uioinfo->irq) { - struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq); - /* * If a level interrupt, dont do lazy disable. Otherwise the * irq will fire again since clearing of the actual cause, on @@ -219,8 +217,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) * irqd_is_level_type() isn't used since isn't valid until * irq is configured. */ - if (irq_data && - irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) { + if (irq_get_trigger_type(uioinfo->irq) & IRQ_TYPE_LEVEL_MASK) { dev_dbg(&pdev->dev, "disable lazy unmask\n"); irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY); } diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c index 496caff66e7ea142a7a2d11d878a358fd869c36b..81454c3e2484c8558c46b93417b24641b69f37c4 100644 --- a/drivers/uio/uio_fsl_elbc_gpcm.c +++ b/drivers/uio/uio_fsl_elbc_gpcm.c @@ -453,7 +453,7 @@ static struct platform_driver uio_fsl_elbc_gpcm_driver = { .dev_groups = uio_fsl_elbc_gpcm_groups, }, .probe = uio_fsl_elbc_gpcm_probe, - .remove_new = uio_fsl_elbc_gpcm_remove, + .remove = uio_fsl_elbc_gpcm_remove, }; module_platform_driver(uio_fsl_elbc_gpcm_driver); diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 8704095994118c2660f345c504b5ea466d053efb..3976360d0096d6681faf88815cc6277fb76a1d9f 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -135,7 +135,7 @@ static void hv_uio_rescind(struct vmbus_channel *channel) * The ring buffer is allocated as contiguous memory by vmbus_open */ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, + const struct bin_attribute *attr, struct vm_area_struct *vma) { struct vmbus_channel *channel diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index 796f5be0a086a5cb98607db502a84c03517b432d..2ec7d25e826490999404382e6aa69e4af56f7fe8 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -173,8 +173,6 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) } if (uioinfo->irq) { - struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq); - /* * If a level interrupt, dont do lazy disable. Otherwise the * irq will fire again since clearing of the actual cause, on @@ -182,8 +180,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) * irqd_is_level_type() isn't used since isn't valid until * irq is configured. */ - if (irq_data && - irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) { + if (irq_get_trigger_type(uioinfo->irq) & IRQ_TYPE_LEVEL_MASK) { dev_dbg(&pdev->dev, "disable lazy unmask\n"); irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY); } diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index e8e43c38aa1b4338c8968dcd4316f920df749700..cd0f7b4bd82ab132399c91057eee27f0d02c9119 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -808,7 +808,7 @@ static int check_dsp_e4(const u8 *dsp, int len) if (l > len) return 1; - /* zero is zero regardless endianes */ + /* zero is zero regardless endianness */ } while (blockidx->NotLastBlock); } @@ -1276,7 +1276,7 @@ static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate) sc->stats.phy.dsrate == dsrate) return; - /* Original timming (1Mbit/s) from ADI (used in windows driver) */ + /* Original timing (1Mbit/s) from ADI (used in windows driver) */ timeout = (dsrate <= 1024*1024) ? 0 : 1; ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); uea_info(INS_TO_USBDEV(sc), "setting new timeout %d%s\n", @@ -1972,7 +1972,7 @@ static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr) if (cmv->bDirection != E1_MODEMTOHOST) goto bad1; - /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to + /* FIXME : ADI930 reply wrong preamble (func = 2, sub = 2) to * the first MEMACCESS cmv. Ignore it... */ if (cmv->bFunction != dsc->function) { diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 2da6615fbb6f4ea6f1661d8354b27a26393dba1f..d1e622bb140622fdf4815fa0620917d9326a0c45 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -1158,7 +1158,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, if (i >= num_rcv_urbs) list_add_tail(&urb->urb_list, &channel->list); - vdbg(&intf->dev, "%s: alloced buffer 0x%p buf size %u urb 0x%p", + vdbg(&intf->dev, "%s: allocated buffer 0x%p buf size %u urb 0x%p", __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb); } diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index bb9d5d7ffefc5448177f4e42e7ed6ec61913fbf5..8f38e2c5369a1f57c84bea54bc53fc8b9260801c 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -201,7 +201,7 @@ static void c67x00_drv_remove(struct platform_device *pdev) static struct platform_driver c67x00_driver = { .probe = c67x00_drv_probe, - .remove_new = c67x00_drv_remove, + .remove = c67x00_drv_remove, .driver = { .name = "c67x00", }, diff --git a/drivers/usb/cdns3/cdns3-imx.c b/drivers/usb/cdns3/cdns3-imx.c index 281de47e2a3b12a81533a75b0423ce7828a1c872..a2f041e1707c0d6ff25d79cb6c452be8680496cf 100644 --- a/drivers/usb/cdns3/cdns3-imx.c +++ b/drivers/usb/cdns3/cdns3-imx.c @@ -422,7 +422,7 @@ MODULE_DEVICE_TABLE(of, cdns_imx_of_match); static struct platform_driver cdns_imx_driver = { .probe = cdns_imx_probe, - .remove_new = cdns_imx_remove, + .remove = cdns_imx_remove, .driver = { .name = "cdns3-imx", .of_match_table = cdns_imx_of_match, diff --git a/drivers/usb/cdns3/cdns3-pci-wrap.c b/drivers/usb/cdns3/cdns3-pci-wrap.c index 591d149de8f3d9f509dfbecc3e92fc924a41ffa9..3b3b3dc75f359018bf22d1d5fadfe25eb2f03351 100644 --- a/drivers/usb/cdns3/cdns3-pci-wrap.c +++ b/drivers/usb/cdns3/cdns3-pci-wrap.c @@ -37,8 +37,6 @@ struct cdns3_wrap { #define PCI_DRIVER_NAME "cdns3-pci-usbss" #define PLAT_DRIVER_NAME "cdns-usb3" -#define PCI_DEVICE_ID_CDNS_USB3 0x0100 - static struct pci_dev *cdns3_get_second_fun(struct pci_dev *pdev) { struct pci_dev *func; @@ -189,7 +187,7 @@ static void cdns3_pci_remove(struct pci_dev *pdev) } static const struct pci_device_id cdns3_pci_ids[] = { - { PCI_VDEVICE(CDNS, PCI_DEVICE_ID_CDNS_USB3) }, + { PCI_VDEVICE(CDNS, PCI_DEVICE_ID_CDNS_USBSS) }, { 0, } }; diff --git a/drivers/usb/cdns3/cdns3-plat.c b/drivers/usb/cdns3/cdns3-plat.c index 3ef8e3c872a37ecf41b7b089d27321aab04293f0..59ec505e198a4b37eb609c904dee34c680e97a08 100644 --- a/drivers/usb/cdns3/cdns3-plat.c +++ b/drivers/usb/cdns3/cdns3-plat.c @@ -327,7 +327,7 @@ MODULE_DEVICE_TABLE(of, of_cdns3_match); static struct platform_driver cdns3_driver = { .probe = cdns3_plat_probe, - .remove_new = cdns3_plat_remove, + .remove = cdns3_plat_remove, .driver = { .name = "cdns-usb3", .of_match_table = of_match_ptr(of_cdns3_match), diff --git a/drivers/usb/cdns3/cdns3-starfive.c b/drivers/usb/cdns3/cdns3-starfive.c index c04d196abd8782901492822d81659b228613ddd7..2ff7f2b48cc2b7255e763b5241f7fb6b0dc7b6bd 100644 --- a/drivers/usb/cdns3/cdns3-starfive.c +++ b/drivers/usb/cdns3/cdns3-starfive.c @@ -230,7 +230,7 @@ MODULE_DEVICE_TABLE(of, cdns_starfive_of_match); static struct platform_driver cdns_starfive_driver = { .probe = cdns_starfive_probe, - .remove_new = cdns_starfive_remove, + .remove = cdns_starfive_remove, .driver = { .name = "cdns3-starfive", .of_match_table = cdns_starfive_of_match, diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c index cfabc12ee0e3c02ed95c06604c9be22eb2739955..040bb91e9c017d8298a7e251fd0e192a336e8a52 100644 --- a/drivers/usb/cdns3/cdns3-ti.c +++ b/drivers/usb/cdns3/cdns3-ti.c @@ -233,7 +233,7 @@ MODULE_DEVICE_TABLE(of, cdns_ti_of_match); static struct platform_driver cdns_ti_driver = { .probe = cdns_ti_probe, - .remove_new = cdns_ti_remove, + .remove = cdns_ti_remove, .driver = { .name = "cdns3-ti", .of_match_table = cdns_ti_of_match, diff --git a/drivers/usb/cdns3/cdnsp-pci.c b/drivers/usb/cdns3/cdnsp-pci.c index 2d05368a6745a1a4fcc166056c019aa4f151af06..a51144504ff337a5888b75cdd060c432ee3fa395 100644 --- a/drivers/usb/cdns3/cdnsp-pci.c +++ b/drivers/usb/cdns3/cdnsp-pci.c @@ -28,12 +28,6 @@ #define PCI_DRIVER_NAME "cdns-pci-usbssp" #define PLAT_DRIVER_NAME "cdns-usbssp" -#define PCI_DEVICE_ID_CDNS_USB3 0x0100 -#define PCI_DEVICE_ID_CDNS_UDC 0x0200 - -#define PCI_CLASS_SERIAL_USB_CDNS_USB3 (PCI_CLASS_SERIAL_USB << 8 | 0x80) -#define PCI_CLASS_SERIAL_USB_CDNS_UDC PCI_CLASS_SERIAL_USB_DEVICE - static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev) { /* @@ -41,10 +35,10 @@ static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev) * Platform has two function. The fist keeps resources for * Host/Device while the secon keeps resources for DRD/OTG. */ - if (pdev->device == PCI_DEVICE_ID_CDNS_UDC) - return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_USB3, NULL); - if (pdev->device == PCI_DEVICE_ID_CDNS_USB3) - return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_UDC, NULL); + if (pdev->device == PCI_DEVICE_ID_CDNS_USBSSP) + return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_USBSS, NULL); + if (pdev->device == PCI_DEVICE_ID_CDNS_USBSS) + return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_USBSSP, NULL); return NULL; } @@ -221,12 +215,12 @@ static const struct dev_pm_ops cdnsp_pci_pm_ops = { }; static const struct pci_device_id cdnsp_pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_UDC), - .class = PCI_CLASS_SERIAL_USB_CDNS_UDC }, - { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_UDC), - .class = PCI_CLASS_SERIAL_USB_CDNS_USB3 }, - { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USB3), - .class = PCI_CLASS_SERIAL_USB_CDNS_USB3 }, + { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USBSSP), + .class = PCI_CLASS_SERIAL_USB_DEVICE }, + { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USBSSP), + .class = PCI_CLASS_SERIAL_USB_CDNS }, + { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USBSS), + .class = PCI_CLASS_SERIAL_USB_CDNS }, { 0, } }; diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 2a38e1eb65466c82a6eb9e4f2feba8fc59ee7dfc..97437de52ef681a70cbab1c0f4d94eab5139e7e2 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -25,6 +25,7 @@ #define TD_PAGE_COUNT 5 #define CI_HDRC_PAGE_SIZE 4096ul /* page size for TD's */ #define ENDPT_MAX 32 +#define CI_MAX_REQ_SIZE (4 * CI_HDRC_PAGE_SIZE) #define CI_MAX_BUF_SIZE (TD_PAGE_COUNT * CI_HDRC_PAGE_SIZE) /****************************************************************************** @@ -260,6 +261,7 @@ struct ci_hdrc { bool b_sess_valid_event; bool imx28_write_fix; bool has_portsc_pec_bug; + bool has_short_pkt_limit; bool supports_runtime_pm; bool in_lpm; bool wakeup_int; diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index c64ab0e07ea030cc7f23120fea1d211408955918..f2801700be8ec1a29bcb8f49f584d181d96be402 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -342,6 +342,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) struct ci_hdrc_platform_data pdata = { .name = dev_name(&pdev->dev), .capoffset = DEF_CAPOFFSET, + .flags = CI_HDRC_HAS_SHORT_PKT_LIMIT, .notify_event = ci_hdrc_imx_notify_event, }; int ret; @@ -675,7 +676,7 @@ static const struct dev_pm_ops ci_hdrc_imx_pm_ops = { }; static struct platform_driver ci_hdrc_imx_driver = { .probe = ci_hdrc_imx_probe, - .remove_new = ci_hdrc_imx_remove, + .remove = ci_hdrc_imx_remove, .shutdown = ci_hdrc_imx_shutdown, .driver = { .name = "imx_usb", diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 1661639cd2ebb7a7a55067d1af7754ad3c426888..3ab3daa78e3401ae1f7ea24b597efac4298f8976 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -292,7 +292,7 @@ MODULE_DEVICE_TABLE(of, msm_ci_dt_match); static struct platform_driver ci_hdrc_msm_driver = { .probe = ci_hdrc_msm_probe, - .remove_new = ci_hdrc_msm_remove, + .remove = ci_hdrc_msm_remove, .driver = { .name = "msm_hsusb", .of_match_table = msm_ci_dt_match, diff --git a/drivers/usb/chipidea/ci_hdrc_npcm.c b/drivers/usb/chipidea/ci_hdrc_npcm.c index 3e5e05dbda8904de33ebc6501644f4fee529aed5..e52a2b05cbe2aea8cb16d5baf724c887188f4621 100644 --- a/drivers/usb/chipidea/ci_hdrc_npcm.c +++ b/drivers/usb/chipidea/ci_hdrc_npcm.c @@ -98,7 +98,7 @@ MODULE_DEVICE_TABLE(of, npcm_udc_dt_match); static struct platform_driver npcm_udc_driver = { .probe = npcm_udc_probe, - .remove_new = npcm_udc_remove, + .remove = npcm_udc_remove, .driver = { .name = "npcm_udc", .of_match_table = npcm_udc_dt_match, diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c index 9538d425f0a02a31af392606c2446dfb8e50d065..372788f0f970144ae34352c36d4ea7cf94200c76 100644 --- a/drivers/usb/chipidea/ci_hdrc_tegra.c +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c @@ -406,7 +406,7 @@ static struct platform_driver tegra_usb_driver = { .pm = pm_ptr(&tegra_usb_pm), }, .probe = tegra_usb_probe, - .remove_new = tegra_usb_remove, + .remove = tegra_usb_remove, }; module_platform_driver(tegra_usb_driver); diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c index 97379f653b06295f19beed9478899f90a1dfd4e4..8ffa1e95d8e8601bcf7e121c33a75a28f073b681 100644 --- a/drivers/usb/chipidea/ci_hdrc_usb2.c +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -116,7 +116,7 @@ static void ci_hdrc_usb2_remove(struct platform_device *pdev) static struct platform_driver ci_hdrc_usb2_driver = { .probe = ci_hdrc_usb2_probe, - .remove_new = ci_hdrc_usb2_remove, + .remove = ci_hdrc_usb2_remove, .driver = { .name = "chipidea-usb2", .of_match_table = ci_hdrc_usb2_of_match, diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 835bf2428dc6eccee263b05024d42885884cd94d..694b4a8e4e1d8583dcbf4a42f8c2dfd785d5745c 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -765,7 +765,7 @@ static int ci_get_platdata(struct device *dev, ext_id = ERR_PTR(-ENODEV); ext_vbus = ERR_PTR(-ENODEV); - if (of_property_read_bool(dev->of_node, "extcon")) { + if (of_property_present(dev->of_node, "extcon")) { /* Each one of them is not mandatory */ ext_vbus = extcon_get_edev_by_phandle(dev, 0); if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV) @@ -1076,6 +1076,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) CI_HDRC_SUPPORTS_RUNTIME_PM); ci->has_portsc_pec_bug = !!(ci->platdata->flags & CI_HDRC_HAS_PORTSC_PEC_MISSED); + ci->has_short_pkt_limit = !!(ci->platdata->flags & + CI_HDRC_HAS_SHORT_PKT_LIMIT); platform_set_drvdata(pdev, ci); ret = hw_device_init(ci, base); @@ -1495,7 +1497,7 @@ static const struct dev_pm_ops ci_pm_ops = { static struct platform_driver ci_hdrc_driver = { .probe = ci_hdrc_probe, - .remove_new = ci_hdrc_remove, + .remove = ci_hdrc_remove, .driver = { .name = "ci_hdrc", .pm = &ci_pm_ops, diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 69ef3cd8d4f836ab52e9cbae847f1d461f966619..8a9b31fd5c89d8ddf4bb1bbe184a9c094983d38c 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -540,6 +541,126 @@ static int prepare_td_for_sg(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) return ret; } +/* + * Verify if the scatterlist is valid by iterating each sg entry. + * Return invalid sg entry index which is less than num_sgs. + */ +static int sglist_get_invalid_entry(struct device *dma_dev, u8 dir, + struct usb_request *req) +{ + int i; + struct scatterlist *s = req->sg; + + if (req->num_sgs == 1) + return 1; + + dir = dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + + for (i = 0; i < req->num_sgs; i++, s = sg_next(s)) { + /* Only small sg (generally last sg) may be bounced. If + * that happens. we can't ensure the addr is page-aligned + * after dma map. + */ + if (dma_kmalloc_needs_bounce(dma_dev, s->length, dir)) + break; + + /* Make sure each sg start address (except first sg) is + * page-aligned and end address (except last sg) is also + * page-aligned. + */ + if (i == 0) { + if (!IS_ALIGNED(s->offset + s->length, + CI_HDRC_PAGE_SIZE)) + break; + } else { + if (s->offset) + break; + if (!sg_is_last(s) && !IS_ALIGNED(s->length, + CI_HDRC_PAGE_SIZE)) + break; + } + } + + return i; +} + +static int sglist_do_bounce(struct ci_hw_req *hwreq, int index, + bool copy, unsigned int *bounced) +{ + void *buf; + int i, ret, nents, num_sgs; + unsigned int rest, rounded; + struct scatterlist *sg, *src, *dst; + + nents = index + 1; + ret = sg_alloc_table(&hwreq->sgt, nents, GFP_KERNEL); + if (ret) + return ret; + + sg = src = hwreq->req.sg; + num_sgs = hwreq->req.num_sgs; + rest = hwreq->req.length; + dst = hwreq->sgt.sgl; + + for (i = 0; i < index; i++) { + memcpy(dst, src, sizeof(*src)); + rest -= src->length; + src = sg_next(src); + dst = sg_next(dst); + } + + /* create one bounce buffer */ + rounded = round_up(rest, CI_HDRC_PAGE_SIZE); + buf = kmalloc(rounded, GFP_KERNEL); + if (!buf) { + sg_free_table(&hwreq->sgt); + return -ENOMEM; + } + + sg_set_buf(dst, buf, rounded); + + hwreq->req.sg = hwreq->sgt.sgl; + hwreq->req.num_sgs = nents; + hwreq->sgt.sgl = sg; + hwreq->sgt.nents = num_sgs; + + if (copy) + sg_copy_to_buffer(src, num_sgs - index, buf, rest); + + *bounced = rest; + + return 0; +} + +static void sglist_do_debounce(struct ci_hw_req *hwreq, bool copy) +{ + void *buf; + int i, nents, num_sgs; + struct scatterlist *sg, *src, *dst; + + sg = hwreq->req.sg; + num_sgs = hwreq->req.num_sgs; + src = sg_last(sg, num_sgs); + buf = sg_virt(src); + + if (copy) { + dst = hwreq->sgt.sgl; + for (i = 0; i < num_sgs - 1; i++) + dst = sg_next(dst); + + nents = hwreq->sgt.nents - num_sgs + 1; + sg_copy_from_buffer(dst, nents, buf, sg_dma_len(src)); + } + + hwreq->req.sg = hwreq->sgt.sgl; + hwreq->req.num_sgs = hwreq->sgt.nents; + hwreq->sgt.sgl = sg; + hwreq->sgt.nents = num_sgs; + + kfree(buf); + sg_free_table(&hwreq->sgt); +} + /** * _hardware_enqueue: configures a request at hardware level * @hwep: endpoint @@ -552,6 +673,8 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) struct ci_hdrc *ci = hwep->ci; int ret = 0; struct td_node *firstnode, *lastnode; + unsigned int bounced_size; + struct scatterlist *sg; /* don't queue twice */ if (hwreq->req.status == -EALREADY) @@ -559,11 +682,29 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) hwreq->req.status = -EALREADY; + if (hwreq->req.num_sgs && hwreq->req.length && + ci->has_short_pkt_limit) { + ret = sglist_get_invalid_entry(ci->dev->parent, hwep->dir, + &hwreq->req); + if (ret < hwreq->req.num_sgs) { + ret = sglist_do_bounce(hwreq, ret, hwep->dir == TX, + &bounced_size); + if (ret) + return ret; + } + } + ret = usb_gadget_map_request_by_dev(ci->dev->parent, &hwreq->req, hwep->dir); if (ret) return ret; + if (hwreq->sgt.sgl) { + /* We've mapped a bigger buffer, now recover the actual size */ + sg = sg_last(hwreq->req.sg, hwreq->req.num_sgs); + sg_dma_len(sg) = min(sg_dma_len(sg), bounced_size); + } + if (hwreq->req.num_mapped_sgs) ret = prepare_td_for_sg(hwep, hwreq); else @@ -612,10 +753,17 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) do { hw_write(ci, OP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW); tmp_stat = hw_read(ci, OP_ENDPTSTAT, BIT(n)); - } while (!hw_read(ci, OP_USBCMD, USBCMD_ATDTW)); + } while (!hw_read(ci, OP_USBCMD, USBCMD_ATDTW) && tmp_stat); hw_write(ci, OP_USBCMD, USBCMD_ATDTW, 0); if (tmp_stat) goto done; + + /* OP_ENDPTSTAT will be clear by HW when the endpoint met + * err. This dTD don't push to dQH if current dTD point is + * not the last one in previous request. + */ + if (hwep->qh.ptr->curr != cpu_to_le32(prevlastnode->dma)) + goto done; } /* QH configuration */ @@ -676,6 +824,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) unsigned remaining_length; unsigned actual = hwreq->req.length; struct ci_hdrc *ci = hwep->ci; + bool is_isoc = hwep->type == USB_ENDPOINT_XFER_ISOC; if (hwreq->req.status != -EALREADY) return -EINVAL; @@ -689,7 +838,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) int n = hw_ep_bit(hwep->num, hwep->dir); if (ci->rev == CI_REVISION_24 || - ci->rev == CI_REVISION_22) + ci->rev == CI_REVISION_22 || is_isoc) if (!hw_read(ci, OP_ENDPTSTAT, BIT(n))) reprime_dtd(ci, hwep, node); hwreq->req.status = -EALREADY; @@ -708,11 +857,15 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) hwreq->req.status = -EPROTO; break; } else if ((TD_STATUS_TR_ERR & hwreq->req.status)) { - hwreq->req.status = -EILSEQ; - break; + if (is_isoc) { + hwreq->req.status = 0; + } else { + hwreq->req.status = -EILSEQ; + break; + } } - if (remaining_length) { + if (remaining_length && !is_isoc) { if (hwep->dir == TX) { hwreq->req.status = -EPROTO; break; @@ -733,6 +886,10 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) usb_gadget_unmap_request_by_dev(hwep->ci->dev->parent, &hwreq->req, hwep->dir); + /* sglist bounced */ + if (hwreq->sgt.sgl) + sglist_do_debounce(hwreq, hwep->dir == RX); + hwreq->req.actual += actual; if (hwreq->req.status) @@ -960,6 +1117,12 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req, return -EMSGSIZE; } + if (ci->has_short_pkt_limit && + hwreq->req.length > CI_MAX_REQ_SIZE) { + dev_err(hwep->ci->dev, "request length too big (max 16KB)\n"); + return -EMSGSIZE; + } + /* first nuke then test link, e.g. previous status has not sent */ if (!list_empty(&hwreq->queue)) { dev_err(hwep->ci->dev, "request already in queue\n"); @@ -1574,6 +1737,9 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) usb_gadget_unmap_request(&hwep->ci->gadget, req, hwep->dir); + if (hwreq->sgt.sgl) + sglist_do_debounce(hwreq, false); + req->status = -ECONNRESET; if (hwreq->req.complete != NULL) { @@ -2063,7 +2229,7 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci) } } - if (USBi_UI & intr) + if ((USBi_UI | USBi_UEI) & intr) isr_tr_complete_handler(ci); if ((USBi_SLI & intr) && !(ci->suspended)) { diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h index 5193df1e18c75beb2efafaa5651f2f4084fe33c9..c8a47389a46bbbddf0bfb125450d01cb64a46792 100644 --- a/drivers/usb/chipidea/udc.h +++ b/drivers/usb/chipidea/udc.h @@ -69,11 +69,13 @@ struct td_node { * @req: request structure for gadget drivers * @queue: link to QH list * @tds: link to TD list + * @sgt: hold original sglist when bounce sglist */ struct ci_hw_req { struct usb_request req; struct list_head queue; struct list_head tds; + struct sg_table sgt; }; #ifdef CONFIG_USB_CHIPIDEA_UDC diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 173c78afd502274483a25475f3f8a9b8e2a99dd7..1394881fde5f5b4915150b9ff001bf32620429e8 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -1285,6 +1285,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { .compatible = "fsl,imx7ulp-usbmisc", .data = &imx7ulp_usbmisc_ops, }, + { + .compatible = "fsl,imx8ulp-usbmisc", + .data = &imx7ulp_usbmisc_ops, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index b7bea1015d7c1dfe1f98822c5236df8d80f35dd2..871cf199b6bf17b9377867ff93a2d868e81479ee 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -415,6 +415,9 @@ EXPORT_SYMBOL_GPL(usb_of_get_companion_dev); struct dentry *usb_debug_root; EXPORT_SYMBOL_GPL(usb_debug_root); +DEFINE_MUTEX(usb_dynids_lock); +EXPORT_SYMBOL_GPL(usb_dynids_lock); + static int __init usb_common_init(void) { usb_debug_root = debugfs_create_dir("usb", NULL); diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c index 501e8bc9738eba54836dcc2b97f83c36e791f1e9..c84b4a70008460f4607050b517a22fba4dc0ffec 100644 --- a/drivers/usb/common/usb-conn-gpio.c +++ b/drivers/usb/common/usb-conn-gpio.c @@ -340,7 +340,7 @@ MODULE_DEVICE_TABLE(of, usb_conn_dt_match); static struct platform_driver usb_conn_driver = { .probe = usb_conn_probe, - .remove_new = usb_conn_remove, + .remove = usb_conn_remove, .driver = { .name = "usb-conn-gpio", .pm = &usb_conn_pm_ops, diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 880d52c0949d4791a19f2cb2a9c9359cee530f4a..25a00f974934fb5a562caf3f5f259ba23031e457 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -924,7 +924,7 @@ int usb_get_configuration(struct usb_device *dev) result = -EINVAL; goto err; } - length = max((int) le16_to_cpu(desc->wTotalLength), + length = max_t(int, le16_to_cpu(desc->wTotalLength), USB_DT_CONFIG_SIZE); /* Now that we know the length, get the whole thing */ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 3beb6a862e8084d97c619aacd32a624f1f6db3ce..f6ce6e26e0d45f67704f40b27c5a09cde9111259 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -238,6 +238,9 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) dma_addr_t dma_handle = DMA_MAPPING_ERROR; int ret; + if (!(file->f_mode & FMODE_WRITE)) + return -EPERM; + ret = usbfs_increase_memory_usage(size + sizeof(struct usb_memory)); if (ret) goto error; @@ -1295,7 +1298,7 @@ static int do_proc_bulk(struct usb_dev_state *ps, return ret; len1 = bulk->len; - if (len1 < 0 || len1 >= (INT_MAX - sizeof(struct urb))) + if (len1 >= (INT_MAX - sizeof(struct urb))) return -EINVAL; if (bulk->ep & USB_DIR_IN) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 0c3f12daac79e0038b991cbd91e9afc40baf3aac..f203fdbfb6f68e6cf52feb077f042045cb9bf3a8 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -95,9 +95,9 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, } } - spin_lock(&dynids->lock); + mutex_lock(&usb_dynids_lock); list_add_tail(&dynid->node, &dynids->list); - spin_unlock(&dynids->lock); + mutex_unlock(&usb_dynids_lock); retval = driver_attach(driver); @@ -116,6 +116,7 @@ ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf) struct usb_dynid *dynid; size_t count = 0; + guard(mutex)(&usb_dynids_lock); list_for_each_entry(dynid, &dynids->list, node) if (dynid->id.bInterfaceClass != 0) count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x %02x\n", @@ -160,7 +161,7 @@ static ssize_t remove_id_store(struct device_driver *driver, const char *buf, if (fields < 2) return -EINVAL; - spin_lock(&usb_driver->dynids.lock); + guard(mutex)(&usb_dynids_lock); list_for_each_entry_safe(dynid, n, &usb_driver->dynids.list, node) { struct usb_device_id *id = &dynid->id; @@ -171,7 +172,6 @@ static ssize_t remove_id_store(struct device_driver *driver, const char *buf, break; } } - spin_unlock(&usb_driver->dynids.lock); return count; } @@ -220,27 +220,24 @@ static void usb_free_dynids(struct usb_driver *usb_drv) { struct usb_dynid *dynid, *n; - spin_lock(&usb_drv->dynids.lock); + guard(mutex)(&usb_dynids_lock); list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) { list_del(&dynid->node); kfree(dynid); } - spin_unlock(&usb_drv->dynids.lock); } static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, - struct usb_driver *drv) + const struct usb_driver *drv) { struct usb_dynid *dynid; - spin_lock(&drv->dynids.lock); + guard(mutex)(&usb_dynids_lock); list_for_each_entry(dynid, &drv->dynids.list, node) { if (usb_match_one_id(intf, &dynid->id)) { - spin_unlock(&drv->dynids.lock); return &dynid->id; } } - spin_unlock(&drv->dynids.lock); return NULL; } @@ -853,7 +850,7 @@ const struct usb_device_id *usb_device_match_id(struct usb_device *udev, EXPORT_SYMBOL_GPL(usb_device_match_id); bool usb_driver_applicable(struct usb_device *udev, - struct usb_device_driver *udrv) + const struct usb_device_driver *udrv) { if (udrv->id_table && udrv->match) return usb_device_match_id(udev, udrv->id_table) != NULL && @@ -873,7 +870,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv) /* devices and interfaces are handled separately */ if (is_usb_device(dev)) { struct usb_device *udev; - struct usb_device_driver *udrv; + const struct usb_device_driver *udrv; /* interface drivers never match devices */ if (!is_usb_device_driver(drv)) @@ -893,7 +890,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv) } else if (is_usb_interface(dev)) { struct usb_interface *intf; - struct usb_driver *usb_drv; + const struct usb_driver *usb_drv; const struct usb_device_id *id; /* device drivers never match interfaces */ @@ -1076,7 +1073,6 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, new_driver->driver.owner = owner; new_driver->driver.mod_name = mod_name; new_driver->driver.dev_groups = new_driver->dev_groups; - spin_lock_init(&new_driver->dynids.lock); INIT_LIST_HEAD(&new_driver->dynids.list); retval = driver_register(&new_driver->driver); diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 4b38b87a13438d382d3bd0d1ace2df069fbb0d00..e48399401608775bf73ba767c979519cc566ad35 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "usb.h" @@ -39,7 +40,7 @@ static ssize_t field##_show(struct device *dev, \ char *buf) \ { \ struct ep_device *ep = to_ep_device(dev); \ - return sprintf(buf, format_string, ep->desc->field); \ + return sysfs_emit(buf, format_string, ep->desc->field); \ } \ static DEVICE_ATTR_RO(field) @@ -52,7 +53,7 @@ static ssize_t wMaxPacketSize_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ep_device *ep = to_ep_device(dev); - return sprintf(buf, "%04x\n", usb_endpoint_maxp(ep->desc)); + return sysfs_emit(buf, "%04x\n", usb_endpoint_maxp(ep->desc)); } static DEVICE_ATTR_RO(wMaxPacketSize); @@ -76,7 +77,7 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr, type = "Interrupt"; break; } - return sprintf(buf, "%s\n", type); + return sysfs_emit(buf, "%s\n", type); } static DEVICE_ATTR_RO(type); @@ -95,7 +96,7 @@ static ssize_t interval_show(struct device *dev, struct device_attribute *attr, interval /= 1000; } - return sprintf(buf, "%d%cs\n", interval, unit); + return sysfs_emit(buf, "%d%cs\n", interval, unit); } static DEVICE_ATTR_RO(interval); @@ -111,7 +112,7 @@ static ssize_t direction_show(struct device *dev, struct device_attribute *attr, direction = "in"; else direction = "out"; - return sprintf(buf, "%s\n", direction); + return sysfs_emit(buf, "%s\n", direction); } static DEVICE_ATTR_RO(direction); diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index 85c999f71ad7c2caae981c1572b95e1d26a44545..5e3c515991f3f100e774cfe8a5c28225a2d00c1f 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -87,7 +88,7 @@ static ssize_t usbport_trig_port_show(struct device *dev, struct usbport_trig_port, attr); - return sprintf(buf, "%d\n", port->observed) + 1; + return sysfs_emit(buf, "%d\n", port->observed) + 1; } static ssize_t usbport_trig_port_store(struct device *dev, diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index e7da2fca11a48cf9c3d53cd53d124d65a1cd751f..45d7af00f8d17eecbf754137a372504254303886 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -166,7 +167,7 @@ static ssize_t location_show(struct device *dev, { struct usb_port *port_dev = to_usb_port(dev); - return sprintf(buf, "0x%08x\n", port_dev->location); + return sysfs_emit(buf, "0x%08x\n", port_dev->location); } static DEVICE_ATTR_RO(location); @@ -191,7 +192,7 @@ static ssize_t connect_type_show(struct device *dev, break; } - return sprintf(buf, "%s\n", result); + return sysfs_emit(buf, "%s\n", result); } static DEVICE_ATTR_RO(connect_type); @@ -210,7 +211,7 @@ static ssize_t over_current_count_show(struct device *dev, { struct usb_port *port_dev = to_usb_port(dev); - return sprintf(buf, "%u\n", port_dev->over_current_count); + return sysfs_emit(buf, "%u\n", port_dev->over_current_count); } static DEVICE_ATTR_RO(over_current_count); @@ -219,7 +220,7 @@ static ssize_t quirks_show(struct device *dev, { struct usb_port *port_dev = to_usb_port(dev); - return sprintf(buf, "%08x\n", port_dev->quirks); + return sysfs_emit(buf, "%08x\n", port_dev->quirks); } static ssize_t quirks_store(struct device *dev, struct device_attribute *attr, @@ -254,7 +255,7 @@ static ssize_t usb3_lpm_permit_show(struct device *dev, p = "0"; } - return sprintf(buf, "%s\n", p); + return sysfs_emit(buf, "%s\n", p); } static ssize_t usb3_lpm_permit_store(struct device *dev, diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 61b6d978892c799e213018bed22d9fb12a19d429..b4cba23831acd2d7d395b9f7683cd3ee3a8623c8 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -925,7 +925,7 @@ static struct bin_attribute *dev_bin_attrs[] = { }; static umode_t dev_bin_attrs_are_visible(struct kobject *kobj, - struct bin_attribute *a, int n) + const struct bin_attribute *a, int n) { struct device *dev = kobj_to_dev(kobj); struct usb_device *udev = to_usb_device(dev); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index b8324ea05b20fb037cff5ae53ec1ac6d6498f6e2..a9b37aeb515bef56cee33a88fdaa93df1f2f6103 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -75,7 +75,7 @@ extern int usb_match_device(struct usb_device *dev, extern const struct usb_device_id *usb_device_match_id(struct usb_device *udev, const struct usb_device_id *id); extern bool usb_driver_applicable(struct usb_device *udev, - struct usb_device_driver *udrv); + const struct usb_device_driver *udrv); extern void usb_forced_unbind_intf(struct usb_interface *intf); extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev); diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index c131719367ecab5429b9f683179705410c0079d5..d7af55a8eced733add04eed7e18e278730884e1b 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -21,7 +21,7 @@ config USB_DWC2 if USB_DWC2 choice - bool "DWC2 Mode Selection" + prompt "DWC2 Mode Selection" default USB_DWC2_DUAL_ROLE if (USB && USB_GADGET) default USB_DWC2_HOST if (USB && !USB_GADGET) default USB_DWC2_PERIPHERAL if (!USB && USB_GADGET) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index c1b7209b94836cd7ca8910b706077e1303daae19..91c80a92d9b8beafe071c06c14f7de7e8c733cf4 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -756,7 +756,7 @@ static struct platform_driver dwc2_platform_driver = { .pm = &dwc2_dev_pm_ops, }, .probe = dwc2_driver_probe, - .remove_new = dwc2_driver_remove, + .remove = dwc2_driver_remove, .shutdown = dwc2_driver_shutdown, }; diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 31078f3d41b88d0e2be63ce9c0b7c92c56a7ef23..310d182e10b50b253d7e5a51674806e6ec442a2a 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -23,7 +23,7 @@ config USB_DWC3_ULPI controller. choice - bool "DWC3 Mode Selection" + prompt "DWC3 Mode Selection" default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET) default USB_DWC3_HOST if (USB && !USB_GADGET) default USB_DWC3_GADGET if (!USB && USB_GADGET) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 98114c2827c09889e63b340450804f7a6d0907d2..f219c82e9619d940300bda6d7cd01cca8977b578 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1409,7 +1409,7 @@ static int dwc3_core_init(struct dwc3 *dwc) /* * When configured in HOST mode, after issuing U3/L2 exit controller - * fails to send proper CRC checksum in CRC5 feild. Because of this + * fails to send proper CRC checksum in CRC5 field. Because of this * behaviour Transaction Error is generated, resulting in reset and * re-enumeration of usb device attached. All the termsel, xcvrsel, * opmode becomes 0 during end of resume. Enabling bit 10 of GUCTL1 @@ -1470,9 +1470,13 @@ static int dwc3_core_init(struct dwc3 *dwc) if (hw_mode != DWC3_GHWPARAMS0_MODE_GADGET && (DWC3_IP_IS(DWC31)) && dwc->maximum_speed == USB_SPEED_SUPER) { - reg = dwc3_readl(dwc->regs, DWC3_LLUCTL); - reg |= DWC3_LLUCTL_FORCE_GEN1; - dwc3_writel(dwc->regs, DWC3_LLUCTL, reg); + int i; + + for (i = 0; i < dwc->num_usb3_ports; i++) { + reg = dwc3_readl(dwc->regs, DWC3_LLUCTL(i)); + reg |= DWC3_LLUCTL_FORCE_GEN1; + dwc3_writel(dwc->regs, DWC3_LLUCTL(i), reg); + } } return 0; @@ -1941,7 +1945,7 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) struct extcon_dev *edev = NULL; const char *name; - if (device_property_read_bool(dev, "extcon")) + if (device_property_present(dev, "extcon")) return extcon_get_edev_by_phandle(dev, 0); /* @@ -2651,7 +2655,7 @@ MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match); static struct platform_driver dwc3_driver = { .probe = dwc3_probe, - .remove_new = dwc3_remove, + .remove = dwc3_remove, .driver = { .name = "dwc3", .of_match_table = of_match_ptr(of_dwc3_match), diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index eab81dfdcc35023cbf13da92c0654bc32824f627..ee73789326bc6112bbd55f2869d372dd0e3216a4 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -81,7 +81,7 @@ #define DWC3_GSNPSREV_MASK 0xffff #define DWC3_GSNPS_ID(p) (((p) & DWC3_GSNPSID_MASK) >> 16) -/* DWC3 registers memory space boundries */ +/* DWC3 registers memory space boundaries */ #define DWC3_XHCI_REGS_START 0x0 #define DWC3_XHCI_REGS_END 0x7fff #define DWC3_GLOBALS_REGS_START 0xc100 @@ -179,7 +179,7 @@ #define DWC3_OEVTEN 0xcc0C #define DWC3_OSTS 0xcc10 -#define DWC3_LLUCTL 0xd024 +#define DWC3_LLUCTL(n) (0xd024 + ((n) * 0x80)) /* Bit fields */ @@ -915,6 +915,7 @@ struct dwc3_hwparams { #define DWC3_MODE(n) ((n) & 0x7) /* HWPARAMS1 */ +#define DWC3_SPRAM_TYPE(n) (((n) >> 23) & 1) #define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15) /* HWPARAMS3 */ @@ -925,6 +926,9 @@ struct dwc3_hwparams { #define DWC3_NUM_IN_EPS(p) (((p)->hwparams3 & \ (DWC3_NUM_IN_EPS_MASK)) >> 18) +/* HWPARAMS6 */ +#define DWC3_RAM0_DEPTH(n) (((n) & (0xffff0000)) >> 16) + /* HWPARAMS7 */ #define DWC3_RAM1_DEPTH(n) ((n) & 0xffff) @@ -937,18 +941,14 @@ struct dwc3_hwparams { * @request: struct usb_request to be transferred * @list: a list_head used for request queueing * @dep: struct dwc3_ep owning this request - * @sg: pointer to first incomplete sg * @start_sg: pointer to the sg which should be queued next * @num_pending_sgs: counter to pending sgs - * @num_queued_sgs: counter to the number of sgs which already got queued * @remaining: amount of data remaining * @status: internal dwc3 request status tracking * @epnum: endpoint number to which this request refers * @trb: pointer to struct dwc3_trb * @trb_dma: DMA address of @trb * @num_trbs: number of TRBs used by this request - * @needs_extra_trb: true when request needs one extra TRB (either due to ZLP - * or unaligned OUT) * @direction: IN or OUT direction flag * @mapped: true when request has been dma-mapped */ @@ -960,7 +960,6 @@ struct dwc3_request { struct scatterlist *start_sg; unsigned int num_pending_sgs; - unsigned int num_queued_sgs; unsigned int remaining; unsigned int status; @@ -978,7 +977,6 @@ struct dwc3_request { unsigned int num_trbs; - unsigned int needs_extra_trb:1; unsigned int direction:1; unsigned int mapped:1; }; diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c index fad151e78fd669f7a136d9217a8124ae88f9473c..5e3d1741701f7e871487e609066beadc022a59f4 100644 --- a/drivers/usb/dwc3/dwc3-am62.c +++ b/drivers/usb/dwc3/dwc3-am62.c @@ -377,7 +377,7 @@ MODULE_DEVICE_TABLE(of, dwc3_ti_of_match); static struct platform_driver dwc3_ti_driver = { .probe = dwc3_ti_probe, - .remove_new = dwc3_ti_remove, + .remove = dwc3_ti_remove, .driver = { .name = "dwc3-am62", .pm = DEV_PM_OPS, diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 9a6e988d165a6776794547395e41577d91e76a41..f5d963fae9e069e1bd145ff5bd1b704da89fb74c 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -243,7 +243,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(dwc3_exynos_dev_pm_ops, static struct platform_driver dwc3_exynos_driver = { .probe = dwc3_exynos_probe, - .remove_new = dwc3_exynos_remove, + .remove = dwc3_exynos_remove, .driver = { .name = "exynos-dwc3", .of_match_table = exynos_dwc3_match, diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c index 64c0cd1995aa066364170990f4a92c89ff947f0f..356812cbcd884aa43794e428d4148dfbb0623c44 100644 --- a/drivers/usb/dwc3/dwc3-imx8mp.c +++ b/drivers/usb/dwc3/dwc3-imx8mp.c @@ -400,7 +400,7 @@ MODULE_DEVICE_TABLE(of, dwc3_imx8mp_of_match); static struct platform_driver dwc3_imx8mp_driver = { .probe = dwc3_imx8mp_probe, - .remove_new = dwc3_imx8mp_remove, + .remove = dwc3_imx8mp_remove, .driver = { .name = "imx8mp-dwc3", .pm = pm_ptr(&dwc3_imx8mp_dev_pm_ops), diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 8899348b627632e647c1762c50106a124ac6eac8..7ee1610162b94f4d02908776338ba637f9bb2d60 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -208,7 +208,7 @@ MODULE_DEVICE_TABLE(of, kdwc3_of_match); static struct platform_driver kdwc3_driver = { .probe = kdwc3_probe, - .remove_new = kdwc3_remove, + .remove = kdwc3_remove, .driver = { .name = "keystone-dwc3", .of_match_table = kdwc3_of_match, diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index 2c07c038b584dc9b4487a76d2a27ec62ec383bf9..7d80bf7b18b0d290d38c08f495b15778122c8782 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -968,7 +968,7 @@ MODULE_DEVICE_TABLE(of, dwc3_meson_g12a_match); static struct platform_driver dwc3_meson_g12a_driver = { .probe = dwc3_meson_g12a_probe, - .remove_new = dwc3_meson_g12a_remove, + .remove = dwc3_meson_g12a_remove, .driver = { .name = "dwc3-meson-g12a", .of_match_table = dwc3_meson_g12a_match, diff --git a/drivers/usb/dwc3/dwc3-octeon.c b/drivers/usb/dwc3/dwc3-octeon.c index 1a3b205367fd55e1362827b4e754f15cb3b0afa1..42bfc14ae0c4644595774e222b8948cb2e0b6da1 100644 --- a/drivers/usb/dwc3/dwc3-octeon.c +++ b/drivers/usb/dwc3/dwc3-octeon.c @@ -520,7 +520,7 @@ MODULE_DEVICE_TABLE(of, dwc3_octeon_of_match); static struct platform_driver dwc3_octeon_driver = { .probe = dwc3_octeon_probe, - .remove_new = dwc3_octeon_remove, + .remove = dwc3_octeon_remove, .driver = { .name = "dwc3-octeon", .of_match_table = dwc3_octeon_of_match, diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index be7be00ecb34911ae170da7f3f8f4796442b2732..a4954a21be9301067a13ac99b17320ea49d76d66 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -180,7 +180,7 @@ MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); static struct platform_driver dwc3_of_simple_driver = { .probe = dwc3_of_simple_probe, - .remove_new = dwc3_of_simple_remove, + .remove = dwc3_of_simple_remove, .shutdown = dwc3_of_simple_shutdown, .driver = { .name = "dwc3-of-simple", diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 2a11fc0ee84f1ebcc285cca1d999561f4e432ab4..b261c46124c612a79fa84970dccc321511583370 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -416,7 +416,7 @@ static int dwc3_omap_extcon_register(struct dwc3_omap *omap) struct device_node *node = omap->dev->of_node; struct extcon_dev *edev; - if (of_property_read_bool(node, "extcon")) { + if (of_property_present(node, "extcon")) { edev = extcon_get_edev_by_phandle(omap->dev, 0); if (IS_ERR(edev)) { dev_vdbg(omap->dev, "couldn't get extcon device\n"); @@ -611,7 +611,7 @@ static const struct dev_pm_ops dwc3_omap_dev_pm_ops = { static struct platform_driver dwc3_omap_driver = { .probe = dwc3_omap_probe, - .remove_new = dwc3_omap_remove, + .remove = dwc3_omap_remove, .driver = { .name = "omap-dwc3", .of_match_table = of_dwc3_match, diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index c1d4b52f25b0631950e2360ec95d0ef978dfa8fd..58683bb672e9522deb321c38daffd856c0d9029c 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -161,7 +161,7 @@ static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom) struct extcon_dev *host_edev; int ret; - if (!of_property_read_bool(dev->of_node, "extcon")) + if (!of_property_present(dev->of_node, "extcon")) return 0; qcom->edev = extcon_get_edev_by_phandle(dev, 0); @@ -921,7 +921,7 @@ MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match); static struct platform_driver dwc3_qcom_driver = { .probe = dwc3_qcom_probe, - .remove_new = dwc3_qcom_remove, + .remove = dwc3_qcom_remove, .driver = { .name = "dwc3-qcom", .pm = &dwc3_qcom_dev_pm_ops, diff --git a/drivers/usb/dwc3/dwc3-rtk.c b/drivers/usb/dwc3/dwc3-rtk.c index e9c8b032c72cb6a303e921e1e855217ad4f59c73..56c53e0c025748e8ef2fd8685b3d617c28d44a69 100644 --- a/drivers/usb/dwc3/dwc3-rtk.c +++ b/drivers/usb/dwc3/dwc3-rtk.c @@ -441,7 +441,7 @@ static const struct dev_pm_ops dwc3_rtk_dev_pm_ops = { static struct platform_driver dwc3_rtk_driver = { .probe = dwc3_rtk_probe, - .remove_new = dwc3_rtk_remove, + .remove = dwc3_rtk_remove, .driver = { .name = "rtk-dwc3", .of_match_table = rtk_dwc3_match, diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index 2841021f3557f88ba5ff7604e9209ee85b2fa1d1..e16c3237180e970c184dfdb147c8abd46ff429a3 100644 --- a/drivers/usb/dwc3/dwc3-st.c +++ b/drivers/usb/dwc3/dwc3-st.c @@ -356,7 +356,7 @@ MODULE_DEVICE_TABLE(of, st_dwc3_match); static struct platform_driver st_dwc3_driver = { .probe = st_dwc3_probe, - .remove_new = st_dwc3_remove, + .remove = st_dwc3_remove, .driver = { .name = "usb-st-dwc3", .of_match_table = st_dwc3_match, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index b5e5be424ce9978b2ebb6ad61a953dc452d28bd0..e3738e1610db208477b7dd912ba74177604a900d 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -420,7 +420,7 @@ static const struct dev_pm_ops dwc3_xlnx_dev_pm_ops = { static struct platform_driver dwc3_xlnx_driver = { .probe = dwc3_xlnx_probe, - .remove_new = dwc3_xlnx_remove, + .remove = dwc3_xlnx_remove, .driver = { .name = "dwc3-xilinx", .of_match_table = dwc3_xlnx_of_match, diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index c9533a99e47c89d61f4c06609680e91a5320600f..666ac432f52d67300c681727a5ed651196634d0c 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -145,7 +145,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, * Unfortunately we have uncovered a limitation wrt the Data Phase. * * Section 9.4 says we can wait for the XferNotReady(DATA) event to - * come before issueing Start Transfer command, but if we do, we will + * come before issuing Start Transfer command, but if we do, we will * miss situations where the host starts another SETUP phase instead of * the DATA phase. Such cases happen at least on TD.7.6 of the Link * Layer Compliance Suite. @@ -232,7 +232,7 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) /* stall is always issued on EP0 */ dep = dwc->eps[0]; __dwc3_gadget_ep_set_halt(dep, 1, false); - dep->flags &= DWC3_EP_RESOURCE_ALLOCATED; + dep->flags &= DWC3_EP_RESOURCE_ALLOCATED | DWC3_EP_TRANSFER_STARTED; dep->flags |= DWC3_EP_ENABLED; dwc->delayed_status = false; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4959c26d3b71b89347e9118b1fb732b512ba8c05..83dc7304d70109ac9675d60f447f3cf96e9c50b5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -197,7 +197,6 @@ static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, list_del(&req->list); req->remaining = 0; - req->needs_extra_trb = false; req->num_trbs = 0; if (req->request.status == -EINPROGRESS) @@ -687,6 +686,44 @@ static int dwc3_gadget_calc_tx_fifo_size(struct dwc3 *dwc, int mult) return fifo_size; } +/** + * dwc3_gadget_calc_ram_depth - calculates the ram depth for txfifo + * @dwc: pointer to the DWC3 context + */ +static int dwc3_gadget_calc_ram_depth(struct dwc3 *dwc) +{ + int ram_depth; + int fifo_0_start; + bool is_single_port_ram; + + /* Check supporting RAM type by HW */ + is_single_port_ram = DWC3_SPRAM_TYPE(dwc->hwparams.hwparams1); + + /* + * If a single port RAM is utilized, then allocate TxFIFOs from + * RAM0. otherwise, allocate them from RAM1. + */ + ram_depth = is_single_port_ram ? DWC3_RAM0_DEPTH(dwc->hwparams.hwparams6) : + DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); + + /* + * In a single port RAM configuration, the available RAM is shared + * between the RX and TX FIFOs. This means that the txfifo can begin + * at a non-zero address. + */ + if (is_single_port_ram) { + u32 reg; + + /* Check if TXFIFOs start at non-zero addr */ + reg = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); + fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(reg); + + ram_depth -= (fifo_0_start >> 16); + } + + return ram_depth; +} + /** * dwc3_gadget_clear_tx_fifos - Clears txfifo allocation * @dwc: pointer to the DWC3 context @@ -753,7 +790,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) { struct dwc3 *dwc = dep->dwc; int fifo_0_start; - int ram1_depth; + int ram_depth; int fifo_size; int min_depth; int num_in_ep; @@ -773,17 +810,32 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) if (dep->flags & DWC3_EP_TXFIFO_RESIZED) return 0; - ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); + ram_depth = dwc3_gadget_calc_ram_depth(dwc); - if ((dep->endpoint.maxburst > 1 && - usb_endpoint_xfer_bulk(dep->endpoint.desc)) || - usb_endpoint_xfer_isoc(dep->endpoint.desc)) - num_fifos = 3; - - if (dep->endpoint.maxburst > 6 && - (usb_endpoint_xfer_bulk(dep->endpoint.desc) || - usb_endpoint_xfer_isoc(dep->endpoint.desc)) && DWC3_IP_IS(DWC31)) - num_fifos = dwc->tx_fifo_resize_max_num; + switch (dwc->gadget->speed) { + case USB_SPEED_SUPER_PLUS: + case USB_SPEED_SUPER: + if (usb_endpoint_xfer_bulk(dep->endpoint.desc) || + usb_endpoint_xfer_isoc(dep->endpoint.desc)) + num_fifos = min_t(unsigned int, + dep->endpoint.maxburst, + dwc->tx_fifo_resize_max_num); + break; + case USB_SPEED_HIGH: + if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { + num_fifos = min_t(unsigned int, + usb_endpoint_maxp_mult(dep->endpoint.desc) + 1, + dwc->tx_fifo_resize_max_num); + break; + } + fallthrough; + case USB_SPEED_FULL: + if (usb_endpoint_xfer_bulk(dep->endpoint.desc)) + num_fifos = 2; + break; + default: + break; + } /* FIFO size for a single buffer */ fifo = dwc3_gadget_calc_tx_fifo_size(dwc, 1); @@ -794,7 +846,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) /* Reserve at least one FIFO for the number of IN EPs */ min_depth = num_in_ep * (fifo + 1); - remaining = ram1_depth - min_depth - dwc->last_fifo_depth; + remaining = ram_depth - min_depth - dwc->last_fifo_depth; remaining = max_t(int, 0, remaining); /* * We've already reserved 1 FIFO per EP, so check what we can fit in @@ -820,9 +872,9 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) dwc->last_fifo_depth += DWC31_GTXFIFOSIZ_TXFDEP(fifo_size); /* Check fifo size allocation doesn't exceed available RAM size. */ - if (dwc->last_fifo_depth >= ram1_depth) { + if (dwc->last_fifo_depth >= ram_depth) { dev_err(dwc->dev, "Fifosize(%d) > RAM size(%d) %s depth:%d\n", - dwc->last_fifo_depth, ram1_depth, + dwc->last_fifo_depth, ram_depth, dep->endpoint.name, fifo_size); if (DWC3_IP_IS(DWC3)) fifo_size = DWC3_GTXFIFOSIZ_TXFDEP(fifo_size); @@ -1177,11 +1229,14 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) * pending to be processed by the driver. */ if (dep->trb_enqueue == dep->trb_dequeue) { + struct dwc3_request *req; + /* - * If there is any request remained in the started_list at - * this point, that means there is no TRB available. + * If there is any request remained in the started_list with + * active TRBs at this point, then there is no TRB available. */ - if (!list_empty(&dep->started_list)) + req = next_request(&dep->started_list); + if (req && req->num_trbs) return 0; return DWC3_TRB_NUM - 1; @@ -1384,6 +1439,7 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); unsigned int rem = req->request.length % maxp; unsigned int num_trbs = 1; + bool needs_extra_trb; if (dwc3_needs_extra_trb(dep, req)) num_trbs++; @@ -1391,15 +1447,15 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, if (dwc3_calc_trbs_left(dep) < num_trbs) return 0; - req->needs_extra_trb = num_trbs > 1; + needs_extra_trb = num_trbs > 1; /* Prepare a normal TRB */ if (req->direction || req->request.length) dwc3_prepare_one_trb(dep, req, entry_length, - req->needs_extra_trb, node, false, false); + needs_extra_trb, node, false, false); /* Prepare extra TRBs for ZLP and MPS OUT transfer alignment */ - if ((!req->direction && !req->request.length) || req->needs_extra_trb) + if ((!req->direction && !req->request.length) || needs_extra_trb) dwc3_prepare_one_trb(dep, req, req->direction ? 0 : maxp - rem, false, 1, true, false); @@ -1414,8 +1470,8 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, struct scatterlist *s; int i; unsigned int length = req->request.length; - unsigned int remaining = req->request.num_mapped_sgs - - req->num_queued_sgs; + unsigned int remaining = req->num_pending_sgs; + unsigned int num_queued_sgs = req->request.num_mapped_sgs - remaining; unsigned int num_trbs = req->num_trbs; bool needs_extra_trb = dwc3_needs_extra_trb(dep, req); @@ -1423,7 +1479,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, * If we resume preparing the request, then get the remaining length of * the request and resume where we left off. */ - for_each_sg(req->request.sg, s, req->num_queued_sgs, i) + for_each_sg(req->request.sg, s, num_queued_sgs, i) length -= sg_dma_len(s); for_each_sg(sg, s, remaining, i) { @@ -1488,7 +1544,6 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, if (!last_sg) req->start_sg = sg_next(s); - req->num_queued_sgs++; req->num_pending_sgs--; /* @@ -1569,9 +1624,7 @@ static int dwc3_prepare_trbs(struct dwc3_ep *dep) if (ret) return ret; - req->sg = req->request.sg; - req->start_sg = req->sg; - req->num_queued_sgs = 0; + req->start_sg = req->request.sg; req->num_pending_sgs = req->request.num_mapped_sgs; if (req->num_pending_sgs > 0) { @@ -3075,7 +3128,7 @@ static int dwc3_gadget_check_config(struct usb_gadget *g) struct dwc3 *dwc = gadget_to_dwc(g); struct usb_ep *ep; int fifo_size = 0; - int ram1_depth; + int ram_depth; int ep_num = 0; if (!dwc->do_fifo_resize) @@ -3098,8 +3151,8 @@ static int dwc3_gadget_check_config(struct usb_gadget *g) fifo_size += dwc->max_cfg_eps; /* Check if we can fit a single fifo per endpoint */ - ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); - if (fifo_size > ram1_depth) + ram_depth = dwc3_gadget_calc_ram_depth(dwc); + if (fifo_size > ram_depth) return -ENOMEM; return 0; @@ -3416,20 +3469,16 @@ static int dwc3_gadget_ep_reclaim_trb_sg(struct dwc3_ep *dep, int status) { struct dwc3_trb *trb; - struct scatterlist *sg = req->sg; - struct scatterlist *s; - unsigned int num_queued = req->num_queued_sgs; + unsigned int num_completed_trbs = req->num_trbs; unsigned int i; int ret = 0; - for_each_sg(sg, s, num_queued, i) { + for (i = 0; i < num_completed_trbs; i++) { trb = &dep->trb_pool[dep->trb_dequeue]; - req->sg = sg_next(s); - req->num_queued_sgs--; - ret = dwc3_gadget_ep_reclaim_completed_trb(dep, req, - trb, event, status, true); + trb, event, status, + !!(trb->ctrl & DWC3_TRB_CTRL_CHN)); if (ret) break; } @@ -3437,19 +3486,9 @@ static int dwc3_gadget_ep_reclaim_trb_sg(struct dwc3_ep *dep, return ret; } -static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep, - struct dwc3_request *req, const struct dwc3_event_depevt *event, - int status) -{ - struct dwc3_trb *trb = &dep->trb_pool[dep->trb_dequeue]; - - return dwc3_gadget_ep_reclaim_completed_trb(dep, req, trb, - event, status, false); -} - static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) { - return req->num_pending_sgs == 0 && req->num_queued_sgs == 0; + return req->num_pending_sgs == 0 && req->num_trbs == 0; } static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, @@ -3459,24 +3498,13 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, int request_status; int ret; - if (req->request.num_mapped_sgs) - ret = dwc3_gadget_ep_reclaim_trb_sg(dep, req, event, - status); - else - ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, - status); + ret = dwc3_gadget_ep_reclaim_trb_sg(dep, req, event, status); req->request.actual = req->request.length - req->remaining; if (!dwc3_gadget_ep_request_completed(req)) goto out; - if (req->needs_extra_trb) { - ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, - status); - req->needs_extra_trb = false; - } - /* * The event status only reflects the status of the TRB with IOC set. * For the requests that don't set interrupt on completion, the driver diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index e0533cee6870badb266560d41b3b62ae02a1f608..b48e108fc8fe7343446946e7babf9ba3bc0d2dc3 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -35,7 +35,7 @@ static void dwc3_power_off_all_roothub_ports(struct dwc3 *dwc) u32 reg; int i; - /* xhci regs is not mapped yet, do it temperary here */ + /* xhci regs are not mapped yet, do it temporarily here */ if (dwc->xhci_resources[0].start) { xhci_regs = ioremap(dwc->xhci_resources[0].start, DWC3_XHCI_REGS_END); if (!xhci_regs) { diff --git a/drivers/usb/fotg210/fotg210-core.c b/drivers/usb/fotg210/fotg210-core.c index 0655afe7f9779f02b721d62e3db065c7bc48fc26..49f25a70b32ebdd8bdad672d31342d5f89c4a502 100644 --- a/drivers/usb/fotg210/fotg210-core.c +++ b/drivers/usb/fotg210/fotg210-core.c @@ -195,7 +195,7 @@ static struct platform_driver fotg210_driver = { .of_match_table = of_match_ptr(fotg210_of_match), }, .probe = fotg210_probe, - .remove_new = fotg210_remove, + .remove = fotg210_remove, }; static int __init fotg210_init(void) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f25dd2cb5d03b148be6f45e3517908de258db03c..bdda8c74602dea0771dfabfb079fc702b031acbc 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1844,7 +1844,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) cdev->desc.bcdUSB = cpu_to_le16(0x0200); } - value = min(w_length, (u16) sizeof cdev->desc); + value = min_t(u16, w_length, sizeof(cdev->desc)); memcpy(req->buf, &cdev->desc, value); break; case USB_DT_DEVICE_QUALIFIER: @@ -1863,19 +1863,19 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_DT_CONFIG: value = config_desc(cdev, w_value); if (value >= 0) - value = min(w_length, (u16) value); + value = min_t(u16, w_length, value); break; case USB_DT_STRING: value = get_string(cdev, req->buf, w_index, w_value & 0xff); if (value >= 0) - value = min(w_length, (u16) value); + value = min_t(u16, w_length, value); break; case USB_DT_BOS: if (gadget_is_superspeed(gadget) || gadget->lpm_capable || cdev->use_webusb) { value = bos_desc(cdev); - value = min(w_length, (u16) value); + value = min_t(u16, w_length, value); } break; case USB_DT_OTG: @@ -1930,7 +1930,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) *(u8 *)req->buf = cdev->config->bConfigurationValue; else *(u8 *)req->buf = 0; - value = min(w_length, (u16) 1); + value = min_t(u16, w_length, 1); break; /* function drivers must handle get/set altsetting */ @@ -1976,7 +1976,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (value < 0) break; *((u8 *)req->buf) = value; - value = min(w_length, (u16) 1); + value = min_t(u16, w_length, 1); break; case USB_REQ_GET_STATUS: if (gadget_is_otg(gadget) && gadget->hnp_polling_support && @@ -2111,8 +2111,20 @@ unknown: memset(buf, 0, w_length); buf[5] = 0x01; switch (ctrl->bRequestType & USB_RECIP_MASK) { + /* + * The Microsoft CompatID OS Descriptor Spec(w_index = 0x4) and + * Extended Prop OS Desc Spec(w_index = 0x5) state that the + * HighByte of wValue is the InterfaceNumber and the LowByte is + * the PageNumber. This high/low byte ordering is incorrectly + * documented in the Spec. USB analyzer output on the below + * request packets show the high/low byte inverted i.e LowByte + * is the InterfaceNumber and the HighByte is the PageNumber. + * Since we dont support >64KB CompatID/ExtendedProp descriptors, + * PageNumber is set to 0. Hence verify that the HighByte is 0 + * for below two cases. + */ case USB_RECIP_DEVICE: - if (w_index != 0x4 || (w_value & 0xff)) + if (w_index != 0x4 || (w_value >> 8)) break; buf[6] = w_index; /* Number of ext compat interfaces */ @@ -2128,9 +2140,9 @@ unknown: } break; case USB_RECIP_INTERFACE: - if (w_index != 0x5 || (w_value & 0xff)) + if (w_index != 0x5 || (w_value >> 8)) break; - interface = w_value >> 8; + interface = w_value & 0xFF; if (interface >= MAX_CONFIG_INTERFACES || !os_desc_cfg->interface[interface]) break; diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index b1f625245713a47060094e341e076a80fd3225a8..95f144a54ed96fdd0e58bc2ac015484a89050258 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -57,11 +57,11 @@ EXPORT_SYMBOL_GPL(usb_descriptor_fillbuf); * usb_gadget_config_buf - builts a complete configuration descriptor * @config: Header for the descriptor, including characteristics such * as power requirements and number of interfaces. - * @desc: Null-terminated vector of pointers to the descriptors (interface, - * endpoint, etc) defining all functions in this device configuration. * @buf: Buffer for the resulting configuration descriptor. * @length: Length of buffer. If this is not big enough to hold the * entire configuration descriptor, an error code will be returned. + * @desc: Null-terminated vector of pointers to the descriptors (interface, + * endpoint, etc) defining all functions in this device configuration. * * This copies descriptors into the response buffer, building a descriptor * for that configuration. It returns the buffer length or a negative diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index c82a6a0fba93ddc34a93c56aa2104241fbac2bdb..6499a88d346cd3dc62a74dd649c9345f400a49aa 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1184,7 +1184,7 @@ static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page, struct gadget_info *gi = os_desc_item_to_gadget_info(item); int res, l; - l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1); + l = min_t(int, len, OS_STRING_QW_SIGN_LEN >> 1); if (page[l - 1] == '\n') --l; diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 87917a7d4a9be89f30fc34878978f08446ea6aae..7ce1637276f099398d695b174afc072c36c5dd93 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -41,6 +41,10 @@ obj-$(CONFIG_USB_F_UAC1_LEGACY) += usb_f_uac1_legacy.o usb_f_uac2-y := f_uac2.o obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o +ifneq ($(CONFIG_TRACING),) + CFLAGS_uvc_trace.o := -I$(src) + usb_f_uvc-y += uvc_trace.o +endif obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o usb_f_midi-y := f_midi.o obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 2920f8000bbd83a80fa92bcd6721acda99ef6960..ad79eb0f729b34b0989a0513888211c96a62c9cb 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -49,7 +49,7 @@ #define DMABUF_ENQUEUE_TIMEOUT_MS 5000 -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); /* Reference counter handling */ static void ffs_data_get(struct ffs_data *ffs); @@ -456,7 +456,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, } /* FFS_SETUP_PENDING and not stall */ - len = min(len, (size_t)le16_to_cpu(ffs->ev.setup.wLength)); + len = min_t(size_t, len, le16_to_cpu(ffs->ev.setup.wLength)); spin_unlock_irq(&ffs->ev.waitq.lock); @@ -590,7 +590,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, /* unlocks spinlock */ return __ffs_ep0_read_events(ffs, buf, - min(n, (size_t)ffs->ev.count)); + min_t(size_t, n, ffs->ev.count)); case FFS_SETUP_PENDING: if (ffs->ev.setup.bRequestType & USB_DIR_IN) { @@ -599,7 +599,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, goto done_mutex; } - len = min(len, (size_t)le16_to_cpu(ffs->ev.setup.wLength)); + len = min_t(size_t, len, le16_to_cpu(ffs->ev.setup.wLength)); spin_unlock_irq(&ffs->ev.waitq.lock); diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 08e0d1c511e8d969fe74ad098c9b5b0b7b405ebe..2eae8fc2e0db783ed65c489594ab42ac22b3a908 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -500,7 +500,7 @@ static int fsg_setup(struct usb_function *f, *(u8 *)req->buf = _fsg_common_get_max_lun(fsg->common); /* Respond with data/status */ - req->length = min((u16)1, w_length); + req->length = min_t(u16, 1, w_length); return ep0_queue(fsg->common); } @@ -655,7 +655,7 @@ static int do_read(struct fsg_common *common) * And don't try to read past the end of the file. */ amount = min(amount_left, FSG_BUFLEN); - amount = min((loff_t)amount, + amount = min_t(loff_t, amount, curlun->file_length - file_offset); /* Wait for the next buffer to become available */ @@ -1005,7 +1005,7 @@ static int do_verify(struct fsg_common *common) * And don't try to read past the end of the file. */ amount = min(amount_left, FSG_BUFLEN); - amount = min((loff_t)amount, + amount = min_t(loff_t, amount, curlun->file_length - file_offset); if (amount == 0) { curlun->sense_data = @@ -2167,7 +2167,7 @@ unknown_cmnd: if (reply == -EINVAL) reply = 0; /* Error reply length */ if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) { - reply = min((u32)reply, common->data_size_from_cmnd); + reply = min_t(u32, reply, common->data_size_from_cmnd); bh->inreq->length = reply; bh->state = BUF_STATE_FULL; common->residue -= reply; diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 1067847cc07995150368f57fab2469fc81e5ab5f..837fcdfa3840ff1dc2fbe819c858f8ab91d915c6 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -819,9 +819,9 @@ static int f_midi_register_card(struct f_midi *midi) goto fail; } - strcpy(card->driver, f_midi_longname); - strcpy(card->longname, f_midi_longname); - strcpy(card->shortname, f_midi_shortname); + strscpy(card->driver, f_midi_longname); + strscpy(card->longname, f_midi_longname); + strscpy(card->shortname, f_midi_shortname); /* Set up rawmidi */ snd_component_add(card, "MIDI"); @@ -833,7 +833,7 @@ static int f_midi_register_card(struct f_midi *midi) } midi->rmidi = rmidi; midi->in_last_port = 0; - strcpy(rmidi->name, card->shortname); + strscpy(rmidi->name, card->shortname); rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c index 8285df9ed6fd781bf6fb1ec2d0c5b27145f6fffb..ee3d9e3578f791bd14393da3b9074b11ecd9023d 100644 --- a/drivers/usb/gadget/function/f_midi2.c +++ b/drivers/usb/gadget/function/f_midi2.c @@ -1285,10 +1285,8 @@ static int f_midi2_set_alt(struct usb_function *fn, unsigned int intf, if (alt == 0) op_mode = MIDI_OP_MODE_MIDI1; - else if (alt == 1) - op_mode = MIDI_OP_MODE_MIDI2; else - op_mode = MIDI_OP_MODE_UNSET; + op_mode = MIDI_OP_MODE_MIDI2; if (midi2->operation_mode == op_mode) return 0; diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 40187b7112e79cf2b25837061c75ebefc88a9544..aa6ab666741a9518690995ccdc04e742b4359a0e 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -465,7 +465,7 @@ uvc_register_video(struct uvc_device *uvc) memcpy(mem, desc, (desc)->bLength); \ *(dst)++ = mem; \ mem += (desc)->bLength; \ - } while (0); + } while (0) #define UVC_COPY_DESCRIPTORS(mem, dst, src) \ do { \ @@ -991,6 +991,8 @@ static void uvc_function_unbind(struct usb_configuration *c, uvcg_info(f, "%s()\n", __func__); + kthread_cancel_work_sync(&video->hw_submit); + if (video->async_wq) destroy_workqueue(video->async_wq); diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index cb35687b11e7e986dd6d8a07be90ba0f994276ef..6f44dd732315074e215f75e5df99c289f9cebe35 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -71,6 +71,11 @@ extern unsigned int uvc_gadget_trace_param; #define UVCG_REQUEST_HEADER_LEN 12 +#define UVCG_REQ_MAX_INT_COUNT 16 +#define UVCG_REQ_MAX_ZERO_COUNT (2 * UVCG_REQ_MAX_INT_COUNT) + +#define UVCG_STREAMING_MIN_BUFFERS 2 + /* ------------------------------------------------------------------------ * Structures */ @@ -91,16 +96,24 @@ struct uvc_video { struct work_struct pump; struct workqueue_struct *async_wq; + struct kthread_worker *kworker; + struct kthread_work hw_submit; + + atomic_t queued; + /* Frame parameters */ u8 bpp; u32 fcc; unsigned int width; unsigned int height; unsigned int imagesize; + unsigned int interval; struct mutex mutex; /* protects frame parameters */ unsigned int uvc_num_requests; + unsigned int reqs_per_frame; + /* Requests */ bool is_enabled; /* tracks whether video stream is enabled */ unsigned int req_size; diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 6fac696ea846370416defcb76c809440a7551560..f131943254a4c44d83ce9be4b03d26a5dfd6ec88 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -1566,11 +1566,13 @@ static const struct uvcg_config_group_type uvcg_control_grp_type = { /* ----------------------------------------------------------------------------- * streaming/uncompressed * streaming/mjpeg + * streaming/framebased */ static const char * const uvcg_format_names[] = { "uncompressed", "mjpeg", + "framebased", }; static struct uvcg_color_matching * @@ -1777,6 +1779,9 @@ static int uvcg_streaming_header_allow_link(struct config_item *src, target_fmt = container_of(to_config_group(target), struct uvcg_format, group); + if (!target_fmt) + goto out; + uvcg_format_set_indices(to_config_group(target)); format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); @@ -1816,6 +1821,9 @@ static void uvcg_streaming_header_drop_link(struct config_item *src, target_fmt = container_of(to_config_group(target), struct uvcg_format, group); + if (!target_fmt) + goto out; + list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry) if (format_ptr->fmt == target_fmt) { list_del(&format_ptr->entry); @@ -1826,6 +1834,7 @@ static void uvcg_streaming_header_drop_link(struct config_item *src, --target_fmt->linked; +out: mutex_unlock(&opts->lock); mutex_unlock(su_mutex); } @@ -2022,6 +2031,7 @@ UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32); UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32); UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32); UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32); +UVCG_FRAME_ATTR(dw_bytes_perline, dwBytesPerLine, 32); #undef UVCG_FRAME_ATTR @@ -2035,7 +2045,7 @@ static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item, int result, i; char *pg = page; - mutex_lock(su_mutex); /* for navigating configfs hierarchy */ + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; opts = to_f_uvc_opts(opts_item); @@ -2105,7 +2115,7 @@ end: UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); -static struct configfs_attribute *uvcg_frame_attrs[] = { +static struct configfs_attribute *uvcg_frame_attrs1[] = { &uvcg_frame_attr_b_frame_index, &uvcg_frame_attr_bm_capabilities, &uvcg_frame_attr_w_width, @@ -2118,12 +2128,31 @@ static struct configfs_attribute *uvcg_frame_attrs[] = { NULL, }; -static const struct config_item_type uvcg_frame_type = { +static struct configfs_attribute *uvcg_frame_attrs2[] = { + &uvcg_frame_attr_b_frame_index, + &uvcg_frame_attr_bm_capabilities, + &uvcg_frame_attr_w_width, + &uvcg_frame_attr_w_height, + &uvcg_frame_attr_dw_min_bit_rate, + &uvcg_frame_attr_dw_max_bit_rate, + &uvcg_frame_attr_dw_default_frame_interval, + &uvcg_frame_attr_dw_frame_interval, + &uvcg_frame_attr_dw_bytes_perline, + NULL, +}; + +static const struct config_item_type uvcg_frame_type1 = { .ct_item_ops = &uvcg_config_item_ops, - .ct_attrs = uvcg_frame_attrs, + .ct_attrs = uvcg_frame_attrs1, .ct_owner = THIS_MODULE, }; +static const struct config_item_type uvcg_frame_type2 = { + .ct_item_ops = &uvcg_config_item_ops, + .ct_attrs = uvcg_frame_attrs2, + .ct_owner = THIS_MODULE, +}; + static struct config_item *uvcg_frame_make(struct config_group *group, const char *name) { @@ -2145,6 +2174,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group, h->frame.dw_max_bit_rate = 55296000; h->frame.dw_max_video_frame_buffer_size = 460800; h->frame.dw_default_frame_interval = 666666; + h->frame.dw_bytes_perline = 0; opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; opts = to_f_uvc_opts(opts_item); @@ -2157,6 +2187,9 @@ static struct config_item *uvcg_frame_make(struct config_group *group, } else if (fmt->type == UVCG_MJPEG) { h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG; h->fmt_type = UVCG_MJPEG; + } else if (fmt->type == UVCG_FRAMEBASED) { + h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED; + h->fmt_type = UVCG_FRAMEBASED; } else { mutex_unlock(&opts->lock); kfree(h); @@ -2175,7 +2208,10 @@ static struct config_item *uvcg_frame_make(struct config_group *group, ++fmt->num_frames; mutex_unlock(&opts->lock); - config_item_init_type_name(&h->item, name, &uvcg_frame_type); + if (fmt->type == UVCG_FRAMEBASED) + config_item_init_type_name(&h->item, name, &uvcg_frame_type2); + else + config_item_init_type_name(&h->item, name, &uvcg_frame_type1); return &h->item; } @@ -2215,9 +2251,6 @@ static void uvcg_format_set_indices(struct config_group *fmt) list_for_each_entry(ci, &fmt->cg_children, ci_entry) { struct uvcg_frame *frm; - if (ci->ci_type != &uvcg_frame_type) - continue; - frm = to_uvcg_frame(ci); frm->frame.b_frame_index = i++; } @@ -2677,6 +2710,251 @@ static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { .name = "mjpeg", }; +/* ----------------------------------------------------------------------------- + * streaming/framebased/ + */ + +static struct configfs_group_operations uvcg_framebased_group_ops = { + .make_item = uvcg_frame_make, + .drop_item = uvcg_frame_drop, +}; + +#define UVCG_FRAMEBASED_ATTR_RO(cname, aname, bits) \ +static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \ + char *page) \ +{ \ + struct uvcg_framebased *u = to_uvcg_framebased(item); \ + struct f_uvc_opts *opts; \ + struct config_item *opts_item; \ + struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ + int result; \ + \ + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ + \ + opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ + opts = to_f_uvc_opts(opts_item); \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ + mutex_unlock(&opts->lock); \ + \ + mutex_unlock(su_mutex); \ + return result; \ +} \ + \ +UVC_ATTR_RO(uvcg_framebased_, cname, aname) + +#define UVCG_FRAMEBASED_ATTR(cname, aname, bits) \ +static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \ + char *page) \ +{ \ + struct uvcg_framebased *u = to_uvcg_framebased(item); \ + struct f_uvc_opts *opts; \ + struct config_item *opts_item; \ + struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ + int result; \ + \ + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ + \ + opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ + opts = to_f_uvc_opts(opts_item); \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ + mutex_unlock(&opts->lock); \ + \ + mutex_unlock(su_mutex); \ + return result; \ +} \ + \ +static ssize_t \ +uvcg_framebased_##cname##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + struct uvcg_framebased *u = to_uvcg_framebased(item); \ + struct f_uvc_opts *opts; \ + struct config_item *opts_item; \ + struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ + int ret; \ + u8 num; \ + \ + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ + \ + opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ + opts = to_f_uvc_opts(opts_item); \ + \ + mutex_lock(&opts->lock); \ + if (u->fmt.linked || opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = kstrtou8(page, 0, &num); \ + if (ret) \ + goto end; \ + \ + if (num > 255) { \ + ret = -EINVAL; \ + goto end; \ + } \ + u->desc.aname = num; \ + ret = len; \ +end: \ + mutex_unlock(&opts->lock); \ + mutex_unlock(su_mutex); \ + return ret; \ +} \ + \ +UVC_ATTR(uvcg_framebased_, cname, aname) + +UVCG_FRAMEBASED_ATTR_RO(b_format_index, bFormatIndex, 8); +UVCG_FRAMEBASED_ATTR_RO(b_bits_per_pixel, bBitsPerPixel, 8); +UVCG_FRAMEBASED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); +UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); +UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); +UVCG_FRAMEBASED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); + +#undef UVCG_FRAMEBASED_ATTR +#undef UVCG_FRAMEBASED_ATTR_RO + +static ssize_t uvcg_framebased_guid_format_show(struct config_item *item, + char *page) +{ + struct uvcg_framebased *ch = to_uvcg_framebased(item); + struct f_uvc_opts *opts; + struct config_item *opts_item; + struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; + + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ + + opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; + opts = to_f_uvc_opts(opts_item); + + mutex_lock(&opts->lock); + memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); + mutex_unlock(&opts->lock); + + mutex_unlock(su_mutex); + + return sizeof(ch->desc.guidFormat); +} + +static ssize_t uvcg_framebased_guid_format_store(struct config_item *item, + const char *page, size_t len) +{ + struct uvcg_framebased *ch = to_uvcg_framebased(item); + struct f_uvc_opts *opts; + struct config_item *opts_item; + struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; + int ret; + + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ + + opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; + opts = to_f_uvc_opts(opts_item); + + mutex_lock(&opts->lock); + if (ch->fmt.linked || opts->refcnt) { + ret = -EBUSY; + goto end; + } + + memcpy(ch->desc.guidFormat, page, + min(sizeof(ch->desc.guidFormat), len)); + ret = sizeof(ch->desc.guidFormat); + +end: + mutex_unlock(&opts->lock); + mutex_unlock(su_mutex); + return ret; +} + +UVC_ATTR(uvcg_framebased_, guid_format, guidFormat); + +static inline ssize_t +uvcg_framebased_bma_controls_show(struct config_item *item, char *page) +{ + struct uvcg_framebased *u = to_uvcg_framebased(item); + + return uvcg_format_bma_controls_show(&u->fmt, page); +} + +static inline ssize_t +uvcg_framebased_bma_controls_store(struct config_item *item, + const char *page, size_t len) +{ + struct uvcg_framebased *u = to_uvcg_framebased(item); + + return uvcg_format_bma_controls_store(&u->fmt, page, len); +} + +UVC_ATTR(uvcg_framebased_, bma_controls, bmaControls); + +static struct configfs_attribute *uvcg_framebased_attrs[] = { + &uvcg_framebased_attr_b_format_index, + &uvcg_framebased_attr_b_default_frame_index, + &uvcg_framebased_attr_b_bits_per_pixel, + &uvcg_framebased_attr_b_aspect_ratio_x, + &uvcg_framebased_attr_b_aspect_ratio_y, + &uvcg_framebased_attr_bm_interface_flags, + &uvcg_framebased_attr_bma_controls, + &uvcg_framebased_attr_guid_format, + NULL, +}; + +static const struct config_item_type uvcg_framebased_type = { + .ct_item_ops = &uvcg_config_item_ops, + .ct_group_ops = &uvcg_framebased_group_ops, + .ct_attrs = uvcg_framebased_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct config_group *uvcg_framebased_make(struct config_group *group, + const char *name) +{ + static char guid[] = { /*Declear frame based as H264 format*/ + 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + }; + struct uvcg_framebased *h; + + h = kzalloc(sizeof(*h), GFP_KERNEL); + if (!h) + return ERR_PTR(-ENOMEM); + + h->desc.bLength = UVC_DT_FORMAT_FRAMEBASED_SIZE; + h->desc.bDescriptorType = USB_DT_CS_INTERFACE; + h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED; + memcpy(h->desc.guidFormat, guid, sizeof(guid)); + h->desc.bBitsPerPixel = 0; + h->desc.bDefaultFrameIndex = 1; + h->desc.bAspectRatioX = 0; + h->desc.bAspectRatioY = 0; + h->desc.bmInterfaceFlags = 0; + h->desc.bCopyProtect = 0; + h->desc.bVariableSize = 1; + + INIT_LIST_HEAD(&h->fmt.frames); + h->fmt.type = UVCG_FRAMEBASED; + config_group_init_type_name(&h->fmt.group, name, + &uvcg_framebased_type); + + return &h->fmt.group; +} + +static struct configfs_group_operations uvcg_framebased_grp_ops = { + .make_group = uvcg_framebased_make, +}; + +static const struct uvcg_config_group_type uvcg_framebased_grp_type = { + .type = { + .ct_item_ops = &uvcg_config_item_ops, + .ct_group_ops = &uvcg_framebased_grp_ops, + .ct_owner = THIS_MODULE, + }, + .name = "framebased", +}; + /* ----------------------------------------------------------------------------- * streaming/color_matching/default */ @@ -2912,6 +3190,7 @@ static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h, if (ret) return ret; grp = &f->fmt->group; + j = 0; list_for_each_entry(item, &grp->cg_children, ci_entry) { frm = to_uvcg_frame(item); ret = fun(frm, priv2, priv3, j++, UVCG_FRAME); @@ -2965,6 +3244,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, container_of(fmt, struct uvcg_mjpeg, fmt); *size += sizeof(m->desc); + } else if (fmt->type == UVCG_FRAMEBASED) { + struct uvcg_framebased *f = + container_of(fmt, struct uvcg_framebased, fmt); + + *size += sizeof(f->desc); } else { return -EINVAL; } @@ -2975,6 +3259,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, int sz = sizeof(frm->dw_frame_interval); *size += sizeof(frm->frame); + /* + * framebased has duplicate member with uncompressed and + * mjpeg, so minus it + */ + *size -= sizeof(u32); *size += frm->frame.b_frame_interval_type * sz; } break; @@ -2991,6 +3280,27 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, return 0; } +static int __uvcg_copy_framebased_desc(void *dest, struct uvcg_frame *frm, + int sz) +{ + struct uvc_frame_framebased *desc = dest; + + desc->bLength = frm->frame.b_length; + desc->bDescriptorType = frm->frame.b_descriptor_type; + desc->bDescriptorSubType = frm->frame.b_descriptor_subtype; + desc->bFrameIndex = frm->frame.b_frame_index; + desc->bmCapabilities = frm->frame.bm_capabilities; + desc->wWidth = frm->frame.w_width; + desc->wHeight = frm->frame.w_height; + desc->dwMinBitRate = frm->frame.dw_min_bit_rate; + desc->dwMaxBitRate = frm->frame.dw_max_bit_rate; + desc->dwDefaultFrameInterval = frm->frame.dw_default_frame_interval; + desc->bFrameIntervalType = frm->frame.b_frame_interval_type; + desc->dwBytesPerLine = frm->frame.dw_bytes_perline; + + return 0; +} + /* * Fill an array of streaming descriptors. * @@ -3045,6 +3355,15 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, m->desc.bNumFrameDescriptors = fmt->num_frames; memcpy(*dest, &m->desc, sizeof(m->desc)); *dest += sizeof(m->desc); + } else if (fmt->type == UVCG_FRAMEBASED) { + struct uvcg_framebased *f = + container_of(fmt, struct uvcg_framebased, + fmt); + + f->desc.bFormatIndex = n + 1; + f->desc.bNumFrameDescriptors = fmt->num_frames; + memcpy(*dest, &f->desc, sizeof(f->desc)); + *dest += sizeof(f->desc); } else { return -EINVAL; } @@ -3054,8 +3373,11 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, struct uvcg_frame *frm = priv1; struct uvc_descriptor_header *h = *dest; - sz = sizeof(frm->frame); - memcpy(*dest, &frm->frame, sz); + sz = sizeof(frm->frame) - 4; + if (frm->fmt_type != UVCG_FRAMEBASED) + memcpy(*dest, &frm->frame, sz); + else + __uvcg_copy_framebased_desc(*dest, frm, sz); *dest += sz; sz = frm->frame.b_frame_interval_type * sizeof(*frm->dw_frame_interval); @@ -3066,7 +3388,10 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, frm->frame.b_frame_interval_type); else if (frm->fmt_type == UVCG_MJPEG) h->bLength = UVC_DT_FRAME_MJPEG_SIZE( - frm->frame.b_frame_interval_type); + frm->frame.b_frame_interval_type); + else if (frm->fmt_type == UVCG_FRAMEBASED) + h->bLength = UVC_DT_FRAME_FRAMEBASED_SIZE( + frm->frame.b_frame_interval_type); } break; case UVCG_COLOR_MATCHING: { @@ -3285,6 +3610,7 @@ static const struct uvcg_config_group_type uvcg_streaming_grp_type = { &uvcg_streaming_header_grp_type, &uvcg_uncompressed_grp_type, &uvcg_mjpeg_grp_type, + &uvcg_framebased_grp_type, &uvcg_color_matching_grp_type, &uvcg_streaming_class_grp_type, NULL, diff --git a/drivers/usb/gadget/function/uvc_configfs.h b/drivers/usb/gadget/function/uvc_configfs.h index c6a690158138fea9dcda2aaf9aa47f521096a770..2f78cd4f396f240e10f8db7e991253c8a1496d5d 100644 --- a/drivers/usb/gadget/function/uvc_configfs.h +++ b/drivers/usb/gadget/function/uvc_configfs.h @@ -49,6 +49,7 @@ container_of(group_ptr, struct uvcg_color_matching, group) enum uvcg_format_type { UVCG_UNCOMPRESSED = 0, UVCG_MJPEG, + UVCG_FRAMEBASED, }; struct uvcg_format { @@ -105,6 +106,7 @@ struct uvcg_frame { u32 dw_max_video_frame_buffer_size; u32 dw_default_frame_interval; u8 b_frame_interval_type; + u32 dw_bytes_perline; } __attribute__((packed)) frame; u32 *dw_frame_interval; }; @@ -142,6 +144,20 @@ static inline struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item) return container_of(to_uvcg_format(item), struct uvcg_mjpeg, fmt); } +/* ----------------------------------------------------------------------------- + * streaming/framebased/ + */ + +struct uvcg_framebased { + struct uvcg_format fmt; + struct uvc_format_framebased desc; +}; + +static inline struct uvcg_framebased *to_uvcg_framebased(struct config_item *item) +{ + return container_of(to_uvcg_format(item), struct uvcg_framebased, fmt); +} + /* ----------------------------------------------------------------------------- * control/extensions/ */ diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 0aa3d7e1f3cc32c696e422196cf1d1e9ab9a34de..5eaeae3e2441c54dff5075c3efc1427cccd27b94 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -21,6 +21,7 @@ #include #include "uvc.h" +#include "uvc_video.h" /* ------------------------------------------------------------------------ * Video buffers queue management. @@ -44,33 +45,23 @@ static int uvc_queue_setup(struct vb2_queue *vq, { struct uvc_video_queue *queue = vb2_get_drv_priv(vq); struct uvc_video *video = container_of(queue, struct uvc_video, queue); - unsigned int req_size; - unsigned int nreq; if (*nbuffers > UVC_MAX_VIDEO_BUFFERS) *nbuffers = UVC_MAX_VIDEO_BUFFERS; + if (*nbuffers < UVCG_STREAMING_MIN_BUFFERS) + *nbuffers = UVCG_STREAMING_MIN_BUFFERS; *nplanes = 1; sizes[0] = video->imagesize; - req_size = video->ep->maxpacket - * max_t(unsigned int, video->ep->maxburst, 1) - * (video->ep->mult); - - /* We divide by two, to increase the chance to run - * into fewer requests for smaller framesizes. - */ - nreq = DIV_ROUND_UP(DIV_ROUND_UP(sizes[0], 2), req_size); - nreq = clamp(nreq, 4U, 64U); - video->uvc_num_requests = nreq; - return 0; } static int uvc_buffer_prepare(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); + struct uvc_video *video = container_of(queue, struct uvc_video, queue); struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); @@ -91,10 +82,15 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) buf->mem = vb2_plane_vaddr(vb, 0); } buf->length = vb2_plane_size(vb, 0); - if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { buf->bytesused = 0; - else + } else { buf->bytesused = vb2_get_plane_payload(vb, 0); + buf->req_payload_size = + DIV_ROUND_UP(buf->bytesused + + (video->reqs_per_frame * UVCG_REQUEST_HEADER_LEN), + video->reqs_per_frame); + } return 0; } diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 41f87b917f6bc1a0e60f6a0afccbc9b1e59700db..b54becc570a38e23d915b6e7c08c23ef7d44f99f 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -39,6 +39,8 @@ struct uvc_buffer { unsigned int offset; unsigned int length; unsigned int bytesused; + /* req_payload_size: only used with isoc */ + unsigned int req_payload_size; }; #define UVC_QUEUE_DISCONNECTED (1 << 0) diff --git a/drivers/usb/gadget/function/uvc_trace.c b/drivers/usb/gadget/function/uvc_trace.c new file mode 100644 index 0000000000000000000000000000000000000000..d384f6d8221a54ae7ac2f7947e36268c5cf7d439 --- /dev/null +++ b/drivers/usb/gadget/function/uvc_trace.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * trace.c - USB UVC Gadget Trace Support + * + * Copyright (C) 2024 Pengutronix e.K. + * + * Author: Michael Grzeschik + */ + +#define CREATE_TRACE_POINTS +#include "uvc_trace.h" diff --git a/drivers/usb/gadget/function/uvc_trace.h b/drivers/usb/gadget/function/uvc_trace.h new file mode 100644 index 0000000000000000000000000000000000000000..04c33cf43cc2d4915befbd0e29aee2baaa701ea8 --- /dev/null +++ b/drivers/usb/gadget/function/uvc_trace.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * trace.h - USB UVC Gadget Trace Support + * + * Copyright (C) 2024 Pengutronix e.K. + * + * Author: Michael Grzeschik + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM uvcg + +#if !defined(__UVCG_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __UVCG_TRACE_H + +#include +#include +#include +#include + +DECLARE_EVENT_CLASS(uvcg_video_req, + TP_PROTO(struct usb_request *req, u32 queued), + TP_ARGS(req, queued), + TP_STRUCT__entry( + __field(struct usb_request *, req) + __field(u32, length) + __field(u32, queued) + ), + TP_fast_assign( + __entry->req = req; + __entry->length = req->length; + __entry->queued = queued; + ), + TP_printk("req %p length %u queued %u", + __entry->req, + __entry->length, + __entry->queued) +); + +DEFINE_EVENT(uvcg_video_req, uvcg_video_complete, + TP_PROTO(struct usb_request *req, u32 queued), + TP_ARGS(req, queued) +); + +DEFINE_EVENT(uvcg_video_req, uvcg_video_queue, + TP_PROTO(struct usb_request *req, u32 queued), + TP_ARGS(req, queued) +); + +#endif /* __UVCG_TRACE_H */ + +/* this part has to be here */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE uvc_trace + +#include diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index de1736f834e6b8fedc41ac47af19e48a4409a45c..fc9a8d31a1e983945838a6ac84f5b9090ac13697 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -31,13 +31,22 @@ static const struct uvc_format_desc *to_uvc_format(struct uvcg_format *uformat) { char guid[16] = UVC_GUID_FORMAT_MJPEG; const struct uvc_format_desc *format; - struct uvcg_uncompressed *unc; if (uformat->type == UVCG_UNCOMPRESSED) { + struct uvcg_uncompressed *unc; + unc = to_uvcg_uncompressed(&uformat->group.cg_item); if (!unc) return ERR_PTR(-EINVAL); + memcpy(guid, unc->desc.guidFormat, sizeof(guid)); + } else if (uformat->type == UVCG_FRAMEBASED) { + struct uvcg_framebased *unc; + + unc = to_uvcg_framebased(&uformat->group.cg_item); + if (!unc) + return ERR_PTR(-EINVAL); + memcpy(guid, unc->desc.guidFormat, sizeof(guid)); } @@ -314,6 +323,56 @@ uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt) return ret; } +static int uvc_v4l2_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct video_device *vdev = video_devdata(file); + struct uvc_device *uvc = video_get_drvdata(vdev); + struct uvc_video *video = &uvc->video; + struct v4l2_fract timeperframe; + + if (!V4L2_TYPE_IS_OUTPUT(parm->type)) + return -EINVAL; + + /* Return the actual frame period. */ + timeperframe.numerator = video->interval; + timeperframe.denominator = 10000000; + v4l2_simplify_fraction(&timeperframe.numerator, + &timeperframe.denominator, 8, 333); + + uvcg_dbg(&uvc->func, "Getting frame interval of %u/%u (%u)\n", + timeperframe.numerator, timeperframe.denominator, + video->interval); + + parm->parm.output.timeperframe = timeperframe; + parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; + + return 0; +} + +static int uvc_v4l2_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct video_device *vdev = video_devdata(file); + struct uvc_device *uvc = video_get_drvdata(vdev); + struct uvc_video *video = &uvc->video; + struct v4l2_fract timeperframe; + + if (!V4L2_TYPE_IS_OUTPUT(parm->type)) + return -EINVAL; + + timeperframe = parm->parm.output.timeperframe; + + video->interval = v4l2_fraction_to_interval(timeperframe.numerator, + timeperframe.denominator); + + uvcg_dbg(&uvc->func, "Setting frame interval to %u/%u (%u)\n", + timeperframe.numerator, timeperframe.denominator, + video->interval); + + return 0; +} + static int uvc_v4l2_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival) @@ -496,6 +555,9 @@ uvc_v4l2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) if (ret < 0) return ret; + if (uvc->state != UVC_STATE_STREAMING) + return 0; + uvc->state = UVC_STATE_CONNECTED; uvc_function_setup_continue(uvc, 1); return 0; @@ -587,6 +649,8 @@ const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = { .vidioc_dqbuf = uvc_v4l2_dqbuf, .vidioc_streamon = uvc_v4l2_streamon, .vidioc_streamoff = uvc_v4l2_streamoff, + .vidioc_s_parm = uvc_v4l2_s_parm, + .vidioc_g_parm = uvc_v4l2_g_parm, .vidioc_subscribe_event = uvc_v4l2_subscribe_event, .vidioc_unsubscribe_event = uvc_v4l2_unsubscribe_event, .vidioc_default = uvc_v4l2_ioctl_default, diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 57a851151225dec1c478a8dee619f5c101a99671..79e223713d8b9336bc927fb3d046bfdde142c6fd 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -19,6 +19,7 @@ #include "uvc.h" #include "uvc_queue.h" #include "uvc_video.h" +#include "uvc_trace.h" /* -------------------------------------------------------------------------- * Video codecs @@ -78,7 +79,7 @@ uvc_video_encode_data(struct uvc_video *video, struct uvc_buffer *buf, /* Copy video data to the USB buffer. */ mem = buf->mem + queue->buf_used; - nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used); + nbytes = min_t(unsigned int, len, buf->bytesused - queue->buf_used); memcpy(data, mem, nbytes); queue->buf_used += nbytes; @@ -104,7 +105,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video, } /* Process video data. */ - len = min((int)(video->max_payload_size - video->payload_size), len); + len = min_t(int, video->max_payload_size - video->payload_size, len); ret = uvc_video_encode_data(video, buf, mem, len); video->payload_size += ret; @@ -136,7 +137,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, unsigned int pending = buf->bytesused - video->queue.buf_used; struct uvc_request *ureq = req->context; struct scatterlist *sg, *iter; - unsigned int len = video->req_size; + unsigned int len = buf->req_payload_size; unsigned int sg_left, part = 0; unsigned int i; int header_len; @@ -146,15 +147,15 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, /* Init the header. */ header_len = uvc_video_encode_header(video, buf, ureq->header, - video->req_size); + buf->req_payload_size); sg_set_buf(sg, ureq->header, header_len); len -= header_len; if (pending <= len) len = pending; - req->length = (len == pending) ? - len + header_len : video->req_size; + req->length = (len == pending) ? len + header_len : + buf->req_payload_size; /* Init the pending sgs with payload */ sg = sg_next(sg); @@ -202,7 +203,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, { void *mem = req->buf; struct uvc_request *ureq = req->context; - int len = video->req_size; + int len = buf->req_payload_size; int ret; /* Add the header. */ @@ -214,7 +215,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, ret = uvc_video_encode_data(video, buf, mem, len); len -= ret; - req->length = video->req_size - len; + req->length = buf->req_payload_size - len; if (buf->bytesused == video->queue.buf_used || video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) { @@ -269,6 +270,10 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req) } } + atomic_inc(&video->queued); + + trace_uvcg_video_queue(req, atomic_read(&video->queued)); + return ret; } @@ -304,7 +309,7 @@ static int uvcg_video_usb_req_queue(struct uvc_video *video, */ if (list_empty(&video->req_free) || ureq->last_buf || !(video->req_int_count % - DIV_ROUND_UP(video->uvc_num_requests, 4))) { + min(DIV_ROUND_UP(video->uvc_num_requests, 4), UVCG_REQ_MAX_INT_COUNT))) { video->req_int_count = 0; req->no_interrupt = 0; } else { @@ -322,50 +327,6 @@ static int uvcg_video_usb_req_queue(struct uvc_video *video, return 0; } -/* - * Must only be called from uvcg_video_enable - since after that we only want to - * queue requests to the endpoint from the uvc_video_complete complete handler. - * This function is needed in order to 'kick start' the flow of requests from - * gadget driver to the usb controller. - */ -static void uvc_video_ep_queue_initial_requests(struct uvc_video *video) -{ - struct usb_request *req = NULL; - unsigned long flags = 0; - unsigned int count = 0; - int ret = 0; - - /* - * We only queue half of the free list since we still want to have - * some free usb_requests in the free list for the video_pump async_wq - * thread to encode uvc buffers into. Otherwise we could get into a - * situation where the free list does not have any usb requests to - * encode into - we always end up queueing 0 length requests to the - * end point. - */ - unsigned int half_list_size = video->uvc_num_requests / 2; - - spin_lock_irqsave(&video->req_lock, flags); - /* - * Take these requests off the free list and queue them all to the - * endpoint. Since we queue 0 length requests with the req_lock held, - * there isn't any 'data' race involved here with the complete handler. - */ - while (count < half_list_size) { - req = list_first_entry(&video->req_free, struct usb_request, - list); - list_del(&req->list); - req->length = 0; - ret = uvcg_video_ep_queue(video, req); - if (ret < 0) { - uvcg_queue_cancel(&video->queue, 0); - break; - } - count++; - } - spin_unlock_irqrestore(&video->req_lock, flags); -} - static void uvc_video_complete(struct usb_ep *ep, struct usb_request *req) { @@ -373,12 +334,10 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) struct uvc_video *video = ureq->video; struct uvc_video_queue *queue = &video->queue; struct uvc_buffer *last_buf; - struct usb_request *to_queue = req; unsigned long flags; - bool is_bulk = video->max_payload_size; - int ret = 0; spin_lock_irqsave(&video->req_lock, flags); + atomic_dec(&video->queued); if (!video->is_enabled) { /* * When is_enabled is false, uvcg_video_disable() ensures @@ -438,51 +397,87 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) return; } + list_add_tail(&req->list, &video->req_free); /* - * Here we check whether any request is available in the ready - * list. If it is, queue it to the ep and add the current - * usb_request to the req_free list - for video_pump to fill in. - * Otherwise, just use the current usb_request to queue a 0 - * length request to the ep. Since we always add to the req_free - * list if we dequeue from the ready list, there will never - * be a situation where the req_free list is completely out of - * requests and cannot recover. + * Queue work to the wq as well since it is possible that a + * buffer may not have been completely encoded with the set of + * in-flight usb requests for whih the complete callbacks are + * firing. + * In that case, if we do not queue work to the worker thread, + * the buffer will never be marked as complete - and therefore + * not be returned to userpsace. As a result, + * dequeue -> queue -> dequeue flow of uvc buffers will not + * happen. Since there are is a new free request wake up the pump. */ - to_queue->length = 0; - if (!list_empty(&video->req_ready)) { - to_queue = list_first_entry(&video->req_ready, - struct usb_request, list); - list_del(&to_queue->list); - list_add_tail(&req->list, &video->req_free); + queue_work(video->async_wq, &video->pump); + + trace_uvcg_video_complete(req, atomic_read(&video->queued)); + + spin_unlock_irqrestore(&video->req_lock, flags); + + kthread_queue_work(video->kworker, &video->hw_submit); +} + +static void uvcg_video_hw_submit(struct kthread_work *work) +{ + struct uvc_video *video = container_of(work, struct uvc_video, hw_submit); + bool is_bulk = video->max_payload_size; + unsigned long flags; + struct usb_request *req; + int ret = 0; + + while (true) { + if (!video->ep->enabled) + return; + spin_lock_irqsave(&video->req_lock, flags); /* - * Queue work to the wq as well since it is possible that a - * buffer may not have been completely encoded with the set of - * in-flight usb requests for whih the complete callbacks are - * firing. - * In that case, if we do not queue work to the worker thread, - * the buffer will never be marked as complete - and therefore - * not be returned to userpsace. As a result, - * dequeue -> queue -> dequeue flow of uvc buffers will not - * happen. + * Here we check whether any request is available in the ready + * list. If it is, queue it to the ep and add the current + * usb_request to the req_free list - for video_pump to fill in. + * Otherwise, just use the current usb_request to queue a 0 + * length request to the ep. Since we always add to the req_free + * list if we dequeue from the ready list, there will never + * be a situation where the req_free list is completely out of + * requests and cannot recover. */ - queue_work(video->async_wq, &video->pump); - } - /* - * Queue to the endpoint. The actual queueing to ep will - * only happen on one thread - the async_wq for bulk endpoints - * and this thread for isoc endpoints. - */ - ret = uvcg_video_usb_req_queue(video, to_queue, !is_bulk); - if (ret < 0) { + if (!list_empty(&video->req_ready)) { + req = list_first_entry(&video->req_ready, + struct usb_request, list); + } else { + if (list_empty(&video->req_free) || + (atomic_read(&video->queued) > UVCG_REQ_MAX_ZERO_COUNT)) { + spin_unlock_irqrestore(&video->req_lock, flags); + + return; + } + req = list_first_entry(&video->req_free, struct usb_request, + list); + req->length = 0; + } + list_del(&req->list); + /* - * Endpoint error, but the stream is still enabled. - * Put request back in req_free for it to be cleaned - * up later. + * Queue to the endpoint. The actual queueing to ep will + * only happen on one thread - the async_wq for bulk endpoints + * and this thread for isoc endpoints. */ - list_add_tail(&to_queue->list, &video->req_free); - } + ret = uvcg_video_usb_req_queue(video, req, !is_bulk); + if (ret < 0) { + /* + * Endpoint error, but the stream is still enabled. + * Put request back in req_free for it to be cleaned + * up later. + */ + list_add_tail(&req->list, &video->req_free); + /* + * There is a new free request - wake up the pump. + */ + queue_work(video->async_wq, &video->pump); - spin_unlock_irqrestore(&video->req_lock, flags); + } + + spin_unlock_irqrestore(&video->req_lock, flags); + } } static int @@ -496,23 +491,71 @@ uvc_video_free_requests(struct uvc_video *video) INIT_LIST_HEAD(&video->ureqs); INIT_LIST_HEAD(&video->req_free); INIT_LIST_HEAD(&video->req_ready); - video->req_size = 0; return 0; } +static void +uvc_video_prep_requests(struct uvc_video *video) +{ + struct uvc_device *uvc = container_of(video, struct uvc_device, video); + struct usb_composite_dev *cdev = uvc->func.config->cdev; + unsigned int interval_duration = video->ep->desc->bInterval * 1250; + unsigned int max_req_size, req_size, header_size; + unsigned int nreq; + + max_req_size = video->ep->maxpacket + * max_t(unsigned int, video->ep->maxburst, 1) + * (video->ep->mult); + + if (!usb_endpoint_xfer_isoc(video->ep->desc)) { + video->req_size = max_req_size; + video->reqs_per_frame = video->uvc_num_requests = + DIV_ROUND_UP(video->imagesize, max_req_size); + + return; + } + + if (cdev->gadget->speed < USB_SPEED_HIGH) + interval_duration = video->ep->desc->bInterval * 10000; + + nreq = DIV_ROUND_UP(video->interval, interval_duration); + + header_size = nreq * UVCG_REQUEST_HEADER_LEN; + + req_size = DIV_ROUND_UP(video->imagesize + header_size, nreq); + + if (req_size > max_req_size) { + /* The prepared interval length and expected buffer size + * is not possible to stream with the currently configured + * isoc bandwidth. Fallback to the maximum. + */ + req_size = max_req_size; + } + video->req_size = req_size; + + /* We need to compensate the amount of requests to be + * allocated with the maximum amount of zero length requests. + * Since it is possible that hw_submit will initially + * enqueue some zero length requests and we then will not be + * able to fully encode one frame. + */ + video->uvc_num_requests = nreq + UVCG_REQ_MAX_ZERO_COUNT; + video->reqs_per_frame = nreq; +} + static int uvc_video_alloc_requests(struct uvc_video *video) { struct uvc_request *ureq; - unsigned int req_size; unsigned int i; int ret = -ENOMEM; - BUG_ON(video->req_size); - - req_size = video->ep->maxpacket - * max_t(unsigned int, video->ep->maxburst, 1) - * (video->ep->mult); + /* + * calculate in uvc_video_prep_requests + * - video->uvc_num_requests + * - video->req_size + */ + uvc_video_prep_requests(video); for (i = 0; i < video->uvc_num_requests; i++) { ureq = kzalloc(sizeof(struct uvc_request), GFP_KERNEL); @@ -523,7 +566,7 @@ uvc_video_alloc_requests(struct uvc_video *video) list_add_tail(&ureq->list, &video->ureqs); - ureq->req_buffer = kmalloc(req_size, GFP_KERNEL); + ureq->req_buffer = kmalloc(video->req_size, GFP_KERNEL); if (ureq->req_buffer == NULL) goto error; @@ -541,12 +584,10 @@ uvc_video_alloc_requests(struct uvc_video *video) list_add_tail(&ureq->req->list, &video->req_free); /* req_size/PAGE_SIZE + 1 for overruns and + 1 for header */ sg_alloc_table(&ureq->sgt, - DIV_ROUND_UP(req_size - UVCG_REQUEST_HEADER_LEN, + DIV_ROUND_UP(video->req_size - UVCG_REQUEST_HEADER_LEN, PAGE_SIZE) + 2, GFP_KERNEL); } - video->req_size = req_size; - return 0; error: @@ -699,7 +740,6 @@ uvcg_video_disable(struct uvc_video *video) INIT_LIST_HEAD(&video->ureqs); INIT_LIST_HEAD(&video->req_free); INIT_LIST_HEAD(&video->req_ready); - video->req_size = 0; spin_unlock_irqrestore(&video->req_lock, flags); /* @@ -752,7 +792,9 @@ int uvcg_video_enable(struct uvc_video *video) video->req_int_count = 0; - uvc_video_ep_queue_initial_requests(video); + atomic_set(&video->queued, 0); + + kthread_queue_work(video->kworker, &video->hw_submit); queue_work(video->async_wq, &video->pump); return ret; @@ -775,12 +817,24 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) if (!video->async_wq) return -EINVAL; + /* Allocate a kthread for asynchronous hw submit handler. */ + video->kworker = kthread_create_worker(0, "UVCG"); + if (IS_ERR(video->kworker)) { + uvcg_err(&video->uvc->func, "failed to create UVCG kworker\n"); + return PTR_ERR(video->kworker); + } + + kthread_init_work(&video->hw_submit, uvcg_video_hw_submit); + + sched_set_fifo(video->kworker->task); + video->uvc = uvc; video->fcc = V4L2_PIX_FMT_YUYV; video->bpp = 16; video->width = 320; video->height = 240; video->imagesize = 320 * 240 * 2; + video->interval = 666666; /* Initialize the video buffers queue. */ uvcg_queue_init(&video->queue, uvc->v4l2_dev.dev->parent, diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 4ca67b2f8f2437dcf1e2fd6ca02524a6acc0fc82..3684546e8801d440b495dc6260393f2e22cf7aea 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -261,7 +261,7 @@ static struct usb_composite_driver hidg_driver = { }; static struct platform_driver hidg_plat_driver = { - .remove_new = hidg_plat_driver_remove, + .remove = hidg_plat_driver_remove, .driver = { .name = "hidg", }, diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index 112fd18d8c99dc3719c9058777e5631798784570..20165e1582d9ba42e8787a2d073844bebc6e1671 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -782,7 +782,7 @@ static int raw_ioctl_ep0_read(struct raw_dev *dev, unsigned long value) if (ret < 0) goto free; - length = min(io.length, (unsigned int)ret); + length = min_t(unsigned int, io.length, ret); if (copy_to_user((void __user *)(value + sizeof(io)), data, length)) ret = -EFAULT; else @@ -1168,7 +1168,7 @@ static int raw_ioctl_ep_read(struct raw_dev *dev, unsigned long value) if (ret < 0) goto free; - length = min(io.length, (unsigned int)ret); + length = min_t(unsigned int, io.length, ret); if (copy_to_user((void __user *)(value + sizeof(io)), data, length)) ret = -EFAULT; else diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c index f60a019bb173015d843834db31557363b1e8bbcc..f2685f89b3e50a2ccb4d979744fb520533a8b90c 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/core.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c @@ -428,7 +428,7 @@ MODULE_DEVICE_TABLE(of, ast_vhub_dt_ids); static struct platform_driver ast_vhub_driver = { .probe = ast_vhub_probe, - .remove_new = ast_vhub_remove, + .remove = ast_vhub_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = ast_vhub_dt_ids, diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c index f4781e611aaa2913088cfb6e0833825a0cff0735..353bfb1ff0a12b49bf60896f200764d0f17a854b 100644 --- a/drivers/usb/gadget/udc/aspeed_udc.c +++ b/drivers/usb/gadget/udc/aspeed_udc.c @@ -156,7 +156,7 @@ #define AST_EP_DMA_DESC_PID_DATA1 (2 << 14) #define AST_EP_DMA_DESC_PID_MDATA (3 << 14) #define EP_DESC1_IN_LEN(x) ((x) & 0x1fff) -#define AST_EP_DMA_DESC_MAX_LEN (7680) /* Max packet length for trasmit in 1 desc */ +#define AST_EP_DMA_DESC_MAX_LEN (7680) /* Max packet length for transmit in 1 desc */ struct ast_udc_request { struct usb_request req; @@ -1590,7 +1590,7 @@ MODULE_DEVICE_TABLE(of, ast_udc_of_dt_ids); static struct platform_driver ast_udc_driver = { .probe = ast_udc_probe, - .remove_new = ast_udc_remove, + .remove = ast_udc_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = ast_udc_of_dt_ids, diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index e3bf17a98b380650cef9b3c007d603fd8feba984..e3af4ec3794e2ef871bc252948b6121921623704 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -2002,7 +2002,7 @@ static int at91udc_resume(struct platform_device *pdev) static struct platform_driver at91_udc_driver = { .probe = at91udc_probe, - .remove_new = at91udc_remove, + .remove = at91udc_remove, .shutdown = at91udc_shutdown, .suspend = at91udc_suspend, .resume = at91udc_resume, diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 4928eba19327215152231c1ec71103b888876733..0c6f2ad81d37f550ca026006c1ff8ca865426c75 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -2444,7 +2444,7 @@ static SIMPLE_DEV_PM_OPS(usba_udc_pm_ops, usba_udc_suspend, usba_udc_resume); static struct platform_driver udc_driver = { .probe = usba_udc_probe, - .remove_new = usba_udc_remove, + .remove = usba_udc_remove, .driver = { .name = "atmel_usba_udc", .pm = &usba_udc_pm_ops, diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index da7011d906e01db59fcac559eea1453bd1c08040..502612a5650e728cccae17acb0cc2c3a2e1b25e0 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -2367,7 +2367,7 @@ static void bcm63xx_udc_remove(struct platform_device *pdev) static struct platform_driver bcm63xx_udc_driver = { .probe = bcm63xx_udc_probe, - .remove_new = bcm63xx_udc_remove, + .remove = bcm63xx_udc_remove, .driver = { .name = DRV_MODULE_NAME, }, diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index 5149e2b7f05087811c1ff16032209d9c6a506901..5c3d8b64c0e76e434cc1bcc39f9976f1a17d83b0 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -648,7 +648,7 @@ static struct platform_driver bdc_driver = { .of_match_table = bdc_of_match, }, .probe = bdc_probe, - .remove_new = bdc_remove, + .remove = bdc_remove, }; module_platform_driver(bdc_driver); diff --git a/drivers/usb/gadget/udc/cdns2/cdns2-pci.c b/drivers/usb/gadget/udc/cdns2/cdns2-pci.c index b1a8f772467c0d6cf4188bfc937d05b8676570af..e589593b4cbf89783108ad8721624b72ea8ef3db 100644 --- a/drivers/usb/gadget/udc/cdns2/cdns2-pci.c +++ b/drivers/usb/gadget/udc/cdns2/cdns2-pci.c @@ -15,7 +15,6 @@ #include "cdns2-gadget.h" #define PCI_DRIVER_NAME "cdns-pci-usbhs" -#define PCI_DEVICE_ID_CDNS_USB2 0x0120 #define PCI_BAR_DEV 0 #define PCI_DEV_FN_DEVICE 0 @@ -113,7 +112,7 @@ static const struct dev_pm_ops cdns2_pci_pm_ops = { }; static const struct pci_device_id cdns2_pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USB2), + { PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USB), .class = PCI_CLASS_SERIAL_USB_DEVICE }, { 0, } }; diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 081ac7683c0b350c4675af107bcac78acf38c915..a7e8fa45776b5c16220bc5181eb6a91c45adf019 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -80,7 +80,7 @@ module_param_named(num, mod_data.num, uint, S_IRUGO); MODULE_PARM_DESC(num, "number of emulated controllers"); /*-------------------------------------------------------------------------*/ -/* gadget side driver data structres */ +/* gadget side driver data structures */ struct dummy_ep { struct list_head queue; unsigned long last_io; /* jiffies timestamp */ @@ -1152,7 +1152,7 @@ static int dummy_udc_resume(struct platform_device *pdev) static struct platform_driver dummy_udc_driver = { .probe = dummy_udc_probe, - .remove_new = dummy_udc_remove, + .remove = dummy_udc_remove, .suspend = dummy_udc_suspend, .resume = dummy_udc_resume, .driver = { @@ -2769,7 +2769,7 @@ static int dummy_hcd_resume(struct platform_device *pdev) static struct platform_driver dummy_hcd_driver = { .probe = dummy_hcd_probe, - .remove_new = dummy_hcd_remove, + .remove = dummy_hcd_remove, .suspend = dummy_hcd_suspend, .resume = dummy_hcd_resume, .driver = { diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 4e88681a79b6331dd7d1e3d0609366db326a924c..aacfde06387c0bd4a54ff9d30006e3a40c133104 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -511,7 +511,7 @@ static int qe_ep_register_init(struct qe_udc *udc, unsigned char pipe_num) out_8(&epparam->tbmr, rtfcr); tmp = (u16)(ep->ep.maxpacket + USB_CRC_SIZE); - /* MRBLR must be divisble by 4 */ + /* MRBLR must be divisible by 4 */ tmp = (u16)(((tmp >> 2) << 2) + 4); out_be16(&epparam->mrblr, tmp); @@ -1413,7 +1413,7 @@ static int ep_txframe_handle(struct qe_ep *ep) return 0; } -/* confirm the already trainsmited bd */ +/* confirm the already transmitted bd */ static int qe_ep_txconf(struct qe_ep *ep) { struct qe_bd __iomem *bd; @@ -2196,7 +2196,7 @@ static int tx_irq(struct qe_udc *udc) } -/* setup packect's rx is handle in the function too */ +/* setup packet's rx is handle in the function too */ static void rx_irq(struct qe_udc *udc) { struct qe_ep *ep; @@ -2704,7 +2704,7 @@ static struct platform_driver udc_driver = { .of_match_table = qe_udc_match, }, .probe = qe_udc_probe, - .remove_new = qe_udc_remove, + .remove = qe_udc_remove, #ifdef CONFIG_PM .suspend = qe_udc_suspend, .resume = qe_udc_resume, diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 0cabd4eee6acb5f6e885ff7a9c624ac1add14be9..8b7f7f96177459f6d295f5740b5ab23c0eab838f 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -2685,7 +2685,7 @@ MODULE_DEVICE_TABLE(of, fsl_udc_dt_ids); static struct platform_driver udc_driver = { .probe = fsl_udc_probe, - .remove_new = fsl_udc_remove, + .remove = fsl_udc_remove, .id_table = fsl_udc_devtype, /* these suspend and resume are not usb suspend and resume */ .suspend = fsl_udc_suspend, diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index 873265634cccb7da05d0e7a456f291dc2c961b65..5e94a99b3e53932c92bb2ac0e4ab18aff056a95c 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1297,7 +1297,7 @@ static void init_controller(struct fusb300 *fusb300) reg |= val; iowrite32(reg, fusb300->reg + FUSB300_OFFSET_HSCR); - /*set u1 u2 timmer*/ + /*set u1 u2 timer*/ fusb300_set_u2_timeout(fusb300, 0xff); fusb300_set_u1_timeout(fusb300, 0xff); @@ -1507,7 +1507,7 @@ clean_up: static struct platform_driver fusb300_driver = { .probe = fusb300_probe, - .remove_new = fusb300_remove, + .remove = fusb300_remove, .driver = { .name = udc_name, }, diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index fb901be5dac1b7a4fe7fc4203c5757bccb8275a6..bf5b3c964c18702e765309584bb32a9c2be7ebdb 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -2249,7 +2249,7 @@ static struct platform_driver gr_driver = { .of_match_table = gr_match, }, .probe = gr_probe, - .remove_new = gr_remove, + .remove = gr_remove, }; module_platform_driver(gr_driver); diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 3bfd889ed56a47623138854ea062105f0b0dae75..89d6daf2bda7a353e0297dbe7c25bbb1c7f56839 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -3249,7 +3249,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_udc_of_match); static struct platform_driver lpc32xx_udc_driver = { .probe = lpc32xx_udc_probe, - .remove_new = lpc32xx_udc_remove, + .remove = lpc32xx_udc_remove, .shutdown = lpc32xx_udc_shutdown, .suspend = lpc32xx_udc_suspend, .resume = lpc32xx_udc_resume, diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index bfaa5291e6c83bd883c239a5fcd8a5447fb2878b..a938b2af0944bc4fe79d4acc5dfe24ce09a07558 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1688,7 +1688,7 @@ clean_up: /*-------------------------------------------------------------------------*/ static struct platform_driver m66592_driver = { .probe = m66592_probe, - .remove_new = m66592_remove, + .remove = m66592_remove, .driver = { .name = udc_name, }, diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index e1dd5cf25d08a0a6eb42663215d7aa00350c4eb1..062f43e146aaac827522627ef90b13622bacbe81 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -2047,7 +2047,7 @@ static void mv_u3d_shutdown(struct platform_device *dev) static struct platform_driver mv_u3d_driver = { .probe = mv_u3d_probe, - .remove_new = mv_u3d_remove, + .remove = mv_u3d_remove, .shutdown = mv_u3d_shutdown, .driver = { .name = "mv-u3d", diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 71012b282891056690a4e14600c5f45abd450a72..ff103e6b3048f53fe462e38839ddcd5a5036b6cd 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -2409,7 +2409,7 @@ static void mv_udc_shutdown(struct platform_device *pdev) static struct platform_driver udc_driver = { .probe = mv_udc_probe, - .remove_new = mv_udc_remove, + .remove = mv_udc_remove, .shutdown = mv_udc_shutdown, .driver = { .name = "mv-udc", diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 9230db57dab7a6361d2d9a5089c8dc3d2018f5a0..7ecddbf5c90db5c393237ff8b74184d3afee3129 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -2097,7 +2097,7 @@ static irqreturn_t net2272_irq(int irq, void *_dev) } /* check dma interrupts */ #endif - /* Platform/devcice interrupt handler */ + /* Platform/device interrupt handler */ #if !defined(PLX_PCI_RDK) net2272_handle_stat1_irqs(dev, net2272_read(dev, IRQSTAT1)); net2272_handle_stat0_irqs(dev, net2272_read(dev, IRQSTAT0)); @@ -2685,7 +2685,7 @@ net2272_plat_remove(struct platform_device *pdev) static struct platform_driver net2272_plat_driver = { .probe = net2272_plat_probe, - .remove_new = net2272_plat_remove, + .remove = net2272_plat_remove, .driver = { .name = driver_name, }, diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index 61a45e4657d5d4996502cb870f478667742e6aaf..698463bf697b29aaf15f05297b8beac9f2bfdab3 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -576,13 +576,13 @@ static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status) static void next_out_dma(struct omap_ep *ep, struct omap_req *req) { - unsigned packets = req->req.length - req->req.actual; + unsigned int packets = req->req.length - req->req.actual; int dma_trigger = 0; u16 w; /* set up this DMA transfer, enable the fifo, start */ packets /= ep->ep.maxpacket; - packets = min(packets, (unsigned)UDC_RXN_TC + 1); + packets = min_t(unsigned int, packets, UDC_RXN_TC + 1); req->dma_bytes = packets * ep->ep.maxpacket; omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, ep->ep.maxpacket >> 1, packets, @@ -2980,7 +2980,7 @@ static int omap_udc_resume(struct platform_device *dev) static struct platform_driver udc_driver = { .probe = omap_udc_probe, - .remove_new = omap_udc_remove, + .remove = omap_udc_remove, .suspend = omap_udc_suspend, .resume = omap_udc_resume, .driver = { diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 7c96fc9f680f1b5f5ae32bde2668769f6881e38a..1e9998024aaa3ccf7a6313516daf004af7b80992 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -2474,7 +2474,7 @@ static int pxa25x_udc_resume(struct platform_device *dev) static struct platform_driver udc_driver = { .shutdown = pxa25x_udc_shutdown, .probe = pxa25x_udc_probe, - .remove_new = pxa25x_udc_remove, + .remove = pxa25x_udc_remove, .suspend = pxa25x_udc_suspend, .resume = pxa25x_udc_resume, .driver = { diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index ea79f85f8e0bb24454dc4fa62f59328b686947e6..f9a55d4f189f4396230afcef85241c858fe40c41 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -2539,7 +2539,7 @@ static struct platform_driver udc_driver = { .of_match_table = of_match_ptr(udc_pxa_dt_ids), }, .probe = pxa_udc_probe, - .remove_new = pxa_udc_remove, + .remove = pxa_udc_remove, .shutdown = pxa_udc_shutdown, #ifdef CONFIG_PM .suspend = pxa_udc_suspend, diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index db4a10a979f9db51c95ed08218091d06b3cf3948..ff6f846b1d411cc46ec716ccbd9cac05f61ce38b 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1965,7 +1965,7 @@ clean_up2: /*-------------------------------------------------------------------------*/ static struct platform_driver r8a66597_driver = { .probe = r8a66597_probe, - .remove_new = r8a66597_remove, + .remove = r8a66597_remove, .driver = { .name = udc_name, }, diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 3b01734ce1b7e5d834f788a036b6a60605d35dff..fce5c41d9f298ba58899e90a2d4f9f7d078f1d41 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -3013,7 +3013,7 @@ static SIMPLE_DEV_PM_OPS(renesas_usb3_pm_ops, renesas_usb3_suspend, static struct platform_driver renesas_usb3_driver = { .probe = renesas_usb3_probe, - .remove_new = renesas_usb3_remove, + .remove = renesas_usb3_remove, .driver = { .name = udc_name, .pm = &renesas_usb3_pm_ops, diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c index 657f265ac7cc57d2ad225aba3cc0550b6136a4c9..14f4b2cf05a48570e90da85a81f2cd28930c2e1e 100644 --- a/drivers/usb/gadget/udc/renesas_usbf.c +++ b/drivers/usb/gadget/udc/renesas_usbf.c @@ -2482,7 +2482,7 @@ static int usbf_handle_ep0_setup(struct usbf_ep *ep0) ep0->delayed_status = 0; if ((crq.ctrlreq.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) { - /* This is not a USB standard request -> delelate */ + /* This is not a USB standard request -> delegate */ goto delegate; } @@ -3381,7 +3381,7 @@ static struct platform_driver udc_driver = { .of_match_table = usbf_match, }, .probe = usbf_probe, - .remove_new = usbf_remove, + .remove = usbf_remove, }; module_platform_driver(udc_driver); diff --git a/drivers/usb/gadget/udc/rzv2m_usb3drd.c b/drivers/usb/gadget/udc/rzv2m_usb3drd.c index 36f4ff00d22fdb6643a2206402d5777103845f57..4692eae89f4435f05b40bf5f743b1d20d40a8179 100644 --- a/drivers/usb/gadget/udc/rzv2m_usb3drd.c +++ b/drivers/usb/gadget/udc/rzv2m_usb3drd.c @@ -127,7 +127,7 @@ static struct platform_driver rzv2m_usb3drd_driver = { .of_match_table = rzv2m_usb3drd_of_match, }, .probe = rzv2m_usb3drd_probe, - .remove_new = rzv2m_usb3drd_remove, + .remove = rzv2m_usb3drd_remove, }; module_platform_driver(rzv2m_usb3drd_driver); diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c index cd89532adec2629473d565eb89f5a4f654bacc77..1f8a99d2a64363018cac3964ef24451886dfd93b 100644 --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -2707,7 +2707,7 @@ static irqreturn_t udc_control_in_isr(struct udc *dev) /* write fifo */ udc_txfifo_write(ep, &req->req); - /* lengh bytes transferred */ + /* length bytes transferred */ len = req->req.length - req->req.actual; if (len > ep->ep.maxpacket) len = ep->ep.maxpacket; diff --git a/drivers/usb/gadget/udc/snps_udc_plat.c b/drivers/usb/gadget/udc/snps_udc_plat.c index ba5a06690507797b91a92f06b115e776c82f3a97..db842a6de643def91fc98f0d4e4c451c61b7a918 100644 --- a/drivers/usb/gadget/udc/snps_udc_plat.c +++ b/drivers/usb/gadget/udc/snps_udc_plat.c @@ -309,7 +309,7 @@ MODULE_DEVICE_TABLE(of, of_udc_match); static struct platform_driver udc_plat_driver = { .probe = udc_plat_probe, - .remove_new = udc_plat_remove, + .remove = udc_plat_remove, .driver = { .name = "snps-udc-plat", .of_match_table = of_udc_match, diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 7aa46d426f31b26a1ee4e650f28871db1e3d4de4..c7fdbc55fb0b97edb6b475184bd1f51944a9797d 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -4071,7 +4071,7 @@ static const struct dev_pm_ops tegra_xudc_pm_ops = { static struct platform_driver tegra_xudc_driver = { .probe = tegra_xudc_probe, - .remove_new = tegra_xudc_remove, + .remove = tegra_xudc_remove, .driver = { .name = "tegra-xudc", .pm = &tegra_xudc_pm_ops, diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index ebc45565c33e54e7d51d22f8a728a17e88330299..ae2aeb2718977da854f523bd996fbfe6e66acbb9 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c @@ -2258,7 +2258,7 @@ static struct platform_driver xudc_driver = { .pm = &xudc_pm_ops, }, .probe = xudc_probe, - .remove_new = xudc_remove, + .remove = xudc_remove, }; module_platform_driver(xudc_driver); diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 75f6f99f8173ed7b9cfd2859e93ea3c777f4c67e..37a2f1b61cbab39387da183fb22d6d26f0950d3d 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c @@ -55,7 +55,7 @@ usb_gadget_get_string (const struct usb_gadget_strings *table, int id, u8 *buf) return -EINVAL; /* string descriptors have length, tag, then UTF16-LE text */ - len = min((size_t)USB_MAX_STRING_LEN, strlen(s->s)); + len = min_t(size_t, USB_MAX_STRING_LEN, strlen(s->s)); len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN, (wchar_t *) &buf[2], USB_MAX_STRING_LEN); if (len < 0) diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 7558cc4d90cc66bd23f9c17997b6cc5d3ca9bad9..519386255886c5c0d4bd1a526771ea518d5e32c1 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 6a6e1c510b2838dc59889cca11f7d217a9b077dc..65747270fd88d0784b9906d7709f0a584727d885 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -220,7 +220,7 @@ static SIMPLE_DEV_PM_OPS(ehci_atmel_pm_ops, ehci_atmel_drv_suspend, static struct platform_driver ehci_atmel_driver = { .probe = ehci_atmel_drv_probe, - .remove_new = ehci_atmel_drv_remove, + .remove = ehci_atmel_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "atmel-ehci", diff --git a/drivers/usb/host/ehci-brcm.c b/drivers/usb/host/ehci-brcm.c index 68cad0620f1a937a1b41e25c8cdf2e01e468188d..888e8f6670d2a10fd1dde56221628b3cfe487391 100644 --- a/drivers/usb/host/ehci-brcm.c +++ b/drivers/usb/host/ehci-brcm.c @@ -250,7 +250,7 @@ MODULE_DEVICE_TABLE(of, brcm_ehci_of_match); static struct platform_driver ehci_brcm_driver = { .probe = ehci_brcm_probe, - .remove_new = ehci_brcm_remove, + .remove = ehci_brcm_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ehci-brcm", diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index e3a961d3f5fc960994b9cbfcfd1d15496a693419..d2a5bedf736a2f255c405c5a306145821e39ab69 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -288,7 +288,7 @@ MODULE_DEVICE_TABLE(of, exynos_ehci_match); static struct platform_driver exynos_ehci_driver = { .probe = exynos_ehci_probe, - .remove_new = exynos_ehci_remove, + .remove = exynos_ehci_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "exynos-ehci", diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 5b1ce394a4174d89eabffcd3b35dd48c11683462..26f13278d4d6982ae2ca50948f930189f1e911a9 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -706,7 +706,7 @@ static void fsl_ehci_drv_remove(struct platform_device *pdev) static struct platform_driver ehci_fsl_driver = { .probe = fsl_ehci_drv_probe, - .remove_new = fsl_ehci_drv_remove, + .remove = fsl_ehci_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index 14150e4d338265ea3cb54bd1c707baaaffeb397c..bd9762eaa135293e3b483705dc6744a74bd3b7e0 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -168,7 +168,7 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_grlib_of_match); static struct platform_driver ehci_grlib_driver = { .probe = ehci_hcd_grlib_probe, - .remove_new = ehci_hcd_grlib_remove, + .remove = ehci_hcd_grlib_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "grlib-ehci", diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index cbc0b86fcc365e145852fd9dd9140c0fbb983e4b..6de79ac5e6a44231a15fb26a1696ebf6f2630e47 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -547,7 +547,7 @@ static int ehci_init(struct usb_hcd *hcd) * make problems: throughput reduction (!), data errors... */ if (park) { - park = min(park, (unsigned) 3); + park = min_t(unsigned int, park, 3); temp |= CMD_PARK; temp |= park << 8; } diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 2f1fc7eb8b727ffb8daa8043a49bffd5489585f7..cbabbe107172106d2187ea695b54e195a34d967c 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -279,7 +279,7 @@ static const struct of_device_id ehci_mv_dt_ids[] = { static struct platform_driver ehci_mv_driver = { .probe = mv_ehci_probe, - .remove_new = mv_ehci_remove, + .remove = mv_ehci_remove, .shutdown = mv_ehci_shutdown, .driver = { .name = "mv-ehci", diff --git a/drivers/usb/host/ehci-npcm7xx.c b/drivers/usb/host/ehci-npcm7xx.c index 3d3317a1a0b3fd6c12ecd3479c4aab3b3ad829a3..f1c7034c1e80d7c908d85da58586fea0b7e5b6ae 100644 --- a/drivers/usb/host/ehci-npcm7xx.c +++ b/drivers/usb/host/ehci-npcm7xx.c @@ -122,7 +122,7 @@ MODULE_DEVICE_TABLE(of, npcm7xx_ehci_id_table); static struct platform_driver npcm7xx_ehci_hcd_driver = { .probe = npcm7xx_ehci_hcd_drv_probe, - .remove_new = npcm7xx_ehci_hcd_drv_remove, + .remove = npcm7xx_ehci_hcd_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "npcm7xx-ehci", diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index b24f371a46f3ecdef56f54ecc7d68a49bf970e01..db4a1acb27dae720b11d60f6855766b95a13ff49 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -264,7 +264,7 @@ MODULE_DEVICE_TABLE(of, omap_ehci_dt_ids); static struct platform_driver ehci_hcd_omap_driver = { .probe = ehci_hcd_omap_probe, - .remove_new = ehci_hcd_omap_remove, + .remove = ehci_hcd_omap_remove, .shutdown = usb_hcd_platform_shutdown, /*.suspend = ehci_hcd_omap_suspend, */ /*.resume = ehci_hcd_omap_resume, */ diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index ad145a54ca74e4003ceadee7f1defc171ddee124..34abff8669f8bf096f4547b6ce0977eb130b3c8d 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -352,7 +352,7 @@ MODULE_DEVICE_TABLE(of, ehci_orion_dt_ids); static struct platform_driver ehci_orion_driver = { .probe = ehci_orion_drv_probe, - .remove_new = ehci_orion_drv_remove, + .remove = ehci_orion_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "orion-ehci", diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 98b073185e1c733b438586d25ff4a719a9a42ace..cdf41886e8cafa35e15e0182195ac5a538a63fe3 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -508,7 +508,7 @@ static SIMPLE_DEV_PM_OPS(ehci_platform_pm_ops, ehci_platform_suspend, static struct platform_driver ehci_platform_driver = { .id_table = ehci_platform_table, .probe = ehci_platform_probe, - .remove_new = ehci_platform_remove, + .remove = ehci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ehci-platform", diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 7fd83e806ae4661631b38bd9e056729f01dac7ff..8063b9d3aebd08082146b30fda6549b4a2a75dc7 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -230,7 +230,7 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match); static struct platform_driver ehci_hcd_ppc_of_driver = { .probe = ehci_hcd_ppc_of_probe, - .remove_new = ehci_hcd_ppc_of_remove, + .remove = ehci_hcd_ppc_of_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ppc-of-ehci", diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index d31d9506e41ab0844cf04f5bbe1485972f8f62a4..5d0d972fb7b1b4f3ab9dca0d66b5c199319ea548 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -169,7 +169,7 @@ static void ehci_hcd_sh_shutdown(struct platform_device *pdev) static struct platform_driver ehci_hcd_sh_driver = { .probe = ehci_hcd_sh_probe, - .remove_new = ehci_hcd_sh_remove, + .remove = ehci_hcd_sh_remove, .shutdown = ehci_hcd_sh_shutdown, .driver = { .name = "sh_ehci", diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index d0e94e4c9fe2742eddc7475e33e849e51f03ed76..e96710192d6b026171ba552f91d969c9ddf0bd6c 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -105,7 +105,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) /* registers start at offset 0x0 */ hcd_to_ehci(hcd)->caps = hcd->regs; - clk_prepare_enable(sehci->clk); + retval = clk_prepare_enable(sehci->clk); + if (retval) + goto err_put_hcd; retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval) goto err_stop_ehci; @@ -130,8 +132,7 @@ static void spear_ehci_hcd_drv_remove(struct platform_device *pdev) usb_remove_hcd(hcd); - if (sehci->clk) - clk_disable_unprepare(sehci->clk); + clk_disable_unprepare(sehci->clk); usb_put_hcd(hcd); } @@ -143,7 +144,7 @@ MODULE_DEVICE_TABLE(of, spear_ehci_id_table); static struct platform_driver spear_ehci_hcd_driver = { .probe = spear_ehci_hcd_drv_probe, - .remove_new = spear_ehci_hcd_drv_remove, + .remove = spear_ehci_hcd_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "spear-ehci", diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c index 2dbb0d86daaaa93543bc4458d66a8919f2da70a5..58867d816af75600e5f7ca7c1aad474d4cd34e44 100644 --- a/drivers/usb/host/ehci-st.c +++ b/drivers/usb/host/ehci-st.c @@ -320,7 +320,7 @@ MODULE_DEVICE_TABLE(of, st_ehci_ids); static struct platform_driver ehci_platform_driver = { .probe = st_ehci_platform_probe, - .remove_new = st_ehci_platform_remove, + .remove = st_ehci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "st-ehci", diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index a2112c28f6314688dbbf9ce7ac60bcc3a7d72731..1d16cfefabd7165ceae34f63eb1e05b6d1a8d7a5 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -220,7 +220,7 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_xilinx_of_match); static struct platform_driver ehci_hcd_xilinx_of_driver = { .probe = ehci_hcd_xilinx_of_probe, - .remove_new = ehci_hcd_xilinx_of_remove, + .remove = ehci_hcd_xilinx_of_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "xilinx-of-ehci", diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 9a1b5224f2396eb441e6b7d57bb466e783831dfe..22a0942f0bcee6430c16ad0a8c1b7d759d7e02ac 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -791,7 +791,7 @@ static struct platform_driver of_fhci_driver = { .of_match_table = of_fhci_match, }, .probe = of_fhci_probe, - .remove_new = of_fhci_remove, + .remove = of_fhci_remove, }; module_platform_driver(of_fhci_driver); diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index a45ede80edfcd175ff499535af95803f50fb9f45..c3acd410ce948c2a31d3163e1691afff6d792d43 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c @@ -158,7 +158,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) struct packet *pkt; u8 *data = NULL; - /* calcalate data address,len and toggle and then add the transaction */ + /* calculate data address,len and toggle and then add the transaction */ if (td->toggle == USB_TD_TOGGLE_CARRY) td->toggle = ed->toggle_carry; @@ -679,7 +679,7 @@ static void process_done_list(unsigned long data) DECLARE_TASKLET_OLD(fhci_tasklet, process_done_list); -/* transfer complted callback */ +/* transfer completed callback */ u32 fhci_transfer_confirm_callback(struct fhci_hcd *fhci) { if (!fhci->process_done_task->state) diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 6cdc3d805c32a58ee408d9f45f244c599f03380e..4e67b9471986040735b726d84a1d7ae31b80aca0 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -362,7 +362,7 @@ static struct platform_driver fsl_usb2_mph_dr_driver = { .of_match_table = fsl_usb2_mph_dr_of_match, }, .probe = fsl_usb2_mph_dr_of_probe, - .remove_new = fsl_usb2_mph_dr_of_remove, + .remove = fsl_usb2_mph_dr_of_remove, }; module_platform_driver(fsl_usb2_mph_dr_driver); diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index a82d8926e922c49151ebda072c94e24719c28b76..71c22c4bd16353c0eb702f3202a4011d14f492a7 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1684,7 +1684,7 @@ MODULE_ALIAS("platform:isp116x-hcd"); static struct platform_driver isp116x_driver = { .probe = isp116x_probe, - .remove_new = isp116x_remove, + .remove = isp116x_remove, .suspend = isp116x_suspend, .resume = isp116x_resume, .driver = { diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 31059c8f94e63f4ecf18d9fb2a87ffc365f4a95c..2d3a082cb52f8265bff67a4282cfa368a16948ff 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2757,7 +2757,7 @@ static int isp1362_resume(struct platform_device *pdev) static struct platform_driver isp1362_driver = { .probe = isp1362_probe, - .remove_new = isp1362_remove, + .remove = isp1362_remove, .suspend = isp1362_suspend, .resume = isp1362_resume, diff --git a/drivers/usb/host/octeon-hcd.c b/drivers/usb/host/octeon-hcd.c index 19d5777f5db25c980fa52f1940a379da039f1373..361d33b0c4d29abb72ec0e010e66d36bd451eb25 100644 --- a/drivers/usb/host/octeon-hcd.c +++ b/drivers/usb/host/octeon-hcd.c @@ -3346,7 +3346,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; case USB_PORT_FEAT_INDICATOR: dev_dbg(dev, " INDICATOR\n"); - /* Port inidicator not supported */ + /* Port indicator not supported */ break; case USB_PORT_FEAT_C_CONNECTION: dev_dbg(dev, " C_CONNECTION\n"); @@ -3711,8 +3711,8 @@ static struct platform_driver octeon_usb_driver = { .name = "octeon-hcd", .of_match_table = octeon_usb_match, }, - .probe = octeon_usb_probe, - .remove_new = octeon_usb_remove, + .probe = octeon_usb_probe, + .remove = octeon_usb_remove, }; static int __init octeon_usb_driver_init(void) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index f691cd98a57466ecf82216843e04dc4c8ed201f4..5df793dcb25dacd7941582ab5bb96d5f947954a0 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -685,7 +685,7 @@ static SIMPLE_DEV_PM_OPS(ohci_hcd_at91_pm_ops, ohci_hcd_at91_drv_suspend, static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, - .remove_new = ohci_hcd_at91_drv_remove, + .remove = ohci_hcd_at91_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "at91_ohci", diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index d2b67da76762c6489581b759500ba2a738bdce92..3c5ca2d7c92ed786af41d98ed124926ae06d4025 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -531,7 +531,7 @@ static const struct ohci_driver_overrides da8xx_overrides __initconst = { */ static struct platform_driver ohci_hcd_da8xx_driver = { .probe = ohci_da8xx_probe, - .remove_new = ohci_da8xx_remove, + .remove = ohci_da8xx_remove, .shutdown = usb_hcd_platform_shutdown, #ifdef CONFIG_PM .suspend = ohci_da8xx_suspend, diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 1379e03644b2a30847c2fcc2fcd3a55d189bf60a..cc5cb09009880a65cb334ba0476300a0dad04f4b 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -262,7 +262,7 @@ MODULE_DEVICE_TABLE(of, exynos_ohci_match); static struct platform_driver exynos_ohci_driver = { .probe = exynos_ohci_probe, - .remove_new = exynos_ohci_remove, + .remove = exynos_ohci_remove, .shutdown = exynos_ohci_shutdown, .driver = { .name = "exynos-ohci", diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 5b775e1ea52707fee7a302f47c379a2cadad857a..24d5a1dc5056047e20b3debc57001325db196bf6 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -254,7 +254,7 @@ static struct platform_driver ohci_hcd_nxp_driver = { .of_match_table = of_match_ptr(ohci_hcd_nxp_match), }, .probe = ohci_hcd_nxp_probe, - .remove_new = ohci_hcd_nxp_remove, + .remove = ohci_hcd_nxp_remove, }; static int __init ohci_nxp_init(void) diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 21a6f6c55e079e5ea585205ba795ce926d26e0a4..f6e56c4b991485f7e8b071d31f990b0a92e0c21f 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -152,7 +152,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd) rh &= ~RH_A_NOCP; - /* gpio9 for overcurrent detction */ + /* gpio9 for overcurrent detection */ omap_cfg_reg(W8_1610_GPIO9); /* for paranoia's sake: disable USB.PUEN */ @@ -390,7 +390,7 @@ static int ohci_omap_resume(struct platform_device *dev) */ static struct platform_driver ohci_hcd_omap_driver = { .probe = ohci_hcd_omap_probe, - .remove_new = ohci_hcd_omap_remove, + .remove = ohci_hcd_omap_remove, .shutdown = usb_hcd_platform_shutdown, #ifdef CONFIG_PM .suspend = ohci_omap_suspend, diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 4a75507325ddcd7b3bed5662429280fc7189609a..f47ae12cde6a26c0796da36cb2156861250c561d 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -344,7 +344,7 @@ static const struct dev_pm_ops ohci_platform_pm_ops = { static struct platform_driver ohci_platform_driver = { .id_table = ohci_platform_table, .probe = ohci_platform_probe, - .remove_new = ohci_platform_remove, + .remove = ohci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ohci-platform", diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index a6be061f86532bd3357f38cf41d89fbc323a2b85..acd0a0e398a4308fae92171ba21158702d647cc3 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -219,7 +219,7 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); static struct platform_driver ohci_hcd_ppc_of_driver = { .probe = ohci_hcd_ppc_of_probe, - .remove_new = ohci_hcd_ppc_of_remove, + .remove = ohci_hcd_ppc_of_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ppc-of-ohci", diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 3348c25ddb18d2c2564a7c9511dc72921107db1f..45d026e85168b46b5d739ecd78fc32179747fbef 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -569,7 +569,7 @@ static const struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = { static struct platform_driver ohci_hcd_pxa27x_driver = { .probe = ohci_hcd_pxa27x_probe, - .remove_new = ohci_hcd_pxa27x_remove, + .remove = ohci_hcd_pxa27x_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "pxa27x-ohci", diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index c5c9b4cbcb9a3c783edeaf4714d54b7a5dc86f09..66d970854357d3b6c2f6ec583917c2a4e4c2ecbf 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -457,7 +457,7 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_s3c2410_dt_ids); static struct platform_driver ohci_hcd_s3c2410_driver = { .probe = ohci_hcd_s3c2410_probe, - .remove_new = ohci_hcd_s3c2410_remove, + .remove = ohci_hcd_s3c2410_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "s3c2410-ohci", diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 4b39e9d6f33a98f10fbf74061244bf640953ad09..843a5378764e6b9dcf5056e73428b7178c132748 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -252,7 +252,7 @@ static int ohci_sm501_resume(struct platform_device *pdev) */ static struct platform_driver ohci_hcd_sm501_driver = { .probe = ohci_hcd_sm501_drv_probe, - .remove_new = ohci_hcd_sm501_drv_remove, + .remove = ohci_hcd_sm501_drv_remove, .shutdown = usb_hcd_platform_shutdown, .suspend = ohci_sm501_suspend, .resume = ohci_sm501_resume, diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 993f347c5c2884b3e3e2a3410aef8d9954a4bcdf..d7131e5a4477c44aaf760029e2c7b2f4d4019e8e 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -157,7 +157,7 @@ MODULE_DEVICE_TABLE(of, spear_ohci_id_table); /* Driver definition to register with the platform bus */ static struct platform_driver spear_ohci_hcd_driver = { .probe = spear_ohci_hcd_drv_probe, - .remove_new = spear_ohci_hcd_drv_remove, + .remove = spear_ohci_hcd_drv_remove, #ifdef CONFIG_PM .suspend = spear_ohci_hcd_drv_suspend, .resume = spear_ohci_hcd_drv_resume, diff --git a/drivers/usb/host/ohci-st.c b/drivers/usb/host/ohci-st.c index 214342013f7ec4126634d09e2f266546e34d5fce..d1656fce54004780867490e11161ae2df90e88f8 100644 --- a/drivers/usb/host/ohci-st.c +++ b/drivers/usb/host/ohci-st.c @@ -298,7 +298,7 @@ MODULE_DEVICE_TABLE(of, st_ohci_platform_ids); static struct platform_driver ohci_platform_driver = { .probe = st_ohci_platform_probe, - .remove_new = st_ohci_platform_remove, + .remove = st_ohci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "st-ohci", diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index ca3859463ba1415cc3c023e51e41a4bfcf894b37..a6c20facf9450153121001d36547eee68d6c9ca9 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -885,7 +885,7 @@ static int oxu_buf_alloc(struct oxu_hcd *oxu, struct ehci_qtd *qtd, int len) int a_blocks; /* blocks allocated */ int i, j; - /* Don't allocte bigger than supported */ + /* Don't allocate bigger than supported */ if (len > BUFFER_SIZE * BUFFER_NUM) { oxu_err(oxu, "buffer too big (%d)\n", len); return -ENOMEM; @@ -902,7 +902,7 @@ static int oxu_buf_alloc(struct oxu_hcd *oxu, struct ehci_qtd *qtd, int len) /* Find a suitable available data buffer */ for (i = 0; i < BUFFER_NUM; - i += max(a_blocks, (int)oxu->db_used[i])) { + i += max_t(int, a_blocks, oxu->db_used[i])) { /* Check all the required blocks are available */ for (j = 0; j < a_blocks; j++) @@ -3040,7 +3040,7 @@ static int oxu_hcd_init(struct usb_hcd *hcd) * make problems: throughput reduction (!), data errors... */ if (park) { - park = min(park, (unsigned) 3); + park = min_t(unsigned int, park, 3); temp |= CMD_PARK; temp |= park << 8; } @@ -4289,7 +4289,7 @@ static int oxu_drv_resume(struct device *dev) static struct platform_driver oxu_driver = { .probe = oxu_drv_probe, - .remove_new = oxu_drv_remove, + .remove = oxu_drv_remove, .shutdown = oxu_drv_shutdown, .suspend = oxu_drv_suspend, .resume = oxu_drv_resume, diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 6576515a29cd370fc6e55129695e57a020fa11e9..a44992e2561b06042e51a8517b43dc58eee9cad3 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -759,7 +759,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, struct r8a66597_pipe_info *info = &pipe->info; unsigned short mbw = mbw_value(r8a66597); - /* pipe dma is only for external controlles */ + /* pipe dma is only for external controllers */ if (r8a66597->pdata->on_chip) return; @@ -1336,7 +1336,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) buf = (void *)urb->transfer_buffer + urb->actual_length; urb_len = urb->transfer_buffer_length - urb->actual_length; } - bufsize = min(urb_len, (int) td->maxpacket); + bufsize = min_t(int, urb_len, td->maxpacket); if (rcv_len <= bufsize) { size = rcv_len; } else { @@ -2510,7 +2510,7 @@ clean_up: static struct platform_driver r8a66597_driver = { .probe = r8a66597_probe, - .remove_new = r8a66597_remove, + .remove = r8a66597_remove, .driver = { .name = hcd_name, .pm = R8A66597_DEV_PM_OPS, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 92f2d12384488f2eab7a66db5dbd44a1dc91c8f9..036f5fd6d159feee18f3be187c6bc9d5ea59dc4f 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1784,7 +1784,7 @@ sl811h_resume(struct platform_device *dev) /* this driver is exported so sl811_cs can depend on it */ struct platform_driver sl811h_driver = { .probe = sl811h_probe, - .remove_new = sl811h_remove, + .remove = sl811h_remove, .suspend = sl811h_suspend, .resume = sl811h_resume, diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index cfebb833668e4b014633d0919be1aa1777c25140..8a1f6d1b5b56082011eb3974eddeb2acecb229e6 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -184,7 +184,7 @@ MODULE_DEVICE_TABLE(of, uhci_hcd_grlib_of_match); static struct platform_driver uhci_grlib_driver = { .probe = uhci_hcd_grlib_probe, - .remove_new = uhci_hcd_grlib_remove, + .remove = uhci_hcd_grlib_remove, .shutdown = uhci_hcd_grlib_shutdown, .driver = { .name = "grlib-uhci", diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index 3dec5dd3a0d5cab9f3d66dd603a3035cf491167a..a7c934404ebc7ed74f64265fafa7830809979ba5 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -184,7 +184,7 @@ MODULE_DEVICE_TABLE(of, platform_uhci_ids); static struct platform_driver uhci_platform_driver = { .probe = uhci_hcd_platform_probe, - .remove_new = uhci_hcd_platform_remove, + .remove = uhci_hcd_platform_remove, .shutdown = uhci_hcd_platform_shutdown, .driver = { .name = "platform-uhci", diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index 241d7aa1fbc20f7e556ada31033bf23734637c42..227e513867dd2773fbdfbcb9a867ded4eae522b8 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -248,8 +248,9 @@ xhci_dbc_queue_trb(struct xhci_ring *ring, u32 field1, trb->generic.field[2] = cpu_to_le32(field3); trb->generic.field[3] = cpu_to_le32(field4); - trace_xhci_dbc_gadget_ep_queue(ring, &trb->generic); - + trace_xhci_dbc_gadget_ep_queue(ring, &trb->generic, + xhci_trb_virt_to_dma(ring->enq_seg, + ring->enqueue)); ring->num_trbs_free--; next = ++(ring->enqueue); if (TRB_TYPE_LINK_LE32(next->link.control)) { @@ -471,7 +472,7 @@ xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags) trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK)); } INIT_LIST_HEAD(&ring->td_list); - xhci_initialize_ring_info(ring, 1); + xhci_initialize_ring_info(ring); return ring; dma_fail: kfree(seg); @@ -747,7 +748,7 @@ static void dbc_handle_xfer_event(struct xhci_dbc *dbc, union xhci_trb *event) return; } - trace_xhci_dbc_handle_transfer(ring, &req->trb->generic); + trace_xhci_dbc_handle_transfer(ring, &req->trb->generic, req->trb_dma); switch (comp_code) { case COMP_SUCCESS: @@ -898,7 +899,9 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc) */ rmb(); - trace_xhci_dbc_handle_event(dbc->ring_evt, &evt->generic); + trace_xhci_dbc_handle_event(dbc->ring_evt, &evt->generic, + xhci_trb_virt_to_dma(dbc->ring_evt->deq_seg, + dbc->ring_evt->dequeue)); switch (le32_to_cpu(evt->event_cmd.flags) & TRB_TYPE_BITMASK) { case TRB_TYPE(TRB_PORT_STATUS): diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index f8ba15e7c225c2a079ae31c74c93a3ddc82a08ee..4f0c1b96e208f2af82a658b5014caf61256c5bcb 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c @@ -214,14 +214,11 @@ static void xhci_ring_dump_segment(struct seq_file *s, static int xhci_ring_trb_show(struct seq_file *s, void *unused) { - int i; struct xhci_ring *ring = *(struct xhci_ring **)s->private; struct xhci_segment *seg = ring->first_seg; - for (i = 0; i < ring->num_segs; i++) { + xhci_for_each_ring_seg(ring->first_seg, seg) xhci_ring_dump_segment(s, seg); - seg = seg->next; - } return 0; } @@ -291,12 +288,13 @@ static int xhci_endpoint_context_show(struct seq_file *s, void *unused) for (ep_index = 0; ep_index < 31; ep_index++) { ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); dma = dev->out_ctx->dma + (ep_index + 1) * CTX_SIZE(xhci->hcc_params); - seq_printf(s, "%pad: %s\n", &dma, + seq_printf(s, "%pad: %s, virt_state:%#x\n", &dma, xhci_decode_ep_context(str, le32_to_cpu(ep_ctx->ep_info), le32_to_cpu(ep_ctx->ep_info2), le64_to_cpu(ep_ctx->deq), - le32_to_cpu(ep_ctx->tx_info))); + le32_to_cpu(ep_ctx->tx_info)), + dev->eps[ep_index].ep_state); } return 0; diff --git a/drivers/usb/host/xhci-histb.c b/drivers/usb/host/xhci-histb.c index f9a4a4b0eb574920d3fdec7800939a80c9d6ebbb..8a7d46dae62c8c9d7691d453ea6f9c1a70a73310 100644 --- a/drivers/usb/host/xhci-histb.c +++ b/drivers/usb/host/xhci-histb.c @@ -373,7 +373,7 @@ MODULE_DEVICE_TABLE(of, histb_xhci_of_match); static struct platform_driver histb_xhci_driver = { .probe = xhci_histb_probe, - .remove_new = xhci_histb_remove, + .remove = xhci_histb_remove, .driver = { .name = "xhci-histb", .pm = DEV_PM_OPS, diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 8d774f19271e6afa6809db5257e28e2b7eee0115..9693464c052049e63f22f5b108eb9b4f0d87104e 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -946,9 +946,9 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, } /* did port event handler already start resume timing? */ if (!port->resume_timestamp) { - /* If not, maybe we are in a host initated resume? */ + /* If not, maybe we are in a host initiated resume? */ if (test_bit(wIndex, &bus_state->resuming_ports)) { - /* Host initated resume doesn't time the resume + /* Host initiated resume doesn't time the resume * signalling using resume_done[]. * It manually sets RESUME state, sleeps 20ms * and sets U0 state. This should probably be @@ -1924,7 +1924,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) /* resume already initiated */ break; default: - /* not in a resumeable state, ignore it */ + /* not in a resumable state, ignore it */ clear_bit(port_index, &bus_state->bus_suspended); break; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index d2900197a49e7474843efff3f8c43d9505346119..15db90c54a45abe3bd9e30a6d719805665fe2c11 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -27,14 +27,12 @@ * "All components of all Command and Transfer TRBs shall be initialized to '0'" */ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, - unsigned int cycle_state, unsigned int max_packet, unsigned int num, gfp_t flags) { struct xhci_segment *seg; dma_addr_t dma; - int i; struct device *dev = xhci_to_hcd(xhci)->self.sysdev; seg = kzalloc_node(sizeof(*seg), flags, dev_to_node(dev)); @@ -56,11 +54,6 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, return NULL; } } - /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */ - if (cycle_state == 0) { - for (i = 0; i < TRBS_PER_SEGMENT; i++) - seg->trbs[i].link.control = cpu_to_le32(TRB_CYCLE); - } seg->num = num; seg->dma = dma; seg->next = NULL; @@ -78,82 +71,104 @@ static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg) kfree(seg); } -static void xhci_free_segments_for_ring(struct xhci_hcd *xhci, - struct xhci_segment *first) +static void xhci_ring_segments_free(struct xhci_hcd *xhci, struct xhci_ring *ring) { - struct xhci_segment *seg; + struct xhci_segment *seg, *next; + + ring->last_seg->next = NULL; + seg = ring->first_seg; - seg = first->next; - while (seg && seg != first) { - struct xhci_segment *next = seg->next; + while (seg) { + next = seg->next; xhci_segment_free(xhci, seg); seg = next; } - xhci_segment_free(xhci, first); } /* - * Make the prev segment point to the next segment. + * Only for transfer and command rings where driver is the producer, not for + * event rings. * - * Change the last TRB in the prev segment to be a Link TRB which points to the + * Change the last TRB in the segment to be a Link TRB which points to the * DMA address of the next segment. The caller needs to set any Link TRB * related flags, such as End TRB, Toggle Cycle, and no snoop. */ -static void xhci_link_segments(struct xhci_segment *prev, - struct xhci_segment *next, - enum xhci_ring_type type, bool chain_links) +static void xhci_set_link_trb(struct xhci_segment *seg, bool chain_links) { + union xhci_trb *trb; u32 val; - if (!prev || !next) + if (!seg || !seg->next) return; - prev->next = next; - if (type != TYPE_EVENT) { - prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = - cpu_to_le64(next->dma); - /* Set the last TRB in the segment to have a TRB type ID of Link TRB */ - val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control); - val &= ~TRB_TYPE_BITMASK; - val |= TRB_TYPE(TRB_LINK); - if (chain_links) - val |= TRB_CHAIN; - prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); - } + trb = &seg->trbs[TRBS_PER_SEGMENT - 1]; + + /* Set the last TRB in the segment to have a TRB type ID of Link TRB */ + val = le32_to_cpu(trb->link.control); + val &= ~TRB_TYPE_BITMASK; + val |= TRB_TYPE(TRB_LINK); + if (chain_links) + val |= TRB_CHAIN; + trb->link.control = cpu_to_le32(val); + trb->link.segment_ptr = cpu_to_le64(seg->next->dma); +} + +static void xhci_initialize_ring_segments(struct xhci_hcd *xhci, struct xhci_ring *ring) +{ + struct xhci_segment *seg; + bool chain_links; + + if (ring->type == TYPE_EVENT) + return; + + chain_links = xhci_link_chain_quirk(xhci, ring->type); + xhci_for_each_ring_seg(ring->first_seg, seg) + xhci_set_link_trb(seg, chain_links); + + /* See section 4.9.2.1 and 6.4.4.1 */ + ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |= cpu_to_le32(LINK_TOGGLE); } /* - * Link the ring to the new segments. + * Link the src ring segments to the dst ring. * Set Toggle Cycle for the new ring if needed. */ -static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, - struct xhci_segment *first, struct xhci_segment *last, - unsigned int num_segs) +static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *src, struct xhci_ring *dst) { - struct xhci_segment *next, *seg; + struct xhci_segment *seg; bool chain_links; - if (!ring || !first || !last) + if (!src || !dst) return; - chain_links = xhci_link_chain_quirk(xhci, ring->type); + /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */ + if (dst->cycle_state == 0) { + xhci_for_each_ring_seg(src->first_seg, seg) { + for (int i = 0; i < TRBS_PER_SEGMENT; i++) + seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE); + } + } - next = ring->enq_seg->next; - xhci_link_segments(ring->enq_seg, first, ring->type, chain_links); - xhci_link_segments(last, next, ring->type, chain_links); - ring->num_segs += num_segs; + src->last_seg->next = dst->enq_seg->next; + dst->enq_seg->next = src->first_seg; + if (dst->type != TYPE_EVENT) { + chain_links = xhci_link_chain_quirk(xhci, dst->type); + xhci_set_link_trb(dst->enq_seg, chain_links); + xhci_set_link_trb(src->last_seg, chain_links); + } + dst->num_segs += src->num_segs; - if (ring->enq_seg == ring->last_seg) { - if (ring->type != TYPE_EVENT) { - ring->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control + if (dst->enq_seg == dst->last_seg) { + if (dst->type != TYPE_EVENT) + dst->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control &= ~cpu_to_le32(LINK_TOGGLE); - last->trbs[TRBS_PER_SEGMENT-1].link.control - |= cpu_to_le32(LINK_TOGGLE); - } - ring->last_seg = last; + + dst->last_seg = src->last_seg; + } else if (dst->type != TYPE_EVENT) { + src->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control &= ~cpu_to_le32(LINK_TOGGLE); } - for (seg = ring->enq_seg; seg != ring->last_seg; seg = seg->next) + for (seg = dst->enq_seg; seg != dst->last_seg; seg = seg->next) seg->next->num = seg->num + 1; } @@ -224,7 +239,6 @@ static int xhci_update_stream_segment_mapping( struct radix_tree_root *trb_address_map, struct xhci_ring *ring, struct xhci_segment *first_seg, - struct xhci_segment *last_seg, gfp_t mem_flags) { struct xhci_segment *seg; @@ -234,28 +248,22 @@ static int xhci_update_stream_segment_mapping( if (WARN_ON_ONCE(trb_address_map == NULL)) return 0; - seg = first_seg; - do { + xhci_for_each_ring_seg(first_seg, seg) { ret = xhci_insert_segment_mapping(trb_address_map, ring, seg, mem_flags); if (ret) goto remove_streams; - if (seg == last_seg) - return 0; - seg = seg->next; - } while (seg != first_seg); + } return 0; remove_streams: failed_seg = seg; - seg = first_seg; - do { + xhci_for_each_ring_seg(first_seg, seg) { xhci_remove_segment_mapping(trb_address_map, seg); if (seg == failed_seg) return ret; - seg = seg->next; - } while (seg != first_seg); + } return ret; } @@ -267,17 +275,14 @@ static void xhci_remove_stream_mapping(struct xhci_ring *ring) if (WARN_ON_ONCE(ring->trb_address_map == NULL)) return; - seg = ring->first_seg; - do { + xhci_for_each_ring_seg(ring->first_seg, seg) xhci_remove_segment_mapping(ring->trb_address_map, seg); - seg = seg->next; - } while (seg != ring->first_seg); } static int xhci_update_stream_mapping(struct xhci_ring *ring, gfp_t mem_flags) { return xhci_update_stream_segment_mapping(ring->trb_address_map, ring, - ring->first_seg, ring->last_seg, mem_flags); + ring->first_seg, mem_flags); } /* XXX: Do we need the hcd structure in all these functions? */ @@ -291,14 +296,13 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) if (ring->first_seg) { if (ring->type == TYPE_STREAM) xhci_remove_stream_mapping(ring); - xhci_free_segments_for_ring(xhci, ring->first_seg); + xhci_ring_segments_free(xhci, ring); } kfree(ring); } -void xhci_initialize_ring_info(struct xhci_ring *ring, - unsigned int cycle_state) +void xhci_initialize_ring_info(struct xhci_ring *ring) { /* The ring is empty, so the enqueue pointer == dequeue pointer */ ring->enqueue = ring->first_seg->trbs; @@ -312,7 +316,7 @@ void xhci_initialize_ring_info(struct xhci_ring *ring, * New rings are initialized with cycle state equal to 1; if we are * handling ring expansion, set the cycle state equal to the old ring. */ - ring->cycle_state = cycle_state; + ring->cycle_state = 1; /* * Each segment has a link TRB, and leave an extra TRB for SW @@ -323,46 +327,36 @@ void xhci_initialize_ring_info(struct xhci_ring *ring, EXPORT_SYMBOL_GPL(xhci_initialize_ring_info); /* Allocate segments and link them for a ring */ -static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, - struct xhci_segment **first, - struct xhci_segment **last, - unsigned int num_segs, - unsigned int cycle_state, - enum xhci_ring_type type, - unsigned int max_packet, - gfp_t flags) +static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, gfp_t flags) { struct xhci_segment *prev; unsigned int num = 0; - bool chain_links; - - chain_links = xhci_link_chain_quirk(xhci, type); - prev = xhci_segment_alloc(xhci, cycle_state, max_packet, num, flags); + prev = xhci_segment_alloc(xhci, ring->bounce_buf_len, num, flags); if (!prev) return -ENOMEM; num++; - *first = prev; - while (num < num_segs) { + ring->first_seg = prev; + while (num < ring->num_segs) { struct xhci_segment *next; - next = xhci_segment_alloc(xhci, cycle_state, max_packet, num, - flags); + next = xhci_segment_alloc(xhci, ring->bounce_buf_len, num, flags); if (!next) goto free_segments; - xhci_link_segments(prev, next, type, chain_links); + prev->next = next; prev = next; num++; } - xhci_link_segments(prev, *first, type, chain_links); - *last = prev; + ring->last_seg = prev; + ring->last_seg->next = ring->first_seg; return 0; free_segments: - xhci_free_segments_for_ring(xhci, *first); + ring->last_seg = prev; + xhci_ring_segments_free(xhci, ring); return -ENOMEM; } @@ -373,9 +367,8 @@ free_segments: * Set the end flag and the cycle toggle bit on the last segment. * See section 4.9.1 and figures 15 and 16. */ -struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, - unsigned int num_segs, unsigned int cycle_state, - enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) +struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs, + enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) { struct xhci_ring *ring; int ret; @@ -392,18 +385,12 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, if (num_segs == 0) return ring; - ret = xhci_alloc_segments_for_ring(xhci, &ring->first_seg, &ring->last_seg, num_segs, - cycle_state, type, max_packet, flags); + ret = xhci_alloc_segments_for_ring(xhci, ring, flags); if (ret) goto fail; - /* Only event ring does not use link TRB */ - if (type != TYPE_EVENT) { - /* See section 4.9.2.1 and 6.4.4.1 */ - ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |= - cpu_to_le32(LINK_TOGGLE); - } - xhci_initialize_ring_info(ring, cycle_state); + xhci_initialize_ring_segments(xhci, ring); + xhci_initialize_ring_info(ring); trace_xhci_ring_alloc(ring); return ring; @@ -427,23 +414,29 @@ void xhci_free_endpoint_ring(struct xhci_hcd *xhci, int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, unsigned int num_new_segs, gfp_t flags) { - struct xhci_segment *first; - struct xhci_segment *last; - int ret; + struct xhci_ring new_ring; + int ret; + + if (num_new_segs == 0) + return 0; - ret = xhci_alloc_segments_for_ring(xhci, &first, &last, num_new_segs, ring->cycle_state, - ring->type, ring->bounce_buf_len, flags); + new_ring.num_segs = num_new_segs; + new_ring.bounce_buf_len = ring->bounce_buf_len; + new_ring.type = ring->type; + ret = xhci_alloc_segments_for_ring(xhci, &new_ring, flags); if (ret) return -ENOMEM; + xhci_initialize_ring_segments(xhci, &new_ring); + if (ring->type == TYPE_STREAM) { - ret = xhci_update_stream_segment_mapping(ring->trb_address_map, - ring, first, last, flags); + ret = xhci_update_stream_segment_mapping(ring->trb_address_map, ring, + new_ring.first_seg, flags); if (ret) goto free_segments; } - xhci_link_rings(xhci, ring, first, last, num_new_segs); + xhci_link_rings(xhci, ring, &new_ring); trace_xhci_ring_expansion(ring); xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion, "ring expansion succeed, now has %d segments", @@ -452,7 +445,7 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, return 0; free_segments: - xhci_free_segments_for_ring(xhci, first); + xhci_ring_segments_free(xhci, &new_ring); return ret; } @@ -642,8 +635,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { stream_info->stream_rings[cur_stream] = - xhci_ring_alloc(xhci, 2, 1, TYPE_STREAM, max_packet, - mem_flags); + xhci_ring_alloc(xhci, 2, TYPE_STREAM, max_packet, mem_flags); cur_ring = stream_info->stream_rings[cur_stream]; if (!cur_ring) goto cleanup_rings; @@ -658,6 +650,8 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, xhci_dbg(xhci, "Setting stream %d ring ptr to 0x%08llx\n", cur_stream, addr); ret = xhci_update_stream_mapping(cur_ring, mem_flags); + + trace_xhci_alloc_stream_info_ctx(stream_info, cur_stream); if (ret) { xhci_ring_free(xhci, cur_ring); stream_info->stream_rings[cur_stream] = NULL; @@ -984,7 +978,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, } /* Allocate endpoint 0 ring */ - dev->eps[0].ring = xhci_ring_alloc(xhci, 2, 1, TYPE_CTRL, 0, flags); + dev->eps[0].ring = xhci_ring_alloc(xhci, 2, TYPE_CTRL, 0, flags); if (!dev->eps[0].ring) goto fail; @@ -1461,7 +1455,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, /* Set up the endpoint ring */ virt_dev->eps[ep_index].new_ring = - xhci_ring_alloc(xhci, 2, 1, ring_type, max_packet, mem_flags); + xhci_ring_alloc(xhci, 2, ring_type, max_packet, mem_flags); if (!virt_dev->eps[ep_index].new_ring) return -ENOMEM; @@ -2271,7 +2265,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags) if (!ir) return NULL; - ir->event_ring = xhci_ring_alloc(xhci, segs, 1, TYPE_EVENT, 0, flags); + ir->event_ring = xhci_ring_alloc(xhci, segs, TYPE_EVENT, 0, flags); if (!ir->event_ring) { xhci_warn(xhci, "Failed to allocate interrupter event ring\n"); kfree(ir); @@ -2473,7 +2467,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) goto fail; /* Set up the command ring to have one segments for now. */ - xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, 0, flags); + xhci->cmd_ring = xhci_ring_alloc(xhci, 1, TYPE_COMMAND, 0, flags); if (!xhci->cmd_ring) goto fail; xhci_dbg_trace(xhci, trace_xhci_dbg_init, @@ -2518,11 +2512,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) ir->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX; - /* - * XXX: Might need to set the Interrupter Moderation Register to - * something other than the default (~1ms minimum between interrupts). - * See section 5.5.1.2. - */ for (i = 0; i < MAX_HC_SLOTS; i++) xhci->devs[i] = NULL; diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 3252e3d2d79cd68e875d6965f3cda650dffa456a..9048313444409e83e7dd00c8e9ec6f0ce740f6f1 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -853,7 +853,7 @@ MODULE_DEVICE_TABLE(of, mtk_xhci_of_match); static struct platform_driver mtk_xhci_driver = { .probe = xhci_mtk_probe, - .remove_new = xhci_mtk_remove, + .remove = xhci_mtk_remove, .driver = { .name = "xhci-mtk", .pm = DEV_PM_OPS, diff --git a/drivers/usb/host/xhci-pci-renesas.c b/drivers/usb/host/xhci-pci-renesas.c index 65fc9319d5e70fd4bf52c4ec9a2857b012794db6..620f8f0febb84bb19a9445e26b83c0d5b72dfa71 100644 --- a/drivers/usb/host/xhci-pci-renesas.c +++ b/drivers/usb/host/xhci-pci-renesas.c @@ -661,5 +661,5 @@ module_pci_driver(xhci_renesas_pci_driver); MODULE_DESCRIPTION("Renesas xHCI PCI Host Controller Driver"); MODULE_FIRMWARE(RENESAS_FW_NAME); -MODULE_IMPORT_NS(xhci); +MODULE_IMPORT_NS("xhci"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index cb07cee9ed0c75de60777f438fcfd07bc7ded092..2d1e205c14c60959ccbac5c2a6f0bda48f841b2a 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -28,18 +28,18 @@ #define SPARSE_CNTL_ENABLE 0xC12C /* Device for a quirk */ -#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 -#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 +#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 +#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1009 0x1009 #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1100 0x1100 #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400 -#define PCI_VENDOR_ID_ETRON 0x1b6f -#define PCI_DEVICE_ID_EJ168 0x7023 -#define PCI_DEVICE_ID_EJ188 0x7052 +#define PCI_VENDOR_ID_ETRON 0x1b6f +#define PCI_DEVICE_ID_ETRON_EJ168 0x7023 +#define PCI_DEVICE_ID_ETRON_EJ188 0x7052 -#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 -#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI 0x9cb1 #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f @@ -82,9 +82,6 @@ #define PCI_DEVICE_ID_ASMEDIA_3042_XHCI 0x3042 #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 -#define PCI_DEVICE_ID_CADENCE 0x17CD -#define PCI_DEVICE_ID_CADENCE_SSP 0x0200 - static const char hcd_name[] = "xhci_hcd"; static struct hc_driver __read_mostly xhci_pci_hc_driver; @@ -150,14 +147,11 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) hcd->irq = 0; /* - * calculate number of MSI-X vectors supported. - * - HCS_MAX_INTRS: the max number of interrupts the host can handle, - * with max number of interrupters based on the xhci HCSPARAMS1. - * - num_online_cpus: maximum MSI-X vectors per CPUs core. - * Add additional 1 vector to ensure always available interrupt. + * Calculate number of MSI/MSI-X vectors supported. + * - max_interrupters: the max number of interrupts requested, capped to xhci HCSPARAMS1. + * - num_online_cpus: one vector per CPUs core, with at least one overall. */ - xhci->nvecs = min(num_online_cpus() + 1, - HCS_MAX_INTRS(xhci->hcs_params1)); + xhci->nvecs = min(num_online_cpus() + 1, xhci->max_interrupters); /* TODO: Check with MSI Soc for sysdev */ xhci->nvecs = pci_alloc_irq_vectors(pdev, 1, xhci->nvecs, @@ -395,14 +389,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; if (pdev->vendor == PCI_VENDOR_ID_ETRON && - pdev->device == PCI_DEVICE_ID_EJ168) { - xhci->quirks |= XHCI_RESET_ON_RESUME; - xhci->quirks |= XHCI_BROKEN_STREAMS; - } - if (pdev->vendor == PCI_VENDOR_ID_ETRON && - pdev->device == PCI_DEVICE_ID_EJ188) { + (pdev->device == PCI_DEVICE_ID_ETRON_EJ168 || + pdev->device == PCI_DEVICE_ID_ETRON_EJ188)) { + xhci->quirks |= XHCI_ETRON_HOST; xhci->quirks |= XHCI_RESET_ON_RESUME; xhci->quirks |= XHCI_BROKEN_STREAMS; + xhci->quirks |= XHCI_NO_SOFT_RETRY; } if (pdev->vendor == PCI_VENDOR_ID_RENESAS && @@ -482,8 +474,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; } - if (pdev->vendor == PCI_DEVICE_ID_CADENCE && - pdev->device == PCI_DEVICE_ID_CADENCE_SSP) + if (pdev->vendor == PCI_VENDOR_ID_CDNS && + pdev->device == PCI_DEVICE_ID_CDNS_USBSSP) xhci->quirks |= XHCI_CDNS_SCTX_QUIRK; /* xHC spec requires PCI devices to support D3hot and D3cold */ @@ -646,6 +638,9 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id) dma_set_max_seg_size(&dev->dev, UINT_MAX); + if (device_property_read_bool(&dev->dev, "ti,pwron-active-high")) + pci_clear_and_set_config_dword(dev, 0xE0, 0, 1 << 22); + return 0; put_usb3_hcd: @@ -656,7 +651,7 @@ put_runtime_pm: pm_runtime_put_noidle(&dev->dev); return retval; } -EXPORT_SYMBOL_NS_GPL(xhci_pci_common_probe, xhci); +EXPORT_SYMBOL_NS_GPL(xhci_pci_common_probe, "xhci"); static const struct pci_device_id pci_ids_reject[] = { /* handled by xhci-pci-renesas */ @@ -700,7 +695,7 @@ void xhci_pci_remove(struct pci_dev *dev) if (set_power_d3) pci_set_power_state(dev, PCI_D3hot); } -EXPORT_SYMBOL_NS_GPL(xhci_pci_remove, xhci); +EXPORT_SYMBOL_NS_GPL(xhci_pci_remove, "xhci"); /* * In some Intel xHCI controllers, in order to get D3 working, diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index ecaa75718e5926816fb3427c58c64292374defed..e6c9006bd5685fd5b9eccf697b4dd048fd6b37ed 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -573,7 +573,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match); static struct platform_driver usb_generic_xhci_driver = { .probe = xhci_generic_plat_probe, - .remove_new = xhci_plat_remove, + .remove = xhci_plat_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "xhci-hcd", diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 8b357647728c2b6ca135d0388cfb0281b2d3b01a..1cc082a3b7939bd911320a9c5acfa1bd9d16fca1 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -274,7 +274,7 @@ static int xhci_renesas_probe(struct platform_device *pdev) static struct platform_driver usb_xhci_renesas_driver = { .probe = xhci_renesas_probe, - .remove_new = xhci_plat_remove, + .remove = xhci_plat_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "xhci-renesas-hcd", diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 928b93ad1ee866a54bb930ada7b8214caf4abfab..4cf5363875c704d9eb2ca18ca4b815716c6029ed 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -52,6 +52,7 @@ * endpoint rings; it generates events on the event ring for these. */ +#include #include #include #include @@ -145,10 +146,8 @@ static void trb_to_noop(union xhci_trb *trb, u32 noop_type) * TRB is in a new segment. This does not skip over link TRBs, and it does not * effect the ring dequeue or enqueue pointers. */ -static void next_trb(struct xhci_hcd *xhci, - struct xhci_ring *ring, - struct xhci_segment **seg, - union xhci_trb **trb) +static void next_trb(struct xhci_segment **seg, + union xhci_trb **trb) { if (trb_is_link(*trb) || last_trb_on_seg(*seg, *trb)) { *seg = (*seg)->next; @@ -169,13 +168,16 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) if (ring->type == TYPE_EVENT) { if (!last_trb_on_seg(ring->deq_seg, ring->dequeue)) { ring->dequeue++; - goto out; + return; } if (last_trb_on_ring(ring, ring->deq_seg, ring->dequeue)) ring->cycle_state ^= 1; ring->deq_seg = ring->deq_seg->next; ring->dequeue = ring->deq_seg->trbs; - goto out; + + trace_xhci_inc_deq(ring); + + return; } /* All other rings have link trbs */ @@ -190,14 +192,13 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) ring->deq_seg = ring->deq_seg->next; ring->dequeue = ring->deq_seg->trbs; + trace_xhci_inc_deq(ring); + if (link_trb_count++ > ring->num_segs) { xhci_warn(xhci, "Ring is an endless link TRB loop\n"); break; } } -out: - trace_xhci_inc_deq(ring); - return; } @@ -266,13 +267,13 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, ring->enqueue = ring->enq_seg->trbs; next = ring->enqueue; + trace_xhci_inc_enq(ring); + if (link_trb_count++ > ring->num_segs) { xhci_warn(xhci, "%s: Ring link TRB loop\n", __func__); break; } } - - trace_xhci_inc_enq(ring); } /* @@ -426,7 +427,7 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, } } -/* Must be called with xhci->lock held, releases and aquires lock back */ +/* Must be called with xhci->lock held, releases and acquires lock back */ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) { struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg; @@ -446,9 +447,9 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) * avoiding corrupting the command ring pointer in case the command ring * is stopped by the time the upper dword is written. */ - next_trb(xhci, NULL, &new_seg, &new_deq); + next_trb(&new_seg, &new_deq); if (trb_is_link(new_deq)) - next_trb(xhci, NULL, &new_seg, &new_deq); + next_trb(&new_seg, &new_deq); crcr = xhci_trb_virt_to_dma(new_seg, new_deq); xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); @@ -660,8 +661,8 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci, /* * We want to find the pointer, segment and cycle state of the new trb - * (the one after current TD's last_trb). We know the cycle state at - * hw_dequeue, so walk the ring until both hw_dequeue and last_trb are + * (the one after current TD's end_trb). We know the cycle state at + * hw_dequeue, so walk the ring until both hw_dequeue and end_trb are * found. */ do { @@ -671,14 +672,14 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci, if (td_last_trb_found) break; } - if (new_deq == td->last_trb) + if (new_deq == td->end_trb) td_last_trb_found = true; if (cycle_found && trb_is_link(new_deq) && link_trb_toggles_cycle(new_deq)) new_cycle ^= 0x1; - next_trb(xhci, ep_ring, &new_seg, &new_deq); + next_trb(&new_seg, &new_deq); /* Search wrapped around, bail out */ if (new_deq == ep->ring->dequeue) { @@ -740,23 +741,22 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci, * (The last TRB actually points to the ring enqueue pointer, which is not part * of this TD.) This is used to remove partially enqueued isoc TDs from a ring. */ -static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, - struct xhci_td *td, bool flip_cycle) +static void td_to_noop(struct xhci_td *td, bool flip_cycle) { struct xhci_segment *seg = td->start_seg; - union xhci_trb *trb = td->first_trb; + union xhci_trb *trb = td->start_trb; while (1) { trb_to_noop(trb, TRB_TR_NOOP); /* flip cycle if asked to */ - if (flip_cycle && trb != td->first_trb && trb != td->last_trb) + if (flip_cycle && trb != td->start_trb && trb != td->end_trb) trb->generic.field[3] ^= cpu_to_le32(TRB_CYCLE); - if (trb == td->last_trb) + if (trb == td->end_trb) break; - next_trb(xhci, ep_ring, &seg, &trb); + next_trb(&seg, &trb); } } @@ -799,7 +799,7 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci, dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len, DMA_FROM_DEVICE); - /* for in tranfers we need to copy the data from bounce to sg */ + /* for in transfers we need to copy the data from bounce to sg */ if (urb->num_sgs) { len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf, seg->bounce_len, seg->bounce_offs); @@ -814,8 +814,8 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci, seg->bounce_offs = 0; } -static int xhci_td_cleanup(struct xhci_hcd *xhci, struct xhci_td *td, - struct xhci_ring *ep_ring, int status) +static void xhci_td_cleanup(struct xhci_hcd *xhci, struct xhci_td *td, + struct xhci_ring *ep_ring, int status) { struct urb *urb = NULL; @@ -858,10 +858,18 @@ static int xhci_td_cleanup(struct xhci_hcd *xhci, struct xhci_td *td, status = 0; xhci_giveback_urb_in_irq(xhci, td, status); } - - return 0; } +/* Give back previous TD and move on to the next TD. */ +static void xhci_dequeue_td(struct xhci_hcd *xhci, struct xhci_td *td, struct xhci_ring *ring, + u32 status) +{ + ring->dequeue = td->end_trb; + ring->deq_seg = td->end_seg; + inc_deq(xhci, ring); + + xhci_td_cleanup(xhci, td, ring, status); +} /* Complete the cancelled URBs we unlinked from td_list. */ static void xhci_giveback_invalidated_tds(struct xhci_virt_ep *ep) @@ -972,13 +980,20 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) unsigned int slot_id = ep->vdev->slot_id; int err; + /* + * This is not going to work if the hardware is changing its dequeue + * pointers as we look at them. Completion handler will call us later. + */ + if (ep->ep_state & SET_DEQ_PENDING) + return 0; + xhci = ep->xhci; list_for_each_entry_safe(td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) { xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Removing canceled TD starting at 0x%llx (dma) in stream %u URB %p", (unsigned long long)xhci_trb_virt_to_dma( - td->start_seg, td->first_trb), + td->start_seg, td->start_trb), td->urb->stream_id, td->urb); list_del_init(&td->td_list); ring = xhci_urb_to_transfer_ring(xhci, td->urb); @@ -1020,16 +1035,16 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) "Found multiple active URBs %p and %p in stream %u?\n", td->urb, cached_td->urb, td->urb->stream_id); - td_to_noop(xhci, ring, cached_td, false); + td_to_noop(cached_td, false); cached_td->cancel_status = TD_CLEARED; } - td_to_noop(xhci, ring, td, false); + td_to_noop(td, false); td->cancel_status = TD_CLEARING_CACHE; cached_td = td; break; } } else { - td_to_noop(xhci, ring, td, false); + td_to_noop(td, false); td->cancel_status = TD_CLEARED; } } @@ -1054,13 +1069,26 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) continue; xhci_warn(xhci, "Failed to clear cancelled cached URB %p, mark clear anyway\n", td->urb); - td_to_noop(xhci, ring, td, false); + td_to_noop(td, false); td->cancel_status = TD_CLEARED; } } return 0; } +/* + * Erase queued TDs from transfer ring(s) and give back those the xHC didn't + * stop on. If necessary, queue commands to move the xHC off cancelled TDs it + * stopped on. Those will be given back later when the commands complete. + * + * Call under xhci->lock on a stopped endpoint. + */ +void xhci_process_cancelled_tds(struct xhci_virt_ep *ep) +{ + xhci_invalidate_cancelled_tds(ep); + xhci_giveback_invalidated_tds(ep); +} + /* * Returns the TD the endpoint ring halted on. * Only call for non-running rings without streams. @@ -1151,16 +1179,35 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, return; case EP_STATE_STOPPED: /* - * NEC uPD720200 sometimes sets this state and fails with - * Context Error while continuing to process TRBs. - * Be conservative and trust EP_CTX_STATE on other chips. + * Per xHCI 4.6.9, Stop Endpoint command on a Stopped + * EP is a Context State Error, and EP stays Stopped. + * + * But maybe it failed on Halted, and somebody ran Reset + * Endpoint later. EP state is now Stopped and EP_HALTED + * still set because Reset EP handler will run after us. + */ + if (ep->ep_state & EP_HALTED) + break; + /* + * On some HCs EP state remains Stopped for some tens of + * us to a few ms or more after a doorbell ring, and any + * new Stop Endpoint fails without aborting the restart. + * This handler may run quickly enough to still see this + * Stopped state, but it will soon change to Running. + * + * Assume this bug on unexpected Stop Endpoint failures. + * Keep retrying until the EP starts and stops again, on + * chips where this is known to help. Wait for 100ms. */ if (!(xhci->quirks & XHCI_NEC_HOST)) break; + if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) + break; fallthrough; case EP_STATE_RUNNING: /* Race, HW handled stop ep cmd before ep was running */ - xhci_dbg(xhci, "Stop ep completion ctx error, ep is running\n"); + xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n", + GET_EP_CTX_STATE(ep_ctx)); command = xhci_alloc_command(xhci, false, GFP_ATOMIC); if (!command) { @@ -1338,8 +1385,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, struct xhci_virt_ep *ep; struct xhci_ep_ctx *ep_ctx; struct xhci_slot_ctx *slot_ctx; + struct xhci_stream_ctx *stream_ctx; struct xhci_td *td, *tmp_td; - bool deferred = false; ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3])); stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2])); @@ -1360,6 +1407,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, trace_xhci_handle_cmd_set_deq(slot_ctx); trace_xhci_handle_cmd_set_deq_ep(ep_ctx); + if (ep->ep_state & EP_HAS_STREAMS) { + stream_ctx = &ep->stream_info->stream_ctx_array[stream_id]; + trace_xhci_handle_cmd_set_deq_stream(ep->stream_info, stream_id); + } + if (cmd_comp_code != COMP_SUCCESS) { unsigned int ep_state; unsigned int slot_state; @@ -1396,9 +1448,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, u64 deq; /* 4.6.10 deq ptr is written to the stream ctx for streams */ if (ep->ep_state & EP_HAS_STREAMS) { - struct xhci_stream_ctx *ctx = - &ep->stream_info->stream_ctx_array[stream_id]; - deq = le64_to_cpu(ctx->stream_ring) & SCTX_DEQ_MASK; + deq = le64_to_cpu(stream_ctx->stream_ring) & SCTX_DEQ_MASK; /* * Cadence xHCI controllers store some endpoint state @@ -1410,8 +1460,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, * To fix this issue driver must clear Rsvd0 field. */ if (xhci->quirks & XHCI_CDNS_SCTX_QUIRK) { - ctx->reserved[0] = 0; - ctx->reserved[1] = 0; + stream_ctx->reserved[0] = 0; + stream_ctx->reserved[1] = 0; } } else { deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK; @@ -1440,8 +1490,6 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, xhci_dbg(ep->xhci, "%s: Giveback cancelled URB %p TD\n", __func__, td->urb); xhci_td_cleanup(ep->xhci, td, ep_ring, td->status); - } else if (td->cancel_status == TD_CLEARING_CACHE_DEFERRED) { - deferred = true; } else { xhci_dbg(ep->xhci, "%s: Keep cancelled URB %p TD as cancel_status is %d\n", __func__, td->urb, td->cancel_status); @@ -1452,11 +1500,15 @@ cleanup: ep->queued_deq_seg = NULL; ep->queued_deq_ptr = NULL; - if (deferred) { - /* We have more streams to clear */ + /* Check for deferred or newly cancelled TDs */ + if (!list_empty(&ep->cancelled_td_list)) { xhci_dbg(ep->xhci, "%s: Pending TDs to clear, continuing with invalidation\n", __func__); xhci_invalidate_cancelled_tds(ep); + /* Try to restart the endpoint if all is done */ + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + /* Start giving back any TDs invalidated above */ + xhci_giveback_invalidated_tds(ep); } else { /* Restart any rings with pending URBs */ xhci_dbg(ep->xhci, "%s: All TDs cleared, ring doorbell\n", __func__); @@ -1716,7 +1768,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, cmd_dma = le64_to_cpu(event->cmd_trb); cmd_trb = xhci->cmd_ring->dequeue; - trace_xhci_handle_command(xhci->cmd_ring, &cmd_trb->generic); + trace_xhci_handle_command(xhci->cmd_ring, &cmd_trb->generic, cmd_dma); cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status)); @@ -2074,7 +2126,7 @@ struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, dma_ad dma_addr_t end_trb_dma; struct xhci_segment *cur_seg; - start_dma = xhci_trb_virt_to_dma(td->start_seg, td->first_trb); + start_dma = xhci_trb_virt_to_dma(td->start_seg, td->start_trb); cur_seg = td->start_seg; do { @@ -2084,7 +2136,7 @@ struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, dma_ad end_seg_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[TRBS_PER_SEGMENT - 1]); /* If the end TRB isn't in this segment, this is set to 0 */ - end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->last_trb); + end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->end_trb); if (debug) xhci_warn(xhci, @@ -2184,9 +2236,9 @@ int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code) return 0; } -static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, - struct xhci_ring *ep_ring, struct xhci_td *td, - u32 trb_comp_code) +static void finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + struct xhci_ring *ep_ring, struct xhci_td *td, + u32 trb_comp_code) { struct xhci_ep_ctx *ep_ctx; @@ -2201,7 +2253,7 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, * stopped TDs. A stopped TD may be restarted, so don't update * the ring dequeue pointer or take this TD off any lists yet. */ - return 0; + return; case COMP_USB_TRANSACTION_ERROR: case COMP_BABBLE_DETECTED_ERROR: case COMP_SPLIT_TRANSACTION_ERROR: @@ -2226,8 +2278,8 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, !list_empty(&td->cancelled_td_list)) { xhci_dbg(xhci, "Already resolving halted ep for 0x%llx\n", (unsigned long long)xhci_trb_virt_to_dma( - td->start_seg, td->first_trb)); - return 0; + td->start_seg, td->start_trb)); + return; } /* endpoint not halted, don't reset it */ break; @@ -2235,7 +2287,7 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, /* Almost same procedure as for STALL_ERROR below */ xhci_clear_hub_tt_buffer(xhci, td, ep); xhci_handle_halted_endpoint(xhci, ep, td, EP_HARD_RESET); - return 0; + return; case COMP_STALL_ERROR: /* * xhci internal endpoint state will go to a "halt" state for @@ -2252,28 +2304,22 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, xhci_handle_halted_endpoint(xhci, ep, td, EP_HARD_RESET); - return 0; /* xhci_handle_halted_endpoint marked td cancelled */ + return; /* xhci_handle_halted_endpoint marked td cancelled */ default: break; } - /* Update ring dequeue pointer */ - ep_ring->dequeue = td->last_trb; - ep_ring->deq_seg = td->last_trb_seg; - inc_deq(xhci, ep_ring); - - return xhci_td_cleanup(xhci, td, ep_ring, td->status); + xhci_dequeue_td(xhci, td, ep_ring, td->status); } -/* sum trb lengths from ring dequeue up to stop_trb, _excluding_ stop_trb */ -static int sum_trb_lengths(struct xhci_hcd *xhci, struct xhci_ring *ring, - union xhci_trb *stop_trb) +/* sum trb lengths from the first trb up to stop_trb, _excluding_ stop_trb */ +static u32 sum_trb_lengths(struct xhci_td *td, union xhci_trb *stop_trb) { u32 sum; - union xhci_trb *trb = ring->dequeue; - struct xhci_segment *seg = ring->deq_seg; + union xhci_trb *trb = td->start_trb; + struct xhci_segment *seg = td->start_seg; - for (sum = 0; trb != stop_trb; next_trb(xhci, ring, &seg, &trb)) { + for (sum = 0; trb != stop_trb; next_trb(&seg, &trb)) { if (!trb_is_noop(trb) && !trb_is_link(trb)) sum += TRB_LEN(le32_to_cpu(trb->generic.field[2])); } @@ -2283,9 +2329,9 @@ static int sum_trb_lengths(struct xhci_hcd *xhci, struct xhci_ring *ring, /* * Process control tds, update urb status and actual_length. */ -static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, - struct xhci_ring *ep_ring, struct xhci_td *td, - union xhci_trb *ep_trb, struct xhci_transfer_event *event) +static void process_ctrl_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + struct xhci_ring *ep_ring, struct xhci_td *td, + union xhci_trb *ep_trb, struct xhci_transfer_event *event) { struct xhci_ep_ctx *ep_ctx; u32 trb_comp_code; @@ -2364,7 +2410,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, td->urb_length_set = true; td->urb->actual_length = requested - remaining; xhci_dbg(xhci, "Waiting for status stage event\n"); - return 0; + return; } /* at status stage */ @@ -2372,15 +2418,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, td->urb->actual_length = requested; finish_td: - return finish_td(xhci, ep, ep_ring, td, trb_comp_code); + finish_td(xhci, ep, ep_ring, td, trb_comp_code); } /* * Process isochronous tds, update urb packet status and actual_length. */ -static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, - struct xhci_ring *ep_ring, struct xhci_td *td, - union xhci_trb *ep_trb, struct xhci_transfer_event *event) +static void process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + struct xhci_ring *ep_ring, struct xhci_td *td, + union xhci_trb *ep_trb, struct xhci_transfer_event *event) { struct urb_priv *urb_priv; int idx; @@ -2425,7 +2471,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, fallthrough; case COMP_ISOCH_BUFFER_OVERRUN: frame->status = -EOVERFLOW; - if (ep_trb != td->last_trb) + if (ep_trb != td->end_trb) td->error_mid_td = true; break; case COMP_INCOMPATIBLE_DEVICE_ERROR: @@ -2435,14 +2481,14 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, case COMP_USB_TRANSACTION_ERROR: frame->status = -EPROTO; sum_trbs_for_length = true; - if (ep_trb != td->last_trb) + if (ep_trb != td->end_trb) td->error_mid_td = true; break; case COMP_STOPPED: sum_trbs_for_length = true; break; case COMP_STOPPED_SHORT_PACKET: - /* field normally containing residue now contains tranferred */ + /* field normally containing residue now contains transferred */ frame->status = short_framestatus; requested = remaining; break; @@ -2462,7 +2508,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, goto finish_td; if (sum_trbs_for_length) - frame->actual_length = sum_trb_lengths(xhci, ep->ring, ep_trb) + + frame->actual_length = sum_trb_lengths(td, ep_trb) + ep_trb_len - remaining; else frame->actual_length = requested; @@ -2471,17 +2517,16 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, finish_td: /* Don't give back TD yet if we encountered an error mid TD */ - if (td->error_mid_td && ep_trb != td->last_trb) { + if (td->error_mid_td && ep_trb != td->end_trb) { xhci_dbg(xhci, "Error mid isoc TD, wait for final completion event\n"); td->urb_length_set = true; - return 0; + return; } - - return finish_td(xhci, ep, ep_ring, td, trb_comp_code); + finish_td(xhci, ep, ep_ring, td, trb_comp_code); } -static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, - struct xhci_virt_ep *ep, int status) +static void skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, + struct xhci_virt_ep *ep, int status) { struct urb_priv *urb_priv; struct usb_iso_packet_descriptor *frame; @@ -2497,20 +2542,15 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, /* calc actual length */ frame->actual_length = 0; - /* Update ring dequeue pointer */ - ep->ring->dequeue = td->last_trb; - ep->ring->deq_seg = td->last_trb_seg; - inc_deq(xhci, ep->ring); - - return xhci_td_cleanup(xhci, td, ep->ring, status); + xhci_dequeue_td(xhci, td, ep->ring, status); } /* * Process bulk and interrupt tds, update urb status and actual_length. */ -static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, - struct xhci_ring *ep_ring, struct xhci_td *td, - union xhci_trb *ep_trb, struct xhci_transfer_event *event) +static void process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + struct xhci_ring *ep_ring, struct xhci_td *td, + union xhci_trb *ep_trb, struct xhci_transfer_event *event) { struct xhci_slot_ctx *slot_ctx; u32 trb_comp_code; @@ -2526,7 +2566,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, case COMP_SUCCESS: ep->err_count = 0; /* handle success with untransferred data as short packet */ - if (ep_trb != td->last_trb || remaining) { + if (ep_trb != td->end_trb || remaining) { xhci_warn(xhci, "WARN Successful completion on short TX\n"); xhci_dbg(xhci, "ep %#x - asked for %d bytes, %d bytes untransferred\n", td->urb->ep->desc.bEndpointAddress, @@ -2542,7 +2582,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, goto finish_td; case COMP_STOPPED_LENGTH_INVALID: /* stopped on ep trb with invalid length, exclude it */ - td->urb->actual_length = sum_trb_lengths(xhci, ep_ring, ep_trb); + td->urb->actual_length = sum_trb_lengths(td, ep_trb); goto finish_td; case COMP_USB_TRANSACTION_ERROR: if (xhci->quirks & XHCI_NO_SOFT_RETRY || @@ -2553,17 +2593,17 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, td->status = 0; xhci_handle_halted_endpoint(xhci, ep, td, EP_SOFT_RESET); - return 0; + return; default: /* do nothing */ break; } - if (ep_trb == td->last_trb) + if (ep_trb == td->end_trb) td->urb->actual_length = requested - remaining; else td->urb->actual_length = - sum_trb_lengths(xhci, ep_ring, ep_trb) + + sum_trb_lengths(td, ep_trb) + ep_trb_len - remaining; finish_td: if (remaining > requested) { @@ -2572,7 +2612,7 @@ finish_td: td->urb->actual_length = 0; } - return finish_td(xhci, ep, ep_ring, td, trb_comp_code); + finish_td(xhci, ep, ep_ring, td, trb_comp_code); } /* Transfer events which don't point to a transfer TRB, see xhci 4.17.4 */ @@ -2792,10 +2832,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, if (td && td->error_mid_td && !trb_in_td(xhci, td, ep_trb_dma, false)) { xhci_dbg(xhci, "Missing TD completion event after mid TD error\n"); - ep_ring->dequeue = td->last_trb; - ep_ring->deq_seg = td->last_trb_seg; - inc_deq(xhci, ep_ring); - xhci_td_cleanup(xhci, td, ep_ring, td->status); + xhci_dequeue_td(xhci, td, ep_ring, td->status); } if (list_empty(&ep_ring->td_list)) { @@ -2889,7 +2926,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, ep_ring->last_td_was_short = false; ep_trb = &ep_seg->trbs[(ep_trb_dma - ep_seg->dma) / sizeof(*ep_trb)]; - trace_xhci_handle_transfer(ep_ring, (struct xhci_generic_trb *) ep_trb); + trace_xhci_handle_transfer(ep_ring, (struct xhci_generic_trb *) ep_trb, ep_trb_dma); /* * No-op TRB could trigger interrupts in a case where a URB was killed @@ -2939,7 +2976,9 @@ static int xhci_handle_event_trb(struct xhci_hcd *xhci, struct xhci_interrupter { u32 trb_type; - trace_xhci_handle_event(ir->event_ring, &event->generic); + trace_xhci_handle_event(ir->event_ring, &event->generic, + xhci_trb_virt_to_dma(ir->event_ring->deq_seg, + ir->event_ring->dequeue)); /* * Barrier between reading the TRB_CYCLE (valid) flag before, and any @@ -3162,7 +3201,8 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, wmb(); trb->field[3] = cpu_to_le32(field4); - trace_xhci_queue_trb(ring, trb); + trace_xhci_queue_trb(ring, trb, + xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue)); inc_enq(xhci, ring, more_trbs_coming); } @@ -3302,7 +3342,7 @@ static int prepare_transfer(struct xhci_hcd *xhci, /* Add this TD to the tail of the endpoint ring's TD list */ list_add_tail(&td->td_list, &ep_ring->td_list); td->start_seg = ep_ring->enq_seg; - td->first_trb = ep_ring->enqueue; + td->start_trb = ep_ring->enqueue; return 0; } @@ -3641,8 +3681,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field &= ~TRB_CHAIN; field |= TRB_IOC; more_trbs_coming = false; - td->last_trb = ring->enqueue; - td->last_trb_seg = ring->enq_seg; + td->end_trb = ring->enqueue; + td->end_seg = ring->enq_seg; if (xhci_urb_suitable_for_idt(urb)) { memcpy(&send_addr, urb->transfer_buffer, trb_buff_len); @@ -3690,8 +3730,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, 1, urb, 1, mem_flags); - urb_priv->td[1].last_trb = ring->enqueue; - urb_priv->td[1].last_trb_seg = ring->enq_seg; + urb_priv->td[1].end_trb = ring->enqueue; + urb_priv->td[1].end_seg = ring->enq_seg; field = TRB_TYPE(TRB_NORMAL) | ring->cycle_state | TRB_IOC; queue_trb(xhci, ring, 0, 0, 0, TRB_INTR_TARGET(0), field); } @@ -3727,6 +3767,20 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (!urb->setup_packet) return -EINVAL; + if ((xhci->quirks & XHCI_ETRON_HOST) && + urb->dev->speed >= USB_SPEED_SUPER) { + /* + * If next available TRB is the Link TRB in the ring segment then + * enqueue a No Op TRB, this can prevent the Setup and Data Stage + * TRB to be breaked by the Link TRB. + */ + if (trb_is_link(ep_ring->enqueue + 1)) { + field = TRB_TYPE(TRB_TR_NOOP) | ep_ring->cycle_state; + queue_trb(xhci, ep_ring, false, 0, 0, + TRB_INTR_TARGET(0), field); + } + } + /* 1 TRB for setup, 1 for status */ num_trbs = 2; /* @@ -3815,8 +3869,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } /* Save the DMA address of the last TRB in the TD */ - td->last_trb = ep_ring->enqueue; - td->last_trb_seg = ep_ring->enq_seg; + td->end_trb = ep_ring->enqueue; + td->end_seg = ep_ring->enq_seg; /* Queue status TRB - see Table 7 and sections 4.11.2.2 and 6.4.1.2.3 */ /* If the device sent data, the status stage is an OUT transfer */ @@ -4101,8 +4155,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field |= TRB_CHAIN; } else { more_trbs_coming = false; - td->last_trb = ep_ring->enqueue; - td->last_trb_seg = ep_ring->enq_seg; + td->end_trb = ep_ring->enqueue; + td->end_seg = ep_ring->enq_seg; field |= TRB_IOC; if (trb_block_event_intr(xhci, num_tds, i, ir)) field |= TRB_BEI; @@ -4168,14 +4222,14 @@ cleanup: /* Use the first TD as a temporary variable to turn the TDs we've queued * into No-ops with a software-owned cycle bit. That way the hardware * won't accidentally start executing bogus TDs when we partially - * overwrite them. td->first_trb and td->start_seg are already set. + * overwrite them. td->start_trb and td->start_seg are already set. */ - urb_priv->td[0].last_trb = ep_ring->enqueue; + urb_priv->td[0].end_trb = ep_ring->enqueue; /* Every TRB except the first & last will have its cycle bit flipped. */ - td_to_noop(xhci, ep_ring, &urb_priv->td[0], true); + td_to_noop(&urb_priv->td[0], true); /* Reset the ring enqueue back to the first TRB and its cycle bit. */ - ep_ring->enqueue = urb_priv->td[0].first_trb; + ep_ring->enqueue = urb_priv->td[0].start_trb; ep_ring->enq_seg = urb_priv->td[0].start_seg; ep_ring->cycle_state = start_cycle; usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 76f228e7443cb6abb7ad5c513d2eaa7ba4f4f228..06ae193ec87407f13487556862c9caf03f51b786 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -2664,7 +2664,7 @@ MODULE_DEVICE_TABLE(of, tegra_xusb_of_match); static struct platform_driver tegra_xusb_driver = { .probe = tegra_xusb_probe, - .remove_new = tegra_xusb_remove, + .remove = tegra_xusb_remove, .shutdown = tegra_xusb_shutdown, .driver = { .name = "tegra-xusb", diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index 24405315ffe6d9de943f6db88f1184702705442c..bfb5c5c170127a364f9455456a86be53e8007df4 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -108,9 +108,10 @@ DEFINE_EVENT(xhci_log_ctx, xhci_address_ctx, ); DECLARE_EVENT_CLASS(xhci_log_trb, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb), + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma), TP_STRUCT__entry( + __field(dma_addr_t, dma) __field(u32, type) __field(u32, field0) __field(u32, field1) @@ -118,51 +119,54 @@ DECLARE_EVENT_CLASS(xhci_log_trb, __field(u32, field3) ), TP_fast_assign( + __entry->dma = dma; __entry->type = ring->type; __entry->field0 = le32_to_cpu(trb->field[0]); __entry->field1 = le32_to_cpu(trb->field[1]); __entry->field2 = le32_to_cpu(trb->field[2]); __entry->field3 = le32_to_cpu(trb->field[3]); ), - TP_printk("%s: %s", xhci_ring_type_string(__entry->type), + TP_printk("%s: @%pad %s", + xhci_ring_type_string(__entry->type), &__entry->dma, xhci_decode_trb(__get_buf(XHCI_MSG_MAX), XHCI_MSG_MAX, __entry->field0, __entry->field1, __entry->field2, __entry->field3) ) ); DEFINE_EVENT(xhci_log_trb, xhci_handle_event, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb) + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma) ); DEFINE_EVENT(xhci_log_trb, xhci_handle_command, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb) + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma) ); DEFINE_EVENT(xhci_log_trb, xhci_handle_transfer, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb) + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma) ); DEFINE_EVENT(xhci_log_trb, xhci_queue_trb, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb) + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma) + ); DEFINE_EVENT(xhci_log_trb, xhci_dbc_handle_event, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb) + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma) ); DEFINE_EVENT(xhci_log_trb, xhci_dbc_handle_transfer, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb) + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma) ); DEFINE_EVENT(xhci_log_trb, xhci_dbc_gadget_ep_queue, - TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb), - TP_ARGS(ring, trb) + TP_PROTO(struct xhci_ring *ring, struct xhci_generic_trb *trb, dma_addr_t dma), + TP_ARGS(ring, trb, dma) ); DECLARE_EVENT_CLASS(xhci_log_free_virt_dev, @@ -310,6 +314,37 @@ DEFINE_EVENT(xhci_log_urb, xhci_urb_dequeue, TP_ARGS(urb) ); +DECLARE_EVENT_CLASS(xhci_log_stream_ctx, + TP_PROTO(struct xhci_stream_info *info, unsigned int stream_id), + TP_ARGS(info, stream_id), + TP_STRUCT__entry( + __field(unsigned int, stream_id) + __field(u64, stream_ring) + __field(dma_addr_t, ctx_array_dma) + + ), + TP_fast_assign( + __entry->stream_id = stream_id; + __entry->stream_ring = le64_to_cpu(info->stream_ctx_array[stream_id].stream_ring); + __entry->ctx_array_dma = info->ctx_array_dma + stream_id * 16; + + ), + TP_printk("stream %u ctx @%pad: SCT %llu deq %llx", __entry->stream_id, + &__entry->ctx_array_dma, CTX_TO_SCT(__entry->stream_ring), + __entry->stream_ring + ) +); + +DEFINE_EVENT(xhci_log_stream_ctx, xhci_alloc_stream_info_ctx, + TP_PROTO(struct xhci_stream_info *info, unsigned int stream_id), + TP_ARGS(info, stream_id) +); + +DEFINE_EVENT(xhci_log_stream_ctx, xhci_handle_cmd_set_deq_stream, + TP_PROTO(struct xhci_stream_info *info, unsigned int stream_id), + TP_ARGS(info, stream_id) +); + DECLARE_EVENT_CLASS(xhci_log_ep_ctx, TP_PROTO(struct xhci_ep_ctx *ctx), TP_ARGS(ctx), @@ -454,8 +489,6 @@ DECLARE_EVENT_CLASS(xhci_log_ring, __field(void *, ring) __field(dma_addr_t, enq) __field(dma_addr_t, deq) - __field(dma_addr_t, enq_seg) - __field(dma_addr_t, deq_seg) __field(unsigned int, num_segs) __field(unsigned int, stream_id) __field(unsigned int, cycle_state) @@ -466,17 +499,15 @@ DECLARE_EVENT_CLASS(xhci_log_ring, __entry->type = ring->type; __entry->num_segs = ring->num_segs; __entry->stream_id = ring->stream_id; - __entry->enq_seg = ring->enq_seg->dma; - __entry->deq_seg = ring->deq_seg->dma; __entry->cycle_state = ring->cycle_state; __entry->bounce_buf_len = ring->bounce_buf_len; __entry->enq = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); __entry->deq = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); ), - TP_printk("%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d bounce %d cycle %d", + TP_printk("%s %p: enq %pad deq %pad segs %d stream %d bounce %d cycle %d", xhci_ring_type_string(__entry->type), __entry->ring, - &__entry->enq, &__entry->enq_seg, - &__entry->deq, &__entry->deq_seg, + &__entry->enq, + &__entry->deq, __entry->num_segs, __entry->stream_id, __entry->bounce_buf_len, diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 899c0effb5d3c16db0b8bf321b9666e6ae5c11fa..5ebde8cae4fc44cdb997b0f61314e309bda56c0d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -8,6 +8,7 @@ * Some code borrowed from the Linux EHCI driver. */ +#include #include #include #include @@ -40,15 +41,15 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring) { - struct xhci_segment *seg = ring->first_seg; + struct xhci_segment *seg; if (!td || !td->start_seg) return false; - do { + + xhci_for_each_ring_seg(ring->first_seg, seg) { if (seg == td->start_seg) return true; - seg = seg->next; - } while (seg && seg != ring->first_seg); + } return false; } @@ -473,14 +474,7 @@ static int xhci_init(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xhci_init"); spin_lock_init(&xhci->lock); - if (xhci->hci_version == 0x95 && link_quirk) { - xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, - "QUIRK: Not clearing Link TRB chain bits."); - xhci->quirks |= XHCI_LINK_TRB_QUIRK; - } else { - xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "xHCI doesn't need link TRB QUIRK"); - } + retval = xhci_mem_init(xhci, GFP_KERNEL); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_init"); @@ -785,16 +779,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) struct xhci_segment *seg; ring = xhci->cmd_ring; - seg = ring->deq_seg; - do { - memset(seg->trbs, 0, - sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1)); - seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= - cpu_to_le32(~TRB_CYCLE); - seg = seg->next; - } while (seg != ring->deq_seg); - - xhci_initialize_ring_info(ring, 1); + xhci_for_each_ring_seg(ring->first_seg, seg) + memset(seg->trbs, 0, sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1)); + + xhci_initialize_ring_info(ring); /* * Reset the hardware dequeue pointer. * Yes, this will need to be re-written after resume, but we're paranoid @@ -1756,7 +1744,7 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) urb->ep->desc.bEndpointAddress, (unsigned long long) xhci_trb_virt_to_dma( urb_priv->td[i].start_seg, - urb_priv->td[i].first_trb)); + urb_priv->td[i].start_trb)); for (; i < urb_priv->num_tds; i++) { td = &urb_priv->td[i]; @@ -1768,15 +1756,27 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) } } - /* Queue a stop endpoint command, but only if this is - * the first cancellation to be handled. - */ - if (!(ep->ep_state & EP_STOP_CMD_PENDING)) { + /* These completion handlers will sort out cancelled TDs for us */ + if (ep->ep_state & (EP_STOP_CMD_PENDING | EP_HALTED | SET_DEQ_PENDING)) { + xhci_dbg(xhci, "Not queuing Stop Endpoint on slot %d ep %d in state 0x%x\n", + urb->dev->slot_id, ep_index, ep->ep_state); + goto done; + } + + /* In this case no commands are pending but the endpoint is stopped */ + if (ep->ep_state & EP_CLEARING_TT) { + /* and cancelled TDs can be given back right away */ + xhci_dbg(xhci, "Invalidating TDs instantly on slot %d ep %d in state 0x%x\n", + urb->dev->slot_id, ep_index, ep->ep_state); + xhci_process_cancelled_tds(ep); + } else { + /* Otherwise, queue a new Stop Endpoint command */ command = xhci_alloc_command(xhci, false, GFP_ATOMIC); if (!command) { ret = -ENOMEM; goto done; } + ep->stop_time = jiffies; ep->ep_state |= EP_STOP_CMD_PENDING; xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id, ep_index, 0); @@ -2794,6 +2794,51 @@ static int xhci_reserve_bandwidth(struct xhci_hcd *xhci, return -ENOMEM; } +/* + * Synchronous XHCI stop endpoint helper. Issues the stop endpoint command and + * waits for the command completion before returning. This does not call + * xhci_handle_cmd_stop_ep(), which has additional handling for 'context error' + * cases, along with transfer ring cleanup. + * + * xhci_stop_endpoint_sync() is intended to be utilized by clients that manage + * their own transfer ring, such as offload situations. + */ +int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, int suspend, + gfp_t gfp_flags) +{ + struct xhci_command *command; + unsigned long flags; + int ret; + + command = xhci_alloc_command(xhci, true, gfp_flags); + if (!command) + return -ENOMEM; + + spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_stop_endpoint(xhci, command, ep->vdev->slot_id, + ep->ep_index, suspend); + if (ret < 0) { + spin_unlock_irqrestore(&xhci->lock, flags); + goto out; + } + + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + wait_for_completion(command->completion); + + /* No handling for COMP_CONTEXT_STATE_ERROR done at command completion*/ + if (command->status == COMP_COMMAND_ABORTED || + command->status == COMP_COMMAND_RING_STOPPED) { + xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n"); + ret = -ETIME; + } +out: + xhci_free_command(xhci, command); + + return ret; +} +EXPORT_SYMBOL_GPL(xhci_stop_endpoint_sync); /* Issue a configure endpoint command or evaluate context command * and wait for it to finish. @@ -3692,6 +3737,8 @@ void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, xhci->num_active_eps); } +static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev); + /* * This submits a Reset Device Command, which will set the device state to 0, * set the device address to 0, and disable all the endpoints except the default @@ -3762,6 +3809,23 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd, SLOT_STATE_DISABLED) return 0; + if (xhci->quirks & XHCI_ETRON_HOST) { + /* + * Obtaining a new device slot to inform the xHCI host that + * the USB device has been reset. + */ + ret = xhci_disable_slot(xhci, udev->slot_id); + xhci_free_virt_device(xhci, udev->slot_id); + if (!ret) { + ret = xhci_alloc_dev(hcd, udev); + if (ret == 1) + ret = 0; + else + ret = -EINVAL; + } + return ret; + } + trace_xhci_discover_or_reset_device(slot_ctx); xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); @@ -5251,6 +5315,11 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) if (xhci->hci_version > 0x96) xhci->quirks |= XHCI_SPURIOUS_SUCCESS; + if (xhci->hci_version == 0x95 && link_quirk) { + xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits"); + xhci->quirks |= XHCI_LINK_TRB_QUIRK; + } + /* Make sure the HC is halted. */ retval = xhci_halt(xhci); if (retval) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index f0fb696d56198618484102e38c7d970d4b22328a..4914f0a10cff42dbc1448dcf7908534d582c848e 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -554,6 +554,7 @@ struct xhci_stream_ctx { /* Stream Context Types (section 6.4.1) - bits 3:1 of stream ctx deq ptr */ #define SCT_FOR_CTX(p) (((p) & 0x7) << 1) +#define CTX_TO_SCT(p) (((p) >> 1) & 0x7) /* Secondary stream array type, dequeue pointer is to a transfer ring */ #define SCT_SEC_TR 0 /* Primary stream array type, dequeue pointer is to a transfer ring */ @@ -690,6 +691,7 @@ struct xhci_virt_ep { /* Bandwidth checking storage */ struct xhci_bw_info bw_info; struct list_head bw_endpoint_list; + unsigned long stop_time; /* Isoch Frame ID checking storage */ int next_frame_id; /* Use new Isoch TRB layout needed for extended TBC support */ @@ -1023,9 +1025,6 @@ enum xhci_setup_dev { /* Interrupter Target - which MSI-X vector to target the completion event at */ #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22) #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff) -/* Total burst count field, Rsvdz on xhci 1.1 with Extended TBC enabled (ETE) */ -#define TRB_TBC(p) (((p) & 0x3) << 7) -#define TRB_TLBPC(p) (((p) & 0xf) << 16) /* Cycle bit - indicates TRB ownership by HC or HCD */ #define TRB_CYCLE (1<<0) @@ -1059,6 +1058,12 @@ enum xhci_setup_dev { /* Isochronous TRB specific fields */ #define TRB_SIA (1<<31) #define TRB_FRAME_ID(p) (((p) & 0x7ff) << 20) +#define GET_FRAME_ID(p) (((p) >> 20) & 0x7ff) +/* Total burst count field, Rsvdz on xhci 1.1 with Extended TBC enabled (ETE) */ +#define TRB_TBC(p) (((p) & 0x3) << 7) +#define GET_TBC(p) (((p) >> 7) & 0x3) +#define TRB_TLBPC(p) (((p) & 0xf) << 16) +#define GET_TLBPC(p) (((p) >> 16) & 0xf) /* TRB cache size for xHC with TRB cache */ #define TRB_CACHE_SIZE_HS 8 @@ -1259,6 +1264,9 @@ static inline const char *xhci_trb_type_string(u8 type) #define AVOID_BEI_INTERVAL_MIN 8 #define AVOID_BEI_INTERVAL_MAX 32 +#define xhci_for_each_ring_seg(head, seg) \ + for (seg = head; seg != NULL; seg = (seg->next != head ? seg->next : NULL)) + struct xhci_segment { union xhci_trb *trbs; /* private to HCD */ @@ -1287,9 +1295,9 @@ struct xhci_td { enum xhci_cancelled_td_status cancel_status; struct urb *urb; struct xhci_segment *start_seg; - union xhci_trb *first_trb; - union xhci_trb *last_trb; - struct xhci_segment *last_trb_seg; + union xhci_trb *start_trb; + struct xhci_segment *end_seg; + union xhci_trb *end_trb; struct xhci_segment *bounce_seg; /* actual_length of the URB has already been set */ bool urb_length_set; @@ -1624,6 +1632,7 @@ struct xhci_hcd { #define XHCI_ZHAOXIN_HOST BIT_ULL(46) #define XHCI_WRITE_64_HI_LO BIT_ULL(47) #define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48) +#define XHCI_ETRON_HOST BIT_ULL(49) unsigned int num_active_eps; unsigned int limit_active_eps; @@ -1788,14 +1797,12 @@ void xhci_slot_copy(struct xhci_hcd *xhci, int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_device *udev, struct usb_host_endpoint *ep, gfp_t mem_flags); -struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, - unsigned int num_segs, unsigned int cycle_state, +struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs, enum xhci_ring_type type, unsigned int max_packet, gfp_t flags); void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, unsigned int num_trbs, gfp_t flags); -void xhci_initialize_ring_info(struct xhci_ring *ring, - unsigned int cycle_state); +void xhci_initialize_ring_info(struct xhci_ring *ring); void xhci_free_endpoint_ring(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, unsigned int ep_index); @@ -1913,6 +1920,9 @@ void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci, void xhci_cleanup_command_queue(struct xhci_hcd *xhci); void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring); unsigned int count_trbs(u64 addr, u64 len); +int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + int suspend, gfp_t gfp_flags); +void xhci_process_cancelled_tds(struct xhci_virt_ep *ep); /* xHCI roothub code */ void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port, @@ -2070,7 +2080,6 @@ static inline const char *xhci_decode_trb(char *str, size_t size, field3 & TRB_CYCLE ? 'C' : 'c'); break; case TRB_NORMAL: - case TRB_ISOC: case TRB_EVENT_DATA: case TRB_TR_NOOP: snprintf(str, size, @@ -2087,7 +2096,25 @@ static inline const char *xhci_decode_trb(char *str, size_t size, field3 & TRB_ENT ? 'E' : 'e', field3 & TRB_CYCLE ? 'C' : 'c'); break; - + case TRB_ISOC: + snprintf(str, size, + "Buffer %08x%08x length %d TD size/TBC %d intr %d type '%s' TBC %u TLBPC %u frame_id %u flags %c:%c:%c:%c:%c:%c:%c:%c:%c", + field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), + GET_INTR_TARGET(field2), + xhci_trb_type_string(type), + GET_TBC(field3), + GET_TLBPC(field3), + GET_FRAME_ID(field3), + field3 & TRB_SIA ? 'S' : 's', + field3 & TRB_BEI ? 'B' : 'b', + field3 & TRB_IDT ? 'I' : 'i', + field3 & TRB_IOC ? 'I' : 'i', + field3 & TRB_CHAIN ? 'C' : 'c', + field3 & TRB_NO_SNOOP ? 'S' : 's', + field3 & TRB_ISP ? 'I' : 'i', + field3 & TRB_ENT ? 'E' : 'e', + field3 & TRB_CYCLE ? 'C' : 'c'); + break; case TRB_CMD_NOOP: case TRB_ENABLE_SLOT: snprintf(str, size, diff --git a/drivers/usb/isp1760/Kconfig b/drivers/usb/isp1760/Kconfig index 2ed2b73291d181c04dfeb2a30519b8c7af218a61..e19178f3cdd39ca8c9fbf8c0053b366f22687966 100644 --- a/drivers/usb/isp1760/Kconfig +++ b/drivers/usb/isp1760/Kconfig @@ -26,7 +26,7 @@ config USB_ISP1761_UDC if USB_ISP1760 choice - bool "ISP1760 Mode Selection" + prompt "ISP1760 Mode Selection" default USB_ISP1760_DUAL_ROLE if (USB && USB_GADGET) default USB_ISP1760_HOST_ROLE if (USB && !USB_GADGET) default USB_ISP1760_GADGET_ROLE if (!USB && USB_GADGET) diff --git a/drivers/usb/isp1760/isp1760-if.c b/drivers/usb/isp1760/isp1760-if.c index fe1e3985419a289bbaa588233f479b6f6b005b70..a64190addba6f92140857bb67709c81d42c99517 100644 --- a/drivers/usb/isp1760/isp1760-if.c +++ b/drivers/usb/isp1760/isp1760-if.c @@ -263,7 +263,7 @@ MODULE_DEVICE_TABLE(of, isp1760_of_match); static struct platform_driver isp1760_plat_driver = { .probe = isp1760_plat_probe, - .remove_new = isp1760_plat_remove, + .remove = isp1760_plat_remove, .driver = { .name = "isp1760", .of_match_table = of_match_ptr(isp1760_of_match), diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c index 6fb5140e29b9dd641be37ddd42034e4f6466a12f..225863321dc4795edaaeb60d76a44fc76633b3bb 100644 --- a/drivers/usb/misc/chaoskey.c +++ b/drivers/usb/misc/chaoskey.c @@ -27,6 +27,8 @@ static struct usb_class_driver chaoskey_class; static int chaoskey_rng_read(struct hwrng *rng, void *data, size_t max, bool wait); +static DEFINE_MUTEX(chaoskey_list_lock); + #define usb_dbg(usb_if, format, arg...) \ dev_dbg(&(usb_if)->dev, format, ## arg) @@ -233,6 +235,7 @@ static void chaoskey_disconnect(struct usb_interface *interface) usb_deregister_dev(interface, &chaoskey_class); usb_set_intfdata(interface, NULL); + mutex_lock(&chaoskey_list_lock); mutex_lock(&dev->lock); dev->present = false; @@ -244,6 +247,7 @@ static void chaoskey_disconnect(struct usb_interface *interface) } else mutex_unlock(&dev->lock); + mutex_unlock(&chaoskey_list_lock); usb_dbg(interface, "disconnect done"); } @@ -251,6 +255,7 @@ static int chaoskey_open(struct inode *inode, struct file *file) { struct chaoskey *dev; struct usb_interface *interface; + int rv = 0; /* get the interface from minor number and driver information */ interface = usb_find_interface(&chaoskey_driver, iminor(inode)); @@ -266,18 +271,23 @@ static int chaoskey_open(struct inode *inode, struct file *file) } file->private_data = dev; + mutex_lock(&chaoskey_list_lock); mutex_lock(&dev->lock); - ++dev->open; + if (dev->present) + ++dev->open; + else + rv = -ENODEV; mutex_unlock(&dev->lock); + mutex_unlock(&chaoskey_list_lock); - usb_dbg(interface, "open success"); - return 0; + return rv; } static int chaoskey_release(struct inode *inode, struct file *file) { struct chaoskey *dev = file->private_data; struct usb_interface *interface; + int rv = 0; if (dev == NULL) return -ENODEV; @@ -286,14 +296,15 @@ static int chaoskey_release(struct inode *inode, struct file *file) usb_dbg(interface, "release"); + mutex_lock(&chaoskey_list_lock); mutex_lock(&dev->lock); usb_dbg(interface, "open count at release is %d", dev->open); if (dev->open <= 0) { usb_dbg(interface, "invalid open count (%d)", dev->open); - mutex_unlock(&dev->lock); - return -ENODEV; + rv = -ENODEV; + goto bail; } --dev->open; @@ -302,13 +313,15 @@ static int chaoskey_release(struct inode *inode, struct file *file) if (dev->open == 0) { mutex_unlock(&dev->lock); chaoskey_free(dev); - } else - mutex_unlock(&dev->lock); - } else - mutex_unlock(&dev->lock); - + goto destruction; + } + } +bail: + mutex_unlock(&dev->lock); +destruction: + mutex_unlock(&chaoskey_list_lock); usb_dbg(interface, "release success"); - return 0; + return rv; } static void chaos_read_callback(struct urb *urb) diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 6d28467ce35227684e0281a39284eba87582195a..365c100693458380c1608a416842d5ea72a5cac6 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -277,28 +277,45 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer, struct iowarrior *dev; int read_idx; int offset; + int retval; dev = file->private_data; + if (file->f_flags & O_NONBLOCK) { + retval = mutex_trylock(&dev->mutex); + if (!retval) + return -EAGAIN; + } else { + retval = mutex_lock_interruptible(&dev->mutex); + if (retval) + return -ERESTARTSYS; + } + /* verify that the device wasn't unplugged */ - if (!dev || !dev->present) - return -ENODEV; + if (!dev->present) { + retval = -ENODEV; + goto exit; + } dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n", dev->minor, count); /* read count must be packet size (+ time stamp) */ if ((count != dev->report_size) - && (count != (dev->report_size + 1))) - return -EINVAL; + && (count != (dev->report_size + 1))) { + retval = -EINVAL; + goto exit; + } /* repeat until no buffer overrun in callback handler occur */ do { atomic_set(&dev->overflow_flag, 0); if ((read_idx = read_index(dev)) == -1) { /* queue empty */ - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto exit; + } else { //next line will return when there is either new data, or the device is unplugged int r = wait_event_interruptible(dev->read_wait, @@ -309,28 +326,37 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer, -1)); if (r) { //we were interrupted by a signal - return -ERESTART; + retval = -ERESTART; + goto exit; } if (!dev->present) { //The device was unplugged - return -ENODEV; + retval = -ENODEV; + goto exit; } if (read_idx == -1) { // Can this happen ??? - return 0; + retval = 0; + goto exit; } } } offset = read_idx * (dev->report_size + 1); if (copy_to_user(buffer, dev->read_queue + offset, count)) { - return -EFAULT; + retval = -EFAULT; + goto exit; } } while (atomic_read(&dev->overflow_flag)); read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx; atomic_set(&dev->read_idx, read_idx); + mutex_unlock(&dev->mutex); return count; + +exit: + mutex_unlock(&dev->mutex); + return retval; } /* @@ -885,7 +911,6 @@ error: static void iowarrior_disconnect(struct usb_interface *interface) { struct iowarrior *dev = usb_get_intfdata(interface); - int minor = dev->minor; usb_deregister_dev(interface, &iowarrior_class); @@ -909,9 +934,6 @@ static void iowarrior_disconnect(struct usb_interface *interface) mutex_unlock(&dev->mutex); iowarrior_delete(dev); } - - dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n", - minor - IOWARRIOR_MINOR_BASE); } /* usb specific object needed to register this driver with the usb subsystem */ diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c index 75dfdca04ff1c26381020ebb1917bc9155a6a28f..36b11127280f3622a6fbad378932f72570745563 100644 --- a/drivers/usb/misc/onboard_usb_dev.c +++ b/drivers/usb/misc/onboard_usb_dev.c @@ -473,7 +473,7 @@ static const struct dev_pm_ops __maybe_unused onboard_dev_pm_ops = { static struct platform_driver onboard_dev_driver = { .probe = onboard_dev_probe, - .remove_new = onboard_dev_remove, + .remove = onboard_dev_remove, .driver = { .name = "onboard-usb-dev", diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 19906301a4eb8aadf43ea88e27843f8e05284d98..83079c414b4f281b2136d0d1eb39418c7f94ff8c 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -239,7 +239,7 @@ MODULE_DEVICE_TABLE(of, eud_dt_match); static struct platform_driver eud_driver = { .probe = eud_probe, - .remove_new = eud_remove, + .remove = eud_remove, .driver = { .name = "qcom_eud", .dev_groups = eud_groups, diff --git a/drivers/usb/misc/usb-ljca.c b/drivers/usb/misc/usb-ljca.c index 01ceafc4ab78ce28ffae8372c58a745247a2ff6b..c562630d862c74c4a51856e016d761d3e57a83c8 100644 --- a/drivers/usb/misc/usb-ljca.c +++ b/drivers/usb/misc/usb-ljca.c @@ -332,14 +332,11 @@ static int ljca_send(struct ljca_adapter *adap, u8 type, u8 cmd, ret = usb_bulk_msg(adap->usb_dev, adap->tx_pipe, header, msg_len, &transferred, LJCA_WRITE_TIMEOUT_MS); - - usb_autopm_put_interface(adap->intf); - if (ret < 0) - goto out; + goto out_put; if (transferred != msg_len) { ret = -EIO; - goto out; + goto out_put; } if (ack) { @@ -347,11 +344,14 @@ static int ljca_send(struct ljca_adapter *adap, u8 type, u8 cmd, timeout); if (!ret) { ret = -ETIMEDOUT; - goto out; + goto out_put; } } ret = adap->actual_length; +out_put: + usb_autopm_put_interface(adap->intf); + out: spin_lock_irqsave(&adap->lock, flags); adap->ex_buf = NULL; @@ -372,7 +372,7 @@ int ljca_transfer(struct ljca_client *client, u8 cmd, const u8 *obuf, obuf, obuf_len, ibuf, ibuf_len, true, LJCA_WRITE_ACK_TIMEOUT_MS); } -EXPORT_SYMBOL_NS_GPL(ljca_transfer, LJCA); +EXPORT_SYMBOL_NS_GPL(ljca_transfer, "LJCA"); int ljca_transfer_noack(struct ljca_client *client, u8 cmd, const u8 *obuf, u8 obuf_len) @@ -380,7 +380,7 @@ int ljca_transfer_noack(struct ljca_client *client, u8 cmd, const u8 *obuf, return ljca_send(client->adapter, client->type, cmd, obuf, obuf_len, NULL, 0, false, LJCA_WRITE_ACK_TIMEOUT_MS); } -EXPORT_SYMBOL_NS_GPL(ljca_transfer_noack, LJCA); +EXPORT_SYMBOL_NS_GPL(ljca_transfer_noack, "LJCA"); int ljca_register_event_cb(struct ljca_client *client, ljca_event_cb_t event_cb, void *context) @@ -404,7 +404,7 @@ int ljca_register_event_cb(struct ljca_client *client, ljca_event_cb_t event_cb, return 0; } -EXPORT_SYMBOL_NS_GPL(ljca_register_event_cb, LJCA); +EXPORT_SYMBOL_NS_GPL(ljca_register_event_cb, "LJCA"); void ljca_unregister_event_cb(struct ljca_client *client) { @@ -417,7 +417,7 @@ void ljca_unregister_event_cb(struct ljca_client *client) spin_unlock_irqrestore(&client->event_cb_lock, flags); } -EXPORT_SYMBOL_NS_GPL(ljca_unregister_event_cb, LJCA); +EXPORT_SYMBOL_NS_GPL(ljca_unregister_event_cb, "LJCA"); static int ljca_match_device_ids(struct acpi_device *adev, void *data) { @@ -811,6 +811,14 @@ static int ljca_probe(struct usb_interface *interface, if (ret) goto err_free; + /* + * This works around problems with ov2740 initialization on some + * Lenovo platforms. The autosuspend delay, has to be smaller than + * the delay after setting the reset_gpio line in ov2740_resume(). + * Otherwise the sensor randomly fails to initialize. + */ + pm_runtime_set_autosuspend_delay(&usb_dev->dev, 10); + usb_enable_autosuspend(usb_dev); return 0; diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index 3b33e4878c608ead68ae41c0c8e9221040eb5842..322e59381b7830e7937ff2c5afdc649c6b81e723 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -423,7 +423,7 @@ static struct platform_driver usb3503_platform_driver = { .pm = pm_ptr(&usb3503_platform_pm_ops), }, .probe = usb3503_platform_probe, - .remove_new = usb3503_platform_remove, + .remove = usb3503_platform_remove, }; static int __init usb3503_init(void) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index caf65f8294db22c74f080d2c2ccd6fe4f994f9bb..8d379ae835bc4524bb48d5796a7a5af1536ce36a 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2021,7 +2021,8 @@ static struct urb *iso_alloc_urb( for (i = 0; i < packets; i++) { /* here, only the last packet will be short */ - urb->iso_frame_desc[i].length = min((unsigned) bytes, maxp); + urb->iso_frame_desc[i].length = min_t(unsigned int, + bytes, maxp); bytes -= urb->iso_frame_desc[i].length; urb->iso_frame_desc[i].offset = maxp * i; diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 6aebc736a80c6625d9bc70b599f6b177353c758e..70dff0db5354ffeddf172f43b7839aedd4538329 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -441,7 +441,10 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, if (count == 0) goto error; - mutex_lock(&dev->io_mutex); + retval = mutex_lock_interruptible(&dev->io_mutex); + if (retval < 0) + return -EINTR; + if (dev->disconnected) { /* already disconnected */ mutex_unlock(&dev->io_mutex); retval = -ENODEV; diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index afb71c18415dd1781483210d27d049fa6ba52743..c93b43f5bc4614ad75568b601c47a1ae51f01fa5 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -823,7 +823,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, ep = MON_OFF2HDR(rp, rp->b_out); if (rp->b_read < hdrbytes) { - step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read)); + step_len = min_t(size_t, nbytes, hdrbytes - rp->b_read); ptr = ((char *)ep) + rp->b_read; if (step_len && copy_to_user(buf, ptr, step_len)) { mutex_unlock(&rp->fetch_lock); diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig index bf98fd36341dab732590882e47e4e09b4eb41317..d281da1cdbccf2d204d57d50fcf135eb3c8a2346 100644 --- a/drivers/usb/mtu3/Kconfig +++ b/drivers/usb/mtu3/Kconfig @@ -21,7 +21,7 @@ config USB_MTU3 if USB_MTU3 choice - bool "MTU3 Mode Selection" + prompt "MTU3 Mode Selection" default USB_MTU3_DUAL_ROLE if (USB && USB_GADGET) default USB_MTU3_HOST if (USB && !USB_GADGET) default USB_MTU3_GADGET if (!USB && USB_GADGET) diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index 6858ed9fc3b2f1276161a60554dee3491063bb3d..7b5a431acb56571ec9c376065a16e2f56f3a8a89 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -307,7 +307,7 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) if (otg_sx->role_sw_used || otg_sx->manual_drd_enabled) goto out; - if (of_property_read_bool(node, "extcon")) { + if (of_property_present(node, "extcon")) { otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0); if (IS_ERR(otg_sx->edev)) { return dev_err_probe(dev, PTR_ERR(otg_sx->edev), @@ -621,7 +621,7 @@ MODULE_DEVICE_TABLE(of, mtu3_of_match); static struct platform_driver mtu3_driver = { .probe = mtu3_probe, - .remove_new = mtu3_remove, + .remove = mtu3_remove, .driver = { .name = MTU3_DRIVER_NAME, .pm = DEV_PM_OPS, diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9a8cf3de061700d2c01e5e532ecac8a5f56ab38f..9e45d12b81d38d00aec61e8b1d91bc05b8826396 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -29,7 +29,7 @@ config USB_MUSB_HDRC if USB_MUSB_HDRC choice - bool "MUSB Mode Selection" + prompt "MUSB Mode Selection" default USB_MUSB_DUAL_ROLE if (USB && USB_GADGET) default USB_MUSB_HOST if (USB && !USB_GADGET) default USB_MUSB_GADGET if (!USB && USB_GADGET) diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 953094c1930c8fd8dcaaa9875905bf3f16107a62..f772aa272bea65eb403655b81a7bec26a1d355e4 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -633,7 +633,7 @@ MODULE_DEVICE_TABLE(of, da8xx_id_table); static struct platform_driver da8xx_driver = { .probe = da8xx_probe, - .remove_new = da8xx_remove, + .remove = da8xx_remove, .driver = { .name = "musb-da8xx", .pm = &da8xx_pm_ops, diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index b38df9226278b04c936cbb7c574e63577fd3565a..acdeb1117cd3f66ecc9c911d284ef2c836d5eb76 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -325,7 +325,7 @@ MODULE_DEVICE_TABLE(of, jz4740_musb_of_match); static struct platform_driver jz4740_driver = { .probe = jz4740_probe, - .remove_new = jz4740_remove, + .remove = jz4740_remove, .driver = { .name = "musb-jz4740", .of_match_table = jz4740_musb_of_match, diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c index 63c86c046b9865b1157a838b318ea7155f1c5bc5..aa988d74b58d0fb7473cb91d998c1234ef0a000c 100644 --- a/drivers/usb/musb/mediatek.c +++ b/drivers/usb/musb/mediatek.c @@ -523,7 +523,7 @@ MODULE_DEVICE_TABLE(of, mtk_musb_match); static struct platform_driver mtk_musb_driver = { .probe = mtk_musb_probe, - .remove_new = mtk_musb_remove, + .remove = mtk_musb_remove, .driver = { .name = "musb-mtk", .of_match_table = of_match_ptr(mtk_musb_match), diff --git a/drivers/usb/musb/mpfs.c b/drivers/usb/musb/mpfs.c index 00e13214aa766c61a6d4c6e6ebfc6b9246141097..7edc8429b274907b0424fa31edafb05805e62925 100644 --- a/drivers/usb/musb/mpfs.c +++ b/drivers/usb/musb/mpfs.c @@ -369,7 +369,7 @@ MODULE_DEVICE_TABLE(of, mpfs_id_table); static struct platform_driver mpfs_musb_driver = { .probe = mpfs_probe, - .remove_new = mpfs_remove, + .remove = mpfs_remove, .driver = { .name = "mpfs-musb", .of_match_table = of_match_ptr(mpfs_id_table) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b24adb5b399fc7dc908e42e718cf54be89b077d4..03b1154a6014ab27b8cca916af3a724b58046c53 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1387,7 +1387,7 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, /* expect hw_ep has already been zero-initialized */ - size = ffs(max(maxpacket, (u16) 8)) - 1; + size = ffs(max_t(u16, maxpacket, 8)) - 1; maxpacket = 1 << size; c_size = size - 3; @@ -2953,7 +2953,7 @@ static struct platform_driver musb_driver = { .dev_groups = musb_groups, }, .probe = musb_probe, - .remove_new = musb_remove, + .remove = musb_remove, }; module_platform_driver(musb_driver); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9c7a8bbc0542ceee69ff9353499207d468f7fe98..2542239ec64eafa2de5bd34f19cb0bb7d68b88ea 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -1032,7 +1032,7 @@ static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume); static struct platform_driver dsps_usbss_driver = { .probe = dsps_probe, - .remove_new = dsps_remove, + .remove = dsps_remove, .driver = { .name = "musb-dsps", .pm = &dsps_pm_ops, diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index bdf13911a1e590a87f34802a6009e34fd1734545..c6076df0d50cc7aa9b733c2685394cd810c39f4a 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1161,12 +1161,19 @@ void musb_free_request(struct usb_ep *ep, struct usb_request *req) */ void musb_ep_restart(struct musb *musb, struct musb_request *req) { + u16 csr; + void __iomem *epio = req->ep->hw_ep->regs; + trace_musb_req_start(req); musb_ep_select(musb->mregs, req->epnum); - if (req->tx) + if (req->tx) { txstate(musb, req); - else - rxstate(musb, req); + } else { + csr = musb_readw(epio, MUSB_RXCSR); + csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_P_WZC_BITS; + musb_writew(epio, MUSB_RXCSR, csr); + musb_writew(epio, MUSB_RXCSR, csr); + } } static int musb_ep_restart_resume_work(struct musb *musb, void *data) diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 6d7336727388b663dce6aa49095f54ab66b7e41c..f0786f8fbb25c2a956f5b408cc9e126f82222457 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -533,7 +533,7 @@ static void ep0_txstate(struct musb *musb) /* load the data */ fifo_src = (u8 *) request->buf + request->actual; - fifo_count = min((unsigned) MUSB_EP0_FIFOSIZE, + fifo_count = min_t(unsigned, MUSB_EP0_FIFOSIZE, request->length - request->actual); musb_write_fifo(&musb->endpoints[0], fifo_count, fifo_src); request->actual += fifo_count; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index bc45077811679698388ff6366a2af8c276c56a99..732ba981e607e750995db0b7cca2bb270e9793e6 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -798,10 +798,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum, } if (can_bulk_split(musb, qh->type)) - load_count = min((u32) hw_ep->max_packet_sz_tx, - len); + load_count = min_t(u32, hw_ep->max_packet_sz_tx, len); else - load_count = min((u32) packet_sz, len); + load_count = min_t(u32, packet_sz, len); if (dma_channel && musb_tx_dma_program(dma_controller, hw_ep, qh, urb, offset, len)) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index b4a4c1df4e0d961cfc75d105a84de8dd4c04a1f2..2970967a4fd28b21bd612b0949d4d4ab4dd810fd 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -608,7 +608,7 @@ MODULE_DEVICE_TABLE(of, omap2430_id_table); static struct platform_driver omap2430_driver = { .probe = omap2430_probe, - .remove_new = omap2430_remove, + .remove = omap2430_remove, .driver = { .name = "musb-omap2430", .pm = DEV_PM_OPS, diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index 05b6e7e52e02757d5fb2431b76a19094d7f2adad..eac1cde86be3fdc9a31cc0debe07fd18aa79cb36 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -857,7 +857,7 @@ MODULE_DEVICE_TABLE(of, sunxi_musb_match); static struct platform_driver sunxi_musb_driver = { .probe = sunxi_musb_probe, - .remove_new = sunxi_musb_remove, + .remove = sunxi_musb_remove, .driver = { .name = "musb-sunxi", .of_match_table = sunxi_musb_match, diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 461587629bf26145775fa6a922e7ed0e7012c3dc..90b760a95e4e34085c77291762d9e10040236cbc 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1290,7 +1290,7 @@ static void tusb_remove(struct platform_device *pdev) static struct platform_driver tusb_driver = { .probe = tusb_probe, - .remove_new = tusb_remove, + .remove = tusb_remove, .driver = { .name = "musb-tusb", }, diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index c8d9d2a1d2f0360da9b1ac4378e452dc549f4b59..8c2a43d992f5c95374d2c36bcc64c021eff5f7fe 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -355,7 +355,7 @@ MODULE_DEVICE_TABLE(of, ux500_match); static struct platform_driver ux500_driver = { .probe = ux500_probe, - .remove_new = ux500_remove, + .remove = ux500_remove, .driver = { .name = "musb-ux500", .pm = &ux500_pm_ops, diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 408f47e390259f37ecf00722f0137364cf78b63d..6a98aeeeae319c25af95202634bd119679936dc3 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -987,7 +987,7 @@ MODULE_DEVICE_TABLE(platform, ab8500_usb_devtype); static struct platform_driver ab8500_usb_driver = { .probe = ab8500_usb_probe, - .remove_new = ab8500_usb_remove, + .remove = ab8500_usb_remove, .id_table = ab8500_usb_devtype, .driver = { .name = "abx5x0-usb", diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 6db88e00f127c192637a4fd594c9d56eed37d49a..ca9353dad71aa2196b1491ca840a82ae56478d12 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -133,7 +133,7 @@ MODULE_DEVICE_TABLE(of, am335x_phy_ids); static struct platform_driver am335x_phy_driver = { .probe = am335x_phy_probe, - .remove_new = am335x_phy_remove, + .remove = am335x_phy_remove, .driver = { .name = "am335x-phy-driver", .pm = &am335x_pm_ops, diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index c5c6b818998eead4509da026843d969145bc62e1..42c42e1932326c66c842f03b8060af2909a50aa0 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -1002,7 +1002,7 @@ static void fsl_otg_remove(struct platform_device *pdev) struct platform_driver fsl_otg_driver = { .probe = fsl_otg_probe, - .remove_new = fsl_otg_remove, + .remove = fsl_otg_remove, .driver = { .name = driver_name, }, diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index e7d50e0a1612389a427e0cbaefcae3c1bbea8458..6c3ececf9137527799d0882ff1a98bb1510c8d2a 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -345,7 +345,7 @@ MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); static struct platform_driver usb_phy_generic_driver = { .probe = usb_phy_generic_probe, - .remove_new = usb_phy_generic_remove, + .remove = usb_phy_generic_remove, .driver = { .name = "usb_phy_generic", .of_match_table = nop_xceiv_dt_ids, diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index 5428b2b67de1fcae6aa2f677c3c51555f7c3449b..ce09e789afd882268834800cd9057e74e892896a 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -385,7 +385,7 @@ static struct platform_driver gpio_vbus_driver = { .of_match_table = gpio_vbus_of_match, }, .probe = gpio_vbus_probe, - .remove_new = gpio_vbus_remove, + .remove = gpio_vbus_remove, }; module_platform_driver(gpio_vbus_driver); diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index 993d7525a102115d6c65aec0d3f2e191aa0260df..f9b5c411aee4e542df9ca1d3403120c9168e765b 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -25,7 +25,7 @@ struct isp1301 { #define phy_to_isp(p) (container_of((p), struct isp1301, phy)) static const struct i2c_device_id isp1301_id[] = { - { "isp1301", 0 }, + { "isp1301" }, { } }; MODULE_DEVICE_TABLE(i2c, isp1301_id); diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c index bd9a98ad1b3093ea89de7be1833963d337f16172..51155c5513d3c620b9bdd84e68d5950914c93824 100644 --- a/drivers/usb/phy/phy-keystone.c +++ b/drivers/usb/phy/phy-keystone.c @@ -103,7 +103,7 @@ MODULE_DEVICE_TABLE(of, keystone_usbphy_ids); static struct platform_driver keystone_usbphy_driver = { .probe = keystone_usbphy_probe, - .remove_new = keystone_usbphy_remove, + .remove = keystone_usbphy_remove, .driver = { .name = "keystone-usbphy", .of_match_table = keystone_usbphy_ids, diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index df7c27474a75a6a3435ead94853299adae9ac577..a7a102f2e163facb7797664a8999207419ae33fd 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -867,7 +867,7 @@ static int mv_otg_resume(struct platform_device *pdev) static struct platform_driver mv_otg_driver = { .probe = mv_otg_probe, - .remove_new = mv_otg_remove, + .remove = mv_otg_remove, .driver = { .name = driver_name, .dev_groups = mv_otg_groups, diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index cc4156c1b148ee9ec47db2a7413c8fb0d3080728..7490f1798b461c39c29bb74e1e57e0a4adce2bd7 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -952,7 +952,7 @@ static SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend, static struct platform_driver mxs_phy_driver = { .probe = mxs_phy_probe, - .remove_new = mxs_phy_remove, + .remove = mxs_phy_remove, .driver = { .name = DRIVER_NAME, .of_match_table = mxs_phy_dt_ids, diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index 5cac31c6029b38da9f2488fbfdaa340b28a2d5b6..ae7bf3ff89ee176d730d2fb1e7377ce4835b7c6f 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -424,7 +424,7 @@ static void tahvo_usb_remove(struct platform_device *pdev) static struct platform_driver tahvo_usb_driver = { .probe = tahvo_usb_probe, - .remove_new = tahvo_usb_remove, + .remove = tahvo_usb_remove, .driver = { .name = "tahvo-usb", .dev_groups = tahvo_groups, diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 4ea47e6f835bfb8517acc87e4a4513b1127bd847..bee222967f6b19c8d43eaeefdbb8954f2ac2d51c 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -1495,7 +1495,7 @@ static void tegra_usb_phy_remove(struct platform_device *pdev) static struct platform_driver tegra_usb_phy_driver = { .probe = tegra_usb_phy_probe, - .remove_new = tegra_usb_phy_remove, + .remove = tegra_usb_phy_remove, .driver = { .name = "tegra-phy", .of_match_table = tegra_usb_phy_id_table, diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index da09cff55abcec526dde7e5749cd11b9c60f9a8f..49d79c1257f3a4004f17322c29eeeb35286685f6 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -432,7 +432,7 @@ MODULE_DEVICE_TABLE(of, twl6030_usb_id_table); static struct platform_driver twl6030_usb_driver = { .probe = twl6030_usb_probe, - .remove_new = twl6030_usb_remove, + .remove = twl6030_usb_remove, .driver = { .name = "twl6030_usb", .of_match_table = of_match_ptr(twl6030_usb_id_table), diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 06f789097989f19fbdd41bbc035013f9958c3cc9..1ce134505cee86102eb2d93ca1d09a52b684d3bb 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -365,7 +365,7 @@ static int usb_add_extcon(struct usb_phy *x) { int ret; - if (of_property_read_bool(x->dev->of_node, "extcon")) { + if (of_property_present(x->dev->of_node, "extcon")) { x->edev = extcon_get_edev_by_phandle(x->dev, 0); if (IS_ERR(x->edev)) return PTR_ERR(x->edev); diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index edc43f169d493c65549c58782f20a1e18e823a6a..935fc496fe94b6d97b2445c5f43ac33c5fa9911d 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -632,7 +632,7 @@ static int usbhs_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - if (of_property_read_bool(dev_of_node(dev), "extcon")) { + if (of_property_present(dev_of_node(dev), "extcon")) { priv->edev = extcon_get_edev_by_phandle(dev, 0); if (IS_ERR(priv->edev)) return PTR_ERR(priv->edev); @@ -835,7 +835,7 @@ static struct platform_driver renesas_usbhs_driver = { .of_match_table = usbhs_of_match, }, .probe = usbhs_probe, - .remove_new = usbhs_remove, + .remove = usbhs_remove, }; module_platform_driver(renesas_usbhs_driver); diff --git a/drivers/usb/roles/intel-xhci-usb-role-switch.c b/drivers/usb/roles/intel-xhci-usb-role-switch.c index e5c6c413a075b6e9c8734d029f20fc558ec69c92..cd2e026dcb22f14185b9cf7a0149908488d57c10 100644 --- a/drivers/usb/roles/intel-xhci-usb-role-switch.c +++ b/drivers/usb/roles/intel-xhci-usb-role-switch.c @@ -217,7 +217,7 @@ static struct platform_driver intel_xhci_usb_driver = { }, .id_table = intel_xhci_usb_table, .probe = intel_xhci_usb_probe, - .remove_new = intel_xhci_usb_remove, + .remove = intel_xhci_usb_remove, }; module_platform_driver(intel_xhci_usb_driver); diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index d200e2c29a8ffe84acda12537fc5d688627f37b3..2fea1b1db4a269c0929a0e8e2effebd9bad9d34e 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -136,12 +136,11 @@ static void free_dynids(struct usb_serial_driver *drv) { struct usb_dynid *dynid, *n; - spin_lock(&drv->dynids.lock); + guard(mutex)(&usb_dynids_lock); list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { list_del(&dynid->node); kfree(dynid); } - spin_unlock(&drv->dynids.lock); } const struct bus_type usb_serial_bus_type = { @@ -157,7 +156,6 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) int retval; driver->driver.bus = &usb_serial_bus_type; - spin_lock_init(&driver->dynids.lock); INIT_LIST_HEAD(&driver->dynids.list); retval = driver_register(&driver->driver); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c6f17d732b9581efc8f9c2808ce882025338cf13..e07c5e3eb18c0d04bb39b788312501fc47b4ac9d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1443,9 +1443,11 @@ static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss) struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); + mutex_lock(&priv->cfg_lock); ss->flags = priv->flags; ss->baud_base = priv->baud_base; ss->custom_divisor = priv->custom_divisor; + mutex_unlock(&priv->cfg_lock); } static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 28c71d99e857262c7359b9050c649ef8784f6bed..1fffda7647f98928d62308b223204d1768b34f61 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1129,7 +1129,7 @@ static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, spin_lock_irqsave(&edge_port->ep_lock, flags); /* calculate number of bytes to put in fifo */ - copySize = min((unsigned int)count, + copySize = min_t(unsigned int, count, (edge_port->txCredits - fifo->count)); dev_dbg(&port->dev, "%s of %d byte(s) Fifo room %d -- will copy %d bytes\n", diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ad41363e3cea5abd09ff24a85e4c670bd5d1de67..010688dd9e49ced5fdf9e5dd808604304b27452b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -31,6 +31,7 @@ #define PL2303_QUIRK_UART_STATE_IDX0 BIT(0) #define PL2303_QUIRK_LEGACY BIT(1) #define PL2303_QUIRK_ENDPOINT_HACK BIT(2) +#define PL2303_QUIRK_NO_BREAK_GETLINE BIT(3) static const struct usb_device_id id_table[] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID), @@ -467,6 +468,25 @@ static int pl2303_detect_type(struct usb_serial *serial) return -ENODEV; } +static bool pl2303_is_hxd_clone(struct usb_serial *serial) +{ + struct usb_device *udev = serial->dev; + unsigned char *buf; + int ret; + + buf = kmalloc(7, GFP_KERNEL); + if (!buf) + return false; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, + 0, 0, buf, 7, 100); + + kfree(buf); + + return ret == -EPIPE; +} + static int pl2303_startup(struct usb_serial *serial) { struct pl2303_serial_private *spriv; @@ -489,6 +509,9 @@ static int pl2303_startup(struct usb_serial *serial) spriv->quirks = (unsigned long)usb_get_serial_data(serial); spriv->quirks |= spriv->type->quirks; + if (type == TYPE_HXD && pl2303_is_hxd_clone(serial)) + spriv->quirks |= PL2303_QUIRK_NO_BREAK_GETLINE; + usb_set_serial_data(serial, spriv); if (type != TYPE_HXN) { @@ -725,9 +748,18 @@ static void pl2303_encode_baud_rate(struct tty_struct *tty, static int pl2303_get_line_request(struct usb_serial_port *port, unsigned char buf[7]) { - struct usb_device *udev = port->serial->dev; + struct usb_serial *serial = port->serial; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); + struct usb_device *udev = serial->dev; int ret; + if (spriv->quirks & PL2303_QUIRK_NO_BREAK_GETLINE) { + struct pl2303_private *priv = usb_get_serial_port_data(port); + + memcpy(buf, priv->line_settings, 7); + return 0; + } + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, 0, 0, buf, 7, 100); @@ -1064,9 +1096,13 @@ static int pl2303_carrier_raised(struct usb_serial_port *port) static int pl2303_set_break(struct usb_serial_port *port, bool enable) { struct usb_serial *serial = port->serial; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); u16 state; int result; + if (spriv->quirks & PL2303_QUIRK_NO_BREAK_GETLINE) + return -ENOTTY; + if (enable) state = BREAK_ON; else diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 64a2e0bb5723ed203b7f84544e7877ce6ba98124..741e68e4613960334cc81f43b5b7555e0e93bf6d 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -421,7 +421,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, unsigned long flags; unsigned char *buffer; struct urb *urb; - size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER); + size_t writesize = min_t(size_t, count, MAX_TRANSFER); int retval = 0; /* verify that we actually have some data to write */ diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index df6a2ae0bf4246fd93b7becb328ece50e80c181a..7266558d823ac2c5e6c00417aef6ab90bd2cb4dd 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -706,14 +706,12 @@ static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf, { struct usb_dynid *dynid; - spin_lock(&drv->dynids.lock); + guard(mutex)(&usb_dynids_lock); list_for_each_entry(dynid, &drv->dynids.list, node) { if (usb_match_one_id(intf, &dynid->id)) { - spin_unlock(&drv->dynids.lock); return &dynid->id; } } - spin_unlock(&drv->dynids.lock); return NULL; } diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 46635fa4a3405dfc7fd8a57db4bafc4c5343e20a..28db337f190bf5389d40f8023b74fd2d0c8e4ee2 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -8,7 +8,7 @@ ccflags-y := -I $(srctree)/drivers/scsi -ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_STORAGE +ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"USB_STORAGE"' obj-$(CONFIG_USB_UAS) += uas.o obj-$(CONFIG_USB_STORAGE) += usb-storage.o diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index a9d3c58ce7d935da0e026e9c036e6580e95cade2..6263c4e61678e890e0192c5c9dad9b97dbaf0e66 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -36,7 +36,7 @@ MODULE_DESCRIPTION("Driver for Alauda-based card readers"); MODULE_AUTHOR("Daniel Drake "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); /* * Status bytes diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index 30dfd0082474c36fe54483778b07c5b4857b798e..2fce5f95be515decd3337bf5ed56977a6c85592d 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c @@ -22,7 +22,7 @@ MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB"); MODULE_AUTHOR("Matthieu Castet "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); /* * The table of devices diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 3ea5601d16b8b78dbe82aadb0dc759b010d3627f..bbfa2398b17036f431c0692bbf794bdb01d68cdf 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -54,7 +54,7 @@ MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader"); MODULE_AUTHOR("Jimmie Mayfield "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); struct datafab_info { unsigned long sectors; /* total sector count */ diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index a4bfbecbf16c33fa052549caefb06aab3afeac49..ce91fb1059754dca40b830a3178d702462d46336 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -26,7 +26,7 @@ MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); MODULE_FIRMWARE(SD_INIT1_FIRMWARE); MODULE_FIRMWARE(SD_INIT2_FIRMWARE); MODULE_FIRMWARE(SD_RW_FIRMWARE); @@ -737,7 +737,7 @@ static int sd_scsi_write(struct us_data *us, struct scsi_cmnd *srb) memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; - bcb->Flags = 0x00; + bcb->Flags = US_BULK_FLAG_OUT; bcb->CDB[0] = 0xF0; bcb->CDB[5] = (unsigned char)(bnByte); bcb->CDB[4] = (unsigned char)(bnByte>>8); @@ -1163,7 +1163,7 @@ static int ms_read_copyblock(struct us_data *us, u16 oldphy, u16 newphy, memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*len; - bcb->Flags = 0x00; + bcb->Flags = US_BULK_FLAG_OUT; bcb->CDB[0] = 0xF0; bcb->CDB[1] = 0x08; bcb->CDB[4] = (unsigned char)(oldphy); @@ -1759,7 +1759,7 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb) memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; - bcb->Flags = 0x00; + bcb->Flags = US_BULK_FLAG_OUT; bcb->CDB[0] = 0xF0; bcb->CDB[1] = 0x04; bcb->CDB[5] = (unsigned char)(bn); @@ -1931,7 +1931,7 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = sd_fw->size; - bcb->Flags = 0x00; + bcb->Flags = US_BULK_FLAG_OUT; bcb->CDB[0] = 0xEF; result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0); diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index cab27ba7a32a65f3f127af19984568ad8bb7dd8b..a075620907b49eda2e97eb274abe251c44821552 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); MODULE_AUTHOR("David Brown "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); #ifdef CONFIG_USB_STORAGE_DEBUG static void pdump(struct us_data *us, void *ibuffer, int length); diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index f2254eb3c0d73f02ada544a98591a25175d2d509..a1669c35bad5e8204c5b23ac1cf56787f04ac9eb 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -53,7 +53,7 @@ MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); MODULE_AUTHOR("Björn Stenberg "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); static int isd200_Initialization(struct us_data *us); diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 0e71a8f33c2b6350b0144c825be1c86357a712ba..39ca84d6859122903de4e64b13e697e8b7d4ab31 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -51,7 +51,7 @@ MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); MODULE_AUTHOR("Jimmie Mayfield "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); /* * The table of devices diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index d6a5e54f2ca823f3bfbd4bccbb1ea188b939ec56..341d6839548a0252f35a494bdfc69a3836f1cda4 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -23,7 +23,7 @@ MODULE_DESCRIPTION("Driver for Rio Karma"); MODULE_AUTHOR("Bob Copeland , Keith Bennett "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); #define RIO_PREFIX "RIOP\x00" #define RIO_PREFIX_LEN 5 diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index f97cf6cadb8eb7c49b0c98097943a3601d006b0e..5a8a1ffda0ec94110c13f4786165ac551d93e1d0 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -25,7 +25,7 @@ MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver"); MODULE_AUTHOR("Nick Sillik "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); #define ONETOUCH_PKT_LEN 0x02 #define ONETOUCH_BUTTON KEY_PROG1 diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 0c423916d7bfa4e325243ea4b0e0b9ce8854a535..2a82ed7b68eaa75993e786afeda0d5d3a3c3bfce 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -35,7 +35,7 @@ MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); MODULE_AUTHOR("wwang "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); static int auto_delink_en = 1; module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); @@ -212,7 +212,7 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun, /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(buf_len); - bcb->Flags = (dir == DMA_FROM_DEVICE) ? US_BULK_FLAG_IN : 0; + bcb->Flags = (dir == DMA_FROM_DEVICE) ? US_BULK_FLAG_IN : US_BULK_FLAG_OUT; bcb->Tag = ++us->tag; bcb->Lun = lun; bcb->Length = cmd_len; @@ -301,7 +301,7 @@ static int rts51x_bulk_transport_special(struct us_data *us, u8 lun, /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(buf_len); - bcb->Flags = (dir == DMA_FROM_DEVICE) ? US_BULK_FLAG_IN : 0; + bcb->Flags = (dir == DMA_FROM_DEVICE) ? US_BULK_FLAG_IN : US_BULK_FLAG_OUT; bcb->Tag = ++us->tag; bcb->Lun = lun; bcb->Length = cmd_len; diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 03d1b9c69ea18f0747f49ac59a67be2a87a563ea..d21ce3466e25842757b3e278d522c55b7c1f19de 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -47,7 +47,7 @@ MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); MODULE_AUTHOR("Andries Brouwer , Robert Baruch "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); static int usb_stor_sddr09_dpcm_init(struct us_data *us); static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); @@ -752,7 +752,7 @@ sddr09_read_data(struct us_data *us, // a bounce buffer and move the data a piece at a time between the // bounce buffer and the actual transfer buffer. - len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; + len = min_t(unsigned int, sectors, info->blocksize) * info->pagesize; buffer = kmalloc(len, GFP_NOIO); if (!buffer) return -ENOMEM; @@ -997,7 +997,7 @@ sddr09_write_data(struct us_data *us, * at a time between the bounce buffer and the actual transfer buffer. */ - len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; + len = min_t(unsigned int, sectors, info->blocksize) * info->pagesize; buffer = kmalloc(len, GFP_NOIO); if (!buffer) { kfree(blockbuffer); diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index b8227478a7add21e48dbe0573f49efb9639f5aa3..d5cdff30f6f31f98d3d58ffcdd2426d7cd385cbb 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); MODULE_AUTHOR("Simon Munton"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); /* * The table of devices @@ -206,7 +206,7 @@ static int sddr55_read_data(struct us_data *us, // a bounce buffer and move the data a piece at a time between the // bounce buffer and the actual transfer buffer. - len = min((unsigned int) sectors, (unsigned int) info->blocksize >> + len = min_t(unsigned int, sectors, info->blocksize >> info->smallpageshift) * PAGESIZE; buffer = kmalloc(len, GFP_NOIO); if (buffer == NULL) @@ -224,7 +224,7 @@ static int sddr55_read_data(struct us_data *us, // Read as many sectors as possible in this block - pages = min((unsigned int) sectors << info->smallpageshift, + pages = min_t(unsigned int, sectors << info->smallpageshift, info->blocksize - page); len = pages << info->pageshift; @@ -333,7 +333,7 @@ static int sddr55_write_data(struct us_data *us, // a bounce buffer and move the data a piece at a time between the // bounce buffer and the actual transfer buffer. - len = min((unsigned int) sectors, (unsigned int) info->blocksize >> + len = min_t(unsigned int, sectors, info->blocksize >> info->smallpageshift) * PAGESIZE; buffer = kmalloc(len, GFP_NOIO); if (buffer == NULL) @@ -351,7 +351,7 @@ static int sddr55_write_data(struct us_data *us, // Write as many sectors as possible in this block - pages = min((unsigned int) sectors << info->smallpageshift, + pages = min_t(unsigned int, sectors << info->smallpageshift, info->blocksize - page); len = pages << info->pageshift; diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index e7c224b7c4646382f460ca588b9c428d881dc518..087c706bb315f9d4b921b9d9eb85df752c90337b 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -48,7 +48,7 @@ MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); MODULE_AUTHOR("Daniel Drake , Robert Baruch "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); /* Supported device types */ #define USBAT_DEV_HP8200 0x01 diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 7449e379077a58d49da2ec60b7e73af6a6bf0318..9d767f6bf7225f830a71267c94c09f0b4d392bfa 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1133,7 +1133,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(transfer_length); bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? - US_BULK_FLAG_IN : 0; + US_BULK_FLAG_IN : US_BULK_FLAG_OUT; bcb->Tag = ++us->tag; bcb->Lun = srb->device->lun; if (us->fflags & US_FL_SCM_MULT_TARG) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 03043d567fa1bebf0c3c4c0c608bf6bf55d1f53c..f9ad90ce7af4bf81fa5170729f6ffa8d35a87e81 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -1289,6 +1289,6 @@ module_exit(uas_exit); MODULE_DESCRIPTION("USB Attached SCSI driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(USB_STORAGE); +MODULE_IMPORT_NS("USB_STORAGE"); MODULE_AUTHOR( "Hans de Goede , Matthew Wilcox and Sarah Sharp"); diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index 92cc1b13612084198fce715c6af317906f0599a5..2f03190a9873acd52dd7703965a10d3e16aa4e28 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -729,7 +729,7 @@ int dp_altmode_probe(struct typec_altmode *alt) /* FIXME: Port can only be DFP_U. */ - /* Make sure we have compatiple pin configurations */ + /* Make sure we have compatible pin configurations */ if (!(DP_CAP_PIN_ASSIGN_DFP_D(port->vdo) & DP_CAP_PIN_ASSIGN_UFP_D(alt->vdo)) && !(DP_CAP_PIN_ASSIGN_UFP_D(port->vdo) & diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 58f40156de56226fb954c3f6495ef9e993234cc9..4b3047e055a3737d3eb841e00fc976a70f8c9c3e 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -219,6 +219,13 @@ static ssize_t usb_power_delivery_revision_show(struct device *dev, char *buf); static DEVICE_ATTR_RO(usb_power_delivery_revision); +static const char * const usb_modes[] = { + [USB_MODE_NONE] = "none", + [USB_MODE_USB2] = "usb2", + [USB_MODE_USB3] = "usb3", + [USB_MODE_USB4] = "usb4" +}; + /* ------------------------------------------------------------------------- */ /* Alternate Modes */ @@ -614,6 +621,75 @@ EXPORT_SYMBOL_GPL(typec_unregister_altmode); /* ------------------------------------------------------------------------- */ /* Type-C Partners */ +/** + * typec_partner_set_usb_mode - Assign active USB Mode for the partner + * @partner: USB Type-C partner + * @mode: USB Mode (USB2, USB3 or USB4) + * + * The port drivers can use this function to assign the active USB Mode to + * @partner. The USB Mode can change for example due to Data Reset. + */ +void typec_partner_set_usb_mode(struct typec_partner *partner, enum usb_mode mode) +{ + if (!partner || partner->usb_mode == mode) + return; + + partner->usb_capability |= BIT(mode - 1); + partner->usb_mode = mode; + sysfs_notify(&partner->dev.kobj, NULL, "usb_mode"); +} +EXPORT_SYMBOL_GPL(typec_partner_set_usb_mode); + +static ssize_t +usb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct typec_partner *partner = to_typec_partner(dev); + int len = 0; + int i; + + for (i = USB_MODE_USB2; i < USB_MODE_USB4 + 1; i++) { + if (!(BIT(i - 1) & partner->usb_capability)) + continue; + + if (i == partner->usb_mode) + len += sysfs_emit_at(buf, len, "[%s] ", usb_modes[i]); + else + len += sysfs_emit_at(buf, len, "%s ", usb_modes[i]); + } + + sysfs_emit_at(buf, len - 1, "\n"); + + return len; +} + +static ssize_t usb_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct typec_partner *partner = to_typec_partner(dev); + struct typec_port *port = to_typec_port(dev->parent); + int mode; + int ret; + + if (!port->ops || !port->ops->enter_usb_mode) + return -EOPNOTSUPP; + + mode = sysfs_match_string(usb_modes, buf); + if (mode < 0) + return mode; + + if (mode == partner->usb_mode) + return size; + + ret = port->ops->enter_usb_mode(port, mode); + if (ret) + return ret; + + typec_partner_set_usb_mode(partner, mode); + + return size; +} +static DEVICE_ATTR_RW(usb_mode); + static ssize_t accessory_mode_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -660,6 +736,7 @@ static struct attribute *typec_partner_attrs[] = { &dev_attr_supports_usb_power_delivery.attr, &dev_attr_number_of_alternate_modes.attr, &dev_attr_type.attr, + &dev_attr_usb_mode.attr, &dev_attr_usb_power_delivery_revision.attr, NULL }; @@ -667,6 +744,14 @@ static struct attribute *typec_partner_attrs[] = { static umode_t typec_partner_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { struct typec_partner *partner = to_typec_partner(kobj_to_dev(kobj)); + struct typec_port *port = to_typec_port(partner->dev.parent); + + if (attr == &dev_attr_usb_mode.attr) { + if (!partner->usb_capability) + return 0; + if (!port->ops || !port->ops->enter_usb_mode) + return 0444; + } if (attr == &dev_attr_number_of_alternate_modes.attr) { if (partner->num_altmodes < 0) @@ -740,10 +825,33 @@ static void typec_partner_unlink_device(struct typec_partner *partner, struct de */ int typec_partner_set_identity(struct typec_partner *partner) { - if (!partner->identity) + u8 usb_capability = partner->usb_capability; + struct device *dev = &partner->dev; + struct usb_pd_identity *id; + + id = get_pd_identity(dev); + if (!id) return -EINVAL; - typec_report_identity(&partner->dev); + if (to_typec_port(dev->parent)->data_role == TYPEC_HOST) { + u32 devcap = PD_VDO_UFP_DEVCAP(id->vdo[0]); + + if (devcap & (DEV_USB2_CAPABLE | DEV_USB2_BILLBOARD)) + usb_capability |= USB_CAPABILITY_USB2; + if (devcap & DEV_USB3_CAPABLE) + usb_capability |= USB_CAPABILITY_USB3; + if (devcap & DEV_USB4_CAPABLE) + usb_capability |= USB_CAPABILITY_USB4; + } else { + usb_capability = PD_VDO_DFP_HOSTCAP(id->vdo[0]); + } + + if (partner->usb_capability != usb_capability) { + partner->usb_capability = usb_capability; + sysfs_notify(&dev->kobj, NULL, "usb_mode"); + } + + typec_report_identity(dev); return 0; } EXPORT_SYMBOL_GPL(typec_partner_set_identity); @@ -913,6 +1021,7 @@ struct typec_partner *typec_register_partner(struct typec_port *port, partner->usb_pd = desc->usb_pd; partner->accessory = desc->accessory; partner->num_altmodes = -1; + partner->usb_capability = desc->usb_capability; partner->pd_revision = desc->pd_revision; partner->svdm_version = port->cap->svdm_version; partner->attach = desc->attach; @@ -932,6 +1041,15 @@ struct typec_partner *typec_register_partner(struct typec_port *port, partner->dev.type = &typec_partner_dev_type; dev_set_name(&partner->dev, "%s-partner", dev_name(&port->dev)); + if (port->usb2_dev) { + partner->usb_capability |= USB_CAPABILITY_USB2; + partner->usb_mode = USB_MODE_USB2; + } + if (port->usb3_dev) { + partner->usb_capability |= USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3; + partner->usb_mode = USB_MODE_USB3; + } + ret = device_register(&partner->dev); if (ret) { dev_err(&port->dev, "failed to register partner (%d)\n", ret); @@ -1292,6 +1410,67 @@ EXPORT_SYMBOL_GPL(typec_unregister_cable); /* ------------------------------------------------------------------------- */ /* USB Type-C ports */ +/** + * typec_port_set_usb_mode - Set the operational USB mode for the port + * @port: USB Type-C port + * @mode: USB Mode (USB2, USB3 or USB4) + * + * @mode will be used with the next Enter_USB message. Existing connections are + * not affected. + */ +void typec_port_set_usb_mode(struct typec_port *port, enum usb_mode mode) +{ + port->usb_mode = mode; +} +EXPORT_SYMBOL_GPL(typec_port_set_usb_mode); + +static ssize_t +usb_capability_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct typec_port *port = to_typec_port(dev); + int len = 0; + int i; + + for (i = USB_MODE_USB2; i < USB_MODE_USB4 + 1; i++) { + if (!(BIT(i - 1) & port->cap->usb_capability)) + continue; + + if (i == port->usb_mode) + len += sysfs_emit_at(buf, len, "[%s] ", usb_modes[i]); + else + len += sysfs_emit_at(buf, len, "%s ", usb_modes[i]); + } + + sysfs_emit_at(buf, len - 1, "\n"); + + return len; +} + +static ssize_t +usb_capability_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct typec_port *port = to_typec_port(dev); + int ret = 0; + int mode; + + if (!port->ops || !port->ops->default_usb_mode_set) + return -EOPNOTSUPP; + + mode = sysfs_match_string(usb_modes, buf); + if (mode < 0) + return mode; + + ret = port->ops->default_usb_mode_set(port, mode); + if (ret) + return ret; + + port->usb_mode = mode; + + return size; +} +static DEVICE_ATTR_RW(usb_capability); + /** * typec_port_set_usb_power_delivery - Assign USB PD for port. * @port: USB Type-C port. @@ -1760,6 +1939,7 @@ static struct attribute *typec_attrs[] = { &dev_attr_vconn_source.attr, &dev_attr_port_type.attr, &dev_attr_orientation.attr, + &dev_attr_usb_capability.attr, NULL, }; @@ -1793,6 +1973,11 @@ static umode_t typec_attr_is_visible(struct kobject *kobj, if (port->cap->orientation_aware) return 0444; return 0; + } else if (attr == &dev_attr_usb_capability.attr) { + if (!port->cap->usb_capability) + return 0; + if (!port->ops || !port->ops->default_usb_mode_set) + return 0444; } return attr->mode; @@ -1864,13 +2049,18 @@ static void typec_partner_attach(struct typec_connector *con, struct device *dev struct typec_port *port = container_of(con, struct typec_port, con); struct typec_partner *partner = typec_get_partner(port); struct usb_device *udev = to_usb_device(dev); + enum usb_mode usb_mode; - if (udev->speed < USB_SPEED_SUPER) + if (udev->speed < USB_SPEED_SUPER) { + usb_mode = USB_MODE_USB2; port->usb2_dev = dev; - else + } else { + usb_mode = USB_MODE_USB3; port->usb3_dev = dev; + } if (partner) { + typec_partner_set_usb_mode(partner, usb_mode); typec_partner_link_device(partner, dev); put_device(&partner->dev); } @@ -2433,6 +2623,13 @@ struct typec_port *typec_register_port(struct device *parent, port->con.attach = typec_partner_attach; port->con.deattach = typec_partner_deattach; + if (cap->usb_capability & USB_CAPABILITY_USB4) + port->usb_mode = USB_MODE_USB4; + else if (cap->usb_capability & USB_CAPABILITY_USB3) + port->usb_mode = USB_MODE_USB3; + else if (cap->usb_capability & USB_CAPABILITY_USB2) + port->usb_mode = USB_MODE_USB2; + device_initialize(&port->dev); port->dev.class = &typec_class; port->dev.parent = parent; diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index 7485cdb9dd2017ce1d55987de2ca6a3f63fe38ae..b3076a24ad2eeef3fc04bebe47c2636306e96f18 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -35,6 +35,8 @@ struct typec_partner { int num_altmodes; u16 pd_revision; /* 0300H = "3.0" */ enum usb_pd_svdm_ver svdm_version; + enum usb_mode usb_mode; + u8 usb_capability; struct usb_power_delivery *pd; @@ -55,6 +57,7 @@ struct typec_port { enum typec_role vconn_role; enum typec_pwr_opmode pwr_opmode; enum typec_port_type port_type; + enum usb_mode usb_mode; struct mutex port_type_lock; enum typec_orientation orientation; diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig index ce7db6ad30572a0a74890f5f11944fb3ff07f635..67381b4ef4f68f4a6e73f157365ee24d0ab7109a 100644 --- a/drivers/usb/typec/mux/Kconfig +++ b/drivers/usb/typec/mux/Kconfig @@ -66,6 +66,15 @@ config TYPEC_MUX_PTN36502 Say Y or M if your system has a NXP PTN36502 Type-C redriver chip found on some devices with a Type-C port. +config TYPEC_MUX_TUSB1046 + tristate "TI TUSB1046 Type-C crosspoint switch driver" + depends on I2C + help + Driver for the Texas Instruments TUSB1046-DCI crosspoint switch. + Supports flipping USB-C SuperSpeed lanes to adapt to orientation + changes, as well as muxing DisplayPort and sideband signals to a + common Type-C connector. + config TYPEC_MUX_WCD939X_USBSS tristate "Qualcomm WCD939x USBSS Analog Audio Switch driver" depends on I2C diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile index bb96f30267af05b33b9277dcf1cc0e1527d2dcdd..60879446da9365183567d3374a2fb7b5171fb3d7 100644 --- a/drivers/usb/typec/mux/Makefile +++ b/drivers/usb/typec/mux/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_TYPEC_MUX_INTEL_PMC) += intel_pmc_mux.o obj-$(CONFIG_TYPEC_MUX_IT5205) += it5205.o obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M) += nb7vpq904m.o obj-$(CONFIG_TYPEC_MUX_PTN36502) += ptn36502.o +obj-$(CONFIG_TYPEC_MUX_TUSB1046) += tusb1046.o obj-$(CONFIG_TYPEC_MUX_WCD939X_USBSS) += wcd939x-usbss.o diff --git a/drivers/usb/typec/mux/gpio-sbu-mux.c b/drivers/usb/typec/mux/gpio-sbu-mux.c index 8902102c05a8ecdb7a8136415117f0c2aa48261a..1834f1a2dd9dd082648050c6aace4124ed70fd38 100644 --- a/drivers/usb/typec/mux/gpio-sbu-mux.c +++ b/drivers/usb/typec/mux/gpio-sbu-mux.c @@ -159,7 +159,7 @@ MODULE_DEVICE_TABLE(of, gpio_sbu_mux_match); static struct platform_driver gpio_sbu_mux_driver = { .probe = gpio_sbu_mux_probe, - .remove_new = gpio_sbu_mux_remove, + .remove = gpio_sbu_mux_remove, .driver = { .name = "gpio_sbu_mux", .of_match_table = gpio_sbu_mux_match, diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c index 46b4c5c3a6beb3260368eea221b405c2969c22e3..5dfe95754394611b46b798f577d56cb1afcde003 100644 --- a/drivers/usb/typec/mux/intel_pmc_mux.c +++ b/drivers/usb/typec/mux/intel_pmc_mux.c @@ -828,7 +828,7 @@ static struct platform_driver pmc_usb_driver = { .acpi_match_table = ACPI_PTR(pmc_usb_acpi_ids), }, .probe = pmc_usb_probe, - .remove_new = pmc_usb_remove, + .remove = pmc_usb_remove, }; static int __init pmc_usb_init(void) diff --git a/drivers/usb/typec/mux/tusb1046.c b/drivers/usb/typec/mux/tusb1046.c new file mode 100644 index 0000000000000000000000000000000000000000..b4f45c217b59fe033551e8e6379ad2d33ebedbcb --- /dev/null +++ b/drivers/usb/typec/mux/tusb1046.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for the TUSB1046-DCI USB Type-C crosspoint switch + * + * Copyright (C) 2024 Bootlin + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TUSB1046_REG_GENERAL 0xa + +/* General register bits */ +#define TUSB1046_GENERAL_FLIPSEL BIT(2) +#define TUSB1046_GENERAL_CTLSEL GENMASK(1, 0) + +/* Mux modes */ +#define TUSB1046_CTLSEL_DISABLED 0x0 +#define TUSB1046_CTLSEL_USB3 0x1 +#define TUSB1046_CTLSEL_4LANE_DP 0x2 +#define TUSB1046_CTLSEL_USB3_AND_2LANE_DP 0x3 + +struct tusb1046_priv { + struct i2c_client *client; + struct typec_switch_dev *sw; + struct typec_mux_dev *mux; + + /* Lock General register during accesses */ + struct mutex general_reg_lock; +}; + +static int tusb1046_mux_set(struct typec_mux_dev *mux, + struct typec_mux_state *state) +{ + struct tusb1046_priv *priv = typec_mux_get_drvdata(mux); + struct i2c_client *client = priv->client; + struct device *dev = &client->dev; + int mode, val, ret = 0; + + if (state->mode >= TYPEC_STATE_MODAL && + state->alt->svid != USB_TYPEC_DP_SID) + return -EINVAL; + + dev_dbg(dev, "mux mode requested: %lu\n", state->mode); + + mutex_lock(&priv->general_reg_lock); + + val = i2c_smbus_read_byte_data(client, TUSB1046_REG_GENERAL); + if (val < 0) { + dev_err(dev, "failed to read ctlsel status, err %d\n", val); + ret = val; + goto out_unlock; + } + + switch (state->mode) { + case TYPEC_STATE_USB: + mode = TUSB1046_CTLSEL_USB3; + break; + case TYPEC_DP_STATE_C: + case TYPEC_DP_STATE_E: + mode = TUSB1046_CTLSEL_4LANE_DP; + break; + case TYPEC_DP_STATE_D: + mode = TUSB1046_CTLSEL_USB3_AND_2LANE_DP; + break; + case TYPEC_STATE_SAFE: + default: + mode = TUSB1046_CTLSEL_DISABLED; + break; + } + + val &= ~TUSB1046_GENERAL_CTLSEL; + val |= mode; + + ret = i2c_smbus_write_byte_data(client, TUSB1046_REG_GENERAL, val); + +out_unlock: + mutex_unlock(&priv->general_reg_lock); + return ret; +} + +static int tusb1046_switch_set(struct typec_switch_dev *sw, + enum typec_orientation orientation) +{ + struct tusb1046_priv *priv = typec_switch_get_drvdata(sw); + struct i2c_client *client = priv->client; + struct device *dev = &client->dev; + int val, ret = 0; + + dev_dbg(dev, "setting USB3.0 lane flip for orientation %d\n", orientation); + + mutex_lock(&priv->general_reg_lock); + + val = i2c_smbus_read_byte_data(client, TUSB1046_REG_GENERAL); + if (val < 0) { + dev_err(dev, "failed to read flipsel status, err %d\n", val); + ret = val; + goto out_unlock; + } + + if (orientation == TYPEC_ORIENTATION_REVERSE) + val |= TUSB1046_GENERAL_FLIPSEL; + else + val &= ~TUSB1046_GENERAL_FLIPSEL; + + ret = i2c_smbus_write_byte_data(client, TUSB1046_REG_GENERAL, val); + +out_unlock: + mutex_unlock(&priv->general_reg_lock); + return ret; +} + +static int tusb1046_i2c_probe(struct i2c_client *client) +{ + struct typec_switch_desc sw_desc = { }; + struct typec_mux_desc mux_desc = { }; + struct device *dev = &client->dev; + struct tusb1046_priv *priv; + int ret = 0; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return dev_err_probe(dev, -ENOMEM, "failed to allocate driver data\n"); + + priv->client = client; + + mutex_init(&priv->general_reg_lock); + + sw_desc.drvdata = priv; + sw_desc.fwnode = dev_fwnode(dev); + sw_desc.set = tusb1046_switch_set; + + priv->sw = typec_switch_register(dev, &sw_desc); + if (IS_ERR(priv->sw)) { + ret = dev_err_probe(dev, PTR_ERR(priv->sw), "failed to register type-c switch\n"); + goto err_destroy_mutex; + } + + mux_desc.drvdata = priv; + mux_desc.fwnode = dev_fwnode(dev); + mux_desc.set = tusb1046_mux_set; + + priv->mux = typec_mux_register(dev, &mux_desc); + if (IS_ERR(priv->mux)) { + ret = dev_err_probe(dev, PTR_ERR(priv->mux), "failed to register type-c mux\n"); + goto err_unregister_switch; + } + + i2c_set_clientdata(client, priv); + + return 0; + +err_unregister_switch: + typec_switch_unregister(priv->sw); +err_destroy_mutex: + mutex_destroy(&priv->general_reg_lock); + return ret; +} + +static void tusb1046_i2c_remove(struct i2c_client *client) +{ + struct tusb1046_priv *priv = i2c_get_clientdata(client); + + typec_switch_unregister(priv->sw); + typec_mux_unregister(priv->mux); + mutex_destroy(&priv->general_reg_lock); +} + +static const struct of_device_id tusb1046_match_table[] = { + {.compatible = "ti,tusb1046"}, + {}, +}; + +static struct i2c_driver tusb1046_driver = { + .driver = { + .name = "tusb1046", + .of_match_table = tusb1046_match_table, + }, + .probe = tusb1046_i2c_probe, + .remove = tusb1046_i2c_remove, +}; + +module_i2c_driver(tusb1046_driver); + +MODULE_DESCRIPTION("TUSB1046 USB Type-C switch driver"); +MODULE_AUTHOR("Romain Gantois "); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/typec/stusb160x.c b/drivers/usb/typec/stusb160x.c index f3140fc04c12e1e6e7baeb6fe59c5101e241613a..6d85b25b40bc0c184faeb7d7d111688460e92aad 100644 --- a/drivers/usb/typec/stusb160x.c +++ b/drivers/usb/typec/stusb160x.c @@ -633,9 +633,8 @@ MODULE_DEVICE_TABLE(of, stusb160x_of_match); static int stusb160x_probe(struct i2c_client *client) { + const struct regmap_config *regmap_config; struct stusb160x *chip; - const struct of_device_id *match; - struct regmap_config *regmap_config; struct fwnode_handle *fwnode; int ret; @@ -645,8 +644,8 @@ static int stusb160x_probe(struct i2c_client *client) i2c_set_clientdata(client, chip); - match = i2c_of_match_device(stusb160x_of_match, client); - regmap_config = (struct regmap_config *)match->data; + regmap_config = i2c_get_match_data(client); + chip->regmap = devm_regmap_init_i2c(client, regmap_config); if (IS_ERR(chip->regmap)) { ret = PTR_ERR(chip->regmap); diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c index b80eb2d78d88b432e227548eeb3e69e40f59b0b2..3766790c1548c7c68c80abeafb0bfe5ab0dc3983 100644 --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c @@ -163,7 +163,7 @@ static struct platform_driver qcom_pmic_typec_driver = { .of_match_table = qcom_pmic_typec_table, }, .probe = qcom_pmic_typec_probe, - .remove_new = qcom_pmic_typec_remove, + .remove = qcom_pmic_typec_remove, }; module_platform_driver(qcom_pmic_typec_driver); diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c b/drivers/usb/typec/tcpm/tcpci_mt6360.c index 02b7fd30226508c27f92706a51440a175994bf3f..881ffacbfd7737c5dbe70a7b82117da7d123ddb8 100644 --- a/drivers/usb/typec/tcpm/tcpci_mt6360.c +++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c @@ -221,7 +221,7 @@ static struct platform_driver mt6360_tcpc_driver = { .of_match_table = mt6360_tcpc_of_id, }, .probe = mt6360_tcpc_probe, - .remove_new = mt6360_tcpc_remove, + .remove = mt6360_tcpc_remove, }; module_platform_driver(mt6360_tcpc_driver); diff --git a/drivers/usb/typec/tcpm/tcpci_mt6370.c b/drivers/usb/typec/tcpm/tcpci_mt6370.c index 9cda1005ef01a5a74a5d82e2218983b7ab482102..1479f961772d0d33bbc3902f6b78d93bebf447c6 100644 --- a/drivers/usb/typec/tcpm/tcpci_mt6370.c +++ b/drivers/usb/typec/tcpm/tcpci_mt6370.c @@ -196,7 +196,7 @@ static struct platform_driver mt6370_tcpc_driver = { .of_match_table = mt6370_tcpc_devid_table, }, .probe = mt6370_tcpc_probe, - .remove_new = mt6370_tcpc_remove, + .remove = mt6370_tcpc_remove, }; module_platform_driver(mt6370_tcpc_driver); diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 7ae341a403424cbc00825ad3c8ac740213ef9193..6021eeb903fec53316dfa2d6b825c334d55b7cab 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -310,6 +310,18 @@ struct pd_data { unsigned int operating_snk_mw; }; +/* + * @sink_wait_cap_time: Deadline (in ms) for tTypeCSinkWaitCap timer + * @ps_src_wait_off_time: Deadline (in ms) for tPSSourceOff timer + * @cc_debounce_time: Deadline (in ms) for tCCDebounce timer + */ +struct pd_timings { + u32 sink_wait_cap_time; + u32 ps_src_off_time; + u32 cc_debounce_time; + u32 snk_bc12_cmpletion_time; +}; + struct tcpm_port { struct device *dev; @@ -552,6 +564,9 @@ struct tcpm_port { */ unsigned int message_id_prime; unsigned int rx_msgid_prime; + + /* Timer deadline values configured at runtime */ + struct pd_timings timings; #ifdef CONFIG_DEBUG_FS struct dentry *dentry; struct mutex logbuffer_lock; /* log buffer access lock */ @@ -4640,15 +4655,15 @@ static void run_state_machine(struct tcpm_port *port) case SRC_ATTACH_WAIT: if (tcpm_port_is_debug(port)) tcpm_set_state(port, DEBUG_ACC_ATTACHED, - PD_T_CC_DEBOUNCE); + port->timings.cc_debounce_time); else if (tcpm_port_is_audio(port)) tcpm_set_state(port, AUDIO_ACC_ATTACHED, - PD_T_CC_DEBOUNCE); + port->timings.cc_debounce_time); else if (tcpm_port_is_source(port) && port->vbus_vsafe0v) tcpm_set_state(port, tcpm_try_snk(port) ? SNK_TRY : SRC_ATTACHED, - PD_T_CC_DEBOUNCE); + port->timings.cc_debounce_time); break; case SNK_TRY: @@ -4699,7 +4714,7 @@ static void run_state_machine(struct tcpm_port *port) } break; case SRC_TRYWAIT_DEBOUNCE: - tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE); + tcpm_set_state(port, SRC_ATTACHED, port->timings.cc_debounce_time); break; case SRC_TRYWAIT_UNATTACHED: tcpm_set_state(port, SNK_UNATTACHED, 0); @@ -4902,7 +4917,7 @@ static void run_state_machine(struct tcpm_port *port) (port->cc1 != TYPEC_CC_OPEN && port->cc2 == TYPEC_CC_OPEN)) tcpm_set_state(port, SNK_DEBOUNCED, - PD_T_CC_DEBOUNCE); + port->timings.cc_debounce_time); else if (tcpm_port_is_disconnected(port)) tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE); @@ -4942,7 +4957,7 @@ static void run_state_machine(struct tcpm_port *port) break; case SNK_TRYWAIT: tcpm_set_cc(port, TYPEC_CC_RD); - tcpm_set_state(port, SNK_TRYWAIT_VBUS, PD_T_CC_DEBOUNCE); + tcpm_set_state(port, SNK_TRYWAIT_VBUS, port->timings.cc_debounce_time); break; case SNK_TRYWAIT_VBUS: /* @@ -4965,7 +4980,16 @@ static void run_state_machine(struct tcpm_port *port) if (ret < 0) tcpm_set_state(port, SNK_UNATTACHED, 0); else - tcpm_set_state(port, SNK_STARTUP, 0); + /* + * For Type C port controllers that use Battery Charging + * Detection (based on BCv1.2 spec) to detect USB + * charger type, add a delay of "snk_bc12_cmpletion_time" + * before transitioning to SNK_STARTUP to allow BC1.2 + * detection to complete before PD is eventually enabled + * in later states. + */ + tcpm_set_state(port, SNK_STARTUP, + port->timings.snk_bc12_cmpletion_time); break; case SNK_STARTUP: opmode = tcpm_get_pwr_opmode(port->polarity ? @@ -5015,7 +5039,7 @@ static void run_state_machine(struct tcpm_port *port) break; case SNK_DISCOVERY_DEBOUNCE: tcpm_set_state(port, SNK_DISCOVERY_DEBOUNCE_DONE, - PD_T_CC_DEBOUNCE); + port->timings.cc_debounce_time); break; case SNK_DISCOVERY_DEBOUNCE_DONE: if (!tcpm_port_is_disconnected(port) && @@ -5042,13 +5066,14 @@ static void run_state_machine(struct tcpm_port *port) if (port->vbus_never_low) { port->vbus_never_low = false; tcpm_set_state(port, SNK_SOFT_RESET, - PD_T_SINK_WAIT_CAP); + port->timings.sink_wait_cap_time); } else { if (!port->self_powered) upcoming_state = SNK_WAIT_CAPABILITIES_TIMEOUT; else upcoming_state = hard_reset_state(port); - tcpm_set_state(port, upcoming_state, PD_T_SINK_WAIT_CAP); + tcpm_set_state(port, SNK_WAIT_CAPABILITIES_TIMEOUT, + port->timings.sink_wait_cap_time); } break; case SNK_WAIT_CAPABILITIES_TIMEOUT: @@ -5070,7 +5095,8 @@ static void run_state_machine(struct tcpm_port *port) if (tcpm_pd_send_control(port, PD_CTRL_GET_SOURCE_CAP, TCPC_TX_SOP)) tcpm_set_state_cond(port, hard_reset_state(port), 0); else - tcpm_set_state(port, hard_reset_state(port), PD_T_SINK_WAIT_CAP); + tcpm_set_state(port, hard_reset_state(port), + port->timings.sink_wait_cap_time); break; case SNK_NEGOTIATE_CAPABILITIES: port->pd_capable = true; @@ -5207,7 +5233,7 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, ACC_UNATTACHED, 0); break; case AUDIO_ACC_DEBOUNCE: - tcpm_set_state(port, ACC_UNATTACHED, PD_T_CC_DEBOUNCE); + tcpm_set_state(port, ACC_UNATTACHED, port->timings.cc_debounce_time); break; /* Hard_Reset states */ @@ -5274,7 +5300,7 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, SRC_UNATTACHED, PD_T_PS_SOURCE_ON); break; case SNK_HARD_RESET_SINK_OFF: - /* Do not discharge/disconnect during hard reseet */ + /* Do not discharge/disconnect during hard reset */ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0); memset(&port->pps_data, 0, sizeof(port->pps_data)); tcpm_set_vconn(port, false); @@ -5424,7 +5450,7 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, ERROR_RECOVERY, 0); break; case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF: - tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_OFF); + tcpm_set_state(port, ERROR_RECOVERY, port->timings.ps_src_off_time); break; case FR_SWAP_SNK_SRC_NEW_SINK_READY: if (port->vbus_source) @@ -5479,7 +5505,7 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_cc(port, TYPEC_CC_RD); /* allow CC debounce */ tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED, - PD_T_CC_DEBOUNCE); + port->timings.cc_debounce_time); break; case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: /* @@ -5514,7 +5540,7 @@ static void run_state_machine(struct tcpm_port *port) port->pps_data.active, 0); tcpm_set_charge(port, false); tcpm_set_state(port, hard_reset_state(port), - PD_T_PS_SOURCE_OFF); + port->timings.ps_src_off_time); break; case PR_SWAP_SNK_SRC_SOURCE_ON: tcpm_enable_auto_vbus_discharge(port, true); @@ -5670,7 +5696,7 @@ static void run_state_machine(struct tcpm_port *port) case PORT_RESET_WAIT_OFF: tcpm_set_state(port, tcpm_default_state(port), - port->vbus_present ? PD_T_PS_SOURCE_OFF : 0); + port->vbus_present ? port->timings.ps_src_off_time : 0); break; /* AMS intermediate state */ @@ -6070,7 +6096,7 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) break; case SNK_ATTACH_WAIT: case SNK_DEBOUNCED: - /* Do nothing, as TCPM is still waiting for vbus to reaach VSAFE5V to connect */ + /* Do nothing, as TCPM is still waiting for vbus to reach VSAFE5V to connect */ break; case SNK_NEGOTIATE_CAPABILITIES: @@ -6161,7 +6187,7 @@ static void _tcpm_pd_vbus_vsafe0v(struct tcpm_port *port) case SRC_ATTACH_WAIT: if (tcpm_port_is_source(port)) tcpm_set_state(port, tcpm_try_snk(port) ? SNK_TRY : SRC_ATTACHED, - PD_T_CC_DEBOUNCE); + port->timings.cc_debounce_time); break; case SRC_STARTUP: case SRC_SEND_CAPABILITIES: @@ -7057,6 +7083,34 @@ err_unregister: return ret; } +static void tcpm_fw_get_timings(struct tcpm_port *port, struct fwnode_handle *fwnode) +{ + int ret; + u32 val; + + ret = fwnode_property_read_u32(fwnode, "sink-wait-cap-time-ms", &val); + if (!ret) + port->timings.sink_wait_cap_time = val; + else + port->timings.sink_wait_cap_time = PD_T_SINK_WAIT_CAP; + + ret = fwnode_property_read_u32(fwnode, "ps-source-off-time-ms", &val); + if (!ret) + port->timings.ps_src_off_time = val; + else + port->timings.ps_src_off_time = PD_T_PS_SOURCE_OFF; + + ret = fwnode_property_read_u32(fwnode, "cc-debounce-time-ms", &val); + if (!ret) + port->timings.cc_debounce_time = val; + else + port->timings.cc_debounce_time = PD_T_CC_DEBOUNCE; + + ret = fwnode_property_read_u32(fwnode, "sink-bc12-completion-time-ms", &val); + if (!ret) + port->timings.snk_bc12_cmpletion_time = val; +} + static int tcpm_fw_get_caps(struct tcpm_port *port, struct fwnode_handle *fwnode) { struct fwnode_handle *capabilities, *child, *caps = NULL; @@ -7371,7 +7425,7 @@ static int tcpm_psy_get_input_power_limit(struct tcpm_port *port, src_mv = pdo_fixed_voltage(pdo); src_ma = pdo_max_current(pdo); tmp = src_mv * src_ma; - max_src_uw = tmp > max_src_uw ? tmp : max_src_uw; + max_src_uw = max(tmp, max_src_uw); } } @@ -7614,6 +7668,8 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) if (err < 0) goto out_destroy_wq; + tcpm_fw_get_timings(port, tcpc->fwnode); + port->try_role = port->typec_caps.prefer_role; port->typec_caps.revision = 0x0120; /* Type-C spec release 1.2 */ diff --git a/drivers/usb/typec/tcpm/wcove.c b/drivers/usb/typec/tcpm/wcove.c index 60b2766a69bf8a448acbfb2941d1dd36826adfd6..759c982bb16a9aad31ff84048130d3d4a550643c 100644 --- a/drivers/usb/typec/tcpm/wcove.c +++ b/drivers/usb/typec/tcpm/wcove.c @@ -687,7 +687,7 @@ static struct platform_driver wcove_typec_driver = { .name = "bxt_wcove_usbc", }, .probe = wcove_typec_probe, - .remove_new = wcove_typec_remove, + .remove = wcove_typec_remove, }; module_platform_driver(wcove_typec_driver); diff --git a/drivers/usb/typec/ucsi/debugfs.c b/drivers/usb/typec/ucsi/debugfs.c index f67733cecfdf5d2b19a1dc8cfb40f78b901bbd11..83ff23086d79487200194b8fa157a49e3935cc1b 100644 --- a/drivers/usb/typec/ucsi/debugfs.c +++ b/drivers/usb/typec/ucsi/debugfs.c @@ -32,6 +32,7 @@ static int ucsi_cmd(void *data, u64 val) case UCSI_SET_UOR: case UCSI_SET_PDR: case UCSI_CONNECTOR_RESET: + case UCSI_SET_SINK_PATH: ret = ucsi_send_command(ucsi, val, NULL, 0); break; case UCSI_GET_CAPABILITY: diff --git a/drivers/usb/typec/ucsi/psy.c b/drivers/usb/typec/ucsi/psy.c index 1c631c7855a9606c82a885b3a4b00998cd2420d2..62ac69730405029498107904dddef9741d923225 100644 --- a/drivers/usb/typec/ucsi/psy.c +++ b/drivers/usb/typec/ucsi/psy.c @@ -55,8 +55,8 @@ static int ucsi_psy_get_online(struct ucsi_connector *con, union power_supply_propval *val) { val->intval = UCSI_PSY_OFFLINE; - if (con->status.flags & UCSI_CONSTAT_CONNECTED && - (con->status.flags & UCSI_CONSTAT_PWR_DIR) == TYPEC_SINK) + if (UCSI_CONSTAT(con, CONNECTED) && + (UCSI_CONSTAT(con, PWR_DIR) == TYPEC_SINK)) val->intval = UCSI_PSY_FIXED_ONLINE; return 0; } @@ -66,7 +66,7 @@ static int ucsi_psy_get_voltage_min(struct ucsi_connector *con, { u32 pdo; - switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: pdo = con->src_pdos[0]; val->intval = pdo_fixed_voltage(pdo) * 1000; @@ -89,7 +89,7 @@ static int ucsi_psy_get_voltage_max(struct ucsi_connector *con, { u32 pdo; - switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: if (con->num_pdos > 0) { pdo = con->src_pdos[con->num_pdos - 1]; @@ -117,7 +117,7 @@ static int ucsi_psy_get_voltage_now(struct ucsi_connector *con, int index; u32 pdo; - switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: index = rdo_index(con->rdo); if (index > 0) { @@ -145,7 +145,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, { u32 pdo; - switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: if (con->num_pdos > 0) { pdo = con->src_pdos[con->num_pdos - 1]; @@ -173,9 +173,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, static int ucsi_psy_get_current_now(struct ucsi_connector *con, union power_supply_propval *val) { - u16 flags = con->status.flags; - - if (UCSI_CONSTAT_PWR_OPMODE(flags) == UCSI_CONSTAT_PWR_OPMODE_PD) + if (UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD) val->intval = rdo_op_current(con->rdo) * 1000; else val->intval = 0; @@ -185,11 +183,9 @@ static int ucsi_psy_get_current_now(struct ucsi_connector *con, static int ucsi_psy_get_usb_type(struct ucsi_connector *con, union power_supply_propval *val) { - u16 flags = con->status.flags; - val->intval = POWER_SUPPLY_USB_TYPE_C; - if (flags & UCSI_CONSTAT_CONNECTED && - UCSI_CONSTAT_PWR_OPMODE(flags) == UCSI_CONSTAT_PWR_OPMODE_PD) + if (UCSI_CONSTAT(con, CONNECTED) && + UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD) val->intval = POWER_SUPPLY_USB_TYPE_PD; return 0; @@ -197,18 +193,18 @@ static int ucsi_psy_get_usb_type(struct ucsi_connector *con, static int ucsi_psy_get_charge_type(struct ucsi_connector *con, union power_supply_propval *val) { - if (!(con->status.flags & UCSI_CONSTAT_CONNECTED)) { + if (!(UCSI_CONSTAT(con, CONNECTED))) { val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; return 0; } /* The Battery Charging Cabability Status field is only valid in sink role. */ - if ((con->status.flags & UCSI_CONSTAT_PWR_DIR) != TYPEC_SINK) { + if (UCSI_CONSTAT(con, PWR_DIR) != TYPEC_SINK) { val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; return 0; } - switch (UCSI_CONSTAT_BC_STATUS(con->status.pwr_status)) { + switch (UCSI_CONSTAT(con, BC_STATUS)) { case UCSI_CONSTAT_BC_NOMINAL_CHARGING: val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD; break; diff --git a/drivers/usb/typec/ucsi/trace.h b/drivers/usb/typec/ucsi/trace.h index a0d3a934d3d92411ec3f588e1309d1080d05e47f..41701dee70564b1c08baef379d4617cda3d82312 100644 --- a/drivers/usb/typec/ucsi/trace.h +++ b/drivers/usb/typec/ucsi/trace.h @@ -40,8 +40,8 @@ DEFINE_EVENT(ucsi_log_command, ucsi_reset_ppm, ); DECLARE_EVENT_CLASS(ucsi_log_connector_status, - TP_PROTO(int port, struct ucsi_connector_status *status), - TP_ARGS(port, status), + TP_PROTO(int port, struct ucsi_connector *con), + TP_ARGS(port, con), TP_STRUCT__entry( __field(int, port) __field(u16, change) @@ -55,14 +55,14 @@ DECLARE_EVENT_CLASS(ucsi_log_connector_status, ), TP_fast_assign( __entry->port = port - 1; - __entry->change = status->change; - __entry->opmode = UCSI_CONSTAT_PWR_OPMODE(status->flags); - __entry->connected = !!(status->flags & UCSI_CONSTAT_CONNECTED); - __entry->pwr_dir = !!(status->flags & UCSI_CONSTAT_PWR_DIR); - __entry->partner_flags = UCSI_CONSTAT_PARTNER_FLAGS(status->flags); - __entry->partner_type = UCSI_CONSTAT_PARTNER_TYPE(status->flags); - __entry->request_data_obj = status->request_data_obj; - __entry->bc_status = UCSI_CONSTAT_BC_STATUS(status->pwr_status); + __entry->change = UCSI_CONSTAT(con, CHANGE); + __entry->opmode = UCSI_CONSTAT(con, PWR_OPMODE); + __entry->connected = UCSI_CONSTAT(con, CONNECTED); + __entry->pwr_dir = UCSI_CONSTAT(con, PWR_DIR); + __entry->partner_flags = UCSI_CONSTAT(con, PARTNER_FLAGS); + __entry->partner_type = UCSI_CONSTAT(con, PARTNER_TYPE); + __entry->request_data_obj = UCSI_CONSTAT(con, RDO); + __entry->bc_status = UCSI_CONSTAT(con, BC_STATUS); ), TP_printk("port%d status: change=%04x, opmode=%x, connected=%d, " "sourcing=%d, partner_flags=%x, partner_type=%x, " @@ -73,13 +73,13 @@ DECLARE_EVENT_CLASS(ucsi_log_connector_status, ); DEFINE_EVENT(ucsi_log_connector_status, ucsi_connector_change, - TP_PROTO(int port, struct ucsi_connector_status *status), - TP_ARGS(port, status) + TP_PROTO(int port, struct ucsi_connector *con), + TP_ARGS(port, con) ); DEFINE_EVENT(ucsi_log_connector_status, ucsi_register_port, - TP_PROTO(int port, struct ucsi_connector_status *status), - TP_ARGS(port, status) + TP_PROTO(int port, struct ucsi_connector *con), + TP_ARGS(port, con) ); DECLARE_EVENT_CLASS(ucsi_log_register_altmode, diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index e0f3925e401b3d6acf794754a0255c32fe8f01b9..c435c0835744ad71cffe6d99630c1eeb1176d072 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -648,6 +648,17 @@ static void ucsi_unregister_altmodes(struct ucsi_connector *con, u8 recipient) } } +static int ucsi_get_connector_status(struct ucsi_connector *con, bool conn_ack) +{ + u64 command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num); + size_t size = min(UCSI_GET_CONNECTOR_STATUS_SIZE, UCSI_MAX_DATA_LENGTH(con->ucsi)); + int ret; + + ret = ucsi_send_command_common(con->ucsi, command, &con->status, size, conn_ack); + + return ret < 0 ? ret : 0; +} + static int ucsi_read_pdos(struct ucsi_connector *con, enum typec_role role, int is_partner, u32 *pdos, int offset, int num_pdos) @@ -658,8 +669,7 @@ static int ucsi_read_pdos(struct ucsi_connector *con, if (is_partner && ucsi->quirks & UCSI_NO_PARTNER_PDOS && - ((con->status.flags & UCSI_CONSTAT_PWR_DIR) || - !is_source(role))) + (UCSI_CONSTAT(con, PWR_DIR) || !is_source(role))) return 0; command = UCSI_COMMAND(UCSI_GET_PDOS) | UCSI_CONNECTOR_NUMBER(con->num); @@ -973,6 +983,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) static int ucsi_check_connector_capability(struct ucsi_connector *con) { + u64 pd_revision; u64 command; int ret; @@ -986,17 +997,17 @@ static int ucsi_check_connector_capability(struct ucsi_connector *con) return ret; } - typec_partner_set_pd_revision(con->partner, - UCSI_CONCAP_FLAG_PARTNER_PD_MAJOR_REV_AS_BCD(con->cap.flags)); + pd_revision = UCSI_CONCAP(con, PARTNER_PD_REVISION_V2_1); + typec_partner_set_pd_revision(con->partner, UCSI_SPEC_REVISION_TO_BCD(pd_revision)); return ret; } static void ucsi_pwr_opmode_change(struct ucsi_connector *con) { - switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: - con->rdo = con->status.request_data_obj; + con->rdo = UCSI_CONSTAT(con, RDO); typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_PD); ucsi_partner_task(con, ucsi_get_src_pdos, 30, 0); ucsi_partner_task(con, ucsi_check_altmodes, 30, HZ); @@ -1020,7 +1031,7 @@ static void ucsi_pwr_opmode_change(struct ucsi_connector *con) static int ucsi_register_partner(struct ucsi_connector *con) { - u8 pwr_opmode = UCSI_CONSTAT_PWR_OPMODE(con->status.flags); + u8 pwr_opmode = UCSI_CONSTAT(con, PWR_OPMODE); struct typec_partner_desc desc; struct typec_partner *partner; @@ -1029,7 +1040,7 @@ static int ucsi_register_partner(struct ucsi_connector *con) memset(&desc, 0, sizeof(desc)); - switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PARTNER_TYPE)) { case UCSI_CONSTAT_PARTNER_TYPE_DEBUG: desc.accessory = TYPEC_ACCESSORY_DEBUG; break; @@ -1047,6 +1058,11 @@ static int ucsi_register_partner(struct ucsi_connector *con) desc.identity = &con->partner_identity; desc.usb_pd = pwr_opmode == UCSI_CONSTAT_PWR_OPMODE_PD; + if (con->ucsi->version >= UCSI_VERSION_2_1) { + u64 pd_revision = UCSI_CONCAP(con, PARTNER_PD_REVISION_V2_1); + desc.pd_revision = UCSI_SPEC_REVISION_TO_BCD(pd_revision); + } + partner = typec_register_partner(con->port, &desc); if (IS_ERR(partner)) { dev_err(con->ucsi->dev, @@ -1057,6 +1073,13 @@ static int ucsi_register_partner(struct ucsi_connector *con) con->partner = partner; + if (con->ucsi->version >= UCSI_VERSION_3_0 && + UCSI_CONSTAT(con, PARTNER_FLAG_USB4_GEN4)) + typec_partner_set_usb_mode(partner, USB_MODE_USB4); + else if (con->ucsi->version >= UCSI_VERSION_2_0 && + UCSI_CONSTAT(con, PARTNER_FLAG_USB4_GEN3)) + typec_partner_set_usb_mode(partner, USB_MODE_USB4); + return 0; } @@ -1081,7 +1104,7 @@ static void ucsi_partner_change(struct ucsi_connector *con) enum usb_role u_role = USB_ROLE_NONE; int ret; - switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PARTNER_TYPE)) { case UCSI_CONSTAT_PARTNER_TYPE_UFP: case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: u_role = USB_ROLE_HOST; @@ -1097,8 +1120,8 @@ static void ucsi_partner_change(struct ucsi_connector *con) break; } - if (con->status.flags & UCSI_CONSTAT_CONNECTED) { - switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + if (UCSI_CONSTAT(con, CONNECTED)) { + switch (UCSI_CONSTAT(con, PARTNER_TYPE)) { case UCSI_CONSTAT_PARTNER_TYPE_DEBUG: typec_set_mode(con->port, TYPEC_MODE_DEBUG); break; @@ -1106,14 +1129,13 @@ static void ucsi_partner_change(struct ucsi_connector *con) typec_set_mode(con->port, TYPEC_MODE_AUDIO); break; default: - if (UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) == - UCSI_CONSTAT_PARTNER_FLAG_USB) + if (UCSI_CONSTAT(con, PARTNER_FLAG_USB)) typec_set_mode(con->port, TYPEC_STATE_USB); } } /* Only notify USB controller if partner supports USB data */ - if (!(UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) & UCSI_CONSTAT_PARTNER_FLAG_USB)) + if (!(UCSI_CONSTAT(con, PARTNER_FLAG_USB))) u_role = USB_ROLE_NONE; ret = usb_role_switch_set_role(con->usb_role_sw, u_role); @@ -1124,21 +1146,18 @@ static void ucsi_partner_change(struct ucsi_connector *con) static int ucsi_check_connection(struct ucsi_connector *con) { - u8 prev_flags = con->status.flags; - u64 command; + u8 prev_state = UCSI_CONSTAT(con, CONNECTED); int ret; - command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num); - ret = ucsi_send_command(con->ucsi, command, &con->status, sizeof(con->status)); - if (ret < 0) { + ret = ucsi_get_connector_status(con, false); + if (ret) { dev_err(con->ucsi->dev, "GET_CONNECTOR_STATUS failed (%d)\n", ret); return ret; } - if (con->status.flags == prev_flags) - return 0; - - if (con->status.flags & UCSI_CONSTAT_CONNECTED) { + if (UCSI_CONSTAT(con, CONNECTED)) { + if (prev_state) + return 0; ucsi_register_partner(con); ucsi_pwr_opmode_change(con); ucsi_partner_change(con); @@ -1194,7 +1213,7 @@ static void ucsi_handle_connector_change(struct work_struct *work) work); struct ucsi *ucsi = con->ucsi; enum typec_role role; - u64 command; + u16 change; int ret; mutex_lock(&con->lock); @@ -1203,25 +1222,23 @@ static void ucsi_handle_connector_change(struct work_struct *work) dev_err_once(ucsi->dev, "%s entered without EVENT_PENDING\n", __func__); - command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num); - - ret = ucsi_send_command_common(ucsi, command, &con->status, - sizeof(con->status), true); - if (ret < 0) { + ret = ucsi_get_connector_status(con, true); + if (ret) { dev_err(ucsi->dev, "%s: GET_CONNECTOR_STATUS failed (%d)\n", __func__, ret); clear_bit(EVENT_PENDING, &con->ucsi->flags); goto out_unlock; } - trace_ucsi_connector_change(con->num, &con->status); + trace_ucsi_connector_change(con->num, con); if (ucsi->ops->connector_status) ucsi->ops->connector_status(con); - role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR); + change = UCSI_CONSTAT(con, CHANGE); + role = UCSI_CONSTAT(con, PWR_DIR); - if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) { + if (change & UCSI_CONSTAT_POWER_DIR_CHANGE) { typec_set_pwr_role(con->port, role); /* Complete pending power role swap */ @@ -1229,12 +1246,12 @@ static void ucsi_handle_connector_change(struct work_struct *work) complete(&con->complete); } - if (con->status.change & UCSI_CONSTAT_CONNECT_CHANGE) { + if (change & UCSI_CONSTAT_CONNECT_CHANGE) { typec_set_pwr_role(con->port, role); ucsi_port_psy_changed(con); ucsi_partner_change(con); - if (con->status.flags & UCSI_CONSTAT_CONNECTED) { + if (UCSI_CONSTAT(con, CONNECTED)) { ucsi_register_partner(con); ucsi_partner_task(con, ucsi_check_connection, 1, HZ); if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE) @@ -1242,8 +1259,7 @@ static void ucsi_handle_connector_change(struct work_struct *work) if (con->ucsi->cap.features & UCSI_CAP_CABLE_DETAILS) ucsi_partner_task(con, ucsi_check_cable, 1, HZ); - if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) == - UCSI_CONSTAT_PWR_OPMODE_PD) { + if (UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD) { ucsi_partner_task(con, ucsi_register_partner_pdos, 1, HZ); ucsi_partner_task(con, ucsi_check_connector_capability, 1, HZ); } @@ -1252,11 +1268,10 @@ static void ucsi_handle_connector_change(struct work_struct *work) } } - if (con->status.change & UCSI_CONSTAT_POWER_OPMODE_CHANGE || - con->status.change & UCSI_CONSTAT_POWER_LEVEL_CHANGE) + if (change & (UCSI_CONSTAT_POWER_OPMODE_CHANGE | UCSI_CONSTAT_POWER_LEVEL_CHANGE)) ucsi_pwr_opmode_change(con); - if (con->partner && con->status.change & UCSI_CONSTAT_PARTNER_CHANGE) { + if (con->partner && (change & UCSI_CONSTAT_PARTNER_CHANGE)) { ucsi_partner_change(con); /* Complete pending data role swap */ @@ -1264,10 +1279,10 @@ static void ucsi_handle_connector_change(struct work_struct *work) complete(&con->complete); } - if (con->status.change & UCSI_CONSTAT_CAM_CHANGE) + if (change & UCSI_CONSTAT_CAM_CHANGE) ucsi_partner_task(con, ucsi_check_altmodes, 1, HZ); - if (con->status.change & UCSI_CONSTAT_BC_CHANGE) + if (change & UCSI_CONSTAT_BC_CHANGE) ucsi_port_psy_changed(con); out_unlock: @@ -1427,7 +1442,7 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role) goto out_unlock; } - partner_type = UCSI_CONSTAT_PARTNER_TYPE(con->status.flags); + partner_type = UCSI_CONSTAT(con, PARTNER_TYPE); if ((partner_type == UCSI_CONSTAT_PARTNER_TYPE_DFP && role == TYPEC_DEVICE) || (partner_type == UCSI_CONSTAT_PARTNER_TYPE_UFP && @@ -1471,7 +1486,7 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) goto out_unlock; } - cur_role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR); + cur_role = UCSI_CONSTAT(con, PWR_DIR); if (cur_role == role) goto out_unlock; @@ -1494,8 +1509,7 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) mutex_lock(&con->lock); /* Something has gone wrong while swapping the role */ - if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) != - UCSI_CONSTAT_PWR_OPMODE_PD) { + if (UCSI_CONSTAT(con, PWR_OPMODE) != UCSI_CONSTAT_PWR_OPMODE_PD) { ucsi_reset_connector(con, true); ret = -EPROTO; } @@ -1563,19 +1577,18 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) if (ret < 0) goto out_unlock; - if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DRP) + if (UCSI_CONCAP(con, OPMODE_DRP)) cap->data = TYPEC_PORT_DRD; - else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DFP) + else if (UCSI_CONCAP(con, OPMODE_DFP)) cap->data = TYPEC_PORT_DFP; - else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_UFP) + else if (UCSI_CONCAP(con, OPMODE_UFP)) cap->data = TYPEC_PORT_UFP; - if ((con->cap.flags & UCSI_CONCAP_FLAG_PROVIDER) && - (con->cap.flags & UCSI_CONCAP_FLAG_CONSUMER)) + if (UCSI_CONCAP(con, PROVIDER) && UCSI_CONCAP(con, CONSUMER)) cap->type = TYPEC_PORT_DRP; - else if (con->cap.flags & UCSI_CONCAP_FLAG_PROVIDER) + else if (UCSI_CONCAP(con, PROVIDER)) cap->type = TYPEC_PORT_SRC; - else if (con->cap.flags & UCSI_CONCAP_FLAG_CONSUMER) + else if (UCSI_CONCAP(con, CONSUMER)) cap->type = TYPEC_PORT_SNK; cap->revision = ucsi->cap.typec_version; @@ -1583,11 +1596,18 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) cap->svdm_version = SVDM_VER_2_0; cap->prefer_role = TYPEC_NO_PREFERRED_ROLE; - if (con->cap.op_mode & UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY) + if (UCSI_CONCAP(con, OPMODE_AUDIO_ACCESSORY)) *accessory++ = TYPEC_ACCESSORY_AUDIO; - if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY) + if (UCSI_CONCAP(con, OPMODE_DEBUG_ACCESSORY)) *accessory = TYPEC_ACCESSORY_DEBUG; + if (UCSI_CONCAP_USB2_SUPPORT(con)) + cap->usb_capability |= USB_CAPABILITY_USB2; + if (UCSI_CONCAP_USB3_SUPPORT(con)) + cap->usb_capability |= USB_CAPABILITY_USB3; + if (UCSI_CONCAP_USB4_SUPPORT(con)) + cap->usb_capability |= USB_CAPABILITY_USB4; + cap->driver_data = con; cap->ops = &ucsi_ops; @@ -1617,19 +1637,16 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) } /* Get the status */ - command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num); - ret = ucsi_send_command(ucsi, command, &con->status, sizeof(con->status)); - if (ret < 0) { + ret = ucsi_get_connector_status(con, false); + if (ret) { dev_err(ucsi->dev, "con%d: failed to get status\n", con->num); - ret = 0; goto out; } - ret = 0; /* ucsi_send_command() returns length on success */ if (ucsi->ops->connector_status) ucsi->ops->connector_status(con); - switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + switch (UCSI_CONSTAT(con, PARTNER_TYPE)) { case UCSI_CONSTAT_PARTNER_TYPE_UFP: case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: u_role = USB_ROLE_HOST; @@ -1646,9 +1663,8 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) } /* Check if there is already something connected */ - if (con->status.flags & UCSI_CONSTAT_CONNECTED) { - typec_set_pwr_role(con->port, - !!(con->status.flags & UCSI_CONSTAT_PWR_DIR)); + if (UCSI_CONSTAT(con, CONNECTED)) { + typec_set_pwr_role(con->port, UCSI_CONSTAT(con, PWR_DIR)); ucsi_register_partner(con); ucsi_pwr_opmode_change(con); ucsi_port_psy_changed(con); @@ -1659,7 +1675,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) } /* Only notify USB controller if partner supports USB data */ - if (!(UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) & UCSI_CONSTAT_PARTNER_FLAG_USB)) + if (!(UCSI_CONSTAT(con, PARTNER_FLAG_USB))) u_role = USB_ROLE_NONE; ret = usb_role_switch_set_role(con->usb_role_sw, u_role); @@ -1669,16 +1685,14 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) ret = 0; } - if (con->partner && - UCSI_CONSTAT_PWR_OPMODE(con->status.flags) == - UCSI_CONSTAT_PWR_OPMODE_PD) { + if (con->partner && UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD) { ucsi_register_device_pdos(con); ucsi_get_src_pdos(con); ucsi_check_altmodes(con); ucsi_check_connector_capability(con); } - trace_ucsi_register_port(con->num, &con->status); + trace_ucsi_register_port(con->num, con); out: fwnode_handle_put(cap->fwnode); @@ -1761,7 +1775,8 @@ static int ucsi_init(struct ucsi *ucsi) /* Get PPM capabilities */ command = UCSI_GET_CAPABILITY; - ret = ucsi_send_command(ucsi, command, &ucsi->cap, sizeof(ucsi->cap)); + ret = ucsi_send_command(ucsi, command, &ucsi->cap, + BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE)); if (ret < 0) goto err_reset; diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 1cf5aad4c23a9e70230449774a89573636fed164..5ff369c24a2fc445e8559201d563c31d83b2c876 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -4,6 +4,7 @@ #define __DRIVER_USB_TYPEC_UCSI_H #include +#include #include #include #include @@ -95,26 +96,31 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num); /* -------------------------------------------------------------------------- */ /* Commands */ -#define UCSI_PPM_RESET 0x01 -#define UCSI_CANCEL 0x02 -#define UCSI_CONNECTOR_RESET 0x03 -#define UCSI_ACK_CC_CI 0x04 -#define UCSI_SET_NOTIFICATION_ENABLE 0x05 -#define UCSI_GET_CAPABILITY 0x06 -#define UCSI_GET_CONNECTOR_CAPABILITY 0x07 -#define UCSI_SET_UOM 0x08 -#define UCSI_SET_UOR 0x09 -#define UCSI_SET_PDM 0x0a -#define UCSI_SET_PDR 0x0b -#define UCSI_GET_ALTERNATE_MODES 0x0c -#define UCSI_GET_CAM_SUPPORTED 0x0d -#define UCSI_GET_CURRENT_CAM 0x0e -#define UCSI_SET_NEW_CAM 0x0f -#define UCSI_GET_PDOS 0x10 -#define UCSI_GET_CABLE_PROPERTY 0x11 -#define UCSI_GET_CONNECTOR_STATUS 0x12 -#define UCSI_GET_ERROR_STATUS 0x13 -#define UCSI_GET_PD_MESSAGE 0x15 +#define UCSI_PPM_RESET 0x01 +#define UCSI_CANCEL 0x02 +#define UCSI_CONNECTOR_RESET 0x03 +#define UCSI_ACK_CC_CI 0x04 +#define UCSI_SET_NOTIFICATION_ENABLE 0x05 +#define UCSI_GET_CAPABILITY 0x06 +#define UCSI_GET_CAPABILITY_SIZE 128 +#define UCSI_GET_CONNECTOR_CAPABILITY 0x07 +#define UCSI_GET_CONNECTOR_CAPABILITY_SIZE 32 +#define UCSI_SET_UOM 0x08 +#define UCSI_SET_UOR 0x09 +#define UCSI_SET_PDM 0x0a +#define UCSI_SET_PDR 0x0b +#define UCSI_GET_ALTERNATE_MODES 0x0c +#define UCSI_GET_CAM_SUPPORTED 0x0d +#define UCSI_GET_CURRENT_CAM 0x0e +#define UCSI_SET_NEW_CAM 0x0f +#define UCSI_GET_PDOS 0x10 +#define UCSI_GET_CABLE_PROPERTY 0x11 +#define UCSI_GET_CABLE_PROPERTY_SIZE 64 +#define UCSI_GET_CONNECTOR_STATUS 0x12 +#define UCSI_GET_CONNECTOR_STATUS_SIZE 152 +#define UCSI_GET_ERROR_STATUS 0x13 +#define UCSI_GET_PD_MESSAGE 0x15 +#define UCSI_SET_SINK_PATH 0x1c #define UCSI_CONNECTOR_NUMBER(_num_) ((u64)(_num_) << 16) #define UCSI_COMMAND(_cmd_) ((_cmd_) & 0xff) @@ -126,7 +132,6 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num); #define UCSI_CONNECTOR_RESET_HARD_VER_1_0 BIT(23) /* Deprecated in v1.1 */ #define UCSI_CONNECTOR_RESET_DATA_VER_2_0 BIT(23) /* Redefined in v2.0 */ - /* ACK_CC_CI bits */ #define UCSI_ACK_CONNECTOR_CHANGE BIT(16) #define UCSI_ACK_COMMAND_COMPLETE BIT(17) @@ -250,42 +255,6 @@ struct ucsi_capability { u16 typec_version; } __packed; -/* Data structure filled by PPM in response to GET_CONNECTOR_CAPABILITY cmd. */ -struct ucsi_connector_capability { - u8 op_mode; -#define UCSI_CONCAP_OPMODE_DFP BIT(0) -#define UCSI_CONCAP_OPMODE_UFP BIT(1) -#define UCSI_CONCAP_OPMODE_DRP BIT(2) -#define UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY BIT(3) -#define UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY BIT(4) -#define UCSI_CONCAP_OPMODE_USB2 BIT(5) -#define UCSI_CONCAP_OPMODE_USB3 BIT(6) -#define UCSI_CONCAP_OPMODE_ALT_MODE BIT(7) - u32 flags; -#define UCSI_CONCAP_FLAG_PROVIDER BIT(0) -#define UCSI_CONCAP_FLAG_CONSUMER BIT(1) -#define UCSI_CONCAP_FLAG_SWAP_TO_DFP BIT(2) -#define UCSI_CONCAP_FLAG_SWAP_TO_UFP BIT(3) -#define UCSI_CONCAP_FLAG_SWAP_TO_SRC BIT(4) -#define UCSI_CONCAP_FLAG_SWAP_TO_SINK BIT(5) -#define UCSI_CONCAP_FLAG_EX_OP_MODE(_f_) \ - (((_f_) & GENMASK(13, 6)) >> 6) -#define UCSI_CONCAP_EX_OP_MODE_USB4_GEN2 BIT(0) -#define UCSI_CONCAP_EX_OP_MODE_EPR_SRC BIT(1) -#define UCSI_CONCAP_EX_OP_MODE_EPR_SINK BIT(2) -#define UCSI_CONCAP_EX_OP_MODE_USB4_GEN3 BIT(3) -#define UCSI_CONCAP_EX_OP_MODE_USB4_GEN4 BIT(4) -#define UCSI_CONCAP_FLAG_MISC_CAPS(_f_) \ - (((_f_) & GENMASK(17, 14)) >> 14) -#define UCSI_CONCAP_MISC_CAP_FW_UPDATE BIT(0) -#define UCSI_CONCAP_MISC_CAP_SECURITY BIT(1) -#define UCSI_CONCAP_FLAG_REV_CURR_PROT_SUPPORT BIT(18) -#define UCSI_CONCAP_FLAG_PARTNER_PD_MAJOR_REV(_f_) \ - (((_f_) & GENMASK(20, 19)) >> 19) -#define UCSI_CONCAP_FLAG_PARTNER_PD_MAJOR_REV_AS_BCD(_f_) \ - UCSI_SPEC_REVISION_TO_BCD(UCSI_CONCAP_FLAG_PARTNER_PD_MAJOR_REV(_f_)) -} __packed; - struct ucsi_altmode { u16 svid; u32 mid; @@ -311,49 +280,143 @@ struct ucsi_cable_property { u8 latency; } __packed; -/* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */ -struct ucsi_connector_status { - u16 change; -#define UCSI_CONSTAT_EXT_SUPPLY_CHANGE BIT(1) -#define UCSI_CONSTAT_POWER_OPMODE_CHANGE BIT(2) -#define UCSI_CONSTAT_PDOS_CHANGE BIT(5) -#define UCSI_CONSTAT_POWER_LEVEL_CHANGE BIT(6) -#define UCSI_CONSTAT_PD_RESET_COMPLETE BIT(7) -#define UCSI_CONSTAT_CAM_CHANGE BIT(8) -#define UCSI_CONSTAT_BC_CHANGE BIT(9) -#define UCSI_CONSTAT_PARTNER_CHANGE BIT(11) -#define UCSI_CONSTAT_POWER_DIR_CHANGE BIT(12) -#define UCSI_CONSTAT_CONNECT_CHANGE BIT(14) -#define UCSI_CONSTAT_ERROR BIT(15) - u16 flags; -#define UCSI_CONSTAT_PWR_OPMODE(_f_) ((_f_) & GENMASK(2, 0)) +/* Get Connector Capability Fields. */ +#define UCSI_CONCAP_OPMODE UCSI_DECLARE_BITFIELD(0, 0, 8) +#define UCSI_CONCAP_OPMODE_DFP UCSI_DECLARE_BITFIELD(0, 0, 1) +#define UCSI_CONCAP_OPMODE_UFP UCSI_DECLARE_BITFIELD(0, 1, 1) +#define UCSI_CONCAP_OPMODE_DRP UCSI_DECLARE_BITFIELD(0, 2, 1) +#define UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY UCSI_DECLARE_BITFIELD(0, 3, 1) +#define UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY UCSI_DECLARE_BITFIELD(0, 4, 1) +#define UCSI_CONCAP_OPMODE_USB2 UCSI_DECLARE_BITFIELD(0, 5, 1) +#define UCSI_CONCAP_OPMODE_USB3 UCSI_DECLARE_BITFIELD(0, 6, 1) +#define UCSI_CONCAP_OPMODE_ALT_MODE UCSI_DECLARE_BITFIELD(0, 7, 1) +#define UCSI_CONCAP_PROVIDER UCSI_DECLARE_BITFIELD(0, 8, 1) +#define UCSI_CONCAP_CONSUMER UCSI_DECLARE_BITFIELD(0, 9, 1) +#define UCSI_CONCAP_SWAP_TO_DFP_V1_1 UCSI_DECLARE_BITFIELD_V1_1(10, 1) +#define UCSI_CONCAP_SWAP_TO_UFP_V1_1 UCSI_DECLARE_BITFIELD_V1_1(11, 1) +#define UCSI_CONCAP_SWAP_TO_SRC_V1_1 UCSI_DECLARE_BITFIELD_V1_1(12, 1) +#define UCSI_CONCAP_SWAP_TO_SNK_V1_1 UCSI_DECLARE_BITFIELD_V1_1(13, 1) +#define UCSI_CONCAP_EXT_OPMODE_V2_0 UCSI_DECLARE_BITFIELD_V2_0(14, 8) +#define UCSI_CONCAP_EXT_OPMODE_USB4_GEN2_V2_0 UCSI_DECLARE_BITFIELD_V2_0(14, 1) +#define UCSI_CONCAP_EXT_OPMODE_EPR_SRC_V2_0 UCSI_DECLARE_BITFIELD_V2_0(15, 1) +#define UCSI_CONCAP_EXT_OPMODE_EPR_SINK_V2_0 UCSI_DECLARE_BITFIELD_V2_0(16, 1) +#define UCSI_CONCAP_EXT_OPMODE_USB4_GEN3_V2_0 UCSI_DECLARE_BITFIELD_V2_0(17, 1) +#define UCSI_CONCAP_EXT_OPMODE_USB4_GEN4_V2_0 UCSI_DECLARE_BITFIELD_V2_0(18, 1) +#define UCSI_CONCAP_MISC_V2_0 UCSI_DECLARE_BITFIELD_V2_0(22, 4) +#define UCSI_CONCAP_MISC_FW_UPDATE_V2_0 UCSI_DECLARE_BITFIELD_V2_0(22, 1) +#define UCSI_CONCAP_MISC_SECURITY_V2_0 UCSI_DECLARE_BITFIELD_V2_0(23, 1) +#define UCSI_CONCAP_REV_CURR_PROT_SUPPORT_V2_0 UCSI_DECLARE_BITFIELD_V2_0(26, 1) +#define UCSI_CONCAP_PARTNER_PD_REVISION_V2_1 UCSI_DECLARE_BITFIELD_V2_1(27, 2) + +/* Helpers for USB capability checks. */ +#define UCSI_CONCAP_USB2_SUPPORT(_con_) UCSI_CONCAP((_con_), OPMODE_USB2) +#define UCSI_CONCAP_USB3_SUPPORT(_con_) UCSI_CONCAP((_con_), OPMODE_USB3) +#define UCSI_CONCAP_USB4_SUPPORT(_con_) \ + ((_con_)->ucsi->version >= UCSI_VERSION_2_0 && \ + (UCSI_CONCAP((_con_), EXT_OPMODE_USB4_GEN2_V2_0) | \ + UCSI_CONCAP((_con_), EXT_OPMODE_USB4_GEN3_V2_0) | \ + UCSI_CONCAP((_con_), EXT_OPMODE_USB4_GEN4_V2_0))) + +/* Get Connector Status Fields. */ +#define UCSI_CONSTAT_CHANGE UCSI_DECLARE_BITFIELD(0, 0, 16) +#define UCSI_CONSTAT_PWR_OPMODE UCSI_DECLARE_BITFIELD(0, 16, 3) #define UCSI_CONSTAT_PWR_OPMODE_NONE 0 #define UCSI_CONSTAT_PWR_OPMODE_DEFAULT 1 #define UCSI_CONSTAT_PWR_OPMODE_BC 2 #define UCSI_CONSTAT_PWR_OPMODE_PD 3 #define UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5 4 #define UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0 5 -#define UCSI_CONSTAT_CONNECTED BIT(3) -#define UCSI_CONSTAT_PWR_DIR BIT(4) -#define UCSI_CONSTAT_PARTNER_FLAGS(_f_) (((_f_) & GENMASK(12, 5)) >> 5) -#define UCSI_CONSTAT_PARTNER_FLAG_USB 1 -#define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE 2 -#define UCSI_CONSTAT_PARTNER_TYPE(_f_) (((_f_) & GENMASK(15, 13)) >> 13) +#define UCSI_CONSTAT_CONNECTED UCSI_DECLARE_BITFIELD(0, 19, 1) +#define UCSI_CONSTAT_PWR_DIR UCSI_DECLARE_BITFIELD(0, 20, 1) +#define UCSI_CONSTAT_PARTNER_FLAGS UCSI_DECLARE_BITFIELD(0, 21, 8) +#define UCSI_CONSTAT_PARTNER_FLAG_USB UCSI_DECLARE_BITFIELD(0, 21, 1) +#define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE UCSI_DECLARE_BITFIELD(0, 22, 1) +#define UCSI_CONSTAT_PARTNER_FLAG_USB4_GEN3 UCSI_DECLARE_BITFIELD(0, 23, 1) +#define UCSI_CONSTAT_PARTNER_FLAG_USB4_GEN4 UCSI_DECLARE_BITFIELD(0, 24, 1) +#define UCSI_CONSTAT_PARTNER_TYPE UCSI_DECLARE_BITFIELD(0, 29, 3) #define UCSI_CONSTAT_PARTNER_TYPE_DFP 1 #define UCSI_CONSTAT_PARTNER_TYPE_UFP 2 -#define UCSI_CONSTAT_PARTNER_TYPE_CABLE 3 /* Powered Cable */ -#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP 4 /* Powered Cable */ +#define UCSI_CONSTAT_PARTNER_TYPE_CABLE 3 /* Powered Cable */ +#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP 4 /* Powered Cable */ #define UCSI_CONSTAT_PARTNER_TYPE_DEBUG 5 #define UCSI_CONSTAT_PARTNER_TYPE_AUDIO 6 - u32 request_data_obj; - - u8 pwr_status; -#define UCSI_CONSTAT_BC_STATUS(_p_) ((_p_) & GENMASK(1, 0)) +#define UCSI_CONSTAT_RDO UCSI_DECLARE_BITFIELD(0, 32, 32) +#define UCSI_CONSTAT_BC_STATUS UCSI_DECLARE_BITFIELD(0, 64, 2) #define UCSI_CONSTAT_BC_NOT_CHARGING 0 #define UCSI_CONSTAT_BC_NOMINAL_CHARGING 1 #define UCSI_CONSTAT_BC_SLOW_CHARGING 2 #define UCSI_CONSTAT_BC_TRICKLE_CHARGING 3 -} __packed; +#define UCSI_CONSTAT_PD_VERSION_V1_2 UCSI_DECLARE_BITFIELD_V1_2(70, 16) + +/* Connector Status Change Bits. */ +#define UCSI_CONSTAT_EXT_SUPPLY_CHANGE BIT(1) +#define UCSI_CONSTAT_POWER_OPMODE_CHANGE BIT(2) +#define UCSI_CONSTAT_PDOS_CHANGE BIT(5) +#define UCSI_CONSTAT_POWER_LEVEL_CHANGE BIT(6) +#define UCSI_CONSTAT_PD_RESET_COMPLETE BIT(7) +#define UCSI_CONSTAT_CAM_CHANGE BIT(8) +#define UCSI_CONSTAT_BC_CHANGE BIT(9) +#define UCSI_CONSTAT_PARTNER_CHANGE BIT(11) +#define UCSI_CONSTAT_POWER_DIR_CHANGE BIT(12) +#define UCSI_CONSTAT_CONNECT_CHANGE BIT(14) +#define UCSI_CONSTAT_ERROR BIT(15) + +#define UCSI_DECLARE_BITFIELD_V1_1(_offset_, _size_) \ + UCSI_DECLARE_BITFIELD(UCSI_VERSION_1_1, (_offset_), (_size_)) +#define UCSI_DECLARE_BITFIELD_V1_2(_offset_, _size_) \ + UCSI_DECLARE_BITFIELD(UCSI_VERSION_1_2, (_offset_), (_size_)) +#define UCSI_DECLARE_BITFIELD_V2_0(_offset_, _size_) \ + UCSI_DECLARE_BITFIELD(UCSI_VERSION_2_0, (_offset_), (_size_)) +#define UCSI_DECLARE_BITFIELD_V2_1(_offset_, _size_) \ + UCSI_DECLARE_BITFIELD(UCSI_VERSION_2_1, (_offset_), (_size_)) +#define UCSI_DECLARE_BITFIELD_V3_0(_offset_, _size_) \ + UCSI_DECLARE_BITFIELD(UCSI_VERSION_3_0, (_offset_), (_size_)) + +#define UCSI_DECLARE_BITFIELD(_ver_, _offset_, _size_) \ +(struct ucsi_bitfield) { \ + .version = _ver_, \ + .offset = _offset_, \ + .size = _size_, \ +} + +struct ucsi_bitfield { + const u16 version; + const u8 offset; + const u8 size; +}; + +/** + * ucsi_bitfield_read - Read a field from UCSI command response + * @_map_: UCSI command response + * @_field_: The field offset in the response data structure + * @_ver_: UCSI version where the field was introduced + * + * Reads the fields in the command responses by first checking that the field is + * valid with the UCSI interface version that is used in the system. + * @_ver_ is the minimum UCSI version for the @_field_. If the UCSI interface is + * older than @_ver_, a warning is generated. + * + * Caveats: + * - Removed fields are not checked - @_ver_ is just the minimum UCSI version. + * + * Returns the value of @_field_, or 0 when the UCSI interface is older than + * @_ver_. + */ +#define ucsi_bitfield_read(_map_, _field_, _ver_) \ +({ \ + struct ucsi_bitfield f = (_field_); \ + WARN((_ver_) < f.version, \ + "Access to unsupported field at offset 0x%x (need version %04x)", \ + f.offset, f.version) ? 0 : \ + bitmap_read((_map_), f.offset, f.size); \ +}) + +/* Helpers to access cached command responses. */ +#define UCSI_CONCAP(_con_, _field_) \ + ucsi_bitfield_read((_con_)->cap, UCSI_CONCAP_##_field_, (_con_)->ucsi->version) + +#define UCSI_CONSTAT(_con_, _field_) \ + ucsi_bitfield_read((_con_)->status, UCSI_CONSTAT_##_field_, (_con_)->ucsi->version) /* -------------------------------------------------------------------------- */ @@ -433,8 +496,10 @@ struct ucsi_connector { struct typec_capability typec_cap; - struct ucsi_connector_status status; - struct ucsi_connector_capability cap; + /* Cached command responses. */ + DECLARE_BITMAP(cap, UCSI_GET_CONNECTOR_CAPABILITY_SIZE); + DECLARE_BITMAP(status, UCSI_GET_CONNECTOR_STATUS_SIZE); + struct power_supply *psy; struct power_supply_desc psy_desc; u32 rdo; diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c index 7a5dff8d9cc6c31657d673e86bc09220ec08c60f..5c55155519634d95b6e544632f869c2867093617 100644 --- a/drivers/usb/typec/ucsi/ucsi_acpi.c +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c @@ -61,9 +61,11 @@ static int ucsi_acpi_read_cci(struct ucsi *ucsi, u32 *cci) struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); int ret; - ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ); - if (ret) - return ret; + if (UCSI_COMMAND(ua->cmd) == UCSI_PPM_RESET) { + ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ); + if (ret) + return ret; + } memcpy(cci, ua->base + UCSI_CCI, sizeof(*cci)); @@ -73,11 +75,6 @@ static int ucsi_acpi_read_cci(struct ucsi *ucsi, u32 *cci) static int ucsi_acpi_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); - int ret; - - ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ); - if (ret) - return ret; memcpy(val, ua->base + UCSI_MESSAGE_IN, val_len); @@ -102,48 +99,11 @@ static const struct ucsi_operations ucsi_acpi_ops = { .async_control = ucsi_acpi_async_control }; -static int -ucsi_zenbook_read_cci(struct ucsi *ucsi, u32 *cci) -{ - struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); - int ret; - - if (UCSI_COMMAND(ua->cmd) == UCSI_PPM_RESET) { - ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ); - if (ret) - return ret; - } - - memcpy(cci, ua->base + UCSI_CCI, sizeof(*cci)); - - return 0; -} - -static int -ucsi_zenbook_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) -{ - struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); - - /* UCSI_MESSAGE_IN is never read for PPM_RESET, return stored data */ - memcpy(val, ua->base + UCSI_MESSAGE_IN, val_len); - - return 0; -} - -static const struct ucsi_operations ucsi_zenbook_ops = { - .read_version = ucsi_acpi_read_version, - .read_cci = ucsi_zenbook_read_cci, - .read_message_in = ucsi_zenbook_read_message_in, - .sync_control = ucsi_sync_control_common, - .async_control = ucsi_acpi_async_control -}; - static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) { u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE | UCSI_CONSTAT_PDOS_CHANGE; struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); - struct ucsi_connector_status *status; int ret; ret = ucsi_acpi_read_message_in(ucsi, val, val_len); @@ -152,11 +112,9 @@ static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_le if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS && ua->check_bogus_event) { - status = (struct ucsi_connector_status *)val; - /* Clear the bogus change */ - if (status->change == bogus_change) - status->change = 0; + if (*(u16 *)val == bogus_change) + *(u16 *)val = 0; ua->check_bogus_event = false; } @@ -190,13 +148,6 @@ static const struct ucsi_operations ucsi_gram_ops = { }; static const struct dmi_system_id ucsi_acpi_quirks[] = { - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"), - }, - .driver_data = (void *)&ucsi_zenbook_ops, - }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), @@ -320,7 +271,7 @@ static struct platform_driver ucsi_acpi_platform_driver = { .acpi_match_table = ACPI_PTR(ucsi_acpi_match), }, .probe = ucsi_acpi_probe, - .remove_new = ucsi_acpi_remove, + .remove = ucsi_acpi_remove, }; module_platform_driver(ucsi_acpi_platform_driver); diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index bccfc03b5986d720a6257584b7b99d68c0ecd421..fcb8e61136cfd77029e5b91a02dd61c08232c1fa 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -644,6 +644,10 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) uc->has_multiple_dp) { con_index = (uc->last_cmd_sent >> 16) & UCSI_CMD_CONNECTOR_MASK; + if (con_index == 0) { + ret = -EINVAL; + goto unlock; + } con = &uc->ucsi->connector[con_index - 1]; ucsi_ccg_update_set_new_cam_cmd(uc, con, &command); } @@ -651,6 +655,7 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) ret = ucsi_sync_control_common(ucsi, command); pm_runtime_put_sync(uc->dev); +unlock: mutex_unlock(&uc->lock); return ret; diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index 03c0fa8edc8db5061ba718d77cba2fc7605a6b49..90948cd6d2972402465a2adaba3e1ed055cf0cfa 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -172,12 +172,12 @@ static int pmic_glink_ucsi_async_control(struct ucsi *__ucsi, u64 command) static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con) { struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); - int i; - for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) { - if (ucsi->port_orientation[i]) - con->typec_cap.orientation_aware = true; - } + if (con->num > PMIC_GLINK_MAX_PORTS || + !ucsi->port_orientation[con->num - 1]) + return; + + con->typec_cap.orientation_aware = true; } static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) @@ -185,7 +185,7 @@ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); int orientation; - if (con->num >= PMIC_GLINK_MAX_PORTS || + if (con->num > PMIC_GLINK_MAX_PORTS || !ucsi->port_orientation[con->num - 1]) return; @@ -322,7 +322,6 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, struct pmic_glink_ucsi *ucsi; struct device *dev = &adev->dev; const struct of_device_id *match; - struct fwnode_handle *fwnode; int ret; ucsi = devm_kzalloc(dev, sizeof(*ucsi), GFP_KERNEL); @@ -354,14 +353,13 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, ucsi_set_drvdata(ucsi->ucsi, ucsi); - device_for_each_child_node(dev, fwnode) { + device_for_each_child_node_scoped(dev, fwnode) { struct gpio_desc *desc; u32 port; ret = fwnode_property_read_u32(fwnode, "reg", &port); if (ret < 0) { dev_err(dev, "missing reg property of %pOFn\n", fwnode); - fwnode_handle_put(fwnode); return ret; } @@ -376,11 +374,10 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, if (!desc) continue; - if (IS_ERR(desc)) { - fwnode_handle_put(fwnode); + if (IS_ERR(desc)) return dev_err_probe(dev, PTR_ERR(desc), "unable to acquire orientation gpio\n"); - } + ucsi->port_orientation[port] = desc; } diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 8dac1edc74d4ee5cbe637f4546040e3ca2391b75..b03e5021c25bd538f93dd9f0d99a24e5443e51f6 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1487,7 +1487,7 @@ static int vhci_hcd_resume(struct platform_device *pdev) static struct platform_driver vhci_driver = { .probe = vhci_hcd_probe, - .remove_new = vhci_hcd_remove, + .remove = vhci_hcd_remove, .suspend = vhci_hcd_suspend, .resume = vhci_hcd_resume, .driver = { diff --git a/drivers/usb/usbip/vudc_main.c b/drivers/usb/usbip/vudc_main.c index 8bee553e48945f66d6c81bd0c1e0d2ca22f798ae..993e721cb840df29c209bbad2bfc35fea434b4db 100644 --- a/drivers/usb/usbip/vudc_main.c +++ b/drivers/usb/usbip/vudc_main.c @@ -19,7 +19,7 @@ MODULE_PARM_DESC(num, "number of emulated controllers"); static struct platform_driver vudc_driver = { .probe = vudc_probe, - .remove_new = vudc_remove, + .remove = vudc_remove, .driver = { .name = GADGET_NAME, .dev_groups = vudc_groups, diff --git a/drivers/vfio/cdx/main.c b/drivers/vfio/cdx/main.c index 67465fad5b4bf3adea3e948ef38a0d32343f6caf..5dd5f5ad768653449a23ca0b01c9273fd7dd16a1 100644 --- a/drivers/vfio/cdx/main.c +++ b/drivers/vfio/cdx/main.c @@ -347,4 +347,4 @@ module_driver(vfio_cdx_driver, cdx_driver_register, cdx_driver_unregister); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("VFIO for CDX devices - User Level meta-driver"); -MODULE_IMPORT_NS(CDX_BUS); +MODULE_IMPORT_NS("CDX_BUS"); diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c index 82eba6966fa508d827c4f1b6f628db0d63d7d6a4..516294fd901be4f40bba018f8565fbde495e5aa6 100644 --- a/drivers/vfio/iommufd.c +++ b/drivers/vfio/iommufd.c @@ -7,8 +7,8 @@ #include "vfio.h" -MODULE_IMPORT_NS(IOMMUFD); -MODULE_IMPORT_NS(IOMMUFD_VFIO); +MODULE_IMPORT_NS("IOMMUFD"); +MODULE_IMPORT_NS("IOMMUFD_VFIO"); bool vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev, struct iommufd_ctx *ictx) diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 8833e60d42f566a1369ce768ec319e409ba851b9..709543e7eb0428ca661ab900d6e6b4bf4361a438 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -1446,7 +1446,7 @@ static struct pci_driver mlx5vf_pci_driver = { module_pci_driver(mlx5vf_pci_driver); -MODULE_IMPORT_NS(IOMMUFD); +MODULE_IMPORT_NS("IOMMUFD"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Max Gurtovoy "); MODULE_AUTHOR("Yishai Hadas "); diff --git a/drivers/vfio/pci/pds/pci_drv.c b/drivers/vfio/pci/pds/pci_drv.c index 16e93b11ab1b0ef9a3b8e07ac4e838397b26e5ea..4923f1823126378ee08de1e1c1d2717588aceab4 100644 --- a/drivers/vfio/pci/pds/pci_drv.c +++ b/drivers/vfio/pci/pds/pci_drv.c @@ -187,7 +187,7 @@ static struct pci_driver pds_vfio_pci_driver = { module_pci_driver(pds_vfio_pci_driver); -MODULE_IMPORT_NS(IOMMUFD); +MODULE_IMPORT_NS("IOMMUFD"); MODULE_DESCRIPTION(PDS_VFIO_DRV_DESCRIPTION); MODULE_AUTHOR("Brett Creeley "); MODULE_LICENSE("GPL"); diff --git a/drivers/vfio/pci/qat/main.c b/drivers/vfio/pci/qat/main.c index c78cb6de93906cc66a77b18db391c5f961afcbda..845ed15b67718c5d7c2b7cd98b091f50cd17c411 100644 --- a/drivers/vfio/pci/qat/main.c +++ b/drivers/vfio/pci/qat/main.c @@ -697,4 +697,4 @@ module_pci_driver(qat_vf_vfio_pci_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Xin Zeng "); MODULE_DESCRIPTION("QAT VFIO PCI - VFIO PCI driver with live migration support for Intel(R) QAT GEN4 device family"); -MODULE_IMPORT_NS(CRYPTO_QAT); +MODULE_IMPORT_NS("CRYPTO_QAT"); diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c index 42d1462c5e19daf852777d395dced89e0d31fbd7..512533501eb7f386546b19ad1d0eea8ffd691480 100644 --- a/drivers/vfio/platform/vfio_platform.c +++ b/drivers/vfio/platform/vfio_platform.c @@ -112,7 +112,7 @@ static const struct vfio_device_ops vfio_platform_ops = { static struct platform_driver vfio_platform_driver = { .probe = vfio_platform_probe, - .remove_new = vfio_platform_remove, + .remove = vfio_platform_remove, .driver = { .name = "vfio-platform", }, diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index a5a62d9d963f72ec704730717f305edae29297d1..1fd261efc582d0d95067ef3034f3611cf3c40eea 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -1751,7 +1751,7 @@ static void __exit vfio_cleanup(void) module_init(vfio_init); module_exit(vfio_cleanup); -MODULE_IMPORT_NS(IOMMUFD); +MODULE_IMPORT_NS("IOMMUFD"); MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c index 68d327ee4b2ed75215ceae5f0ce87e85c8646162..8b790df1e842b3251df46478a8beec54096b3579 100644 --- a/drivers/video/backlight/aat2870_bl.c +++ b/drivers/video/backlight/aat2870_bl.c @@ -186,7 +186,7 @@ static struct platform_driver aat2870_bl_driver = { .name = "aat2870-backlight", }, .probe = aat2870_bl_probe, - .remove_new = aat2870_bl_remove, + .remove = aat2870_bl_remove, }; static int __init aat2870_bl_init(void) diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index 8e0e9cfe5fe938645a7dad0077c4b35b52ba6dc6..aa5c15e8db86ed21163ef1d9dbedb8153b0e263d 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c @@ -375,7 +375,7 @@ static struct platform_driver adp5520_bl_driver = { .pm = &adp5520_bl_pm_ops, }, .probe = adp5520_bl_probe, - .remove_new = adp5520_bl_remove, + .remove = adp5520_bl_remove, }; module_platform_driver(adp5520_bl_driver); diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c index b8ff7046510eb90165c126c913c5678a4dcc61c5..5e13ef96b717cca8a7ab582b81bbf3884753a0aa 100644 --- a/drivers/video/backlight/da9052_bl.c +++ b/drivers/video/backlight/da9052_bl.c @@ -165,7 +165,7 @@ MODULE_DEVICE_TABLE(platform, da9052_wled_ids); static struct platform_driver da9052_wled_driver = { .probe = da9052_backlight_probe, - .remove_new = da9052_backlight_remove, + .remove = da9052_backlight_remove, .id_table = da9052_wled_ids, .driver = { .name = "da9052-wled", diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index ddb7ab4df77e9c577fabdc983e576cc2fa8730b9..fa9a983533b2dea77d1383ce1087a96c3cf6487a 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -130,7 +130,7 @@ static void hp680bl_remove(struct platform_device *pdev) static struct platform_driver hp680bl_driver = { .probe = hp680bl_probe, - .remove_new = hp680bl_remove, + .remove = hp680bl_remove, .driver = { .name = "hp680-bl", .pm = &hp680bl_pm_ops, diff --git a/drivers/video/backlight/ktd2801-backlight.c b/drivers/video/backlight/ktd2801-backlight.c index d295c27660251fd1896c1f3d1d49b1daab9ff288..0489b0615cebc91e27384fb9dffcefc8cad74297 100644 --- a/drivers/video/backlight/ktd2801-backlight.c +++ b/drivers/video/backlight/ktd2801-backlight.c @@ -122,7 +122,7 @@ static struct platform_driver ktd2801_backlight_driver = { }; module_platform_driver(ktd2801_backlight_driver); -MODULE_IMPORT_NS(EXPRESSWIRE); +MODULE_IMPORT_NS("EXPRESSWIRE"); MODULE_AUTHOR("Duje Mihanović "); MODULE_DESCRIPTION("Kinetic KTD2801 Backlight Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c index c7aefcd6e4e3e339278e8fab4f9f5adb92ba76b3..ae34d1ecbfbef7dc839aa6b450b896dcb089db38 100644 --- a/drivers/video/backlight/led_bl.c +++ b/drivers/video/backlight/led_bl.c @@ -246,7 +246,7 @@ static struct platform_driver led_bl_driver = { .of_match_table = led_bl_of_match, }, .probe = led_bl_probe, - .remove_new = led_bl_remove, + .remove = led_bl_remove, }; module_platform_driver(led_bl_driver); diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c index 5d06f8ca976cd445f1db8c731e324521a20aeeb1..babfd3ceec8663bb4222b3b96bae4e38d68da2da 100644 --- a/drivers/video/backlight/lm3533_bl.c +++ b/drivers/video/backlight/lm3533_bl.c @@ -387,7 +387,7 @@ static struct platform_driver lm3533_bl_driver = { .pm = &lm3533_bl_pm_ops, }, .probe = lm3533_bl_probe, - .remove_new = lm3533_bl_remove, + .remove = lm3533_bl_remove, .shutdown = lm3533_bl_shutdown, }; module_platform_driver(lm3533_bl_driver); diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c index 0b7663519fa5f49f1ac071633599057a4b76a69b..f61a64905a02dc722158f800465f36cc66ef2d87 100644 --- a/drivers/video/backlight/lp8788_bl.c +++ b/drivers/video/backlight/lp8788_bl.c @@ -177,7 +177,7 @@ static void lp8788_backlight_remove(struct platform_device *pdev) static struct platform_driver lp8788_bl_driver = { .probe = lp8788_backlight_probe, - .remove_new = lp8788_backlight_remove, + .remove = lp8788_backlight_remove, .driver = { .name = LP8788_DEV_BACKLIGHT, }, diff --git a/drivers/video/backlight/mt6370-backlight.c b/drivers/video/backlight/mt6370-backlight.c index 94422c956453d8b8dc978a260e02b36bfa9bcb04..e55f26888d0fb9893d62d1abe8d72f179a845272 100644 --- a/drivers/video/backlight/mt6370-backlight.c +++ b/drivers/video/backlight/mt6370-backlight.c @@ -340,7 +340,7 @@ static struct platform_driver mt6370_bl_driver = { .of_match_table = mt6370_bl_of_match, }, .probe = mt6370_bl_probe, - .remove_new = mt6370_bl_remove, + .remove = mt6370_bl_remove, }; module_platform_driver(mt6370_bl_driver); diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index e942908d1275fe380c9e74f7a39ac26771ecf027..237d3d3f3bb1a6d713c5f6ec3198af772bf1268c 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -697,7 +697,7 @@ static struct platform_driver pwm_backlight_driver = { .of_match_table = of_match_ptr(pwm_backlight_of_match), }, .probe = pwm_backlight_probe, - .remove_new = pwm_backlight_remove, + .remove = pwm_backlight_remove, .shutdown = pwm_backlight_shutdown, }; diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 10129095a4c1781115798c436d0bbd41556be31d..9afe701b2a1b648f2bd6645a7f2caf1c9394f239 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -1741,7 +1741,7 @@ MODULE_DEVICE_TABLE(of, wled_match_table); static struct platform_driver wled_driver = { .probe = wled_probe, - .remove_new = wled_remove, + .remove = wled_remove, .driver = { .name = "qcom,wled", .of_match_table = wled_match_table, diff --git a/drivers/video/backlight/rt4831-backlight.c b/drivers/video/backlight/rt4831-backlight.c index c2f6fb29e1d04b2f8d11ab0956cbbfe6e1b970ef..7ead75929a437a822b5dc666b3f67df3cbe6ba28 100644 --- a/drivers/video/backlight/rt4831-backlight.c +++ b/drivers/video/backlight/rt4831-backlight.c @@ -224,7 +224,7 @@ static struct platform_driver rt4831_bl_driver = { .of_match_table = rt4831_bl_of_match, }, .probe = rt4831_bl_probe, - .remove_new = rt4831_bl_remove, + .remove = rt4831_bl_remove, }; module_platform_driver(rt4831_bl_driver); diff --git a/drivers/video/backlight/sky81452-backlight.c b/drivers/video/backlight/sky81452-backlight.c index 935043b6778698bd5310f995a7b046a564d654aa..2749231f0385449b530287cfd7a021c4eeaab288 100644 --- a/drivers/video/backlight/sky81452-backlight.c +++ b/drivers/video/backlight/sky81452-backlight.c @@ -337,7 +337,7 @@ static struct platform_driver sky81452_bl_driver = { .of_match_table = of_match_ptr(sky81452_bl_of_match), }, .probe = sky81452_bl_probe, - .remove_new = sky81452_bl_remove, + .remove = sky81452_bl_remove, }; module_platform_driver(sky81452_bl_driver); diff --git a/drivers/virt/coco/efi_secret/efi_secret.c b/drivers/virt/coco/efi_secret/efi_secret.c index cd29e66b1543ffa92f48af83e8c3dd5f8221e0c6..1864f9f80617e082feb574a15327949972c8cc1e 100644 --- a/drivers/virt/coco/efi_secret/efi_secret.c +++ b/drivers/virt/coco/efi_secret/efi_secret.c @@ -334,7 +334,7 @@ static void efi_secret_remove(struct platform_device *dev) static struct platform_driver efi_secret_driver = { .probe = efi_secret_probe, - .remove_new = efi_secret_remove, + .remove = efi_secret_remove, .driver = { .name = "efi_secret", }, diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index fca5c45ed5cd9d5367134f5a7f9f8759679beec0..b699771be029c3b12ed72f35ecd38793fce676f2 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -1116,7 +1116,7 @@ static void __exit sev_guest_remove(struct platform_device *pdev) * triggering a section mismatch warning. */ static struct platform_driver sev_guest_driver __refdata = { - .remove_new = __exit_p(sev_guest_remove), + .remove = __exit_p(sev_guest_remove), .driver = { .name = "sev-guest", }, diff --git a/drivers/virtio/virtio_dma_buf.c b/drivers/virtio/virtio_dma_buf.c index 3034a2f605c8d5bff8b40ca9afd9c12c1f1032f2..3fe1d03b06454db5a94659598d9a0115ffa9611f 100644 --- a/drivers/virtio/virtio_dma_buf.c +++ b/drivers/virtio/virtio_dma_buf.c @@ -87,4 +87,4 @@ EXPORT_SYMBOL(virtio_dma_buf_get_uuid); MODULE_DESCRIPTION("dma-bufs for virtio exported objects"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 90e784e7b7210da05cf93d091b60f1c88f9b6a5e..5d78c2d572abfcfe2b84cdd82df622320fe97d5d 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -845,7 +845,7 @@ MODULE_DEVICE_TABLE(acpi, virtio_mmio_acpi_match); static struct platform_driver virtio_mmio_driver = { .probe = virtio_mmio_probe, - .remove_new = virtio_mmio_remove, + .remove = virtio_mmio_remove, .driver = { .name = "virtio-mmio", .of_match_table = virtio_mmio_match, diff --git a/drivers/w1/masters/amd_axi_w1.c b/drivers/w1/masters/amd_axi_w1.c index 4d3a68ca9263ab102f5aaeb0906eb1b9aaf5853b..5da8b8d8681185535338a92fc668e155530528a3 100644 --- a/drivers/w1/masters/amd_axi_w1.c +++ b/drivers/w1/masters/amd_axi_w1.c @@ -383,7 +383,7 @@ MODULE_DEVICE_TABLE(of, amd_axi_w1_of_match); static struct platform_driver amd_axi_w1_driver = { .probe = amd_axi_w1_probe, - .remove_new = amd_axi_w1_remove, + .remove = amd_axi_w1_remove, .driver = { .name = DRIVER_NAME, .of_match_table = amd_axi_w1_of_match, diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index ba1d0866d1c40c99205aae5a15539954e64806fb..30a190ce4298fc271e545195308234c87b25d6a3 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -172,7 +172,7 @@ static struct platform_driver mxc_w1_driver = { .of_match_table = mxc_w1_dt_ids, }, .probe = mxc_w1_probe, - .remove_new = mxc_w1_remove, + .remove = mxc_w1_remove, }; module_platform_driver(mxc_w1_driver); diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index d1cb5190445a9035799c3879037ee0252bcfcd95..69b1d145657a3d047b240f6c48106ca15fe0f354 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -672,7 +672,7 @@ MODULE_DEVICE_TABLE(of, omap_hdq_dt_ids); static struct platform_driver omap_hdq_driver = { .probe = omap_hdq_probe, - .remove_new = omap_hdq_remove, + .remove = omap_hdq_remove, .driver = { .name = "omap_hdq", .of_match_table = omap_hdq_dt_ids, diff --git a/drivers/w1/masters/sgi_w1.c b/drivers/w1/masters/sgi_w1.c index 7bb7876aa70e6f561e16d7f0f198a25f8eee5401..af6b1186b76329be5cdec82cd3503e6d325109a7 100644 --- a/drivers/w1/masters/sgi_w1.c +++ b/drivers/w1/masters/sgi_w1.c @@ -117,7 +117,7 @@ static struct platform_driver sgi_w1_driver = { .name = "sgi_w1", }, .probe = sgi_w1_probe, - .remove_new = sgi_w1_remove, + .remove = sgi_w1_remove, }; module_platform_driver(sgi_w1_driver); diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index a39fa8bf866ae3da885d7bb1277a3d3e4891f0a7..a579f95be8f13526e8f659af27026d4f23b6d917 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -146,7 +146,7 @@ static struct platform_driver w1_gpio_driver = { .of_match_table = w1_gpio_dt_ids, }, .probe = w1_gpio_probe, - .remove_new = w1_gpio_remove, + .remove = w1_gpio_remove, }; module_platform_driver(w1_gpio_driver); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 2333476a42c02be75208d7d342f635a0d2d342bf..f81705f8539aa0b12d156a86aae521aa40b4527d 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -408,6 +408,14 @@ config SL28CPLD_WATCHDOG # ARM Architecture +config AIROHA_WATCHDOG + tristate "Airoha EN7581 Watchdog" + depends on ARCH_AIROHA || COMPILE_TEST + select WATCHDOG_CORE + help + Watchdog timer embedded into Airoha SoC. This will reboot your + system when the timeout is reached. + config ARM_SP805_WATCHDOG tristate "ARM SP805 Watchdog" depends on (ARM || ARM64 || COMPILE_TEST) && ARM_AMBA @@ -549,6 +557,7 @@ config S3C2410_WATCHDOG tristate "S3C6410/S5Pv210/Exynos Watchdog" depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST select WATCHDOG_CORE + select MFD_SYSCON if ARCH_EXYNOS help Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos SoCs. This will reboot the system when the timer expires with @@ -1543,14 +1552,6 @@ config SBC7240_WDT To compile this driver as a module, choose M here: the module will be called sbc7240_wdt. -config CPU5_WDT - tristate "SMA CPU5 Watchdog" - depends on (X86 || COMPILE_TEST) && HAS_IOPORT - help - TBD. - To compile this driver as a module, choose M here: the - module will be called cpu5wdt. - config SMSC_SCH311X_WDT tristate "SMSC SCH311X Watchdog Timer" depends on (X86 || COMPILE_TEST) && HAS_IOPORT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 386d88d89fe5db536d8fd77b5f3a36c0a675a7da..8411626fa162268e8ccd06349f7193b15a9d281a 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o obj-$(CONFIG_ARMADA_37XX_WATCHDOG) += armada_37xx_wdt.o +obj-$(CONFIG_AIROHA_WATCHDOG) += airoha_wdt.o obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o @@ -138,7 +139,6 @@ obj-$(CONFIG_RDC321X_WDT) += rdc321x_wdt.o obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o obj-$(CONFIG_SBC8360_WDT) += sbc8360.o obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o -obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o obj-$(CONFIG_TQMX86_WDT) += tqmx86_wdt.o diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 08ca18e91124dd3c7c75598795ddf4fea08ab5b0..052f65c48a703e32426a7e8dadd588151a624df6 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c @@ -285,7 +285,7 @@ static void acq_shutdown(struct platform_device *dev) } static struct platform_driver acquirewdt_driver = { - .remove_new = acq_remove, + .remove = acq_remove, .shutdown = acq_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index e41cd3ba4e0e95f0212e3248ce75140bf5a73875..42d3f377178109a767037fac61b658c129bcd0cc 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c @@ -293,7 +293,7 @@ static void advwdt_shutdown(struct platform_device *dev) } static struct platform_driver advwdt_driver = { - .remove_new = advwdt_remove, + .remove = advwdt_remove, .shutdown = advwdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/airoha_wdt.c b/drivers/watchdog/airoha_wdt.c new file mode 100644 index 0000000000000000000000000000000000000000..dc8ca11c14d81a58d2153caf83b9ea9f1edb2390 --- /dev/null +++ b/drivers/watchdog/airoha_wdt.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Airoha Watchdog Driver + * + * Copyright (c) 2024, AIROHA All rights reserved. + * + * Mayur Kumar + * Christian Marangi + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Base address of timer and watchdog registers */ +#define TIMER_CTRL 0x0 +#define WDT_ENABLE BIT(25) +#define WDT_TIMER_INTERRUPT BIT(21) +/* Timer3 is used as Watchdog Timer */ +#define WDT_TIMER_ENABLE BIT(5) +#define WDT_TIMER_LOAD_VALUE 0x2c +#define WDT_TIMER_CUR_VALUE 0x30 +#define WDT_TIMER_VAL GENMASK(31, 0) +#define WDT_RELOAD 0x38 +#define WDT_RLD BIT(0) + +/* Airoha watchdog structure description */ +struct airoha_wdt_desc { + struct watchdog_device wdog_dev; + unsigned int wdt_freq; + void __iomem *base; +}; + +#define WDT_HEARTBEAT 24 +static int heartbeat = WDT_HEARTBEAT; +module_param(heartbeat, int, 0); +MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default=" + __MODULE_STRING(WDT_HEARTBEAT) ")"); + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static int airoha_wdt_start(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + TIMER_CTRL); + val |= (WDT_TIMER_ENABLE | WDT_ENABLE | WDT_TIMER_INTERRUPT); + writel(val, airoha_wdt->base + TIMER_CTRL); + val = wdog_dev->timeout * airoha_wdt->wdt_freq; + writel(val, airoha_wdt->base + WDT_TIMER_LOAD_VALUE); + + return 0; +} + +static int airoha_wdt_stop(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + TIMER_CTRL); + val &= (~WDT_ENABLE & ~WDT_TIMER_ENABLE); + writel(val, airoha_wdt->base + TIMER_CTRL); + + return 0; +} + +static int airoha_wdt_ping(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + WDT_RELOAD); + val |= WDT_RLD; + writel(val, airoha_wdt->base + WDT_RELOAD); + + return 0; +} + +static int airoha_wdt_set_timeout(struct watchdog_device *wdog_dev, unsigned int timeout) +{ + wdog_dev->timeout = timeout; + + if (watchdog_active(wdog_dev)) { + airoha_wdt_stop(wdog_dev); + return airoha_wdt_start(wdog_dev); + } + + return 0; +} + +static unsigned int airoha_wdt_get_timeleft(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + WDT_TIMER_CUR_VALUE); + return DIV_ROUND_UP(val, airoha_wdt->wdt_freq); +} + +static const struct watchdog_info airoha_wdt_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, + .identity = "Airoha Watchdog", +}; + +static const struct watchdog_ops airoha_wdt_ops = { + .owner = THIS_MODULE, + .start = airoha_wdt_start, + .stop = airoha_wdt_stop, + .ping = airoha_wdt_ping, + .set_timeout = airoha_wdt_set_timeout, + .get_timeleft = airoha_wdt_get_timeleft, +}; + +static int airoha_wdt_probe(struct platform_device *pdev) +{ + struct airoha_wdt_desc *airoha_wdt; + struct watchdog_device *wdog_dev; + struct device *dev = &pdev->dev; + struct clk *bus_clk; + int ret; + + airoha_wdt = devm_kzalloc(dev, sizeof(*airoha_wdt), GFP_KERNEL); + if (!airoha_wdt) + return -ENOMEM; + + airoha_wdt->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(airoha_wdt->base)) + return PTR_ERR(airoha_wdt->base); + + bus_clk = devm_clk_get_enabled(dev, "bus"); + if (IS_ERR(bus_clk)) + return dev_err_probe(dev, PTR_ERR(bus_clk), + "failed to enable bus clock\n"); + + /* Watchdog ticks at half the bus rate */ + airoha_wdt->wdt_freq = clk_get_rate(bus_clk) / 2; + + /* Initialize struct watchdog device */ + wdog_dev = &airoha_wdt->wdog_dev; + wdog_dev->timeout = heartbeat; + wdog_dev->info = &airoha_wdt_info; + wdog_dev->ops = &airoha_wdt_ops; + /* Bus 300MHz, watchdog 150MHz, 28 seconds */ + wdog_dev->max_timeout = FIELD_MAX(WDT_TIMER_VAL) / airoha_wdt->wdt_freq; + wdog_dev->parent = dev; + + watchdog_set_drvdata(wdog_dev, airoha_wdt); + watchdog_set_nowayout(wdog_dev, nowayout); + watchdog_stop_on_unregister(wdog_dev); + + ret = devm_watchdog_register_device(dev, wdog_dev); + if (ret) + return ret; + + platform_set_drvdata(pdev, airoha_wdt); + return 0; +} + +static int airoha_wdt_suspend(struct device *dev) +{ + struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); + + if (watchdog_active(&airoha_wdt->wdog_dev)) + airoha_wdt_stop(&airoha_wdt->wdog_dev); + + return 0; +} + +static int airoha_wdt_resume(struct device *dev) +{ + struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); + + if (watchdog_active(&airoha_wdt->wdog_dev)) { + airoha_wdt_start(&airoha_wdt->wdog_dev); + airoha_wdt_ping(&airoha_wdt->wdog_dev); + } + return 0; +} + +static const struct of_device_id airoha_wdt_of_match[] = { + { .compatible = "airoha,en7581-wdt", }, + { }, +}; + +MODULE_DEVICE_TABLE(of, airoha_wdt_of_match); + +static DEFINE_SIMPLE_DEV_PM_OPS(airoha_wdt_pm_ops, airoha_wdt_suspend, airoha_wdt_resume); + +static struct platform_driver airoha_wdt_driver = { + .probe = airoha_wdt_probe, + .driver = { + .name = "airoha-wdt", + .pm = pm_sleep_ptr(&airoha_wdt_pm_ops), + .of_match_table = airoha_wdt_of_match, + }, +}; + +module_platform_driver(airoha_wdt_driver); + +MODULE_AUTHOR("Mayur Kumar "); +MODULE_AUTHOR("Christian Marangi "); +MODULE_DESCRIPTION("Airoha EN7581 Watchdog Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/apple_wdt.c b/drivers/watchdog/apple_wdt.c index d4f739932f0be8394c827e9beed3c1bbc4aace0d..95d9e37df41cd371a45b1390646cadc55fade72c 100644 --- a/drivers/watchdog/apple_wdt.c +++ b/drivers/watchdog/apple_wdt.c @@ -127,11 +127,11 @@ static int apple_wdt_restart(struct watchdog_device *wdd, unsigned long mode, /* * Flush writes and then wait for the SoC to reset. Even though the * reset is queued almost immediately experiments have shown that it - * can take up to ~20-25ms until the SoC is actually reset. Just wait - * 50ms here to be safe. + * can take up to ~120-125ms until the SoC is actually reset. Just + * wait 150ms here to be safe. */ - (void)readl_relaxed(wdt->regs + APPLE_WDT_WD1_CUR_TIME); - mdelay(50); + (void)readl(wdt->regs + APPLE_WDT_WD1_CUR_TIME); + mdelay(150); return 0; } diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c index 8133a5d05647c2aff136c854eed5a78447b00c26..a17a7911771ace2d4c36a8e3b2a616c433562191 100644 --- a/drivers/watchdog/armada_37xx_wdt.c +++ b/drivers/watchdog/armada_37xx_wdt.c @@ -248,7 +248,6 @@ static const struct watchdog_ops armada_37xx_wdt_ops = { static int armada_37xx_wdt_probe(struct platform_device *pdev) { struct armada_37xx_watchdog *dev; - struct resource *res; struct regmap *regmap; int ret; @@ -266,12 +265,9 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev) return PTR_ERR(regmap); dev->cpu_misc = regmap; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - dev->reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!dev->reg) - return -ENOMEM; + dev->reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(dev->reg)) + return PTR_ERR(dev->reg); /* init clock */ dev->clk = devm_clk_get_enabled(&pdev->dev, NULL); diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index 17382512a6096f82c99360021852f4e0db0bca9e..1795aaf1ec45e340f81619e3970de5383cbe6f06 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -295,7 +295,7 @@ MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids); static struct platform_driver at91wdt_driver = { .probe = at91wdt_probe, - .remove_new = at91wdt_remove, + .remove = at91wdt_remove, .shutdown = at91wdt_shutdown, .suspend = pm_ptr(at91wdt_suspend), .resume = pm_ptr(at91wdt_resume), diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 2c6474cb858b742c4b31db6a16612da032a8183c..7be70b98d0912eb951d81a7ecc9b5875d8548f2e 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -392,7 +392,7 @@ MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids); static struct platform_driver at91wdt_driver = { .probe = at91wdt_probe, - .remove_new = at91wdt_remove, + .remove = at91wdt_remove, .driver = { .name = "at91_wdt", .of_match_table = of_match_ptr(at91_wdt_dt_ids), diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index d16b2c583fa4079680fbcfebaf8aa82978c9cf78..7df703e9852a6ea14fafb51078f66b6a33a9801e 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c @@ -305,7 +305,7 @@ MODULE_DEVICE_TABLE(of, ath79_wdt_match); static struct platform_driver ath79_wdt_driver = { .probe = ath79_wdt_probe, - .remove_new = ath79_wdt_remove, + .remove = ath79_wdt_remove, .shutdown = ath79_wdt_shutdown, .driver = { .name = DRIVER_NAME, diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index bb001c5d7f17fd635b1a084f4a24d4c9ab01ba59..9fcfee63905b9b72c69ad9d4d597d0826f2ccfc9 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c @@ -227,7 +227,7 @@ static void bcm2835_wdt_remove(struct platform_device *pdev) static struct platform_driver bcm2835_wdt_driver = { .probe = bcm2835_wdt_probe, - .remove_new = bcm2835_wdt_remove, + .remove = bcm2835_wdt_remove, .driver = { .name = "bcm2835-wdt", }, diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index 49e12d47b073da3077f65e8b4ac6836eadc5a669..66bd0324fd68dbea2036dad3d409de1cea7c2cb4 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -328,7 +328,7 @@ static struct platform_driver bcm_kona_wdt_driver = { .of_match_table = bcm_kona_wdt_of_match, }, .probe = bcm_kona_wdt_probe, - .remove_new = bcm_kona_wdt_remove, + .remove = bcm_kona_wdt_remove, }; module_platform_driver(bcm_kona_wdt_driver); diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c deleted file mode 100644 index f94b840486121b54bfdaa78cc8b879b2225a3a52..0000000000000000000000000000000000000000 --- a/drivers/watchdog/cpu5wdt.c +++ /dev/null @@ -1,284 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * sma cpu5 watchdog driver - * - * Copyright (C) 2003 Heiko Ronsdorf - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* adjustable parameters */ - -static int verbose; -static int port = 0x91; -static int ticks = 10000; -static DEFINE_SPINLOCK(cpu5wdt_lock); - -#define PFX "cpu5wdt: " - -#define CPU5WDT_EXTENT 0x0A - -#define CPU5WDT_STATUS_REG 0x00 -#define CPU5WDT_TIME_A_REG 0x02 -#define CPU5WDT_TIME_B_REG 0x03 -#define CPU5WDT_MODE_REG 0x04 -#define CPU5WDT_TRIGGER_REG 0x07 -#define CPU5WDT_ENABLE_REG 0x08 -#define CPU5WDT_RESET_REG 0x09 - -#define CPU5WDT_INTERVAL (HZ/10+1) - -/* some device data */ - -static struct { - struct completion stop; - int running; - struct timer_list timer; - int queue; - int default_ticks; - unsigned long inuse; -} cpu5wdt_device; - -/* generic helper functions */ - -static void cpu5wdt_trigger(struct timer_list *unused) -{ - if (verbose > 2) - pr_debug("trigger at %i ticks\n", ticks); - - if (cpu5wdt_device.running) - ticks--; - - spin_lock(&cpu5wdt_lock); - /* keep watchdog alive */ - outb(1, port + CPU5WDT_TRIGGER_REG); - - /* requeue?? */ - if (cpu5wdt_device.queue && ticks) - mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL); - else { - /* ticks doesn't matter anyway */ - complete(&cpu5wdt_device.stop); - } - spin_unlock(&cpu5wdt_lock); - -} - -static void cpu5wdt_reset(void) -{ - ticks = cpu5wdt_device.default_ticks; - - if (verbose) - pr_debug("reset (%i ticks)\n", (int) ticks); - -} - -static void cpu5wdt_start(void) -{ - unsigned long flags; - - spin_lock_irqsave(&cpu5wdt_lock, flags); - if (!cpu5wdt_device.queue) { - cpu5wdt_device.queue = 1; - outb(0, port + CPU5WDT_TIME_A_REG); - outb(0, port + CPU5WDT_TIME_B_REG); - outb(1, port + CPU5WDT_MODE_REG); - outb(0, port + CPU5WDT_RESET_REG); - outb(0, port + CPU5WDT_ENABLE_REG); - mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL); - } - /* if process dies, counter is not decremented */ - cpu5wdt_device.running++; - spin_unlock_irqrestore(&cpu5wdt_lock, flags); -} - -static int cpu5wdt_stop(void) -{ - unsigned long flags; - - spin_lock_irqsave(&cpu5wdt_lock, flags); - if (cpu5wdt_device.running) - cpu5wdt_device.running = 0; - ticks = cpu5wdt_device.default_ticks; - spin_unlock_irqrestore(&cpu5wdt_lock, flags); - if (verbose) - pr_crit("stop not possible\n"); - return -EIO; -} - -/* filesystem operations */ - -static int cpu5wdt_open(struct inode *inode, struct file *file) -{ - if (test_and_set_bit(0, &cpu5wdt_device.inuse)) - return -EBUSY; - return stream_open(inode, file); -} - -static int cpu5wdt_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &cpu5wdt_device.inuse); - return 0; -} - -static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - unsigned int value; - static const struct watchdog_info ident = { - .options = WDIOF_CARDRESET, - .identity = "CPU5 WDT", - }; - - switch (cmd) { - case WDIOC_GETSUPPORT: - if (copy_to_user(argp, &ident, sizeof(ident))) - return -EFAULT; - break; - case WDIOC_GETSTATUS: - value = inb(port + CPU5WDT_STATUS_REG); - value = (value >> 2) & 1; - return put_user(value, p); - case WDIOC_GETBOOTSTATUS: - return put_user(0, p); - case WDIOC_SETOPTIONS: - if (get_user(value, p)) - return -EFAULT; - if (value & WDIOS_ENABLECARD) - cpu5wdt_start(); - if (value & WDIOS_DISABLECARD) - cpu5wdt_stop(); - break; - case WDIOC_KEEPALIVE: - cpu5wdt_reset(); - break; - default: - return -ENOTTY; - } - return 0; -} - -static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - if (!count) - return -EIO; - cpu5wdt_reset(); - return count; -} - -static const struct file_operations cpu5wdt_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = cpu5wdt_ioctl, - .compat_ioctl = compat_ptr_ioctl, - .open = cpu5wdt_open, - .write = cpu5wdt_write, - .release = cpu5wdt_release, -}; - -static struct miscdevice cpu5wdt_misc = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &cpu5wdt_fops, -}; - -/* init/exit function */ - -static int cpu5wdt_init(void) -{ - unsigned int val; - int err; - - if (verbose) - pr_debug("port=0x%x, verbose=%i\n", port, verbose); - - init_completion(&cpu5wdt_device.stop); - cpu5wdt_device.queue = 0; - timer_setup(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); - cpu5wdt_device.default_ticks = ticks; - - if (!request_region(port, CPU5WDT_EXTENT, PFX)) { - pr_err("request_region failed\n"); - err = -EBUSY; - goto no_port; - } - - /* watchdog reboot? */ - val = inb(port + CPU5WDT_STATUS_REG); - val = (val >> 2) & 1; - if (!val) - pr_info("sorry, was my fault\n"); - - err = misc_register(&cpu5wdt_misc); - if (err < 0) { - pr_err("misc_register failed\n"); - goto no_misc; - } - - - pr_info("init success\n"); - return 0; - -no_misc: - release_region(port, CPU5WDT_EXTENT); -no_port: - return err; -} - -static int cpu5wdt_init_module(void) -{ - return cpu5wdt_init(); -} - -static void cpu5wdt_exit(void) -{ - if (cpu5wdt_device.queue) { - cpu5wdt_device.queue = 0; - wait_for_completion(&cpu5wdt_device.stop); - timer_shutdown_sync(&cpu5wdt_device.timer); - } - - misc_deregister(&cpu5wdt_misc); - - release_region(port, CPU5WDT_EXTENT); - -} - -static void cpu5wdt_exit_module(void) -{ - cpu5wdt_exit(); -} - -/* module entry points */ - -module_init(cpu5wdt_init_module); -module_exit(cpu5wdt_exit_module); - -MODULE_AUTHOR("Heiko Ronsdorf "); -MODULE_DESCRIPTION("sma cpu5 watchdog driver"); -MODULE_LICENSE("GPL"); - -module_param_hw(port, int, ioport, 0); -MODULE_PARM_DESC(port, "base address of watchdog card, default is 0x91"); - -module_param(verbose, int, 0); -MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)"); - -module_param(ticks, int, 0); -MODULE_PARM_DESC(ticks, "count down ticks, default is 10000"); diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 8ee81f018dda09f52597fc77b678a6a5b18f45c3..4fb92c9e046af440603f8bda427bc8e4a23527ae 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -653,7 +653,7 @@ static struct platform_driver cpwd_driver = { .of_match_table = cpwd_match, }, .probe = cpwd_probe, - .remove_new = cpwd_remove, + .remove = cpwd_remove, }; module_platform_driver(cpwd_driver); diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c index 389a4bdd208ce69b9f6053a4d7ecd592a1b3ee7a..9d5a2009466f74cf664ee752270edda2ad07549c 100644 --- a/drivers/watchdog/da9055_wdt.c +++ b/drivers/watchdog/da9055_wdt.c @@ -146,12 +146,7 @@ static int da9055_wdt_probe(struct platform_device *pdev) return ret; } - ret = devm_watchdog_register_device(dev, &driver_data->wdt); - if (ret != 0) - dev_err(da9055->dev, "watchdog_register_device() failed: %d\n", - ret); - - return ret; + return devm_watchdog_register_device(dev, &driver_data->wdt); } static struct platform_driver da9055_wdt_driver = { diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 684667469b10c0bc1db3b31a236b0444082145f4..92e1b78ff48107df16373990a77713c83bd93cd1 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c @@ -27,7 +27,6 @@ * others: timeout = 2048 ms * 2^(TWDSCALE-1). */ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 }; -static bool use_sw_pm; #define DA9063_TWDSCALE_DISABLE 0 #define DA9063_TWDSCALE_MIN 1 @@ -230,7 +229,7 @@ static int da9063_wdt_probe(struct platform_device *pdev) if (!wdd) return -ENOMEM; - use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); + da9063->use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); wdd->info = &da9063_watchdog_info; wdd->ops = &da9063_watchdog_ops; @@ -264,11 +263,12 @@ static int da9063_wdt_probe(struct platform_device *pdev) return devm_watchdog_register_device(dev, wdd); } -static int __maybe_unused da9063_wdt_suspend(struct device *dev) +static int da9063_wdt_suspend(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); - if (!use_sw_pm) + if (!da9063->use_sw_pm) return 0; if (watchdog_active(wdd)) @@ -277,11 +277,12 @@ static int __maybe_unused da9063_wdt_suspend(struct device *dev) return 0; } -static int __maybe_unused da9063_wdt_resume(struct device *dev) +static int da9063_wdt_resume(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); - if (!use_sw_pm) + if (!da9063->use_sw_pm) return 0; if (watchdog_active(wdd)) @@ -290,14 +291,14 @@ static int __maybe_unused da9063_wdt_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, - da9063_wdt_suspend, da9063_wdt_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, da9063_wdt_suspend, + da9063_wdt_resume); static struct platform_driver da9063_wdt_driver = { .probe = da9063_wdt_probe, .driver = { .name = DA9063_DRVNAME_WATCHDOG, - .pm = &da9063_wdt_pm_ops, + .pm = pm_sleep_ptr(&da9063_wdt_pm_ops), }, }; module_platform_driver(da9063_wdt_driver); diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 84dca3695f862dc2a2c26717c8cbb27cad7db80e..26efca9ae0e7d2fea1b2eaf68085a70829b62b3a 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -684,7 +684,7 @@ MODULE_DEVICE_TABLE(of, dw_wdt_of_match); static struct platform_driver dw_wdt_driver = { .probe = dw_wdt_drv_probe, - .remove_new = dw_wdt_drv_remove, + .remove = dw_wdt_drv_remove, .driver = { .name = "dw_wdt", .of_match_table = of_match_ptr(dw_wdt_of_match), diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index d854fcfbfa5bce7715e6a8bd24049b0a82707acd..bf6f733dfb5f7b3ab846a35a5b645ee11ffefc02 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -305,7 +305,7 @@ static struct platform_driver gef_wdt_driver = { .of_match_table = gef_wdt_ids, }, .probe = gef_wdt_probe, - .remove_new = gef_wdt_remove, + .remove = gef_wdt_remove, }; static int __init gef_wdt_init(void) diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 4ed6d139320b98d0cd12429f9929716ef9b2da4e..5b80ade1c6814ae5d48bda31911c71ed7859ee1d 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -248,7 +248,7 @@ static void geodewdt_shutdown(struct platform_device *dev) } static struct platform_driver geodewdt_driver = { - .remove_new = geodewdt_remove, + .remove = geodewdt_remove, .shutdown = geodewdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/gxp-wdt.c b/drivers/watchdog/gxp-wdt.c index 2fd85be882786418125172732a2bf0507f67ff2e..f2c236160266210239bf24339821c4e9f11d420c 100644 --- a/drivers/watchdog/gxp-wdt.c +++ b/drivers/watchdog/gxp-wdt.c @@ -151,10 +151,8 @@ static int gxp_wdt_probe(struct platform_device *pdev) watchdog_stop_on_reboot(&drvdata->wdd); err = devm_watchdog_register_device(dev, &drvdata->wdd); - if (err) { - dev_err(dev, "Failed to register watchdog device"); + if (err) return err; - } dev_info(dev, "HPE GXP watchdog timer"); diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 35b358bcf94ce68fdb80d57ed4da760f09a14d18..7672582fa407649285e78c26d46b188b8f24e0c4 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -82,6 +82,13 @@ #define TCO2_CNT(p) (TCOBASE(p) + 0x0a) /* TCO2 Control Register */ #define TCOv2_TMR(p) (TCOBASE(p) + 0x12) /* TCOv2 Timer Initial Value*/ +/* + * NMI_NOW is bit 8 of TCO1_CNT register + * Read/Write + * This bit is implemented as RW but has no effect on HW. + */ +#define NMI_NOW BIT(8) + /* internal variables */ struct iTCO_wdt_private { struct watchdog_device wddev; @@ -219,13 +226,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set) struct iTCO_wdt_private *p = priv; u16 val, newval; - val = inw(TCO1_CNT(p)); + /* + * writing back 1b1 to NMI_NOW of TCO1_CNT register + * causes NMI_NOW bit inversion what consequently does + * not allow to perform the register's value comparison + * properly. + * + * NMI_NOW bit masking for TCO1_CNT register values + * helps to avoid possible NMI_NOW bit inversions on + * following write operation. + */ + val = inw(TCO1_CNT(p)) & ~NMI_NOW; if (set) val |= BIT(0); else val &= ~BIT(0); outw(val, TCO1_CNT(p)); - newval = inw(TCO1_CNT(p)); + newval = inw(TCO1_CNT(p)) & ~NMI_NOW; /* make sure the update is successful */ return val != newval ? -EIO : 0; @@ -592,10 +609,8 @@ static int iTCO_wdt_probe(struct platform_device *pdev) watchdog_stop_on_reboot(&p->wddev); watchdog_stop_on_unregister(&p->wddev); ret = devm_watchdog_register_device(dev, &p->wddev); - if (ret != 0) { - dev_err(dev, "cannot register watchdog device (err=%d)\n", ret); + if (ret != 0) return ret; - } dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n", heartbeat, nowayout); diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index b041ad90a62c53c413c9317f80bf13603a4316b7..5ce6101d236d7a0426d28825fb4493a087576805 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c @@ -331,7 +331,7 @@ static void ibwdt_shutdown(struct platform_device *dev) } static struct platform_driver ibwdt_driver = { - .remove_new = ibwdt_remove, + .remove = ibwdt_remove, .shutdown = ibwdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c index e5cbb409df252aa8cad4debfa11f17ba6eedf4ed..5a7bb7e84653f5203b9defc4b42ca19037498e93 100644 --- a/drivers/watchdog/ie6xx_wdt.c +++ b/drivers/watchdog/ie6xx_wdt.c @@ -280,7 +280,7 @@ static void ie6xx_wdt_remove(struct platform_device *pdev) static struct platform_driver ie6xx_wdt_driver = { .probe = ie6xx_wdt_probe, - .remove_new = ie6xx_wdt_remove, + .remove = ie6xx_wdt_remove, .driver = { .name = DRIVER_NAME, }, diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index 3e8c15138eddadf5ff880788bad8dd1ebc3e483a..a1e23dce88103e57aa5aacf502f717f0b6d29b1a 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -20,6 +20,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include #include #include #include @@ -40,6 +42,7 @@ #define VAL 0x2f /* Logical device Numbers LDN */ +#define EC 0x04 #define GPIO 0x07 /* Configuration Registers and Functions */ @@ -73,6 +76,12 @@ #define IT8784_ID 0x8784 #define IT8786_ID 0x8786 +/* Environment Controller Configuration Registers LDN=0x04 */ +#define SCR1 0xfa + +/* Environment Controller Bits SCR1 */ +#define WDT_PWRGD 0x20 + /* GPIO Configuration Registers LDN=0x07 */ #define WDTCTRL 0x71 #define WDTCFG 0x72 @@ -240,6 +249,21 @@ static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int t) return ret; } +enum { + IT87_WDT_OUTPUT_THROUGH_PWRGD = BIT(0), +}; + +static const struct dmi_system_id it87_quirks[] = { + { + /* Qotom Q30900P (IT8786) */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "QCML04"), + }, + .driver_data = (void *)IT87_WDT_OUTPUT_THROUGH_PWRGD, + }, + {} +}; + static const struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, .firmware_version = 1, @@ -261,8 +285,10 @@ static struct watchdog_device wdt_dev = { static int __init it87_wdt_init(void) { + const struct dmi_system_id *dmi_id; u8 chip_rev; u8 ctrl; + int quirks = 0; int rc; rc = superio_enter(); @@ -273,6 +299,10 @@ static int __init it87_wdt_init(void) chip_rev = superio_inb(CHIPREV) & 0x0f; superio_exit(); + dmi_id = dmi_first_match(it87_quirks); + if (dmi_id) + quirks = (long)dmi_id->driver_data; + switch (chip_type) { case IT8702_ID: max_units = 255; @@ -333,6 +363,15 @@ static int __init it87_wdt_init(void) superio_outb(0x00, WDTCTRL); } + if (quirks & IT87_WDT_OUTPUT_THROUGH_PWRGD) { + superio_select(EC); + ctrl = superio_inb(SCR1); + if (!(ctrl & WDT_PWRGD)) { + ctrl |= WDT_PWRGD; + superio_outb(ctrl, SCR1); + } + } + superio_exit(); if (timeout < 1 || timeout > max_units * 60) { @@ -349,10 +388,8 @@ static int __init it87_wdt_init(void) watchdog_stop_on_reboot(&wdt_dev); rc = watchdog_register_device(&wdt_dev); - if (rc) { - pr_err("Cannot register watchdog device (err=%d)\n", rc); + if (rc) return rc; - } pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", chip_type, chip_rev, timeout, nowayout, testmode); diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c index 19535f4a2fd2e5d2b4ae56280d7da89fa7234760..f19580e1b3182784e039ab1849d32926fe2e9e86 100644 --- a/drivers/watchdog/lpc18xx_wdt.c +++ b/drivers/watchdog/lpc18xx_wdt.c @@ -281,7 +281,7 @@ static struct platform_driver lpc18xx_wdt_driver = { .of_match_table = lpc18xx_wdt_match, }, .probe = lpc18xx_wdt_probe, - .remove_new = lpc18xx_wdt_remove, + .remove = lpc18xx_wdt_remove, }; module_platform_driver(lpc18xx_wdt_driver); diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c index 0508a65acfa65665f23f367f286ee2e75a34e404..6e5e4e5c0b5660bdf05bc56c3910ae1ab51d50d2 100644 --- a/drivers/watchdog/menz69_wdt.c +++ b/drivers/watchdog/menz69_wdt.c @@ -164,4 +164,4 @@ MODULE_AUTHOR("Johannes Thumshirn "); MODULE_DESCRIPTION("Watchdog driver for the MEN z069 IP-Core"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("mcb:16z069"); -MODULE_IMPORT_NS(MCB); +MODULE_IMPORT_NS("MCB"); diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index c35f85ce8d69cc5f141180316133c75d07413183..91d110646e16f7c11b3bf156c2b503b238cf8c9e 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -87,6 +88,10 @@ static const struct mtk_wdt_data mt2712_data = { .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM, }; +static const struct mtk_wdt_data mt6735_data = { + .toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM, +}; + static const struct mtk_wdt_data mt6795_data = { .toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM, }; @@ -225,9 +230,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev, { struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); void __iomem *wdt_base; + u32 reg; wdt_base = mtk_wdt->wdt_base; + /* Enable reset in order to issue a system reset instead of an IRQ */ + reg = readl(wdt_base + WDT_MODE); + reg &= ~WDT_MODE_IRQ_EN; + writel(reg | WDT_MODE_KEY, wdt_base + WDT_MODE); + while (1) { writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); mdelay(5); @@ -483,6 +494,7 @@ static int mtk_wdt_resume(struct device *dev) static const struct of_device_id mtk_wdt_dt_ids[] = { { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, { .compatible = "mediatek,mt6589-wdt" }, + { .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data }, { .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data }, { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data }, { .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data }, diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 11f05024a1812d23d77f151236bb1358ff9b4088..f75426cfa425294d12c768cdc37c80917ec917de 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -233,7 +233,7 @@ static void mtx1_wdt_remove(struct platform_device *pdev) static struct platform_driver mtx1_wdt_driver = { .probe = mtx1_wdt_probe, - .remove_new = mtx1_wdt_remove, + .remove = mtx1_wdt_remove, .driver.name = "mtx1-wdt", }; diff --git a/drivers/watchdog/nic7018_wdt.c b/drivers/watchdog/nic7018_wdt.c index c3f0a4926667e5be678d6b49bf1f6eaaf37078fb..44982b37ba6f56e9385cb70654d7726b663891d1 100644 --- a/drivers/watchdog/nic7018_wdt.c +++ b/drivers/watchdog/nic7018_wdt.c @@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(acpi, nic7018_device_ids); static struct platform_driver watchdog_driver = { .probe = nic7018_probe, - .remove_new = nic7018_remove, + .remove = nic7018_remove, .driver = { .name = KBUILD_MODNAME, .acpi_match_table = ACPI_PTR(nic7018_device_ids), diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c index f8eb1f65a59e69f380d7b017f7595790fc80dc84..f16cee5173d5046171a5d044ea864046f139eb09 100644 --- a/drivers/watchdog/nv_tco.c +++ b/drivers/watchdog/nv_tco.c @@ -466,7 +466,7 @@ static void nv_tco_shutdown(struct platform_device *dev) static struct platform_driver nv_tco_driver = { .probe = nv_tco_init, - .remove_new = nv_tco_remove, + .remove = nv_tco_remove, .shutdown = nv_tco_shutdown, .driver = { .name = TCO_MODULE_NAME, diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index 52d49e4e35a0c343924454e4cd8ec330434aa97f..0615bb8160821231ad54bdf14e4426ba0ab1da92 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c @@ -559,10 +559,8 @@ static int __init octeon_wdt_init(void) watchdog_set_nowayout(&octeon_wdt, nowayout); ret = watchdog_register_device(&octeon_wdt); - if (ret) { - pr_err("watchdog_register_device() failed: %d\n", ret); + if (ret) return ret; - } if (disable) { pr_notice("disabled\n"); diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index b6e0236509bbd668b9c57d25445f65b593c7a7f1..d523428a8d22035898a9fadc656a4ea2a65b8bd7 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -357,7 +357,7 @@ MODULE_DEVICE_TABLE(of, omap_wdt_of_match); static struct platform_driver omap_wdt_driver = { .probe = omap_wdt_probe, - .remove_new = omap_wdt_remove, + .remove = omap_wdt_remove, .shutdown = omap_wdt_shutdown, .suspend = pm_ptr(omap_wdt_suspend), .resume = pm_ptr(omap_wdt_resume), diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 1fe583e8a95b2ec2d7bcab9ccc9448b6a9e8e606..0e145f762f6f237dd85bbfde0ff3a045a6e90bc0 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -665,7 +665,7 @@ static void orion_wdt_shutdown(struct platform_device *pdev) static struct platform_driver orion_wdt_driver = { .probe = orion_wdt_probe, - .remove_new = orion_wdt_remove, + .remove = orion_wdt_remove, .shutdown = orion_wdt_shutdown, .driver = { .name = "orion_wdt", diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index 1a4282235aac581ba7c7e8fe3b5ce1e3db1371e1..31d3dcbf815e975ba54f48b4d9eb59b3fd2f900b 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c @@ -833,7 +833,7 @@ static int pcwd_isa_match(struct device *dev, unsigned int id) port0 = inb_p(base_addr); port1 = inb_p(base_addr + 1); - /* Has either hearbeat bit changed? */ + /* Has either heartbeat bit changed? */ if ((port0 ^ last_port0) & WD_HRTBT || (port1 ^ last_port1) & WD_REVC_HRBT) { retval = 1; diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index efadbb9d7ce7865f3c261fce9f053b660194153c..0e5c5c96af58d26d66b49cfa31b3f390a21faa2e 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -309,7 +309,7 @@ static void rc32434_wdt_shutdown(struct platform_device *pdev) static struct platform_driver rc32434_wdt_driver = { .probe = rc32434_wdt_probe, - .remove_new = rc32434_wdt_remove, + .remove = rc32434_wdt_remove, .shutdown = rc32434_wdt_shutdown, .driver = { .name = "rc32434_wdt", diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 80490316a27f82fb6e3741243b0ebc25382f62cb..8955177072fa44c3a0caec6ec92ec57661b599d0 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -268,7 +268,7 @@ static void rdc321x_wdt_remove(struct platform_device *pdev) static struct platform_driver rdc321x_wdt_driver = { .probe = rdc321x_wdt_probe, - .remove_new = rdc321x_wdt_remove, + .remove = rdc321x_wdt_remove, .driver = { .name = "rdc321x-wdt", }, diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 12c41d6e5cd6f53ee7bc5ef35ac67df741b45468..c0b2a9c5250dd721b6b3336d29b020770cd4dbf5 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -337,7 +337,7 @@ static struct platform_driver rwdt_driver = { .pm = &rwdt_pm_ops, }, .probe = rwdt_probe, - .remove_new = rwdt_remove, + .remove = rwdt_remove, }; module_platform_driver(rwdt_driver); diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index f47d90d01c199808abec3a2f14e292b79e8e6e6a..83806ccf06d1a7f571233dfce058c0fa2572e32c 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -238,7 +238,7 @@ static struct platform_driver riowd_driver = { .of_match_table = riowd_match, }, .probe = riowd_probe, - .remove_new = riowd_remove, + .remove = riowd_remove, }; module_platform_driver(riowd_driver); diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index 4895a69015a8ea3579675af59f23bec69669f5ab..58c9445c0f885ca44c221a2cc145fc7d56e55de1 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -61,7 +61,7 @@ #define MAX_HW_ERROR 250 -static int heartbeat = DEFAULT_HEARTBEAT; +static int heartbeat; /* * struct to hold data for each WDT device @@ -252,6 +252,7 @@ static int rti_wdt_probe(struct platform_device *pdev) wdd->min_timeout = 1; wdd->max_hw_heartbeat_ms = (WDT_PRELOAD_MAX << WDT_PRELOAD_SHIFT) / wdt->freq * 1000; + wdd->timeout = DEFAULT_HEARTBEAT; wdd->parent = dev; watchdog_set_drvdata(wdd, wdt); @@ -336,10 +337,8 @@ static int rti_wdt_probe(struct platform_device *pdev) watchdog_init_timeout(wdd, heartbeat, dev); ret = watchdog_register_device(wdd); - if (ret) { - dev_err(dev, "cannot register watchdog device\n"); + if (ret) goto err_iomap; - } if (last_ping) watchdog_set_last_hw_keepalive(wdd, last_ping); @@ -380,7 +379,7 @@ static struct platform_driver rti_wdt_driver = { .of_match_table = rti_wdt_of_match, }, .probe = rti_wdt_probe, - .remove_new = rti_wdt_remove, + .remove = rti_wdt_remove, }; module_platform_driver(rti_wdt_driver); diff --git a/drivers/watchdog/rza_wdt.c b/drivers/watchdog/rza_wdt.c index cb4901b3f7778914995f0339213bd04f9fae0d51..9334255a37e9338fa7add8229000ae9e1d79f139 100644 --- a/drivers/watchdog/rza_wdt.c +++ b/drivers/watchdog/rza_wdt.c @@ -169,7 +169,6 @@ static int rza_wdt_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rza_wdt *priv; unsigned long rate; - int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -218,11 +217,7 @@ static int rza_wdt_probe(struct platform_device *pdev) watchdog_init_timeout(&priv->wdev, 0, dev); watchdog_set_drvdata(&priv->wdev, priv); - ret = devm_watchdog_register_device(dev, &priv->wdev); - if (ret) - dev_err(dev, "Cannot register watchdog device\n"); - - return ret; + return devm_watchdog_register_device(dev, &priv->wdev); } static const struct of_device_id rza_wdt_of_match[] = { diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c index 2a35f890a2883a2b3f2d0ad42bd4be0a0f944528..11bbe48160ec9c7a9b896daf2a1ec0fd42cad758 100644 --- a/drivers/watchdog/rzg2l_wdt.c +++ b/drivers/watchdog/rzg2l_wdt.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -166,8 +167,22 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); int ret; - clk_prepare_enable(priv->pclk); - clk_prepare_enable(priv->osc_clk); + /* + * In case of RZ/G3S the watchdog device may be part of an IRQ safe power + * domain that is currently powered off. In this case we need to power + * it on before accessing registers. Along with this the clocks will be + * enabled. We don't undo the pm_runtime_resume_and_get() as the device + * need to be on for the reboot to happen. + * + * For the rest of SoCs not registering a watchdog IRQ safe power + * domain it is safe to call pm_runtime_resume_and_get() as the + * irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume() + * returns non zero value and the genpd_lock() is avoided, thus, there + * will be no invalid wait context reported by lockdep. + */ + ret = pm_runtime_resume_and_get(wdev->parent); + if (ret) + return ret; if (priv->devtype == WDT_RZG2L) { ret = reset_control_deassert(priv->rstc); @@ -275,6 +290,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) priv->devtype = (uintptr_t)of_device_get_match_data(dev); + pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); priv->wdev.info = &rzg2l_wdt_ident; diff --git a/drivers/watchdog/rzn1_wdt.c b/drivers/watchdog/rzn1_wdt.c index 7d3192d34afd50c22071eab0f0841a788b69c635..96fd04fbc2a267df034648f16572f81af3a3d06e 100644 --- a/drivers/watchdog/rzn1_wdt.c +++ b/drivers/watchdog/rzn1_wdt.c @@ -52,7 +52,7 @@ static int rzn1_wdt_ping(struct watchdog_device *w) { struct rzn1_watchdog *wdt = watchdog_get_drvdata(w); - /* Any value retrigggers the watchdog */ + /* Any value retriggers the watchdog */ writel(0, wdt->base + RZN1_WDT_RETRIGGER); return 0; diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 686cf544d0ae7a607f087a09c0ff6a64b3803158..30450e99e5e9d40b5596e2f87cc47c80ccbd2ddd 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -24,9 +24,9 @@ #include #include #include +#include #include #include -#include #define S3C2410_WTCON 0x00 #define S3C2410_WTDAT 0x04 @@ -63,6 +63,10 @@ #define EXYNOS850_CLUSTER1_NONCPU_INT_EN 0x1644 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_OUT 0x1520 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_INT_EN 0x1544 +#define EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT 0x1420 +#define EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN 0x1444 +#define EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT 0x1720 +#define EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN 0x1744 #define EXYNOS850_CLUSTER0_WDTRESET_BIT 24 #define EXYNOS850_CLUSTER1_WDTRESET_BIT 23 @@ -303,6 +307,32 @@ static const struct s3c2410_wdt_variant drv_data_gs101_cl1 = { QUIRK_HAS_DBGACK_BIT, }; +static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl0 = { + .mask_reset_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN, + .mask_bit = 2, + .mask_reset_inv = true, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = EXYNOSAUTOV9_CLUSTER0_WDTRESET_BIT, + .cnt_en_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT, + .cnt_en_bit = 7, + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | + QUIRK_HAS_DBGACK_BIT, +}; + +static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { + .mask_reset_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN, + .mask_bit = 2, + .mask_reset_inv = true, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = EXYNOSAUTOV9_CLUSTER1_WDTRESET_BIT, + .cnt_en_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT, + .cnt_en_bit = 7, + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | + QUIRK_HAS_DBGACK_BIT, +}; + static const struct of_device_id s3c2410_wdt_match[] = { { .compatible = "google,gs101-wdt", .data = &drv_data_gs101_cl0 }, @@ -320,6 +350,8 @@ static const struct of_device_id s3c2410_wdt_match[] = { .data = &drv_data_exynos850_cl0 }, { .compatible = "samsung,exynosautov9-wdt", .data = &drv_data_exynosautov9_cl0 }, + { .compatible = "samsung,exynosautov920-wdt", + .data = &drv_data_exynosautov920_cl0 }, {}, }; MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); @@ -643,7 +675,8 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) /* Choose Exynos850/ExynosAutov9 driver data w.r.t. cluster index */ if (variant == &drv_data_exynos850_cl0 || variant == &drv_data_exynosautov9_cl0 || - variant == &drv_data_gs101_cl0) { + variant == &drv_data_gs101_cl0 || + variant == &drv_data_exynosautov920_cl0) { u32 index; int err; @@ -662,6 +695,8 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) variant = &drv_data_exynosautov9_cl1; else if (variant == &drv_data_gs101_cl0) variant = &drv_data_gs101_cl1; + else if (variant == &drv_data_exynosautov920_cl0) + variant = &drv_data_exynosautov920_cl1; break; default: return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index); @@ -699,11 +734,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev) return ret; if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { - wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node, - "samsung,syscon-phandle"); + wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,syscon-phandle"); if (IS_ERR(wdt->pmureg)) return dev_err_probe(dev, PTR_ERR(wdt->pmureg), - "PMU regmap lookup failed.\n"); + "syscon regmap lookup failed.\n"); } wdt_irq = platform_get_irq(pdev, 0); diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index 6e91ee3fbfb5fabc9f1ceadc4f2ecd19c0cef9f4..729a8508b31d28519bf77766d199a92b792977a4 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c @@ -236,8 +236,8 @@ static void sa1100dog_remove(struct platform_device *pdev) static struct platform_driver sa1100dog_driver = { .driver.name = "sa1100_wdt", - .probe = sa1100dog_probe, - .remove_new = sa1100dog_remove, + .probe = sa1100dog_probe, + .remove = sa1100dog_remove, }; module_platform_driver(sa1100dog_driver); diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 76053158d259e9b70cacd9cfb7871502a881199d..9670a1ea57cbd9c54807fd72b8a2657e21b6008d 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -445,7 +445,7 @@ static void sch311x_wdt_shutdown(struct platform_device *dev) static struct platform_driver sch311x_wdt_driver = { .probe = sch311x_wdt_probe, - .remove_new = sch311x_wdt_remove, + .remove = sch311x_wdt_remove, .shutdown = sch311x_wdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 10f1fba78ec2d77036ff5ff0a14e5604dc61e49d..7f0150c39421628d6ffc882590e1767d1f97c7a9 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -297,7 +297,7 @@ static struct platform_driver sh_wdt_driver = { }, .probe = sh_wdt_probe, - .remove_new = sh_wdt_remove, + .remove = sh_wdt_remove, .shutdown = sh_wdt_shutdown, }; diff --git a/drivers/watchdog/sl28cpld_wdt.c b/drivers/watchdog/sl28cpld_wdt.c index 9ce456f09f7361784867839231d79509534a01e5..8630c29818f2e19baee49e1dc87261a02634b002 100644 --- a/drivers/watchdog/sl28cpld_wdt.c +++ b/drivers/watchdog/sl28cpld_wdt.c @@ -198,10 +198,8 @@ static int sl28cpld_wdt_probe(struct platform_device *pdev) } ret = devm_watchdog_register_device(&pdev->dev, wdd); - if (ret < 0) { - dev_err(&pdev->dev, "failed to register watchdog device\n"); + if (ret < 0) return ret; - } dev_info(&pdev->dev, "initial timeout %d sec%s\n", wdd->timeout, nowayout ? ", nowayout" : ""); diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c index 97ca500ec8a8af2c6a01602ef691dc86d5184908..3011e1af00f98a49bb6802e3d4a0dbf7e2a1c3bf 100644 --- a/drivers/watchdog/smsc37b787_wdt.c +++ b/drivers/watchdog/smsc37b787_wdt.c @@ -485,7 +485,7 @@ static long wb_smsc_wdt_ioctl(struct file *file, } } -/* -- Notifier funtions -----------------------------------------*/ +/* -- Notifier functions -----------------------------------------*/ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c index 4c5b8d98a4f30e5b4c2eecba06946238be7dabb6..d206452072ae2e8fbf7133e69d56f9fff538bec8 100644 --- a/drivers/watchdog/st_lpc_wdt.c +++ b/drivers/watchdog/st_lpc_wdt.c @@ -286,7 +286,7 @@ static struct platform_driver st_wdog_driver = { .of_match_table = st_wdog_match, }, .probe = st_wdog_probe, - .remove_new = st_wdog_remove, + .remove = st_wdog_remove, }; module_platform_driver(st_wdog_driver); diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index 19a2620d3d3893db1f57db78d230f94bc385db22..355918d62f63d54ae1efd804c575a655e9d3587d 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -80,7 +80,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); struct starfive_wdt_variant { - unsigned int control; /* Watchdog Control Resgister for reset enable */ + unsigned int control; /* Watchdog Control Register for reset enable */ unsigned int load; /* Watchdog Load register */ unsigned int reload; /* Watchdog Reload Control register */ unsigned int enable; /* Watchdog Enable Register */ @@ -597,7 +597,7 @@ MODULE_DEVICE_TABLE(of, starfive_wdt_match); static struct platform_driver starfive_wdt_driver = { .probe = starfive_wdt_probe, - .remove_new = starfive_wdt_remove, + .remove = starfive_wdt_remove, .shutdown = starfive_wdt_shutdown, .driver = { .name = "starfive-wdt", diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index 5404e0387620218d38be644aa70a7e21f2d57edc..d700e0d49bb95d5f25d60045b6462b109bf2f63a 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #define DEFAULT_TIMEOUT 10 @@ -28,6 +29,7 @@ #define IWDG_RLR 0x08 /* ReLoad Register */ #define IWDG_SR 0x0C /* Status Register */ #define IWDG_WINR 0x10 /* Windows Register */ +#define IWDG_EWCR 0x14 /* Early Wake-up Register */ /* IWDG_KR register bit mask */ #define KR_KEY_RELOAD 0xAAAA /* reload counter enable */ @@ -47,22 +49,29 @@ #define SR_PVU BIT(0) /* Watchdog prescaler value update */ #define SR_RVU BIT(1) /* Watchdog counter reload value update */ +#define EWCR_EWIT GENMASK(11, 0) /* Watchdog counter window value */ +#define EWCR_EWIC BIT(14) /* Watchdog early interrupt acknowledge */ +#define EWCR_EWIE BIT(15) /* Watchdog early interrupt enable */ + /* set timeout to 100000 us */ #define TIMEOUT_US 100000 #define SLEEP_US 1000 struct stm32_iwdg_data { bool has_pclk; + bool has_early_wakeup; u32 max_prescaler; }; static const struct stm32_iwdg_data stm32_iwdg_data = { .has_pclk = false, + .has_early_wakeup = false, .max_prescaler = 256, }; static const struct stm32_iwdg_data stm32mp1_iwdg_data = { .has_pclk = true, + .has_early_wakeup = true, .max_prescaler = 1024, }; @@ -88,13 +97,18 @@ static inline void reg_write(void __iomem *base, u32 reg, u32 val) static int stm32_iwdg_start(struct watchdog_device *wdd) { struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); - u32 tout, presc, iwdg_rlr, iwdg_pr, iwdg_sr; + u32 tout, ptot, presc, iwdg_rlr, iwdg_ewcr, iwdg_pr, iwdg_sr; int ret; dev_dbg(wdd->parent, "%s\n", __func__); + if (!wdd->pretimeout) + wdd->pretimeout = 3 * wdd->timeout / 4; + tout = clamp_t(unsigned int, wdd->timeout, wdd->min_timeout, wdd->max_hw_heartbeat_ms / 1000); + ptot = clamp_t(unsigned int, tout - wdd->pretimeout, + wdd->min_timeout, tout); presc = DIV_ROUND_UP(tout * wdt->rate, RLR_MAX + 1); @@ -102,6 +116,7 @@ static int stm32_iwdg_start(struct watchdog_device *wdd) presc = roundup_pow_of_two(presc); iwdg_pr = presc <= 1 << PR_SHIFT ? 0 : ilog2(presc) - PR_SHIFT; iwdg_rlr = ((tout * wdt->rate) / presc) - 1; + iwdg_ewcr = ((ptot * wdt->rate) / presc) - 1; /* enable write access */ reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA); @@ -109,6 +124,8 @@ static int stm32_iwdg_start(struct watchdog_device *wdd) /* set prescaler & reload registers */ reg_write(wdt->regs, IWDG_PR, iwdg_pr); reg_write(wdt->regs, IWDG_RLR, iwdg_rlr); + if (wdt->data->has_early_wakeup) + reg_write(wdt->regs, IWDG_EWCR, iwdg_ewcr | EWCR_EWIE); reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE); /* wait for the registers to be updated (max 100ms) */ @@ -151,6 +168,34 @@ static int stm32_iwdg_set_timeout(struct watchdog_device *wdd, return 0; } +static int stm32_iwdg_set_pretimeout(struct watchdog_device *wdd, + unsigned int pretimeout) +{ + dev_dbg(wdd->parent, "%s pretimeout: %d sec\n", __func__, pretimeout); + + wdd->pretimeout = pretimeout; + + if (watchdog_active(wdd)) + return stm32_iwdg_start(wdd); + + return 0; +} + +static irqreturn_t stm32_iwdg_isr(int irq, void *wdog_arg) +{ + struct watchdog_device *wdd = wdog_arg; + struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); + u32 reg; + + reg = reg_read(wdt->regs, IWDG_EWCR); + reg |= EWCR_EWIC; + reg_write(wdt->regs, IWDG_EWCR, reg); + + watchdog_notify_pretimeout(wdd); + + return IRQ_HANDLED; +} + static void stm32_clk_disable_unprepare(void *data) { clk_disable_unprepare(data); @@ -207,11 +252,20 @@ static const struct watchdog_info stm32_iwdg_info = { .identity = "STM32 Independent Watchdog", }; +static const struct watchdog_info stm32_iwdg_preinfo = { + .options = WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE | + WDIOF_KEEPALIVEPING | + WDIOF_PRETIMEOUT, + .identity = "STM32 Independent Watchdog", +}; + static const struct watchdog_ops stm32_iwdg_ops = { .owner = THIS_MODULE, .start = stm32_iwdg_start, .ping = stm32_iwdg_ping, .set_timeout = stm32_iwdg_set_timeout, + .set_pretimeout = stm32_iwdg_set_pretimeout, }; static const struct of_device_id stm32_iwdg_of_match[] = { @@ -221,6 +275,40 @@ static const struct of_device_id stm32_iwdg_of_match[] = { }; MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); +static int stm32_iwdg_irq_init(struct platform_device *pdev, + struct stm32_iwdg *wdt) +{ + struct device_node *np = pdev->dev.of_node; + struct watchdog_device *wdd = &wdt->wdd; + struct device *dev = &pdev->dev; + int irq, ret; + + if (!wdt->data->has_early_wakeup) + return 0; + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) + return 0; + + if (of_property_read_bool(np, "wakeup-source")) { + ret = device_init_wakeup(dev, true); + if (ret) + return ret; + + ret = dev_pm_set_wake_irq(dev, irq); + if (ret) + return ret; + } + + ret = devm_request_irq(dev, irq, stm32_iwdg_isr, 0, + dev_name(dev), wdd); + if (ret) + return ret; + + wdd->info = &stm32_iwdg_preinfo; + return 0; +} + static int stm32_iwdg_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -255,6 +343,11 @@ static int stm32_iwdg_probe(struct platform_device *pdev) wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler * 1000) / wdt->rate; + /* Initialize IRQ, this might override wdd->info, hence it is here. */ + ret = stm32_iwdg_irq_init(pdev, wdt); + if (ret) + return ret; + watchdog_set_drvdata(wdd, wdt); watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); watchdog_init_timeout(wdd, 0, dev); diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c index 4b2caa9807ac83213366bd3a7c29d725123a67e6..060447101f4866d6adbaf1fa8ab3867f1717403a 100644 --- a/drivers/watchdog/stmp3xxx_rtc_wdt.c +++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c @@ -143,7 +143,7 @@ static struct platform_driver stmp3xxx_wdt_driver = { .pm = &stmp3xxx_wdt_pm_ops, }, .probe = stmp3xxx_wdt_probe, - .remove_new = stmp3xxx_wdt_remove, + .remove = stmp3xxx_wdt_remove, }; module_platform_driver(stmp3xxx_wdt_driver); diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 8d5f67acbff2acdaff3861781fca8c14d494e024..305349844b4f1d906379cc134d50f963e3220313 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c @@ -159,7 +159,7 @@ static void txx9wdt_shutdown(struct platform_device *dev) static struct platform_driver txx9wdt_driver = { .probe = txx9wdt_probe, - .remove_new = txx9wdt_remove, + .remove = txx9wdt_remove, .shutdown = txx9wdt_shutdown, .driver = { .name = "txx9wdt", diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index aff2c3912ead69cae51fe8228b9f568ab2a61b41..d46d8c8c01f2d3db8d3b6121af8eaa73ca4a8fee 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c @@ -237,7 +237,7 @@ void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority) } EXPORT_SYMBOL_GPL(watchdog_set_restart_priority); -static int __watchdog_register_device(struct watchdog_device *wdd) +static int ___watchdog_register_device(struct watchdog_device *wdd) { int ret, id = -1; @@ -337,6 +337,22 @@ static int __watchdog_register_device(struct watchdog_device *wdd) return 0; } +static int __watchdog_register_device(struct watchdog_device *wdd) +{ + const char *dev_str; + int ret; + + ret = ___watchdog_register_device(wdd); + if (ret) { + dev_str = wdd->parent ? dev_name(wdd->parent) : + (const char *)wdd->info->identity; + pr_err("%s: failed to register watchdog device (err = %d)\n", + dev_str, ret); + } + + return ret; +} + /** * watchdog_register_device() - register a watchdog device * @wdd: watchdog device @@ -350,7 +366,6 @@ static int __watchdog_register_device(struct watchdog_device *wdd) int watchdog_register_device(struct watchdog_device *wdd) { - const char *dev_str; int ret = 0; mutex_lock(&wtd_deferred_reg_mutex); @@ -360,13 +375,6 @@ int watchdog_register_device(struct watchdog_device *wdd) watchdog_deferred_registration_add(wdd); mutex_unlock(&wtd_deferred_reg_mutex); - if (ret) { - dev_str = wdd->parent ? dev_name(wdd->parent) : - (const char *)wdd->info->identity; - pr_err("%s: failed to register watchdog device (err = %d)\n", - dev_str, ret); - } - return ret; } EXPORT_SYMBOL_GPL(watchdog_register_device); diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c index d271e2e8d6e27141e4112edddcb58d72556509bb..3d2a156f718009416c1d741cb2fd07dd3387e888 100644 --- a/drivers/watchdog/xilinx_wwdt.c +++ b/drivers/watchdog/xilinx_wwdt.c @@ -2,7 +2,7 @@ /* * Window watchdog device driver for Xilinx Versal WWDT * - * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. */ #include @@ -36,6 +36,12 @@ #define XWWDT_CLOSE_WINDOW_PERCENT 50 +/* Maximum count value of each 32 bit window */ +#define XWWDT_MAX_COUNT_WINDOW GENMASK(31, 0) + +/* Maximum count value of closed and open window combined */ +#define XWWDT_MAX_COUNT_WINDOW_COMBINED GENMASK_ULL(32, 1) + static int wwdt_timeout; static int closed_window_percent; @@ -54,6 +60,8 @@ MODULE_PARM_DESC(closed_window_percent, * @xilinx_wwdt_wdd: watchdog device structure * @freq: source clock frequency of WWDT * @close_percent: Closed window percent + * @closed_timeout: Closed window timeout in ticks + * @open_timeout: Open window timeout in ticks */ struct xwwdt_device { void __iomem *base; @@ -61,27 +69,22 @@ struct xwwdt_device { struct watchdog_device xilinx_wwdt_wdd; unsigned long freq; u32 close_percent; + u64 closed_timeout; + u64 open_timeout; }; static int xilinx_wwdt_start(struct watchdog_device *wdd) { struct xwwdt_device *xdev = watchdog_get_drvdata(wdd); struct watchdog_device *xilinx_wwdt_wdd = &xdev->xilinx_wwdt_wdd; - u64 time_out, closed_timeout, open_timeout; u32 control_status_reg; - /* Calculate timeout count */ - time_out = xdev->freq * wdd->timeout; - closed_timeout = div_u64(time_out * xdev->close_percent, 100); - open_timeout = time_out - closed_timeout; - wdd->min_hw_heartbeat_ms = xdev->close_percent * 10 * wdd->timeout; - spin_lock(&xdev->spinlock); iowrite32(XWWDT_MWR_MASK, xdev->base + XWWDT_MWR_OFFSET); iowrite32(~(u32)XWWDT_ESR_WEN_MASK, xdev->base + XWWDT_ESR_OFFSET); - iowrite32((u32)closed_timeout, xdev->base + XWWDT_FWR_OFFSET); - iowrite32((u32)open_timeout, xdev->base + XWWDT_SWR_OFFSET); + iowrite32((u32)xdev->closed_timeout, xdev->base + XWWDT_FWR_OFFSET); + iowrite32((u32)xdev->open_timeout, xdev->base + XWWDT_SWR_OFFSET); /* Enable the window watchdog timer */ control_status_reg = ioread32(xdev->base + XWWDT_ESR_OFFSET); @@ -133,7 +136,12 @@ static int xwwdt_probe(struct platform_device *pdev) struct watchdog_device *xilinx_wwdt_wdd; struct device *dev = &pdev->dev; struct xwwdt_device *xdev; + u64 max_per_window_ms; + u64 min_per_window_ms; + u64 timeout_count; struct clk *clk; + u32 timeout_ms; + u64 ms_count; int ret; xdev = devm_kzalloc(dev, sizeof(*xdev), GFP_KERNEL); @@ -154,12 +162,13 @@ static int xwwdt_probe(struct platform_device *pdev) return PTR_ERR(clk); xdev->freq = clk_get_rate(clk); - if (!xdev->freq) + if (xdev->freq < 1000000) return -EINVAL; xilinx_wwdt_wdd->min_timeout = XWWDT_MIN_TIMEOUT; xilinx_wwdt_wdd->timeout = XWWDT_DEFAULT_TIMEOUT; - xilinx_wwdt_wdd->max_hw_heartbeat_ms = 1000 * xilinx_wwdt_wdd->timeout; + xilinx_wwdt_wdd->max_hw_heartbeat_ms = + div64_u64(XWWDT_MAX_COUNT_WINDOW_COMBINED, xdev->freq) * 1000; if (closed_window_percent == 0 || closed_window_percent >= 100) xdev->close_percent = XWWDT_CLOSE_WINDOW_PERCENT; @@ -167,6 +176,48 @@ static int xwwdt_probe(struct platform_device *pdev) xdev->close_percent = closed_window_percent; watchdog_init_timeout(xilinx_wwdt_wdd, wwdt_timeout, &pdev->dev); + + /* Calculate ticks for 1 milli-second */ + ms_count = div_u64(xdev->freq, 1000); + timeout_ms = xilinx_wwdt_wdd->timeout * 1000; + timeout_count = timeout_ms * ms_count; + + if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms) { + /* + * To avoid ping restrictions until the minimum hardware heartbeat, + * we will solely rely on the open window and + * adjust the minimum hardware heartbeat to 0. + */ + xdev->closed_timeout = 0; + xdev->open_timeout = XWWDT_MAX_COUNT_WINDOW; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = 0; + xilinx_wwdt_wdd->max_hw_heartbeat_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2; + } else { + xdev->closed_timeout = div64_u64(timeout_count * xdev->close_percent, 100); + xilinx_wwdt_wdd->min_hw_heartbeat_ms = + div64_u64(timeout_ms * xdev->close_percent, 100); + + if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2) { + max_per_window_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2; + min_per_window_ms = timeout_ms - max_per_window_ms; + + if (xilinx_wwdt_wdd->min_hw_heartbeat_ms > max_per_window_ms) { + dev_info(xilinx_wwdt_wdd->parent, + "Closed window cannot be set to %d%%. Using maximum supported value.\n", + xdev->close_percent); + xdev->closed_timeout = max_per_window_ms * ms_count; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = max_per_window_ms; + } else if (xilinx_wwdt_wdd->min_hw_heartbeat_ms < min_per_window_ms) { + dev_info(xilinx_wwdt_wdd->parent, + "Closed window cannot be set to %d%%. Using minimum supported value.\n", + xdev->close_percent); + xdev->closed_timeout = min_per_window_ms * ms_count; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = min_per_window_ms; + } + } + xdev->open_timeout = timeout_count - xdev->closed_timeout; + } + spin_lock_init(&xdev->spinlock); watchdog_set_drvdata(xilinx_wwdt_wdd, xdev); watchdog_set_nowayout(xilinx_wwdt_wdd, 1); diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c index 775838346bb50b5fe939d71444e2762144d42145..fcc1ba02e75b6631d758fc0c77c66f84005fae97 100644 --- a/drivers/watchdog/ziirave_wdt.c +++ b/drivers/watchdog/ziirave_wdt.c @@ -715,7 +715,7 @@ static void ziirave_wdt_remove(struct i2c_client *client) } static const struct i2c_device_id ziirave_wdt_id[] = { - { "rave-wdt", 0 }, + { "rave-wdt" }, { } }; MODULE_DEVICE_TABLE(i2c, ziirave_wdt_id); diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c index 42adc2c1e06b37319be85755ec83d47ff5d2e398..5453d86324f66f956b16fdb2fc7c3366ca3a75e3 100644 --- a/drivers/xen/gntdev-dmabuf.c +++ b/drivers/xen/gntdev-dmabuf.c @@ -23,7 +23,7 @@ #include "gntdev-common.h" #include "gntdev-dmabuf.h" -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); struct gntdev_dmabuf { struct gntdev_dmabuf_priv *priv; diff --git a/drivers/xen/grant-dma-iommu.c b/drivers/xen/grant-dma-iommu.c index 2ee750a03c2f7b0463be8eb2ac9bd748692ba080..0965e2dd4edf53fa8da99666e9b4a89c6c148c6d 100644 --- a/drivers/xen/grant-dma-iommu.c +++ b/drivers/xen/grant-dma-iommu.c @@ -65,7 +65,7 @@ static struct platform_driver grant_dma_iommu_driver = { .of_match_table = grant_dma_iommu_of_match, }, .probe = grant_dma_iommu_probe, - .remove_new = grant_dma_iommu_remove, + .remove = grant_dma_iommu_remove, }; static int __init grant_dma_iommu_init(void) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 281a1ed03a04162eadb7a2f5bcd44b28728ed81d..77e9c4387c1dfd4de8a54e9b6f676bdf987dbdc9 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -659,21 +659,6 @@ static void v9fs_destroy_inode_cache(void) kmem_cache_destroy(v9fs_inode_cache); } -static int v9fs_cache_register(void) -{ - int ret; - - ret = v9fs_init_inode_cache(); - if (ret < 0) - return ret; - return ret; -} - -static void v9fs_cache_unregister(void) -{ - v9fs_destroy_inode_cache(); -} - /** * init_v9fs - Initialize module * @@ -686,7 +671,7 @@ static int __init init_v9fs(void) pr_info("Installing v9fs 9p2000 file system support\n"); /* TODO: Setup list of registered trasnport modules */ - err = v9fs_cache_register(); + err = v9fs_init_inode_cache(); if (err < 0) { pr_err("Failed to register v9fs for caching\n"); return err; @@ -709,7 +694,7 @@ out_sysfs_cleanup: v9fs_sysfs_cleanup(); out_cache: - v9fs_cache_unregister(); + v9fs_destroy_inode_cache(); return err; } @@ -722,7 +707,7 @@ out_cache: static void __exit exit_v9fs(void) { v9fs_sysfs_cleanup(); - v9fs_cache_unregister(); + v9fs_destroy_inode_cache(); unregister_filesystem(&v9fs_fs_type); } diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 148648ea1c8b9513bca44c13a7c6012b3d3a00db..693dc27ffb8979c06da18996aa6bb98c72a6e75e 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2046,7 +2046,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, const struct btrfs_key *key, struct btrfs_path *p, int ins_len, int cow) { - struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_fs_info *fs_info; struct extent_buffer *b; int slot; int ret; @@ -2059,6 +2059,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, int min_write_lock_level; int prev_cmp; + if (!root) + return -EINVAL; + + fs_info = root->fs_info; might_sleep(); lowest_level = p->lowest_level; diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 412e318e4a22d9bd57aec1a1a56effa9a24a67b1..bd09dd3ad1a0a5dbdc1a37c66b44e2a6c4d5d409 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2422,7 +2422,7 @@ int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset, goto out; ret = check_delayed_ref(root, path, objectid, offset, bytenr); - } while (ret == -EAGAIN); + } while (ret == -EAGAIN && !path->nowait); out: btrfs_release_path(path); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 03fe0de2cd0dd137f7841f7ff134d14af22be2c1..fa648ab6fe80664212fb27db58a7a89e567a7519 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3063,6 +3063,19 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) goto out; } + /* + * If it's a COW write we need to lock the extent range as we will be + * inserting/replacing file extent items and unpinning an extent map. + * This must be taken before joining a transaction, as it's a higher + * level lock (like the inode's VFS lock), otherwise we can run into an + * ABBA deadlock with other tasks (transactions work like a lock, + * depending on their current state). + */ + if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { + clear_bits |= EXTENT_LOCKED; + lock_extent(io_tree, start, end, &cached_state); + } + if (freespace_inode) trans = btrfs_join_transaction_spacecache(root); else @@ -3099,9 +3112,6 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) goto out; } - clear_bits |= EXTENT_LOCKED; - lock_extent(io_tree, start, end, &cached_state); - if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) compress_type = ordered_extent->compress_type; if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { @@ -9089,7 +9099,7 @@ static void btrfs_encoded_read_endio(struct btrfs_bio *bbio) */ WRITE_ONCE(priv->status, bbio->bio.bi_status); } - if (atomic_dec_return(&priv->pending) == 0) { + if (atomic_dec_and_test(&priv->pending)) { int err = blk_status_to_errno(READ_ONCE(priv->status)); if (priv->uring_ctx) { diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index c9302d1931870dca5916ac66b218eeb28a4357ff..3af8bb0c8d75d79a74abcd36891f6aa2dd57dcac 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4751,6 +4751,9 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss size_t page_offset; ssize_t ret; + /* The inode lock has already been acquired in btrfs_uring_read_extent. */ + btrfs_lockdep_inode_acquire(inode, i_rwsem); + if (priv->err) { ret = priv->err; goto out; @@ -4859,6 +4862,13 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, * and inode and freeing the allocations. */ + /* + * We're returning to userspace with the inode lock held, and that's + * okay - it'll get unlocked in a worker thread. Call + * btrfs_lockdep_inode_release() to avoid confusing lockdep. + */ + btrfs_lockdep_inode_release(inode, i_rwsem); + return -EIOCBQUEUED; out_fail: diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index 46c8be2afab1c690502587b8236756de288bbde5..35036b151bf5b090be340bb9a100e1e90e3d9d44 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h @@ -128,6 +128,16 @@ enum btrfs_lockdep_trans_states { #define btrfs_lockdep_release(owner, lock) \ rwsem_release(&owner->lock##_map, _THIS_IP_) +/* + * Used to account for the fact that when doing io_uring encoded I/O, we can + * return to userspace with the inode lock still held. + */ +#define btrfs_lockdep_inode_acquire(owner, lock) \ + rwsem_acquire_read(&owner->vfs_inode.lock.dep_map, 0, 0, _THIS_IP_) + +#define btrfs_lockdep_inode_release(owner, lock) \ + rwsem_release(&owner->vfs_inode.lock.dep_map, _THIS_IP_) + /* * Macros for the transaction states wait events, similar to the generic wait * event macros. diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c index 9522a8b79d22b5a9970c44c571222b40424eec44..2928abf7eb827141255e8f3caf45b49ec0de81ed 100644 --- a/fs/btrfs/ref-verify.c +++ b/fs/btrfs/ref-verify.c @@ -857,6 +857,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info, "dropping a ref for a root that doesn't have a ref on the block"); dump_block_entry(fs_info, be); dump_ref_action(fs_info, ra); + rb_erase(&ref->node, &be->refs); kfree(ref); kfree(ra); goto out_unlock; diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index b843308e2bc6f6d23b58e0c6a75f8b2292d9b4b5..fdcbf650ac31f96d9afba6b440d037c9568c2c35 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -295,7 +295,7 @@ BTRFS_FEAT_ATTR_INCOMPAT(simple_quota, SIMPLE_QUOTA); #ifdef CONFIG_BLK_DEV_ZONED BTRFS_FEAT_ATTR_INCOMPAT(zoned, ZONED); #endif -#ifdef CONFIG_BTRFS_DEBUG +#ifdef CONFIG_BTRFS_EXPERIMENTAL /* Remove once support for extent tree v2 is feature complete */ BTRFS_FEAT_ATTR_INCOMPAT(extent_tree_v2, EXTENT_TREE_V2); /* Remove once support for raid stripe tree is feature complete. */ @@ -329,7 +329,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = { #ifdef CONFIG_BLK_DEV_ZONED BTRFS_FEAT_ATTR_PTR(zoned), #endif -#ifdef CONFIG_BTRFS_DEBUG +#ifdef CONFIG_BTRFS_EXPERIMENTAL BTRFS_FEAT_ATTR_PTR(extent_tree_v2), BTRFS_FEAT_ATTR_PTR(raid_stripe_tree), #endif diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 4c82348fe1e60fdbd352a5a535a47c4e9245ceb6..85936f6d2bf705d6585535462d94fceb57786273 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -2195,7 +2195,7 @@ int ceph_pool_perm_check(struct inode *inode, int need) if (ci->i_vino.snap != CEPH_NOSNAP) { /* * Pool permission check needs to write to the first object. - * But for snapshot, head of the first object may have alread + * But for snapshot, head of the first object may have already * been deleted. Skip check to avoid creating orphan object. */ return 0; diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index bed34fc11c9195d926d400524b5d1ba055a5d602..a8d8b56cf9d2113cfaeec9ae681cc486b68d1afa 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -978,20 +978,6 @@ int __ceph_caps_revoking_other(struct ceph_inode_info *ci, return 0; } -int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) -{ - struct inode *inode = &ci->netfs.inode; - struct ceph_client *cl = ceph_inode_to_client(inode); - int ret; - - spin_lock(&ci->i_ceph_lock); - ret = __ceph_caps_revoking_other(ci, NULL, mask); - spin_unlock(&ci->i_ceph_lock); - doutc(cl, "%p %llx.%llx %s = %d\n", inode, ceph_vinop(inode), - ceph_cap_string(mask), ret); - return ret; -} - int __ceph_caps_used(struct ceph_inode_info *ci) { int used = 0; @@ -2813,7 +2799,7 @@ void ceph_take_cap_refs(struct ceph_inode_info *ci, int got, * requested from the MDS. * * Returns 0 if caps were not able to be acquired (yet), 1 if succeed, - * or a negative error code. There are 3 speical error codes: + * or a negative error code. There are 3 special error codes: * -EAGAIN: need to sleep but non-blocking is specified * -EFBIG: ask caller to call check_max_size() and try again. * -EUCLEAN: ask caller to call ceph_renew_caps() and try again. @@ -4085,23 +4071,22 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, struct ceph_cap *cap, *tcap, *new_cap = NULL; struct ceph_inode_info *ci = ceph_inode(inode); u64 t_cap_id; - unsigned mseq = le32_to_cpu(ex->migrate_seq); - unsigned t_seq, t_mseq; + u32 t_issue_seq, t_mseq; int target, issued; int mds = session->s_mds; if (ph) { t_cap_id = le64_to_cpu(ph->cap_id); - t_seq = le32_to_cpu(ph->seq); + t_issue_seq = le32_to_cpu(ph->issue_seq); t_mseq = le32_to_cpu(ph->mseq); target = le32_to_cpu(ph->mds); } else { - t_cap_id = t_seq = t_mseq = 0; + t_cap_id = t_issue_seq = t_mseq = 0; target = -1; } - doutc(cl, "%p %llx.%llx ci %p mds%d mseq %d target %d\n", - inode, ceph_vinop(inode), ci, mds, mseq, target); + doutc(cl, " cap %llx.%llx export to peer %d piseq %u pmseq %u\n", + ceph_vinop(inode), target, t_issue_seq, t_mseq); retry: down_read(&mdsc->snap_rwsem); spin_lock(&ci->i_ceph_lock); @@ -4134,12 +4119,12 @@ retry: if (tcap) { /* already have caps from the target */ if (tcap->cap_id == t_cap_id && - ceph_seq_cmp(tcap->seq, t_seq) < 0) { + ceph_seq_cmp(tcap->seq, t_issue_seq) < 0) { doutc(cl, " updating import cap %p mds%d\n", tcap, target); tcap->cap_id = t_cap_id; - tcap->seq = t_seq - 1; - tcap->issue_seq = t_seq - 1; + tcap->seq = t_issue_seq - 1; + tcap->issue_seq = t_issue_seq - 1; tcap->issued |= issued; tcap->implemented |= issued; if (cap == ci->i_auth_cap) { @@ -4154,7 +4139,7 @@ retry: int flag = (cap == ci->i_auth_cap) ? CEPH_CAP_FLAG_AUTH : 0; tcap = new_cap; ceph_add_cap(inode, tsession, t_cap_id, issued, 0, - t_seq - 1, t_mseq, (u64)-1, flag, &new_cap); + t_issue_seq - 1, t_mseq, (u64)-1, flag, &new_cap); if (!list_empty(&ci->i_cap_flush_list) && ci->i_auth_cap == tcap) { @@ -4228,18 +4213,22 @@ static void handle_cap_import(struct ceph_mds_client *mdsc, u64 realmino = le64_to_cpu(im->realm); u64 cap_id = le64_to_cpu(im->cap_id); u64 p_cap_id; + u32 piseq = 0; + u32 pmseq = 0; int peer; if (ph) { p_cap_id = le64_to_cpu(ph->cap_id); peer = le32_to_cpu(ph->mds); + piseq = le32_to_cpu(ph->issue_seq); + pmseq = le32_to_cpu(ph->mseq); } else { p_cap_id = 0; peer = -1; } - doutc(cl, "%p %llx.%llx ci %p mds%d mseq %d peer %d\n", - inode, ceph_vinop(inode), ci, mds, mseq, peer); + doutc(cl, " cap %llx.%llx import from peer %d piseq %u pmseq %u\n", + ceph_vinop(inode), peer, piseq, pmseq); retry: cap = __get_cap_for_mds(ci, mds); if (!cap) { @@ -4268,15 +4257,13 @@ retry: doutc(cl, " remove export cap %p mds%d flags %d\n", ocap, peer, ph->flags); if ((ph->flags & CEPH_CAP_FLAG_AUTH) && - (ocap->seq != le32_to_cpu(ph->seq) || - ocap->mseq != le32_to_cpu(ph->mseq))) { + (ocap->seq != piseq || + ocap->mseq != pmseq)) { pr_err_ratelimited_client(cl, "mismatched seq/mseq: " "%p %llx.%llx mds%d seq %d mseq %d" " importer mds%d has peer seq %d mseq %d\n", inode, ceph_vinop(inode), peer, - ocap->seq, ocap->mseq, mds, - le32_to_cpu(ph->seq), - le32_to_cpu(ph->mseq)); + ocap->seq, ocap->mseq, mds, piseq, pmseq); } ceph_remove_cap(mdsc, ocap, (ph->flags & CEPH_CAP_FLAG_RELEASE)); } @@ -4350,7 +4337,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, struct ceph_snap_realm *realm = NULL; int op; int msg_version = le16_to_cpu(msg->hdr.version); - u32 seq, mseq; + u32 seq, mseq, issue_seq; struct ceph_vino vino; void *snaptrace; size_t snaptrace_len; @@ -4360,8 +4347,6 @@ void ceph_handle_caps(struct ceph_mds_session *session, bool close_sessions = false; bool do_cap_release = false; - doutc(cl, "from mds%d\n", session->s_mds); - if (!ceph_inc_mds_stopping_blocker(mdsc, session)) return; @@ -4375,6 +4360,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, vino.snap = CEPH_NOSNAP; seq = le32_to_cpu(h->seq); mseq = le32_to_cpu(h->migrate_seq); + issue_seq = le32_to_cpu(h->issue_seq); snaptrace = h + 1; snaptrace_len = le32_to_cpu(h->snap_trace_len); @@ -4462,12 +4448,11 @@ void ceph_handle_caps(struct ceph_mds_session *session, /* lookup ino */ inode = ceph_find_inode(mdsc->fsc->sb, vino); - doutc(cl, " op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), - vino.ino, vino.snap, inode); + doutc(cl, " caps mds%d op %s ino %llx.%llx inode %p seq %u iseq %u mseq %u\n", + session->s_mds, ceph_cap_op_name(op), vino.ino, vino.snap, inode, + seq, issue_seq, mseq); mutex_lock(&session->s_mutex); - doutc(cl, " mds%d seq %lld cap seq %u\n", session->s_mds, - session->s_seq, (unsigned)seq); if (!inode) { doutc(cl, " i don't have ino %llx\n", vino.ino); diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h index 47e0c319fc68cfa07582f6c04cfd603a64b66f82..d0768239a1c9c96bc0b992b6160f334e19a47f89 100644 --- a/fs/ceph/crypto.h +++ b/fs/ceph/crypto.h @@ -27,7 +27,7 @@ struct ceph_fname { }; /* - * Header for the crypted file when truncating the size, this + * Header for the encrypted file when truncating the size, this * will be sent to MDS, and the MDS will update the encrypted * last block and then truncate the size. */ diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 24c08078f5aa3e49d6d1bea454e503cbc1810019..fdf9dc15eafaefcc63be128c23b5339475163b79 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -357,7 +357,7 @@ static int status_show(struct seq_file *s, void *p) seq_printf(s, "instance: %s.%lld %s/%u\n", ENTITY_NAME(inst->name), ceph_pr_addr(client_addr), le32_to_cpu(client_addr->nonce)); - seq_printf(s, "blocklisted: %s\n", fsc->blocklisted ? "true" : "false"); + seq_printf(s, "blocklisted: %s\n", str_true_false(fsc->blocklisted)); return 0; } diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 952109292d6912fc87c0e3650af9580cdb12de1b..0bf388e07a0278f2d3d3815c36290919c7e3b39c 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -207,7 +207,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, dentry = __dcache_find_get_entry(parent, idx + step, &cache_ctl); if (!dentry) { - /* use linar search */ + /* use linear search */ idx = 0; break; } @@ -659,7 +659,7 @@ static bool need_reset_readdir(struct ceph_dir_file_info *dfi, loff_t new_pos) return true; if (is_hash_order(new_pos)) { /* no need to reset last_name for a forward seek when - * dentries are sotred in hash order */ + * dentries are sorted in hash order */ } else if (dfi->frag != fpos_frag(new_pos)) { return true; } diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 44451749c5446b55d6ff14d79703fc6ce78d014a..150076ced9374b71ab69acbc6c0aa8d9e373ef45 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c @@ -393,9 +393,9 @@ static struct dentry *ceph_get_parent(struct dentry *child) } dir = snapdir; } - /* If directory has already been deleted, futher get_parent + /* If directory has already been deleted, further get_parent * will fail. Do not mark snapdir dentry as disconnected, - * this prevent exportfs from doing futher get_parent. */ + * this prevents exportfs from doing further get_parent. */ if (unlinked) dn = d_obtain_root(dir); else @@ -452,7 +452,13 @@ static int __get_snap_name(struct dentry *parent, char *name, goto out; if (ceph_snap(inode) == CEPH_SNAPDIR) { if (ceph_snap(dir) == CEPH_NOSNAP) { - strcpy(name, fsc->mount_options->snapdir_name); + /* + * .get_name() from struct export_operations + * assumes that its 'name' parameter is pointing + * to a NAME_MAX+1 sized buffer + */ + strscpy(name, fsc->mount_options->snapdir_name, + NAME_MAX + 1); err = 0; } goto out; diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 315ef02f9a3fa68bd6abc151b7f7c514bd4f9c96..7dd6c2275085b9cd116683453d34aae9baf62045 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -160,7 +160,7 @@ struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino, } /* - * get/constuct snapdir inode for a given directory + * get/construct snapdir inode for a given directory */ struct inode *ceph_get_snapdir(struct inode *parent) { diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index c4a5fd94bbbb3ba440891a5f0a860260c6e4d0d5..219a2cc2bf3cc2f22a0d76d822df3aef6de8649f 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -827,7 +827,7 @@ static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info) * And the worst case is that for the none async openc request it will * successfully open the file if the CDentry hasn't been unlinked yet, * but later the previous delayed async unlink request will remove the - * CDenty. That means the just created file is possiblly deleted later + * CDentry. That means the just created file is possibly deleted later * by accident. * * We need to wait for the inflight async unlink requests to finish @@ -1747,14 +1747,6 @@ static void __open_export_target_sessions(struct ceph_mds_client *mdsc, } } -void ceph_mdsc_open_export_target_sessions(struct ceph_mds_client *mdsc, - struct ceph_mds_session *session) -{ - mutex_lock(&mdsc->mutex); - __open_export_target_sessions(mdsc, session); - mutex_unlock(&mdsc->mutex); -} - /* * session caps */ @@ -2362,7 +2354,7 @@ again: item->ino = cpu_to_le64(cap->cap_ino); item->cap_id = cpu_to_le64(cap->cap_id); item->migrate_seq = cpu_to_le32(cap->mseq); - item->seq = cpu_to_le32(cap->issue_seq); + item->issue_seq = cpu_to_le32(cap->issue_seq); msg->front.iov_len += sizeof(*item); ceph_put_cap(mdsc, cap); @@ -3269,7 +3261,7 @@ static int __prepare_send_request(struct ceph_mds_session *session, &session->s_features); /* - * Avoid inifinite retrying after overflow. The client will + * Avoid infinite retrying after overflow. The client will * increase the retry count and if the MDS is old version, * so we limit to retry at most 256 times. */ @@ -3522,7 +3514,7 @@ static void __do_request(struct ceph_mds_client *mdsc, /* * For async create we will choose the auth MDS of frag in parent - * directory to send the request and ususally this works fine, but + * directory to send the request and usually this works fine, but * if the migrated the dirtory to another MDS before it could handle * it the request will be forwarded. * @@ -4033,7 +4025,7 @@ static void handle_forward(struct ceph_mds_client *mdsc, __unregister_request(mdsc, req); } else if (fwd_seq <= req->r_num_fwd || (uint32_t)fwd_seq >= U32_MAX) { /* - * Avoid inifinite retrying after overflow. + * Avoid infinite retrying after overflow. * * The MDS will increase the fwd count and in client side * if the num_fwd is less than the one saved in request @@ -5609,9 +5601,9 @@ void send_flush_mdlog(struct ceph_mds_session *s) static int ceph_mds_auth_match(struct ceph_mds_client *mdsc, struct ceph_mds_cap_auth *auth, + const struct cred *cred, char *tpath) { - const struct cred *cred = get_current_cred(); u32 caller_uid = from_kuid(&init_user_ns, cred->fsuid); u32 caller_gid = from_kgid(&init_user_ns, cred->fsgid); struct ceph_client *cl = mdsc->fsc->client; @@ -5734,11 +5726,12 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask) for (i = 0; i < mdsc->s_cap_auths_num; i++) { struct ceph_mds_cap_auth *s = &mdsc->s_cap_auths[i]; - err = ceph_mds_auth_match(mdsc, s, tpath); + err = ceph_mds_auth_match(mdsc, s, cred, tpath); if (err < 0) { + put_cred(cred); return err; } else if (err > 0) { - /* always follow the last auth caps' permision */ + /* always follow the last auth caps' permission */ root_squash_perms = true; rw_perms_s = NULL; if ((mask & MAY_WRITE) && s->writeable && @@ -5751,6 +5744,8 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask) } } + put_cred(cred); + doutc(cl, "root_squash_perms %d, rw_perms_s %p\n", root_squash_perms, rw_perms_s); if (root_squash_perms && rw_perms_s == NULL) { diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 3dd54587944ac05f39e2e8d79592202707c26463..38bb7e0d2d7916b6371574f082de2ab1cd79806b 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -634,8 +634,6 @@ extern void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc, extern struct ceph_mds_session * ceph_mdsc_open_export_target_session(struct ceph_mds_client *mdsc, int target); -extern void ceph_mdsc_open_export_target_sessions(struct ceph_mds_client *mdsc, - struct ceph_mds_session *session); extern int ceph_trim_caps(struct ceph_mds_client *mdsc, struct ceph_mds_session *session, diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 73f321b52895ea8b06717835f627db4dde0e2782..de03cd6eb86ee41cb521f83f6110467f9a8e0eeb 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -285,8 +285,10 @@ static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end, size_t len; struct ceph_fsid fsid; struct ceph_parse_opts_ctx *pctx = fc->fs_private; + struct ceph_options *opts = pctx->copts; struct ceph_mount_options *fsopt = pctx->opts; - char *fsid_start, *fs_name_start; + const char *name_start = dev_name; + const char *fsid_start, *fs_name_start; if (*dev_name_end != '=') { dout("separator '=' missing in source"); @@ -296,8 +298,14 @@ static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end, fsid_start = strchr(dev_name, '@'); if (!fsid_start) return invalfc(fc, "missing cluster fsid"); - ++fsid_start; /* start of cluster fsid */ + len = fsid_start - name_start; + kfree(opts->name); + opts->name = kstrndup(name_start, len, GFP_KERNEL); + if (!opts->name) + return -ENOMEM; + dout("using %s entity name", opts->name); + ++fsid_start; /* start of cluster fsid */ fs_name_start = strchr(fsid_start, '.'); if (!fs_name_start) return invalfc(fc, "missing file system name"); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 037eac35a9e02ae27f0261e1cba97fb4e596c2f3..af14ec382246257aaf5b1f7445168a6039697376 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -60,7 +60,7 @@ /* max size of osd read request, limited by libceph */ #define CEPH_MAX_READ_SIZE CEPH_MSG_MAX_DATA_LEN -/* osd has a configurable limitaion of max write size. +/* osd has a configurable limitation of max write size. * CEPH_MSG_MAX_DATA_LEN should be small enough. */ #define CEPH_MAX_WRITE_SIZE CEPH_MSG_MAX_DATA_LEN #define CEPH_RASIZE_DEFAULT (8192*1024) /* max readahead */ @@ -796,7 +796,6 @@ extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, extern int __ceph_caps_revoking_other(struct ceph_inode_info *ci, struct ceph_cap *ocap, int mask); -extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); extern int __ceph_caps_used(struct ceph_inode_info *ci); static inline bool __ceph_is_file_opened(struct ceph_inode_info *ci) diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index e066a556eccbfe370afdbf6f4aade3e26df80bb9..1a9f12204666637307d102815fb530bf0a84efc8 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -899,7 +899,7 @@ static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size, } /* - * If there are dirty xattrs, reencode xattrs into the prealloc_blob + * If there are dirty xattrs, re-encode xattrs into the prealloc_blob * and swap into place. It returns the old i_xattrs.blob (or NULL) so * that it can be freed by the caller as the i_ceph_lock is likely to be * held. diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c index 3cc89bb624f071d316a6923bdb83011b20adb69b..f7d43c847ee9518cf3aa128688fdc15817e74941 100644 --- a/fs/efivarfs/vars.c +++ b/fs/efivarfs/vars.c @@ -22,7 +22,7 @@ #include "internal.h" -MODULE_IMPORT_NS(EFIVAR); +MODULE_IMPORT_NS("EFIVAR"); static bool validate_device_path(efi_char16_t *var_name, int match, u8 *buffer, diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 6d1cf2436ead68a874913ef8508a03afd9bc419c..7e51d2cec64b48aa9e43caf40d6eebdd88eb58c6 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -57,6 +57,7 @@ static int __init hostfs_args(char *options, int *add) { char *ptr; + *add = 0; ptr = strchr(options, ','); if (ptr != NULL) *ptr++ = '\0'; @@ -471,8 +472,8 @@ static int hostfs_write_begin(struct file *file, struct address_space *mapping, *foliop = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN, mapping_gfp_mask(mapping)); - if (!*foliop) - return -ENOMEM; + if (IS_ERR(*foliop)) + return PTR_ERR(*foliop); return 0; } diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c index 79e771ab624f47d7bb20323941a6a22e9c643127..2b9ef713b844afa71ab047c23a244b76c2bce6a1 100644 --- a/fs/jffs2/compr_rtime.c +++ b/fs/jffs2/compr_rtime.c @@ -95,6 +95,9 @@ static int jffs2_rtime_decompress(unsigned char *data_in, positions[value]=outpos; if (repeat) { + if ((outpos + repeat) >= destlen) { + return 1; + } if (backoffs + repeat >= outpos) { while(repeat) { cpage_out[outpos++] = cpage_out[backoffs++]; diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c index 556de100ebd5a5318fec58cc47c6187315ed2b7b..9854253d0108bb10ecef74e17afa85f3ed6a1cf0 100644 --- a/fs/jffs2/compr_rubin.c +++ b/fs/jffs2/compr_rubin.c @@ -276,11 +276,6 @@ static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, end_rubin(&rs); - if (outpos > pos) { - /* We failed */ - return -1; - } - /* Tell the caller how much we managed to compress, * and how much space it took */ diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index acd32f05b51988f5bb84b073fb4d182b28d10c54..ef3a1e1b6cb0652e9267110cb0a21032a4a18147 100644 --- a/fs/jffs2/erase.c +++ b/fs/jffs2/erase.c @@ -338,10 +338,9 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl } while(--retlen); mtd_unpoint(c->mtd, jeb->offset, c->sector_size); if (retlen) { - pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08tx\n", - *wordebuf, - jeb->offset + - c->sector_size-retlen * sizeof(*wordebuf)); + *bad_offset = jeb->offset + c->sector_size - retlen * sizeof(*wordebuf); + pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08x\n", + *wordebuf, *bad_offset); return -EIO; } return 0; diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 822949d0eb00517758bea7e17aaeae0d699fe39a..1b833bbffcf5c3e2ffe96ce953f8de33e704c3d7 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c @@ -82,7 +82,7 @@ again: nextlist = &c->erasable_list; } else if (!list_empty(&c->erasable_pending_wbuf_list)) { - /* There are blocks are wating for the wbuf sync */ + /* There are blocks are waiting for the wbuf sync */ jffs2_dbg(1, "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n"); spin_unlock(&c->erase_completion_lock); jffs2_flush_wbuf_pad(c); diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index bbab2bdc71b6ecc5f8cf7bb729e8f1e75dfa43fc..3fb9f9807b6656f167775fd7c208125519a20e11 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "nodelist.h" #include "debug.h" @@ -317,9 +318,9 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c) And there's no space left. At all. */ pr_crit("Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n", c->nr_erasing_blocks, c->nr_free_blocks, - list_empty(&c->erasable_list) ? "yes" : "no", - list_empty(&c->erasing_list) ? "yes" : "no", - list_empty(&c->erase_pending_list) ? "yes" : "no"); + str_yes_no(list_empty(&c->erasable_list)), + str_yes_no(list_empty(&c->erasing_list)), + str_yes_no(list_empty(&c->erase_pending_list))); return -ENOSPC; } @@ -630,8 +631,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref ref->flash_offset, jeb->used_size); BUG(); }) - jffs2_dbg(1, "Obsoleting previously unchecked node at 0x%08x of len %x\n", - ref_offset(ref), freed_len); + jffs2_dbg(1, "Obsoleting previously unchecked node at 0x%08x of len %x\n", + ref_offset(ref), freed_len); jeb->unchecked_size -= freed_len; c->unchecked_size -= freed_len; } else { @@ -641,8 +642,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref ref->flash_offset, jeb->used_size); BUG(); }) - jffs2_dbg(1, "Obsoleting node at 0x%08x of len %#x: ", - ref_offset(ref), freed_len); + jffs2_dbg(1, "Obsoleting node at 0x%08x of len %#x: ", + ref_offset(ref), freed_len); jeb->used_size -= freed_len; c->used_size -= freed_len; } @@ -883,7 +884,7 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c) jffs2_dbg(1, "%s(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x, vdirty_blocks %d: %s\n", __func__, c->nr_free_blocks, c->nr_erasing_blocks, - c->dirty_size, nr_very_dirty, ret ? "yes" : "no"); + c->dirty_size, nr_very_dirty, str_yes_no(ret)); return ret; } diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 03b4f99614bef86ee840e34131b652675d7fa8b6..f987f78a894e7526c0745e8333772bb6c83c0fbb 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -72,7 +72,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info if (err != -EOPNOTSUPP) JFFS2_WARNING("MTD point failed: error code %d.\n", err); } else - pointed = 1; /* succefully pointed to device */ + pointed = 1; /* successfully pointed to device */ #endif if (!pointed) { diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index 0becdec129704f233ef9fdddcd6ef2122a7e4d72..47189476b5538bd277fec46254631025c642c7d3 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c @@ -571,19 +571,32 @@ retry: if (!node) return ERR_PTR(-ENODEV); + /* + * Devices that are marked unavailable are left in the cache with a + * timeout to avoid sending GETDEVINFO after every LAYOUTGET, or + * constantly attempting to register the device. Once marked as + * unavailable they must be deleted and never reused. + */ if (test_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags)) { unsigned long end = jiffies; unsigned long start = end - PNFS_DEVICE_RETRY_TIMEOUT; if (!time_in_range(node->timestamp_unavailable, start, end)) { + /* Uncork subsequent GETDEVINFO operations for this device */ nfs4_delete_deviceid(node->ld, node->nfs_client, id); goto retry; } goto out_put; } - if (!bl_register_dev(container_of(node, struct pnfs_block_dev, node))) + if (!bl_register_dev(container_of(node, struct pnfs_block_dev, node))) { + /* + * If we cannot register, treat this device as transient: + * Make a negative cache entry for the device + */ + nfs4_mark_deviceid_unavailable(node); goto out_put; + } return node; diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c index 6252f44479457b42fa69c79db7289fb6e1b55952..cab8809f0e0f4864dcd4bfa6cdadaaba4421c1d2 100644 --- a/fs/nfs/blocklayout/dev.c +++ b/fs/nfs/blocklayout/dev.c @@ -20,9 +20,6 @@ static void bl_unregister_scsi(struct pnfs_block_dev *dev) const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; int status; - if (!test_and_clear_bit(PNFS_BDEV_REGISTERED, &dev->flags)) - return; - status = ops->pr_register(bdev, dev->pr_key, 0, false); if (status) trace_bl_pr_key_unreg_err(bdev, dev->pr_key, status); @@ -58,7 +55,8 @@ static void bl_unregister_dev(struct pnfs_block_dev *dev) return; } - if (dev->type == PNFS_BLOCK_VOLUME_SCSI) + if (dev->type == PNFS_BLOCK_VOLUME_SCSI && + test_and_clear_bit(PNFS_BDEV_REGISTERED, &dev->flags)) bl_unregister_scsi(dev); } diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 03ecc77656151ef89aaf3fa063becec3612372fb..550ca934c9cfca57446661afbab381733a25a92d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -55,9 +55,13 @@ #define NFSDBG_FACILITY NFSDBG_CLIENT static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); -static DEFINE_SPINLOCK(nfs_version_lock); -static DEFINE_MUTEX(nfs_version_mutex); -static LIST_HEAD(nfs_versions); +static DEFINE_RWLOCK(nfs_version_lock); + +static struct nfs_subversion *nfs_version_mods[5] = { + [2] = NULL, + [3] = NULL, + [4] = NULL, +}; /* * RPC cruft for NFS @@ -76,38 +80,38 @@ const struct rpc_program nfs_program = { .pipe_dir_name = NFS_PIPE_DIRNAME, }; -static struct nfs_subversion *find_nfs_version(unsigned int version) +static struct nfs_subversion *__find_nfs_version(unsigned int version) { struct nfs_subversion *nfs; - spin_lock(&nfs_version_lock); - - list_for_each_entry(nfs, &nfs_versions, list) { - if (nfs->rpc_ops->version == version) { - spin_unlock(&nfs_version_lock); - return nfs; - } - } - spin_unlock(&nfs_version_lock); - return ERR_PTR(-EPROTONOSUPPORT); + read_lock(&nfs_version_lock); + nfs = nfs_version_mods[version]; + read_unlock(&nfs_version_lock); + return nfs; } -struct nfs_subversion *get_nfs_version(unsigned int version) +struct nfs_subversion *find_nfs_version(unsigned int version) { - struct nfs_subversion *nfs = find_nfs_version(version); + struct nfs_subversion *nfs = __find_nfs_version(version); - if (IS_ERR(nfs)) { - mutex_lock(&nfs_version_mutex); - request_module("nfsv%d", version); - nfs = find_nfs_version(version); - mutex_unlock(&nfs_version_mutex); - } + if (!nfs && request_module("nfsv%d", version) == 0) + nfs = __find_nfs_version(version); - if (!IS_ERR(nfs) && !try_module_get(nfs->owner)) + if (!nfs) + return ERR_PTR(-EPROTONOSUPPORT); + + if (!get_nfs_version(nfs)) return ERR_PTR(-EAGAIN); + return nfs; } +int get_nfs_version(struct nfs_subversion *nfs) +{ + return try_module_get(nfs->owner); +} +EXPORT_SYMBOL_GPL(get_nfs_version); + void put_nfs_version(struct nfs_subversion *nfs) { module_put(nfs->owner); @@ -115,23 +119,23 @@ void put_nfs_version(struct nfs_subversion *nfs) void register_nfs_version(struct nfs_subversion *nfs) { - spin_lock(&nfs_version_lock); + write_lock(&nfs_version_lock); - list_add(&nfs->list, &nfs_versions); + nfs_version_mods[nfs->rpc_ops->version] = nfs; nfs_version[nfs->rpc_ops->version] = nfs->rpc_vers; - spin_unlock(&nfs_version_lock); + write_unlock(&nfs_version_lock); } EXPORT_SYMBOL_GPL(register_nfs_version); void unregister_nfs_version(struct nfs_subversion *nfs) { - spin_lock(&nfs_version_lock); + write_lock(&nfs_version_lock); nfs_version[nfs->rpc_ops->version] = NULL; - list_del(&nfs->list); + nfs_version_mods[nfs->rpc_ops->version] = NULL; - spin_unlock(&nfs_version_lock); + write_unlock(&nfs_version_lock); } EXPORT_SYMBOL_GPL(unregister_nfs_version); @@ -151,7 +155,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) clp->cl_minorversion = cl_init->minorversion; clp->cl_nfs_mod = cl_init->nfs_mod; - if (!try_module_get(clp->cl_nfs_mod->owner)) + if (!get_nfs_version(clp->cl_nfs_mod)) goto error_dealloc; clp->rpc_ops = clp->cl_nfs_mod->rpc_ops; diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 90079ca134dd3cbf6591c6a6e3b98c0e3a9bf5c7..b08dbe96bc579603f03839023bd8f7a1abffac09 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -454,8 +454,16 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter, if (user_backed_iter(iter)) dreq->flags = NFS_ODIRECT_SHOULD_DIRTY; - if (!swap) - nfs_start_io_direct(inode); + if (!swap) { + result = nfs_start_io_direct(inode); + if (result) { + /* release the reference that would usually be + * consumed by nfs_direct_read_schedule_iovec() + */ + nfs_direct_req_release(dreq); + goto out_release; + } + } NFS_I(inode)->read_io += count; requested = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos); @@ -1007,7 +1015,14 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, requested = nfs_direct_write_schedule_iovec(dreq, iter, pos, FLUSH_STABLE); } else { - nfs_start_io_direct(inode); + result = nfs_start_io_direct(inode); + if (result) { + /* release the reference that would usually be + * consumed by nfs_direct_write_schedule_iovec() + */ + nfs_direct_req_release(dreq); + goto out_release; + } requested = nfs_direct_write_schedule_iovec(dreq, iter, pos, FLUSH_COND_STABLE); diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 6800ee92d742a86c55363701f72a966a7a83a035..1bb646752e4663ee79dc94c0b1f8231bf77ca598 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -166,7 +166,10 @@ nfs_file_read(struct kiocb *iocb, struct iov_iter *to) iocb->ki_filp, iov_iter_count(to), (unsigned long) iocb->ki_pos); - nfs_start_io_read(inode); + result = nfs_start_io_read(inode); + if (result) + return result; + result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); if (!result) { result = generic_file_read_iter(iocb, to); @@ -187,7 +190,10 @@ nfs_file_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe dprintk("NFS: splice_read(%pD2, %zu@%llu)\n", in, len, *ppos); - nfs_start_io_read(inode); + result = nfs_start_io_read(inode); + if (result) + return result; + result = nfs_revalidate_mapping(inode, in->f_mapping); if (!result) { result = filemap_splice_read(in, ppos, pipe, len, flags); @@ -668,7 +674,9 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) nfs_clear_invalid_mapping(file->f_mapping); since = filemap_sample_wb_err(file->f_mapping); - nfs_start_io_write(inode); + error = nfs_start_io_write(inode); + if (error) + return error; result = generic_write_checks(iocb, from); if (result > 0) result = generic_perform_write(iocb, from); diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 7e000d782e2831fa96e63e1a3ac74e028d813715..b069385eea176766591cb7fd010f7efed687c34a 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -1467,7 +1467,7 @@ static int nfs_fs_context_validate(struct fs_context *fc) /* Load the NFS protocol module if we haven't done so yet */ if (!ctx->nfs_mod) { - nfs_mod = get_nfs_version(ctx->version); + nfs_mod = find_nfs_version(ctx->version); if (IS_ERR(nfs_mod)) { ret = PTR_ERR(nfs_mod); goto out_version_unavailable; @@ -1541,7 +1541,7 @@ static int nfs_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) } nfs_copy_fh(ctx->mntfh, src->mntfh); - __module_get(ctx->nfs_mod->owner); + get_nfs_version(ctx->nfs_mod); ctx->client_address = NULL; ctx->mount_server.hostname = NULL; ctx->nfs_server.export_path = NULL; @@ -1633,7 +1633,7 @@ static int nfs_init_fs_context(struct fs_context *fc) } ctx->nfs_mod = nfss->nfs_client->cl_nfs_mod; - __module_get(ctx->nfs_mod->owner); + get_nfs_version(ctx->nfs_mod); } else { /* defaults */ ctx->timeo = NFS_UNSPEC_TIMEO; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 430733e3eff260d60d8f09dbbdac8d14d92eccdb..e564bd11ba607c5b954d91506bca230a619c0647 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -6,13 +6,14 @@ #include "nfs4_fs.h" #include #include +#include #include #include #include #include #include -#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) +#define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) extern const struct export_operations nfs_export_ops; @@ -516,11 +517,11 @@ extern const struct netfs_request_ops nfs_netfs_ops; #endif /* io.c */ -extern void nfs_start_io_read(struct inode *inode); +extern __must_check int nfs_start_io_read(struct inode *inode); extern void nfs_end_io_read(struct inode *inode); -extern void nfs_start_io_write(struct inode *inode); +extern __must_check int nfs_start_io_write(struct inode *inode); extern void nfs_end_io_write(struct inode *inode); -extern void nfs_start_io_direct(struct inode *inode); +extern __must_check int nfs_start_io_direct(struct inode *inode); extern void nfs_end_io_direct(struct inode *inode); static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi) diff --git a/fs/nfs/io.c b/fs/nfs/io.c index b5551ed8f648bce3a73d62c423965bff3cc48426..3388faf2acb9f59c20feb5bfc3f01023e9c18147 100644 --- a/fs/nfs/io.c +++ b/fs/nfs/io.c @@ -39,19 +39,28 @@ static void nfs_block_o_direct(struct nfs_inode *nfsi, struct inode *inode) * Note that buffered writes and truncates both take a write lock on * inode->i_rwsem, meaning that those are serialised w.r.t. the reads. */ -void +int nfs_start_io_read(struct inode *inode) { struct nfs_inode *nfsi = NFS_I(inode); + int err; + /* Be an optimist! */ - down_read(&inode->i_rwsem); + err = down_read_killable(&inode->i_rwsem); + if (err) + return err; if (test_bit(NFS_INO_ODIRECT, &nfsi->flags) == 0) - return; + return 0; up_read(&inode->i_rwsem); + /* Slow path.... */ - down_write(&inode->i_rwsem); + err = down_write_killable(&inode->i_rwsem); + if (err) + return err; nfs_block_o_direct(nfsi, inode); downgrade_write(&inode->i_rwsem); + + return 0; } /** @@ -74,11 +83,15 @@ nfs_end_io_read(struct inode *inode) * Declare that a buffered read operation is about to start, and ensure * that we block all direct I/O. */ -void +int nfs_start_io_write(struct inode *inode) { - down_write(&inode->i_rwsem); - nfs_block_o_direct(NFS_I(inode), inode); + int err; + + err = down_write_killable(&inode->i_rwsem); + if (!err) + nfs_block_o_direct(NFS_I(inode), inode); + return err; } /** @@ -119,19 +132,28 @@ static void nfs_block_buffered(struct nfs_inode *nfsi, struct inode *inode) * Note that buffered writes and truncates both take a write lock on * inode->i_rwsem, meaning that those are serialised w.r.t. O_DIRECT. */ -void +int nfs_start_io_direct(struct inode *inode) { struct nfs_inode *nfsi = NFS_I(inode); + int err; + /* Be an optimist! */ - down_read(&inode->i_rwsem); + err = down_read_killable(&inode->i_rwsem); + if (err) + return err; if (test_bit(NFS_INO_ODIRECT, &nfsi->flags) != 0) - return; + return 0; up_read(&inode->i_rwsem); + /* Slow path.... */ - down_write(&inode->i_rwsem); + err = down_write_killable(&inode->i_rwsem); + if (err) + return err; nfs_block_buffered(nfsi, inode); downgrade_write(&inode->i_rwsem); + + return 0; } /** diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 8f0ce82a677e1589092a30240d6e60a289d64a58..4b8618cf114caf4c52794ae734ab9de769f12934 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -42,10 +42,8 @@ struct nfs_local_fsync_ctx { struct nfsd_file *localio; struct nfs_commit_data *data; struct work_struct work; - struct kref kref; struct completion *done; }; -static void nfs_local_fsync_work(struct work_struct *work); static bool localio_enabled __read_mostly = true; module_param(localio_enabled, bool, 0644); @@ -274,7 +272,7 @@ nfs_local_iocb_free(struct nfs_local_kiocb *iocb) static struct nfs_local_kiocb * nfs_local_iocb_alloc(struct nfs_pgio_header *hdr, - struct nfsd_file *localio, gfp_t flags) + struct file *file, gfp_t flags) { struct nfs_local_kiocb *iocb; @@ -287,9 +285,8 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr, kfree(iocb); return NULL; } - init_sync_kiocb(&iocb->kiocb, nfs_to->nfsd_file_file(localio)); + init_sync_kiocb(&iocb->kiocb, file); iocb->kiocb.ki_pos = hdr->args.offset; - iocb->localio = localio; iocb->hdr = hdr; iocb->kiocb.ki_flags &= ~IOCB_APPEND; return iocb; @@ -354,6 +351,12 @@ nfs_local_read_done(struct nfs_local_kiocb *iocb, long status) nfs_local_pgio_done(hdr, status); + /* + * Must clear replen otherwise NFSv3 data corruption will occur + * if/when switching from LOCALIO back to using normal RPC. + */ + hdr->res.replen = 0; + if (hdr->res.count != hdr->args.count || hdr->args.offset + hdr->res.count >= i_size_read(file_inode(filp))) hdr->res.eof = true; @@ -390,13 +393,19 @@ nfs_do_local_read(struct nfs_pgio_header *hdr, const struct rpc_call_ops *call_ops) { struct nfs_local_kiocb *iocb; + struct file *file = nfs_to->nfsd_file_file(localio); + + /* Don't support filesystems without read_iter */ + if (!file->f_op->read_iter) + return -EAGAIN; dprintk("%s: vfs_read count=%u pos=%llu\n", __func__, hdr->args.count, hdr->args.offset); - iocb = nfs_local_iocb_alloc(hdr, localio, GFP_KERNEL); + iocb = nfs_local_iocb_alloc(hdr, file, GFP_KERNEL); if (iocb == NULL) return -ENOMEM; + iocb->localio = localio; nfs_local_pgio_init(hdr, call_ops); hdr->res.eof = false; @@ -521,12 +530,7 @@ nfs_local_write_done(struct nfs_local_kiocb *iocb, long status) } if (status < 0) nfs_reset_boot_verifier(inode); - else if (nfs_should_remove_suid(inode)) { - /* Deal with the suid/sgid bit corner case */ - spin_lock(&inode->i_lock); - nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE); - spin_unlock(&inode->i_lock); - } + nfs_local_pgio_done(hdr, status); } @@ -564,14 +568,20 @@ nfs_do_local_write(struct nfs_pgio_header *hdr, const struct rpc_call_ops *call_ops) { struct nfs_local_kiocb *iocb; + struct file *file = nfs_to->nfsd_file_file(localio); + + /* Don't support filesystems without write_iter */ + if (!file->f_op->write_iter) + return -EAGAIN; dprintk("%s: vfs_write count=%u pos=%llu %s\n", __func__, hdr->args.count, hdr->args.offset, (hdr->args.stable == NFS_UNSTABLE) ? "unstable" : "stable"); - iocb = nfs_local_iocb_alloc(hdr, localio, GFP_NOIO); + iocb = nfs_local_iocb_alloc(hdr, file, GFP_NOIO); if (iocb == NULL) return -ENOMEM; + iocb->localio = localio; switch (hdr->args.stable) { default: @@ -597,16 +607,9 @@ int nfs_local_doio(struct nfs_client *clp, struct nfsd_file *localio, const struct rpc_call_ops *call_ops) { int status = 0; - struct file *filp = nfs_to->nfsd_file_file(localio); if (!hdr->args.count) return 0; - /* Don't support filesystems without read_iter/write_iter */ - if (!filp->f_op->read_iter || !filp->f_op->write_iter) { - nfs_local_disable(clp); - status = -EAGAIN; - goto out; - } switch (hdr->rw_mode) { case FMODE_READ: @@ -620,8 +623,10 @@ int nfs_local_doio(struct nfs_client *clp, struct nfsd_file *localio, hdr->rw_mode); status = -EINVAL; } -out: + if (status != 0) { + if (status == -EAGAIN) + nfs_local_disable(clp); nfs_to_nfsd_file_put_local(localio); hdr->task.tk_status = status; nfs_local_hdr_release(hdr, call_ops); @@ -678,40 +683,12 @@ nfs_local_release_commit_data(struct nfsd_file *localio, call_ops->rpc_release(data); } -static struct nfs_local_fsync_ctx * -nfs_local_fsync_ctx_alloc(struct nfs_commit_data *data, - struct nfsd_file *localio, gfp_t flags) -{ - struct nfs_local_fsync_ctx *ctx = kmalloc(sizeof(*ctx), flags); - - if (ctx != NULL) { - ctx->localio = localio; - ctx->data = data; - INIT_WORK(&ctx->work, nfs_local_fsync_work); - kref_init(&ctx->kref); - ctx->done = NULL; - } - return ctx; -} - -static void -nfs_local_fsync_ctx_kref_free(struct kref *kref) -{ - kfree(container_of(kref, struct nfs_local_fsync_ctx, kref)); -} - -static void -nfs_local_fsync_ctx_put(struct nfs_local_fsync_ctx *ctx) -{ - kref_put(&ctx->kref, nfs_local_fsync_ctx_kref_free); -} - static void nfs_local_fsync_ctx_free(struct nfs_local_fsync_ctx *ctx) { nfs_local_release_commit_data(ctx->localio, ctx->data, ctx->data->task.tk_ops); - nfs_local_fsync_ctx_put(ctx); + kfree(ctx); } static void @@ -730,6 +707,21 @@ nfs_local_fsync_work(struct work_struct *work) nfs_local_fsync_ctx_free(ctx); } +static struct nfs_local_fsync_ctx * +nfs_local_fsync_ctx_alloc(struct nfs_commit_data *data, + struct nfsd_file *localio, gfp_t flags) +{ + struct nfs_local_fsync_ctx *ctx = kmalloc(sizeof(*ctx), flags); + + if (ctx != NULL) { + ctx->localio = localio; + ctx->data = data; + INIT_WORK(&ctx->work, nfs_local_fsync_work); + ctx->done = NULL; + } + return ctx; +} + int nfs_local_commit(struct nfsd_file *localio, struct nfs_commit_data *data, const struct rpc_call_ops *call_ops, int how) @@ -744,7 +736,7 @@ int nfs_local_commit(struct nfsd_file *localio, } nfs_local_init_commit(data, call_ops); - kref_get(&ctx->kref); + if (how & FLUSH_SYNC) { DECLARE_COMPLETION_ONSTACK(done); ctx->done = &done; @@ -752,6 +744,6 @@ int nfs_local_commit(struct nfsd_file *localio, wait_for_completion(&done); } else queue_work(nfsiod_workqueue, &ctx->work); - nfs_local_fsync_ctx_put(ctx); + return 0; } diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index e7494cdd957e51bfc830df03dc2f74c8848d1f45..2d53574da6059093e89ee4761b930ec20dd10968 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -182,7 +182,7 @@ struct vfsmount *nfs_d_automount(struct path *path) ctx->version = client->rpc_ops->version; ctx->minorversion = client->cl_minorversion; ctx->nfs_mod = client->cl_nfs_mod; - __module_get(ctx->nfs_mod->owner); + get_nfs_version(ctx->nfs_mod); ret = client->rpc_ops->submount(fc, server); if (ret < 0) { diff --git a/fs/nfs/nfs.h b/fs/nfs/nfs.h index 0d3ce0460e35b9e0371e3d2f296350e1a4bb121c..8a5f51be013a6ab4c1557934246fa56911cc72ce 100644 --- a/fs/nfs/nfs.h +++ b/fs/nfs/nfs.h @@ -19,10 +19,10 @@ struct nfs_subversion { const struct nfs_rpc_ops *rpc_ops; /* NFS operations */ const struct super_operations *sops; /* NFS Super operations */ const struct xattr_handler * const *xattr; /* NFS xattr handlers */ - struct list_head list; /* List of NFS versions */ }; -struct nfs_subversion *get_nfs_version(unsigned int); +struct nfs_subversion *find_nfs_version(unsigned int); +int get_nfs_version(struct nfs_subversion *); void put_nfs_version(struct nfs_subversion *); void register_nfs_version(struct nfs_subversion *); void unregister_nfs_version(struct nfs_subversion *); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 9d40319e063dea48bce9c94bc4ba971fc839b4ba..405f17e6e0b45b26cebae06c5bbe932895af9a56 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2603,12 +2603,14 @@ static void nfs4_open_release(void *calldata) struct nfs4_opendata *data = calldata; struct nfs4_state *state = NULL; + /* In case of error, no cleanup! */ + if (data->rpc_status != 0 || !data->rpc_done) { + nfs_release_seqid(data->o_arg.seqid); + goto out_free; + } /* If this request hasn't been cancelled, do nothing */ if (!data->cancelled) goto out_free; - /* In case of error, no cleanup! */ - if (data->rpc_status != 0 || !data->rpc_done) - goto out_free; /* In case we need an open_confirm, no cleanup! */ if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM) goto out_free; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index dafd61186557f8f4577235af852ab96f3da4c10b..9a9f60a2291b44a6c728dd42093acb7e9130eb80 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1083,14 +1083,12 @@ void nfs_release_seqid(struct nfs_seqid *seqid) return; sequence = seqid->sequence; spin_lock(&sequence->lock); - list_del_init(&seqid->list); - if (!list_empty(&sequence->list)) { - struct nfs_seqid *next; - - next = list_first_entry(&sequence->list, - struct nfs_seqid, list); + if (list_is_first(&seqid->list, &sequence->list) && + !list_is_singular(&sequence->list)) { + struct nfs_seqid *next = list_next_entry(seqid, list); rpc_wake_up_queued_task(&sequence->wait, next->task); } + list_del_init(&seqid->list); spin_unlock(&sequence->lock); } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ead2dc55952dba18cc4dbdc4f9eb4866100aeb47..50fa539611f5ecbc96a2ae7be90670001457dda4 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -144,6 +144,31 @@ static void nfs_io_completion_put(struct nfs_io_completion *ioc) kref_put(&ioc->refcount, nfs_io_completion_release); } +static void +nfs_page_set_inode_ref(struct nfs_page *req, struct inode *inode) +{ + if (!test_and_set_bit(PG_INODE_REF, &req->wb_flags)) { + kref_get(&req->wb_kref); + atomic_long_inc(&NFS_I(inode)->nrequests); + } +} + +static int +nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode) +{ + int ret; + + if (!test_bit(PG_REMOVE, &req->wb_flags)) + return 0; + ret = nfs_page_group_lock(req); + if (ret) + return ret; + if (test_and_clear_bit(PG_REMOVE, &req->wb_flags)) + nfs_page_set_inode_ref(req, inode); + nfs_page_group_unlock(req); + return 0; +} + /** * nfs_folio_find_head_request - find head request associated with a folio * @folio: pointer to folio @@ -540,7 +565,6 @@ static struct nfs_page *nfs_lock_and_join_requests(struct folio *folio) struct inode *inode = folio->mapping->host; struct nfs_page *head, *subreq; struct nfs_commit_info cinfo; - bool removed; int ret; /* @@ -565,18 +589,18 @@ retry: goto retry; } - ret = nfs_page_group_lock(head); + ret = nfs_cancel_remove_inode(head, inode); if (ret < 0) goto out_unlock; - removed = test_bit(PG_REMOVE, &head->wb_flags); + ret = nfs_page_group_lock(head); + if (ret < 0) + goto out_unlock; /* lock each request in the page group */ for (subreq = head->wb_this_page; subreq != head; subreq = subreq->wb_this_page) { - if (test_bit(PG_REMOVE, &subreq->wb_flags)) - removed = true; ret = nfs_page_group_lock_subreq(head, subreq); if (ret < 0) goto out_unlock; @@ -584,21 +608,6 @@ retry: nfs_page_group_unlock(head); - /* - * If PG_REMOVE is set on any request, I/O on that request has - * completed, but some requests were still under I/O at the time - * we locked the head request. - * - * In that case the above wait for all requests means that all I/O - * has now finished, and we can restart from a clean slate. Let the - * old requests go away and start from scratch instead. - */ - if (removed) { - nfs_unroll_locks(head, head); - nfs_unlock_and_release_request(head); - goto retry; - } - nfs_init_cinfo_from_inode(&cinfo, inode); nfs_join_page_group(head, &cinfo, inode); return head; @@ -772,7 +781,8 @@ static void nfs_inode_add_request(struct nfs_page *req) nfs_lock_request(req); spin_lock(&mapping->i_private_lock); set_bit(PG_MAPPED, &req->wb_flags); - folio_attach_private(folio, req); + folio_set_private(folio); + folio->private = req; spin_unlock(&mapping->i_private_lock); atomic_long_inc(&nfsi->nrequests); /* this a head request for a page group - mark it as having an @@ -796,7 +806,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) spin_lock(&mapping->i_private_lock); if (likely(folio)) { - folio_detach_private(folio); + folio->private = NULL; + folio_clear_private(folio); clear_bit(PG_MAPPED, &req->wb_head->wb_flags); } spin_unlock(&mapping->i_private_lock); diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 4311fcbc84f298864ad99d58fe7ebd31d530ae12..bc68b4de5287db1de49b1eaa925b2d2d4172ea3f 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -901,7 +901,7 @@ MODULE_DEVICE_TABLE(of, dt_match); static struct platform_driver ramoops_driver = { .probe = ramoops_probe, - .remove_new = ramoops_remove, + .remove = ramoops_remove, .driver = { .name = "ramoops", .of_match_table = dt_match, diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 3dd8d6f277253853decf987b0df1d8b3fa9a7df5..f9578918cfb25dea6fb4cc2efd4043b0308089fb 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -688,6 +688,8 @@ int dquot_writeback_dquots(struct super_block *sb, int type) WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount)); + flush_delayed_work("a_release_work); + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && cnt != type) continue; diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 06eb19dabb0ecc12e6f254cbeb3830db1d255882..fe738623cf1ba91ee44e23de346c60460cbc647d 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -17,6 +17,11 @@ static void free_cached_dir(struct cached_fid *cfid); static void smb2_close_cached_fid(struct kref *ref); static void cfids_laundromat_worker(struct work_struct *work); +struct cached_dir_dentry { + struct list_head entry; + struct dentry *dentry; +}; + static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids, const char *path, bool lookup_only, @@ -157,15 +162,17 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, const char *npath; int retries = 0, cur_sleep = 1; - if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache || - is_smb1_server(tcon->ses->server) || (dir_cache_timeout == 0)) + if (cifs_sb->root == NULL) + return -ENOENT; + + if (tcon == NULL) return -EOPNOTSUPP; ses = tcon->ses; cfids = tcon->cfids; - if (cifs_sb->root == NULL) - return -ENOENT; + if (cfids == NULL) + return -EOPNOTSUPP; replay_again: /* reinitialize for possible replay */ @@ -222,6 +229,7 @@ replay_again: } } cfid->dentry = dentry; + cfid->tcon = tcon; /* * We do not hold the lock for the open because in case @@ -293,7 +301,6 @@ replay_again: } goto oshr_free; } - cfid->tcon = tcon; cfid->is_open = true; spin_lock(&cfids->cfid_list_lock); @@ -389,7 +396,7 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, struct cached_fids *cfids = tcon->cfids; if (cfids == NULL) - return -ENOENT; + return -EOPNOTSUPP; spin_lock(&cfids->cfid_list_lock); list_for_each_entry(cfid, &cfids->entries, entry) { @@ -470,7 +477,10 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) struct cifs_tcon *tcon; struct tcon_link *tlink; struct cached_fids *cfids; + struct cached_dir_dentry *tmp_list, *q; + LIST_HEAD(entry); + spin_lock(&cifs_sb->tlink_tree_lock); for (node = rb_first(root); node; node = rb_next(node)) { tlink = rb_entry(node, struct tcon_link, tl_rbnode); tcon = tlink_tcon(tlink); @@ -479,11 +489,30 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) cfids = tcon->cfids; if (cfids == NULL) continue; + spin_lock(&cfids->cfid_list_lock); list_for_each_entry(cfid, &cfids->entries, entry) { - dput(cfid->dentry); + tmp_list = kmalloc(sizeof(*tmp_list), GFP_ATOMIC); + if (tmp_list == NULL) + break; + spin_lock(&cfid->fid_lock); + tmp_list->dentry = cfid->dentry; cfid->dentry = NULL; + spin_unlock(&cfid->fid_lock); + + list_add_tail(&tmp_list->entry, &entry); } + spin_unlock(&cfids->cfid_list_lock); } + spin_unlock(&cifs_sb->tlink_tree_lock); + + list_for_each_entry_safe(tmp_list, q, &entry, entry) { + list_del(&tmp_list->entry); + dput(tmp_list->dentry); + kfree(tmp_list); + } + + /* Flush any pending work that will drop dentries */ + flush_workqueue(cfid_put_wq); } /* @@ -494,14 +523,18 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) { struct cached_fids *cfids = tcon->cfids; struct cached_fid *cfid, *q; - LIST_HEAD(entry); if (cfids == NULL) return; + /* + * Mark all the cfids as closed, and move them to the cfids->dying list. + * They'll be cleaned up later by cfids_invalidation_worker. Take + * a reference to each cfid during this process. + */ spin_lock(&cfids->cfid_list_lock); list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { - list_move(&cfid->entry, &entry); + list_move(&cfid->entry, &cfids->dying); cfids->num_entries--; cfid->is_open = false; cfid->on_list = false; @@ -514,26 +547,47 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) } else kref_get(&cfid->refcount); } + /* + * Queue dropping of the dentries once locks have been dropped + */ + if (!list_empty(&cfids->dying)) + queue_work(cfid_put_wq, &cfids->invalidation_work); spin_unlock(&cfids->cfid_list_lock); - - list_for_each_entry_safe(cfid, q, &entry, entry) { - list_del(&cfid->entry); - cancel_work_sync(&cfid->lease_break); - /* - * Drop the ref-count from above, either the lease-ref (if there - * was one) or the extra one acquired. - */ - kref_put(&cfid->refcount, smb2_close_cached_fid); - } } static void -smb2_cached_lease_break(struct work_struct *work) +cached_dir_offload_close(struct work_struct *work) { struct cached_fid *cfid = container_of(work, - struct cached_fid, lease_break); + struct cached_fid, close_work); + struct cifs_tcon *tcon = cfid->tcon; + + WARN_ON(cfid->on_list); kref_put(&cfid->refcount, smb2_close_cached_fid); + cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close); +} + +/* + * Release the cached directory's dentry, and then queue work to drop cached + * directory itself (closing on server if needed). + * + * Must be called with a reference to the cached_fid and a reference to the + * tcon. + */ +static void cached_dir_put_work(struct work_struct *work) +{ + struct cached_fid *cfid = container_of(work, struct cached_fid, + put_work); + struct dentry *dentry; + + spin_lock(&cfid->fid_lock); + dentry = cfid->dentry; + cfid->dentry = NULL; + spin_unlock(&cfid->fid_lock); + + dput(dentry); + queue_work(serverclose_wq, &cfid->close_work); } int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]) @@ -560,8 +614,10 @@ int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]) cfid->on_list = false; cfids->num_entries--; - queue_work(cifsiod_wq, - &cfid->lease_break); + ++tcon->tc_count; + trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count, + netfs_trace_tcon_ref_get_cached_lease_break); + queue_work(cfid_put_wq, &cfid->put_work); spin_unlock(&cfids->cfid_list_lock); return true; } @@ -583,7 +639,8 @@ static struct cached_fid *init_cached_dir(const char *path) return NULL; } - INIT_WORK(&cfid->lease_break, smb2_cached_lease_break); + INIT_WORK(&cfid->close_work, cached_dir_offload_close); + INIT_WORK(&cfid->put_work, cached_dir_put_work); INIT_LIST_HEAD(&cfid->entry); INIT_LIST_HEAD(&cfid->dirents.entries); mutex_init(&cfid->dirents.de_mutex); @@ -596,6 +653,9 @@ static void free_cached_dir(struct cached_fid *cfid) { struct cached_dirent *dirent, *q; + WARN_ON(work_pending(&cfid->close_work)); + WARN_ON(work_pending(&cfid->put_work)); + dput(cfid->dentry); cfid->dentry = NULL; @@ -613,10 +673,30 @@ static void free_cached_dir(struct cached_fid *cfid) kfree(cfid); } +static void cfids_invalidation_worker(struct work_struct *work) +{ + struct cached_fids *cfids = container_of(work, struct cached_fids, + invalidation_work); + struct cached_fid *cfid, *q; + LIST_HEAD(entry); + + spin_lock(&cfids->cfid_list_lock); + /* move cfids->dying to the local list */ + list_cut_before(&entry, &cfids->dying, &cfids->dying); + spin_unlock(&cfids->cfid_list_lock); + + list_for_each_entry_safe(cfid, q, &entry, entry) { + list_del(&cfid->entry); + /* Drop the ref-count acquired in invalidate_all_cached_dirs */ + kref_put(&cfid->refcount, smb2_close_cached_fid); + } +} + static void cfids_laundromat_worker(struct work_struct *work) { struct cached_fids *cfids; struct cached_fid *cfid, *q; + struct dentry *dentry; LIST_HEAD(entry); cfids = container_of(work, struct cached_fids, laundromat_work.work); @@ -642,18 +722,28 @@ static void cfids_laundromat_worker(struct work_struct *work) list_for_each_entry_safe(cfid, q, &entry, entry) { list_del(&cfid->entry); - /* - * Cancel and wait for the work to finish in case we are racing - * with it. - */ - cancel_work_sync(&cfid->lease_break); - /* - * Drop the ref-count from above, either the lease-ref (if there - * was one) or the extra one acquired. - */ - kref_put(&cfid->refcount, smb2_close_cached_fid); + + spin_lock(&cfid->fid_lock); + dentry = cfid->dentry; + cfid->dentry = NULL; + spin_unlock(&cfid->fid_lock); + + dput(dentry); + if (cfid->is_open) { + spin_lock(&cifs_tcp_ses_lock); + ++cfid->tcon->tc_count; + trace_smb3_tcon_ref(cfid->tcon->debug_id, cfid->tcon->tc_count, + netfs_trace_tcon_ref_get_cached_laundromat); + spin_unlock(&cifs_tcp_ses_lock); + queue_work(serverclose_wq, &cfid->close_work); + } else + /* + * Drop the ref-count from above, either the lease-ref (if there + * was one) or the extra one acquired. + */ + kref_put(&cfid->refcount, smb2_close_cached_fid); } - queue_delayed_work(cifsiod_wq, &cfids->laundromat_work, + queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout * HZ); } @@ -666,9 +756,11 @@ struct cached_fids *init_cached_dirs(void) return NULL; spin_lock_init(&cfids->cfid_list_lock); INIT_LIST_HEAD(&cfids->entries); + INIT_LIST_HEAD(&cfids->dying); + INIT_WORK(&cfids->invalidation_work, cfids_invalidation_worker); INIT_DELAYED_WORK(&cfids->laundromat_work, cfids_laundromat_worker); - queue_delayed_work(cifsiod_wq, &cfids->laundromat_work, + queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout * HZ); return cfids; @@ -687,6 +779,7 @@ void free_cached_dirs(struct cached_fids *cfids) return; cancel_delayed_work_sync(&cfids->laundromat_work); + cancel_work_sync(&cfids->invalidation_work); spin_lock(&cfids->cfid_list_lock); list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { @@ -694,6 +787,11 @@ void free_cached_dirs(struct cached_fids *cfids) cfid->is_open = false; list_move(&cfid->entry, &entry); } + list_for_each_entry_safe(cfid, q, &cfids->dying, entry) { + cfid->on_list = false; + cfid->is_open = false; + list_move(&cfid->entry, &entry); + } spin_unlock(&cfids->cfid_list_lock); list_for_each_entry_safe(cfid, q, &entry, entry) { diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h index 81ba0fd5cc16d6bd9bb782dc4a13f32a9b1322f5..1dfe79d947a62faab6df347d3463cc44af96fb83 100644 --- a/fs/smb/client/cached_dir.h +++ b/fs/smb/client/cached_dir.h @@ -44,7 +44,8 @@ struct cached_fid { spinlock_t fid_lock; struct cifs_tcon *tcon; struct dentry *dentry; - struct work_struct lease_break; + struct work_struct put_work; + struct work_struct close_work; struct smb2_file_all_info file_all_info; struct cached_dirents dirents; }; @@ -53,10 +54,13 @@ struct cached_fid { struct cached_fids { /* Must be held when: * - accessing the cfids->entries list + * - accessing the cfids->dying list */ spinlock_t cfid_list_lock; int num_entries; struct list_head entries; + struct list_head dying; + struct work_struct invalidation_work; struct delayed_work laundromat_work; }; diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 97985347102792a987b419300c90d710ca93ad1d..c9f9b6e97964838bffa34b70d436aa95c7b3f4ae 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -157,6 +157,7 @@ struct workqueue_struct *fileinfo_put_wq; struct workqueue_struct *cifsoplockd_wq; struct workqueue_struct *deferredclose_wq; struct workqueue_struct *serverclose_wq; +struct workqueue_struct *cfid_put_wq; __u32 cifs_lock_secret; /* @@ -1920,9 +1921,16 @@ init_cifs(void) goto out_destroy_deferredclose_wq; } + cfid_put_wq = alloc_workqueue("cfid_put_wq", + WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); + if (!cfid_put_wq) { + rc = -ENOMEM; + goto out_destroy_serverclose_wq; + } + rc = cifs_init_inodecache(); if (rc) - goto out_destroy_serverclose_wq; + goto out_destroy_cfid_put_wq; rc = cifs_init_netfs(); if (rc) @@ -1990,6 +1998,8 @@ out_destroy_netfs: cifs_destroy_netfs(); out_destroy_inodecache: cifs_destroy_inodecache(); +out_destroy_cfid_put_wq: + destroy_workqueue(cfid_put_wq); out_destroy_serverclose_wq: destroy_workqueue(serverclose_wq); out_destroy_deferredclose_wq: diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h index 71b720dbb2ce341a1fbd0926246801a41169785b..a762dbbbd959b4bbcd696b8fc0e23f5ada991b20 100644 --- a/fs/smb/client/cifsfs.h +++ b/fs/smb/client/cifsfs.h @@ -146,6 +146,6 @@ extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ /* when changing internal version - update following two lines at same time */ -#define SMB3_PRODUCT_BUILD 51 -#define CIFS_VERSION "2.51" +#define SMB3_PRODUCT_BUILD 52 +#define CIFS_VERSION "2.52" #endif /* _CIFSFS_H */ diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index fc33dfe7e925453e6366144934bffa30af5bbe58..6e63abe461fd2e31e8554867e58b3c6a04d56b94 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -594,6 +594,7 @@ struct smb_version_operations { /* Check for STATUS_NETWORK_NAME_DELETED */ bool (*is_network_name_deleted)(char *buf, struct TCP_Server_Info *srv); int (*parse_reparse_point)(struct cifs_sb_info *cifs_sb, + const char *full_path, struct kvec *rsp_iov, struct cifs_open_info_data *data); int (*create_reparse_symlink)(const unsigned int xid, @@ -1990,7 +1991,7 @@ require use of the stronger protocol */ * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once * ->can_cache_brlcks * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc - * cached_fid->fid_mutex cifs_tcon->crfid tcon_info_alloc + * cached_fids->cfid_list_lock cifs_tcon->cfids->entries init_cached_dirs * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo * ->invalidHandle initiate_cifs_search @@ -2078,6 +2079,7 @@ extern struct workqueue_struct *fileinfo_put_wq; extern struct workqueue_struct *cifsoplockd_wq; extern struct workqueue_struct *deferredclose_wq; extern struct workqueue_struct *serverclose_wq; +extern struct workqueue_struct *cfid_put_wq; extern __u32 cifs_lock_secret; extern mempool_t *cifs_sm_req_poolp; diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 075985bfb13a8c5296c562b9d596b43a9e4edceb..bbaaf16af20fda1a321c71aa54d618d0aa669ddd 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -314,8 +314,7 @@ extern void cifs_move_llist(struct list_head *source, struct list_head *dest); extern void cifs_free_llist(struct list_head *llist); extern void cifs_del_lock_waiters(struct cifsLockInfo *lock); -extern int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, - const struct nls_table *nlsc); +int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon); extern int cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, @@ -661,6 +660,7 @@ char *extract_hostname(const char *unc); char *extract_sharename(const char *unc); int parse_reparse_point(struct reparse_data_buffer *buf, u32 plen, struct cifs_sb_info *cifs_sb, + const char *full_path, bool unicode, struct cifs_open_info_data *data); int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index 4858331ee9182d40dc6bc37ac4bf582b152eb951..bd42a419458e324521b90f738dbd2edee46ad00a 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -70,10 +70,9 @@ static struct { static int cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) { - int rc; - struct cifs_ses *ses; struct TCP_Server_Info *server; - struct nls_table *nls_codepage = NULL; + struct cifs_ses *ses; + int rc; /* * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for @@ -131,8 +130,6 @@ again: } spin_unlock(&server->srv_lock); - nls_codepage = ses->local_nls; - /* * need to prevent multiple threads trying to simultaneously * reconnect the same SMB session @@ -156,7 +153,7 @@ again: rc = cifs_negotiate_protocol(0, ses, server); if (!rc) - rc = cifs_setup_session(0, ses, server, nls_codepage); + rc = cifs_setup_session(0, ses, server, ses->local_nls); /* do we need to reconnect tcon? */ if (rc || !tcon->need_reconnect) { @@ -166,7 +163,7 @@ again: skip_sess_setup: cifs_mark_open_files_invalid(tcon); - rc = cifs_tree_connect(0, tcon, nls_codepage); + rc = cifs_tree_connect(0, tcon); mutex_unlock(&ses->session_mutex); cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); @@ -4320,8 +4317,8 @@ getDFSRetry: * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus * causing an infinite recursion. */ - rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, - (void **)&pSMB, (void **)&pSMBr); + rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, + (void **)&pSMB, (void **)&pSMBr); if (rc) return rc; diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 0a97228c06b1e77246f2723a3c327fef7cb98ea8..56b3a9eb9b05558e358df735b326a19d0ea9fd84 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -1897,11 +1897,35 @@ static int match_session(struct cifs_ses *ses, CIFS_MAX_USERNAME_LEN)) return 0; if ((ctx->username && strlen(ctx->username) != 0) && - ses->password != NULL && - strncmp(ses->password, - ctx->password ? ctx->password : "", - CIFS_MAX_PASSWORD_LEN)) - return 0; + ses->password != NULL) { + + /* New mount can only share sessions with an existing mount if: + * 1. Both password and password2 match, or + * 2. password2 of the old mount matches password of the new mount + * and password of the old mount matches password2 of the new + * mount + */ + if (ses->password2 != NULL && ctx->password2 != NULL) { + if (!((strncmp(ses->password, ctx->password ? + ctx->password : "", CIFS_MAX_PASSWORD_LEN) == 0 && + strncmp(ses->password2, ctx->password2, + CIFS_MAX_PASSWORD_LEN) == 0) || + (strncmp(ses->password, ctx->password2, + CIFS_MAX_PASSWORD_LEN) == 0 && + strncmp(ses->password2, ctx->password ? + ctx->password : "", CIFS_MAX_PASSWORD_LEN) == 0))) + return 0; + + } else if ((ses->password2 == NULL && ctx->password2 != NULL) || + (ses->password2 != NULL && ctx->password2 == NULL)) { + return 0; + + } else { + if (strncmp(ses->password, ctx->password ? + ctx->password : "", CIFS_MAX_PASSWORD_LEN)) + return 0; + } + } } if (strcmp(ctx->local_nls->charset, ses->local_nls->charset)) @@ -2244,6 +2268,7 @@ struct cifs_ses * cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) { int rc = 0; + int retries = 0; unsigned int xid; struct cifs_ses *ses; struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; @@ -2262,6 +2287,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) cifs_dbg(FYI, "Session needs reconnect\n"); mutex_lock(&ses->session_mutex); + +retry_old_session: rc = cifs_negotiate_protocol(xid, ses, server); if (rc) { mutex_unlock(&ses->session_mutex); @@ -2274,6 +2301,13 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) rc = cifs_setup_session(xid, ses, server, ctx->local_nls); if (rc) { + if (((rc == -EACCES) || (rc == -EKEYEXPIRED) || + (rc == -EKEYREVOKED)) && !retries && ses->password2) { + retries++; + cifs_dbg(FYI, "Session reconnect failed, retrying with alternate password\n"); + swap(ses->password, ses->password2); + goto retry_old_session; + } mutex_unlock(&ses->session_mutex); /* problem -- put our reference */ cifs_put_smb_ses(ses); @@ -2369,6 +2403,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) ses->chans_need_reconnect = 1; spin_unlock(&ses->chan_lock); +retry_new_session: mutex_lock(&ses->session_mutex); rc = cifs_negotiate_protocol(xid, ses, server); if (!rc) @@ -2381,8 +2416,16 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) sizeof(ses->smb3signingkey)); spin_unlock(&ses->chan_lock); - if (rc) - goto get_ses_fail; + if (rc) { + if (((rc == -EACCES) || (rc == -EKEYEXPIRED) || + (rc == -EKEYREVOKED)) && !retries && ses->password2) { + retries++; + cifs_dbg(FYI, "Session setup failed, retrying with alternate password\n"); + swap(ses->password, ses->password2); + goto retry_new_session; + } else + goto get_ses_fail; + } /* * success, put it on the list and add it as first channel @@ -2571,7 +2614,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) if (ses->server->dialect >= SMB20_PROT_ID && (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)) - nohandlecache = ctx->nohandlecache; + nohandlecache = ctx->nohandlecache || !dir_cache_timeout; else nohandlecache = true; tcon = tcon_info_alloc(!nohandlecache, netfs_trace_tcon_ref_new); @@ -4344,10 +4387,10 @@ cifs_prune_tlinks(struct work_struct *work) } #ifndef CONFIG_CIFS_DFS_UPCALL -int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) +int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon) { - int rc; const struct smb_version_operations *ops = tcon->ses->server->ops; + int rc; /* only send once per connect */ spin_lock(&tcon->tc_lock); @@ -4370,7 +4413,8 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru tcon->status = TID_IN_TCON; spin_unlock(&tcon->tc_lock); - rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, nlsc); + rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, + tcon, tcon->ses->local_nls); if (rc) { spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_TCON) diff --git a/fs/smb/client/dfs.c b/fs/smb/client/dfs.c index 3f6077c68d68aa4a4f0c5ebe9abe157abdb170a7..4647df9e1e3bfcdc258ad77eb18951d841e5fe89 100644 --- a/fs/smb/client/dfs.c +++ b/fs/smb/client/dfs.c @@ -321,49 +321,6 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx) return rc; } -/* Update dfs referral path of superblock */ -static int update_server_fullpath(struct TCP_Server_Info *server, struct cifs_sb_info *cifs_sb, - const char *target) -{ - int rc = 0; - size_t len = strlen(target); - char *refpath, *npath; - - if (unlikely(len < 2 || *target != '\\')) - return -EINVAL; - - if (target[1] == '\\') { - len += 1; - refpath = kmalloc(len, GFP_KERNEL); - if (!refpath) - return -ENOMEM; - - scnprintf(refpath, len, "%s", target); - } else { - len += sizeof("\\"); - refpath = kmalloc(len, GFP_KERNEL); - if (!refpath) - return -ENOMEM; - - scnprintf(refpath, len, "\\%s", target); - } - - npath = dfs_cache_canonical_path(refpath, cifs_sb->local_nls, cifs_remap(cifs_sb)); - kfree(refpath); - - if (IS_ERR(npath)) { - rc = PTR_ERR(npath); - } else { - mutex_lock(&server->refpath_lock); - spin_lock(&server->srv_lock); - kfree(server->leaf_fullpath); - server->leaf_fullpath = npath; - spin_unlock(&server->srv_lock); - mutex_unlock(&server->refpath_lock); - } - return rc; -} - static int target_share_matches_server(struct TCP_Server_Info *server, char *share, bool *target_match) { @@ -388,77 +345,22 @@ static int target_share_matches_server(struct TCP_Server_Info *server, char *sha return rc; } -static void __tree_connect_ipc(const unsigned int xid, char *tree, - struct cifs_sb_info *cifs_sb, - struct cifs_ses *ses) -{ - struct TCP_Server_Info *server = ses->server; - struct cifs_tcon *tcon = ses->tcon_ipc; - int rc; - - spin_lock(&ses->ses_lock); - spin_lock(&ses->chan_lock); - if (cifs_chan_needs_reconnect(ses, server) || - ses->ses_status != SES_GOOD) { - spin_unlock(&ses->chan_lock); - spin_unlock(&ses->ses_lock); - cifs_server_dbg(FYI, "%s: skipping ipc reconnect due to disconnected ses\n", - __func__); - return; - } - spin_unlock(&ses->chan_lock); - spin_unlock(&ses->ses_lock); - - cifs_server_lock(server); - scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); - cifs_server_unlock(server); - - rc = server->ops->tree_connect(xid, ses, tree, tcon, - cifs_sb->local_nls); - cifs_server_dbg(FYI, "%s: tree_reconnect %s: %d\n", __func__, tree, rc); - spin_lock(&tcon->tc_lock); - if (rc) { - tcon->status = TID_NEED_TCON; - } else { - tcon->status = TID_GOOD; - tcon->need_reconnect = false; - } - spin_unlock(&tcon->tc_lock); -} - -static void tree_connect_ipc(const unsigned int xid, char *tree, - struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon) -{ - struct cifs_ses *ses = tcon->ses; - - __tree_connect_ipc(xid, tree, cifs_sb, ses); - __tree_connect_ipc(xid, tree, cifs_sb, CIFS_DFS_ROOT_SES(ses)); -} - -static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, char *tree, bool islink, - struct dfs_cache_tgt_list *tl) +static int tree_connect_dfs_target(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + char *tree, bool islink, + struct dfs_cache_tgt_list *tl) { - int rc; + const struct smb_version_operations *ops = tcon->ses->server->ops; struct TCP_Server_Info *server = tcon->ses->server; - const struct smb_version_operations *ops = server->ops; - struct cifs_ses *root_ses = CIFS_DFS_ROOT_SES(tcon->ses); - char *share = NULL, *prefix = NULL; struct dfs_cache_tgt_iterator *tit; + char *share = NULL, *prefix = NULL; bool target_match; - - tit = dfs_cache_get_tgt_iterator(tl); - if (!tit) { - rc = -ENOENT; - goto out; - } + int rc = -ENOENT; /* Try to tree connect to all dfs targets */ - for (; tit; tit = dfs_cache_get_next_tgt(tl, tit)) { - const char *target = dfs_cache_get_tgt_name(tit); - DFS_CACHE_TGT_LIST(ntl); - + for (tit = dfs_cache_get_tgt_iterator(tl); + tit; tit = dfs_cache_get_next_tgt(tl, tit)) { kfree(share); kfree(prefix); share = prefix = NULL; @@ -479,74 +381,21 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t } dfs_cache_noreq_update_tgthint(server->leaf_fullpath + 1, tit); - tree_connect_ipc(xid, tree, cifs_sb, tcon); - scnprintf(tree, MAX_TREE_SIZE, "\\%s", share); - if (!islink) { - rc = ops->tree_connect(xid, tcon->ses, tree, tcon, cifs_sb->local_nls); - break; - } - - /* - * If no dfs referrals were returned from link target, then just do a TREE_CONNECT - * to it. Otherwise, cache the dfs referral and then mark current tcp ses for - * reconnect so either the demultiplex thread or the echo worker will reconnect to - * newly resolved target. - */ - if (dfs_cache_find(xid, root_ses, cifs_sb->local_nls, cifs_remap(cifs_sb), target, - NULL, &ntl)) { - rc = ops->tree_connect(xid, tcon->ses, tree, tcon, cifs_sb->local_nls); - if (rc) - continue; - + rc = ops->tree_connect(xid, tcon->ses, tree, + tcon, tcon->ses->local_nls); + if (islink && !rc && cifs_sb) rc = cifs_update_super_prepath(cifs_sb, prefix); - } else { - /* Target is another dfs share */ - rc = update_server_fullpath(server, cifs_sb, target); - dfs_cache_free_tgts(tl); - - if (!rc) { - rc = -EREMOTE; - list_replace_init(&ntl.tl_list, &tl->tl_list); - } else - dfs_cache_free_tgts(&ntl); - } break; } -out: kfree(share); kfree(prefix); - - return rc; -} - -static int tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, char *tree, bool islink, - struct dfs_cache_tgt_list *tl) -{ - int rc; - int num_links = 0; - struct TCP_Server_Info *server = tcon->ses->server; - char *old_fullpath = server->leaf_fullpath; - - do { - rc = __tree_connect_dfs_target(xid, tcon, cifs_sb, tree, islink, tl); - if (!rc || rc != -EREMOTE) - break; - } while (rc = -ELOOP, ++num_links < MAX_NESTED_LINKS); - /* - * If we couldn't tree connect to any targets from last referral path, then - * retry it from newly resolved dfs referral. - */ - if (rc && server->leaf_fullpath != old_fullpath) - cifs_signal_cifsd_for_reconnect(server, true); - dfs_cache_free_tgts(tl); return rc; } -int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) +int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon) { int rc; struct TCP_Server_Info *server = tcon->ses->server; @@ -588,7 +437,8 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru cifs_server_lock(server); scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); cifs_server_unlock(server); - rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); + rc = ops->tree_connect(xid, tcon->ses, tree, + tcon, tcon->ses->local_nls); goto out; } @@ -596,14 +446,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru if (!IS_ERR(sb)) cifs_sb = CIFS_SB(sb); - /* - * Tree connect to last share in @tcon->tree_name whether dfs super or - * cached dfs referral was not found. - */ - if (!cifs_sb || !server->leaf_fullpath || + /* Tree connect to last share in @tcon->tree_name if no DFS referral */ + if (!server->leaf_fullpath || dfs_cache_noreq_find(server->leaf_fullpath + 1, &ref, &tl)) { - rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, - cifs_sb ? cifs_sb->local_nls : nlsc); + rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, + tcon, tcon->ses->local_nls); goto out; } diff --git a/fs/smb/client/dfs_cache.c b/fs/smb/client/dfs_cache.c index 00820f57b434e22dbe3708c2d30711481ac5407b..541608b0267efff53ac4d60eac4559a52539f7d8 100644 --- a/fs/smb/client/dfs_cache.c +++ b/fs/smb/client/dfs_cache.c @@ -24,8 +24,8 @@ #include "dfs_cache.h" -#define CACHE_HTABLE_SIZE 32 -#define CACHE_MAX_ENTRIES 64 +#define CACHE_HTABLE_SIZE 512 +#define CACHE_MAX_ENTRIES 1024 #define CACHE_MIN_TTL 120 /* 2 minutes */ #define CACHE_DEFAULT_TTL 300 /* 5 minutes */ diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index c87879e4739b1a48653cb61ec8ea5565f21cec0e..49123f458d0c72e6e0a77223dfcc9e01180fbbc3 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -920,12 +920,37 @@ do { \ cifs_sb->ctx->field = NULL; \ } while (0) +int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) +{ + if (ses->password && + cifs_sb->ctx->password && + strcmp(ses->password, cifs_sb->ctx->password)) { + kfree_sensitive(cifs_sb->ctx->password); + cifs_sb->ctx->password = kstrdup(ses->password, GFP_KERNEL); + if (!cifs_sb->ctx->password) + return -ENOMEM; + } + if (ses->password2 && + cifs_sb->ctx->password2 && + strcmp(ses->password2, cifs_sb->ctx->password2)) { + kfree_sensitive(cifs_sb->ctx->password2); + cifs_sb->ctx->password2 = kstrdup(ses->password2, GFP_KERNEL); + if (!cifs_sb->ctx->password2) { + kfree_sensitive(cifs_sb->ctx->password); + cifs_sb->ctx->password = NULL; + return -ENOMEM; + } + } + return 0; +} + static int smb3_reconfigure(struct fs_context *fc) { struct smb3_fs_context *ctx = smb3_fc2context(fc); struct dentry *root = fc->root; struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb); struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses; + char *new_password = NULL, *new_password2 = NULL; bool need_recon = false; int rc; @@ -945,21 +970,63 @@ static int smb3_reconfigure(struct fs_context *fc) STEAL_STRING(cifs_sb, ctx, UNC); STEAL_STRING(cifs_sb, ctx, source); STEAL_STRING(cifs_sb, ctx, username); + if (need_recon == false) STEAL_STRING_SENSITIVE(cifs_sb, ctx, password); else { - kfree_sensitive(ses->password); - ses->password = kstrdup(ctx->password, GFP_KERNEL); - if (!ses->password) - return -ENOMEM; - kfree_sensitive(ses->password2); - ses->password2 = kstrdup(ctx->password2, GFP_KERNEL); - if (!ses->password2) { - kfree_sensitive(ses->password); - ses->password = NULL; + if (ctx->password) { + new_password = kstrdup(ctx->password, GFP_KERNEL); + if (!new_password) + return -ENOMEM; + } else + STEAL_STRING_SENSITIVE(cifs_sb, ctx, password); + } + + /* + * if a new password2 has been specified, then reset it's value + * inside the ses struct + */ + if (ctx->password2) { + new_password2 = kstrdup(ctx->password2, GFP_KERNEL); + if (!new_password2) { + kfree_sensitive(new_password); return -ENOMEM; } + } else + STEAL_STRING_SENSITIVE(cifs_sb, ctx, password2); + + /* + * we may update the passwords in the ses struct below. Make sure we do + * not race with smb2_reconnect + */ + mutex_lock(&ses->session_mutex); + + /* + * smb2_reconnect may swap password and password2 in case session setup + * failed. First get ctx passwords in sync with ses passwords. It should + * be okay to do this even if this function were to return an error at a + * later stage + */ + rc = smb3_sync_session_ctx_passwords(cifs_sb, ses); + if (rc) { + mutex_unlock(&ses->session_mutex); + return rc; } + + /* + * now that allocations for passwords are done, commit them + */ + if (new_password) { + kfree_sensitive(ses->password); + ses->password = new_password; + } + if (new_password2) { + kfree_sensitive(ses->password2); + ses->password2 = new_password2; + } + + mutex_unlock(&ses->session_mutex); + STEAL_STRING(cifs_sb, ctx, domainname); STEAL_STRING(cifs_sb, ctx, nodename); STEAL_STRING(cifs_sb, ctx, iocharset); diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h index 67b7fc48ac583c2b04dbac4d81373af4080004bd..ac6baa774ad3a9c5f26f244be74b983a69001e92 100644 --- a/fs/smb/client/fs_context.h +++ b/fs/smb/client/fs_context.h @@ -309,6 +309,7 @@ static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *f } extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx); +extern int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses); extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb); /* diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index de8063b44072fb76eaed45b10fdde4d61a9cb81c..42c030687918d32875b7320808e08782a930c76d 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -1137,6 +1137,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, rc = 0; } else if (iov && server->ops->parse_reparse_point) { rc = server->ops->parse_reparse_point(cifs_sb, + full_path, iov, data); } break; @@ -2495,13 +2496,10 @@ cifs_dentry_needs_reval(struct dentry *dentry) return true; if (!open_cached_dir_by_dentry(tcon, dentry->d_parent, &cfid)) { - spin_lock(&cfid->fid_lock); if (cfid->time && cifs_i->time > cfid->time) { - spin_unlock(&cfid->fid_lock); close_cached_dir(cfid); return false; } - spin_unlock(&cfid->fid_lock); close_cached_dir(cfid); } /* diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 90da1e2b6217b6afe00f4cff9be601e8a5aff2d7..e81d2d78ddb7c0637eda1c3de5e85b300f078925 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -378,8 +378,8 @@ static int wsl_set_xattrs(struct inode *inode, umode_t _mode, memset(iov, 0, sizeof(*iov)); - /* Exclude $LXDEV xattr for sockets and fifos */ - if (S_ISSOCK(_mode) || S_ISFIFO(_mode)) + /* Exclude $LXDEV xattr for non-device files */ + if (!S_ISBLK(_mode) && !S_ISCHR(_mode)) num_xattrs = ARRAY_SIZE(xattrs) - 1; else num_xattrs = ARRAY_SIZE(xattrs); @@ -535,9 +535,95 @@ static int parse_reparse_posix(struct reparse_posix_data *buf, return 0; } +int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len, + bool unicode, bool relative, + const char *full_path, + struct cifs_sb_info *cifs_sb) +{ + char sep = CIFS_DIR_SEP(cifs_sb); + char *linux_target = NULL; + char *smb_target = NULL; + int levels; + int rc; + int i; + + /* Check that length it valid for unicode/non-unicode mode */ + if (!len || (unicode && (len % 2))) { + cifs_dbg(VFS, "srv returned malformed symlink buffer\n"); + rc = -EIO; + goto out; + } + + /* + * Check that buffer does not contain UTF-16 null codepoint in unicode + * mode or null byte in non-unicode mode because Linux cannot process + * symlink with null byte. + */ + if ((unicode && UniStrnlen((wchar_t *)buf, len/2) != len/2) || + (!unicode && strnlen(buf, len) != len)) { + cifs_dbg(VFS, "srv returned null byte in native symlink target location\n"); + rc = -EIO; + goto out; + } + + smb_target = cifs_strndup_from_utf16(buf, len, unicode, cifs_sb->local_nls); + if (!smb_target) { + rc = -ENOMEM; + goto out; + } + + if (smb_target[0] == sep && relative) { + /* + * This is a relative SMB symlink from the top of the share, + * which is the top level directory of the Linux mount point. + * Linux does not support such relative symlinks, so convert + * it to the relative symlink from the current directory. + * full_path is the SMB path to the symlink (from which is + * extracted current directory) and smb_target is the SMB path + * where symlink points, therefore full_path must always be on + * the SMB share. + */ + int smb_target_len = strlen(smb_target)+1; + levels = 0; + for (i = 1; full_path[i]; i++) { /* i=1 to skip leading sep */ + if (full_path[i] == sep) + levels++; + } + linux_target = kmalloc(levels*3 + smb_target_len, GFP_KERNEL); + if (!linux_target) { + rc = -ENOMEM; + goto out; + } + for (i = 0; i < levels; i++) { + linux_target[i*3 + 0] = '.'; + linux_target[i*3 + 1] = '.'; + linux_target[i*3 + 2] = sep; + } + memcpy(linux_target + levels*3, smb_target+1, smb_target_len); /* +1 to skip leading sep */ + } else { + linux_target = smb_target; + smb_target = NULL; + } + + if (sep == '\\') + convert_delimiter(linux_target, '/'); + + rc = 0; + *target = linux_target; + + cifs_dbg(FYI, "%s: symlink target: %s\n", __func__, *target); + +out: + if (rc != 0) + kfree(linux_target); + kfree(smb_target); + return rc; +} + static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym, u32 plen, bool unicode, struct cifs_sb_info *cifs_sb, + const char *full_path, struct cifs_open_info_data *data) { unsigned int len; @@ -552,20 +638,64 @@ static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym, return -EIO; } - data->symlink_target = cifs_strndup_from_utf16(sym->PathBuffer + offs, - len, unicode, + return smb2_parse_native_symlink(&data->symlink_target, + sym->PathBuffer + offs, + len, + unicode, + le32_to_cpu(sym->Flags) & SYMLINK_FLAG_RELATIVE, + full_path, + cifs_sb); +} + +static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf, + struct cifs_sb_info *cifs_sb, + struct cifs_open_info_data *data) +{ + int len = le16_to_cpu(buf->ReparseDataLength); + int symname_utf8_len; + __le16 *symname_utf16; + int symname_utf16_len; + + if (len <= sizeof(buf->Flags)) { + cifs_dbg(VFS, "srv returned malformed wsl symlink buffer\n"); + return -EIO; + } + + /* PathBuffer is in UTF-8 but without trailing null-term byte */ + symname_utf8_len = len - sizeof(buf->Flags); + /* + * Check that buffer does not contain null byte + * because Linux cannot process symlink with null byte. + */ + if (strnlen(buf->PathBuffer, symname_utf8_len) != symname_utf8_len) { + cifs_dbg(VFS, "srv returned null byte in wsl symlink target location\n"); + return -EIO; + } + symname_utf16 = kzalloc(symname_utf8_len * 2, GFP_KERNEL); + if (!symname_utf16) + return -ENOMEM; + symname_utf16_len = utf8s_to_utf16s(buf->PathBuffer, symname_utf8_len, + UTF16_LITTLE_ENDIAN, + symname_utf16, symname_utf8_len * 2); + if (symname_utf16_len < 0) { + kfree(symname_utf16); + return symname_utf16_len; + } + symname_utf16_len *= 2; /* utf8s_to_utf16s() returns number of u16 items, not byte length */ + + data->symlink_target = cifs_strndup_from_utf16((u8 *)symname_utf16, + symname_utf16_len, true, cifs_sb->local_nls); + kfree(symname_utf16); if (!data->symlink_target) return -ENOMEM; - convert_delimiter(data->symlink_target, '/'); - cifs_dbg(FYI, "%s: target path: %s\n", __func__, data->symlink_target); - return 0; } int parse_reparse_point(struct reparse_data_buffer *buf, u32 plen, struct cifs_sb_info *cifs_sb, + const char *full_path, bool unicode, struct cifs_open_info_data *data) { struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); @@ -580,12 +710,20 @@ int parse_reparse_point(struct reparse_data_buffer *buf, case IO_REPARSE_TAG_SYMLINK: return parse_reparse_symlink( (struct reparse_symlink_data_buffer *)buf, - plen, unicode, cifs_sb, data); + plen, unicode, cifs_sb, full_path, data); case IO_REPARSE_TAG_LX_SYMLINK: + return parse_reparse_wsl_symlink( + (struct reparse_wsl_symlink_data_buffer *)buf, + cifs_sb, data); case IO_REPARSE_TAG_AF_UNIX: case IO_REPARSE_TAG_LX_FIFO: case IO_REPARSE_TAG_LX_CHR: case IO_REPARSE_TAG_LX_BLK: + if (le16_to_cpu(buf->ReparseDataLength) != 0) { + cifs_dbg(VFS, "srv returned malformed buffer for reparse point: 0x%08x\n", + le32_to_cpu(buf->ReparseTag)); + return -EIO; + } break; default: cifs_tcon_dbg(VFS | ONCE, "unhandled reparse tag: 0x%08x\n", @@ -596,6 +734,7 @@ int parse_reparse_point(struct reparse_data_buffer *buf, } int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, + const char *full_path, struct kvec *rsp_iov, struct cifs_open_info_data *data) { @@ -605,7 +744,7 @@ int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, buf = (struct reparse_data_buffer *)((u8 *)io + le32_to_cpu(io->OutputOffset)); - return parse_reparse_point(buf, plen, cifs_sb, true, data); + return parse_reparse_point(buf, plen, cifs_sb, full_path, true, data); } static void wsl_to_fattr(struct cifs_open_info_data *data, diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h index 2a9f4f9f79de08c40cf66f63b2a5c511bd59c4ad..ff05b0e75c92840668b3798843c8d624b4dcd498 100644 --- a/fs/smb/client/reparse.h +++ b/fs/smb/client/reparse.h @@ -117,7 +117,9 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode, int smb2_mknod_reparse(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, const char *full_path, umode_t mode, dev_t dev); -int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, struct kvec *rsp_iov, +int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb, + const char *full_path, + struct kvec *rsp_iov, struct cifs_open_info_data *data); #endif /* _CIFS_REPARSE_H */ diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index c88e9657f47a8d80b10396ffe4826b948ef05c08..0bb77f9ec686138e81ca56b7e5b50d13b4fc02bb 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -347,10 +347,7 @@ done: spin_unlock(&ses->chan_lock); } -/* - * update the iface for the channel if necessary. - * Must be called with chan_lock held. - */ +/* update the iface for the channel if necessary. */ void cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) { diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index 9a6ece66c4d34ef7cc068d1ba94aca62a92a3a0f..db3695eddcf9d51f038672c7522c756f990de191 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -994,17 +994,17 @@ static int cifs_query_symlink(const unsigned int xid, } static int cifs_parse_reparse_point(struct cifs_sb_info *cifs_sb, + const char *full_path, struct kvec *rsp_iov, struct cifs_open_info_data *data) { struct reparse_data_buffer *buf; TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base; - bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE); u32 plen = le16_to_cpu(io->ByteCount); buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol + le32_to_cpu(io->DataOffset)); - return parse_reparse_point(buf, plen, cifs_sb, unicode, data); + return parse_reparse_point(buf, plen, cifs_sb, full_path, true, data); } static bool diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c index e301349b0078d18792721256f4eda67bf41e6255..e836bc2193ddd30df2d54a5abf791af5343aa4cc 100644 --- a/fs/smb/client/smb2file.c +++ b/fs/smb/client/smb2file.c @@ -63,12 +63,12 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) return sym; } -int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path) +int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, + const char *full_path, char **path) { struct smb2_symlink_err_rsp *sym; unsigned int sub_offs, sub_len; unsigned int print_offs, print_len; - char *s; if (!cifs_sb || !iov || !iov->iov_base || !iov->iov_len || !path) return -EINVAL; @@ -86,15 +86,13 @@ int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + print_offs + print_len) return -EINVAL; - s = cifs_strndup_from_utf16((char *)sym->PathBuffer + sub_offs, sub_len, true, - cifs_sb->local_nls); - if (!s) - return -ENOMEM; - convert_delimiter(s, '/'); - cifs_dbg(FYI, "%s: symlink target: %s\n", __func__, s); - - *path = s; - return 0; + return smb2_parse_native_symlink(path, + (char *)sym->PathBuffer + sub_offs, + sub_len, + true, + le32_to_cpu(sym->Flags) & SYMLINK_FLAG_RELATIVE, + full_path, + cifs_sb); } int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf) @@ -126,6 +124,7 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 goto out; if (hdr->Status == STATUS_STOPPED_ON_SYMLINK) { rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov, + oparms->path, &data->symlink_target); if (!rc) { memset(smb2_data, 0, sizeof(*smb2_data)); diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index e49d0c25eb0384e04a0c5663029d20a76752887e..a188908914fe8f4626f79935d6960c4dbc8b5f74 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -828,6 +828,7 @@ finished: static int parse_create_response(struct cifs_open_info_data *data, struct cifs_sb_info *cifs_sb, + const char *full_path, const struct kvec *iov) { struct smb2_create_rsp *rsp = iov->iov_base; @@ -841,6 +842,7 @@ static int parse_create_response(struct cifs_open_info_data *data, break; case STATUS_STOPPED_ON_SYMLINK: rc = smb2_parse_symlink_response(cifs_sb, iov, + full_path, &data->symlink_target); if (rc) return rc; @@ -930,14 +932,14 @@ int smb2_query_path_info(const unsigned int xid, switch (rc) { case 0: - rc = parse_create_response(data, cifs_sb, &out_iov[0]); + rc = parse_create_response(data, cifs_sb, full_path, &out_iov[0]); break; case -EOPNOTSUPP: /* * BB TODO: When support for special files added to Samba * re-verify this path. */ - rc = parse_create_response(data, cifs_sb, &out_iov[0]); + rc = parse_create_response(data, cifs_sb, full_path, &out_iov[0]); if (rc || !data->reparse_point) goto out; diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index fa96ebed831082d029e85db6373304a1a867a21e..87cb1872db28b038cae94e082ae2ad9833bf3b15 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2932,7 +2932,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, struct fsctl_get_dfs_referral_req *dfs_req = NULL; struct get_dfs_referral_rsp *dfs_rsp = NULL; u32 dfs_req_size = 0, dfs_rsp_size = 0; - int retry_count = 0; + int retry_once = 0; cifs_dbg(FYI, "%s: path: %s\n", __func__, search_name); @@ -2981,21 +2981,25 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, /* Path to resolve in an UTF-16 null-terminated string */ memcpy(dfs_req->RequestFileName, utf16_path, utf16_path_len); - do { + for (;;) { rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, FSCTL_DFS_GET_REFERRALS, (char *)dfs_req, dfs_req_size, CIFSMaxBufSize, (char **)&dfs_rsp, &dfs_rsp_size); - if (!is_retryable_error(rc)) + if (fatal_signal_pending(current)) { + rc = -EINTR; + break; + } + if (!is_retryable_error(rc) || retry_once++) break; usleep_range(512, 2048); - } while (++retry_count < 5); + } if (!rc && !dfs_rsp) rc = -EIO; if (rc) { if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP) - cifs_tcon_dbg(VFS, "%s: ioctl error: rc=%d\n", __func__, rc); + cifs_tcon_dbg(FYI, "%s: ioctl error: rc=%d\n", __func__, rc); goto out; } diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 0552368355370a08c41cf19510fed397ae2d7bcf..010eae9d6c47e24d46ddc588d8f0e17dd6445095 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -216,10 +216,9 @@ static int smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, struct TCP_Server_Info *server, bool from_reconnect) { - int rc = 0; - struct nls_table *nls_codepage = NULL; struct cifs_ses *ses; int xid; + int rc = 0; /* * SMB2s NegProt, SessSetup, Logoff do not have tcon yet so @@ -229,11 +228,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, if (tcon == NULL) return 0; - /* - * Need to also skip SMB2_IOCTL because it is used for checking nested dfs links in - * cifs_tree_connect(). - */ - if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL) + if (smb2_command == SMB2_TREE_CONNECT) return 0; spin_lock(&tcon->tc_lock); @@ -334,8 +329,6 @@ again: } spin_unlock(&server->srv_lock); - nls_codepage = ses->local_nls; - /* * need to prevent multiple threads trying to simultaneously * reconnect the same SMB session @@ -372,7 +365,7 @@ again: } } - rc = cifs_setup_session(0, ses, server, nls_codepage); + rc = cifs_setup_session(0, ses, server, ses->local_nls); if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED)) { /* * Try alternate password for next reconnect (key rotation @@ -406,7 +399,7 @@ skip_sess_setup: if (tcon->use_persistent) tcon->need_reopen_files = true; - rc = cifs_tree_connect(0, tcon, nls_codepage); + rc = cifs_tree_connect(0, tcon); cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); if (rc) { @@ -494,6 +487,7 @@ out: case SMB2_CHANGE_NOTIFY: case SMB2_QUERY_INFO: case SMB2_SET_INFO: + case SMB2_IOCTL: rc = -EAGAIN; } failed: @@ -1231,7 +1225,9 @@ SMB2_negotiate(const unsigned int xid, * SMB3.0 supports only 1 cipher and doesn't have a encryption neg context * Set the cipher type manually. */ - if (server->dialect == SMB30_PROT_ID && (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) + if ((server->dialect == SMB30_PROT_ID || + server->dialect == SMB302_PROT_ID) && + (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) server->cipher_type = SMB2_ENCRYPTION_AES128_CCM; security_blob = smb2_get_data_area_len(&blob_offset, &blob_length, diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index 71504b30909e1e1f1cb78774e1d98e5cb0dc9a78..09349fa8da039aff8412c5090a9b242a58226025 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -111,7 +111,14 @@ extern int smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const unsigned char *path, char *pbuf, unsigned int *pbytes_read); -int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path); +int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len, + bool unicode, bool relative, + const char *full_path, + struct cifs_sb_info *cifs_sb); +int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, + const struct kvec *iov, + const char *full_path, + char **path); int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf); extern int smb2_unlock_range(struct cifsFileInfo *cfile, diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h index 0b52d22a91a0cb059fc5ecaa785c6a7a317c7cea..12cbd3428a6da591f06454161da2a4dd1205c703 100644 --- a/fs/smb/client/trace.h +++ b/fs/smb/client/trace.h @@ -44,6 +44,8 @@ EM(netfs_trace_tcon_ref_free_ipc, "FRE Ipc ") \ EM(netfs_trace_tcon_ref_free_ipc_fail, "FRE Ipc-F ") \ EM(netfs_trace_tcon_ref_free_reconnect_server, "FRE Reconn") \ + EM(netfs_trace_tcon_ref_get_cached_laundromat, "GET Ch-Lau") \ + EM(netfs_trace_tcon_ref_get_cached_lease_break, "GET Ch-Lea") \ EM(netfs_trace_tcon_ref_get_cancelled_close, "GET Cn-Cls") \ EM(netfs_trace_tcon_ref_get_dfs_refer, "GET DfsRef") \ EM(netfs_trace_tcon_ref_get_find, "GET Find ") \ @@ -52,6 +54,7 @@ EM(netfs_trace_tcon_ref_new, "NEW ") \ EM(netfs_trace_tcon_ref_new_ipc, "NEW Ipc ") \ EM(netfs_trace_tcon_ref_new_reconnect_server, "NEW Reconn") \ + EM(netfs_trace_tcon_ref_put_cached_close, "PUT Ch-Cls") \ EM(netfs_trace_tcon_ref_put_cancelled_close, "PUT Cn-Cls") \ EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \ EM(netfs_trace_tcon_ref_put_cancelled_mid, "PUT Cn-Mid") \ diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h index 9f272cc8f5660dfd0f49912ab2b4581152a016bb..3c7c706c797d2aa3cb67c789fe722013d5fb9af9 100644 --- a/fs/smb/common/smb2pdu.h +++ b/fs/smb/common/smb2pdu.h @@ -1552,6 +1552,15 @@ struct reparse_symlink_data_buffer { /* See MS-FSCC 2.1.2.6 and cifspdu.h for struct reparse_posix_data */ +/* For IO_REPARSE_TAG_LX_SYMLINK */ +struct reparse_wsl_symlink_data_buffer { + __le32 ReparseTag; + __le16 ReparseDataLength; + __u16 Reserved; + __le32 Flags; + __u8 PathBuffer[]; /* Variable Length UTF-8 string without nul-term */ +} __packed; + struct validate_negotiate_info_req { __le32 Capabilities; __u8 Guid[SMB2_CLIENT_GUID_SIZE]; diff --git a/fs/smb/server/asn1.c b/fs/smb/server/asn1.c index b931a99ab9c85e016319244070a21bbf54028ef7..5c4c5121fece1cfc4cc0428d7f1dc8a86ddaf661 100644 --- a/fs/smb/server/asn1.c +++ b/fs/smb/server/asn1.c @@ -104,7 +104,7 @@ int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen, oid_len + ntlmssp_len) * 2 + neg_result_len + oid_len + ntlmssp_len; - buf = kmalloc(total_len, GFP_KERNEL); + buf = kmalloc(total_len, KSMBD_DEFAULT_GFP); if (!buf) return -ENOMEM; @@ -140,7 +140,7 @@ int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen, int total_len = 4 + compute_asn_hdr_len_bytes(neg_result_len) * 2 + neg_result_len; - buf = kmalloc(total_len, GFP_KERNEL); + buf = kmalloc(total_len, KSMBD_DEFAULT_GFP); if (!buf) return -ENOMEM; @@ -217,7 +217,7 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen, if (!vlen) return -EINVAL; - conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL); + conn->mechToken = kmemdup_nul(value, vlen, KSMBD_DEFAULT_GFP); if (!conn->mechToken) return -ENOMEM; diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c index 611716bc8f27c1701458536c0b37d73849e995c8..1d1ffd0acaca275984d94a6aa1a58e13bc71aa09 100644 --- a/fs/smb/server/auth.c +++ b/fs/smb/server/auth.c @@ -151,7 +151,7 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess, /* convert user_name to unicode */ len = strlen(user_name(sess->user)); - uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL); + uniname = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP); if (!uniname) { ret = -ENOMEM; goto out; @@ -175,7 +175,7 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess, /* Convert domain name or conn name to unicode and uppercase */ len = strlen(dname); - domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL); + domain = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP); if (!domain) { ret = -ENOMEM; goto out; @@ -254,7 +254,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess, } len = CIFS_CRYPTO_KEY_SIZE + blen; - construct = kzalloc(len, GFP_KERNEL); + construct = kzalloc(len, KSMBD_DEFAULT_GFP); if (!construct) { rc = -ENOMEM; goto out; @@ -361,7 +361,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, if (sess_key_len > CIFS_KEY_SIZE) return -EINVAL; - ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL); + ctx_arc4 = kmalloc(sizeof(*ctx_arc4), KSMBD_DEFAULT_GFP); if (!ctx_arc4) return -ENOMEM; @@ -451,7 +451,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob, chgblob->NegotiateFlags = cpu_to_le32(flags); len = strlen(ksmbd_netbios_name()); - name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL); + name = kmalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP); if (!name) return -ENOMEM; @@ -1043,7 +1043,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, if (!nvec) return NULL; - nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL); + nr_entries = kcalloc(nvec, sizeof(int), KSMBD_DEFAULT_GFP); if (!nr_entries) return NULL; @@ -1063,7 +1063,8 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, /* Add two entries for transform header and signature */ total_entries += 2; - sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL); + sg = kmalloc_array(total_entries, sizeof(struct scatterlist), + KSMBD_DEFAULT_GFP); if (!sg) { kfree(nr_entries); return NULL; @@ -1163,7 +1164,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov, goto free_ctx; } - req = aead_request_alloc(tfm, GFP_KERNEL); + req = aead_request_alloc(tfm, KSMBD_DEFAULT_GFP); if (!req) { rc = -ENOMEM; goto free_ctx; @@ -1182,7 +1183,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov, } iv_len = crypto_aead_ivsize(tfm); - iv = kzalloc(iv_len, GFP_KERNEL); + iv = kzalloc(iv_len, KSMBD_DEFAULT_GFP); if (!iv) { rc = -ENOMEM; goto free_sg; diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c index e6a72f75ab94ba1029c2386375ce2987717fb27f..c14dd72e1b301ef87f3c4d21ed11b35485acb3f4 100644 --- a/fs/smb/server/connection.c +++ b/fs/smb/server/connection.c @@ -52,7 +52,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) { struct ksmbd_conn *conn; - conn = kzalloc(sizeof(struct ksmbd_conn), GFP_KERNEL); + conn = kzalloc(sizeof(struct ksmbd_conn), KSMBD_DEFAULT_GFP); if (!conn) return NULL; @@ -359,7 +359,7 @@ int ksmbd_conn_handler_loop(void *p) /* 4 for rfc1002 length field */ /* 1 for implied bcc[0] */ size = pdu_size + 4 + 1; - conn->request_buf = kvmalloc(size, GFP_KERNEL); + conn->request_buf = kvmalloc(size, KSMBD_DEFAULT_GFP); if (!conn->request_buf) break; @@ -404,6 +404,7 @@ int ksmbd_conn_handler_loop(void *p) out: ksmbd_conn_set_releasing(conn); /* Wait till all reference dropped to the Server object*/ + ksmbd_debug(CONN, "Wait for all pending requests(%d)\n", atomic_read(&conn->r_count)); wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0); if (IS_ENABLED(CONFIG_UNICODE)) @@ -462,7 +463,7 @@ again: up_read(&conn_list_lock); if (!list_empty(&conn_list)) { - schedule_timeout_interruptible(HZ / 10); /* 100ms */ + msleep(100); goto again; } } diff --git a/fs/smb/server/crypto_ctx.c b/fs/smb/server/crypto_ctx.c index 81488d04199da8da6a83d638a44a431fdfa629f6..ce733dc9a4a35b4aefbf6a0556d77dc92083a7c7 100644 --- a/fs/smb/server/crypto_ctx.c +++ b/fs/smb/server/crypto_ctx.c @@ -89,7 +89,7 @@ static struct shash_desc *alloc_shash_desc(int id) return NULL; shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm), - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (!shash) crypto_free_shash(tfm); else @@ -133,7 +133,7 @@ static struct ksmbd_crypto_ctx *ksmbd_find_crypto_ctx(void) ctx_list.avail_ctx++; spin_unlock(&ctx_list.ctx_lock); - ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), GFP_KERNEL); + ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP); if (!ctx) { spin_lock(&ctx_list.ctx_lock); ctx_list.avail_ctx--; @@ -258,7 +258,7 @@ int ksmbd_crypto_create(void) init_waitqueue_head(&ctx_list.ctx_wait); ctx_list.avail_ctx = 1; - ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), GFP_KERNEL); + ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP); if (!ctx) return -ENOMEM; list_add(&ctx->list, &ctx_list.idle_ctx); diff --git a/fs/smb/server/glob.h b/fs/smb/server/glob.h index d528b20b37a85f6fab7dad4088247940d8616efc..4ea187af234803ba3a3463053462fcb372e8f6e2 100644 --- a/fs/smb/server/glob.h +++ b/fs/smb/server/glob.h @@ -44,4 +44,6 @@ extern int ksmbd_debug_types; #define UNICODE_LEN(x) ((x) * 2) +#define KSMBD_DEFAULT_GFP (GFP_KERNEL | __GFP_RETRY_MAYFAIL) + #endif /* __KSMBD_GLOB_H */ diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c index d7c676c151e209e89cb29b68eb9d14e7e3b9d70c..4af2e6007c29d3ca3f92a728c8417e4d39581f79 100644 --- a/fs/smb/server/ksmbd_work.c +++ b/fs/smb/server/ksmbd_work.c @@ -18,7 +18,7 @@ static struct workqueue_struct *ksmbd_wq; struct ksmbd_work *ksmbd_alloc_work_struct(void) { - struct ksmbd_work *work = kmem_cache_zalloc(work_cache, GFP_KERNEL); + struct ksmbd_work *work = kmem_cache_zalloc(work_cache, KSMBD_DEFAULT_GFP); if (work) { work->compound_fid = KSMBD_NO_FID; @@ -30,7 +30,7 @@ struct ksmbd_work *ksmbd_alloc_work_struct(void) INIT_LIST_HEAD(&work->aux_read_list); work->iov_alloc_cnt = 4; work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec), - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (!work->iov) { kmem_cache_free(work_cache, work); work = NULL; @@ -114,7 +114,7 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, if (aux_size) { need_iov_cnt++; - ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL); + ar = kmalloc(sizeof(struct aux_read), KSMBD_DEFAULT_GFP); if (!ar) return -ENOMEM; } @@ -125,7 +125,7 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, work->iov_alloc_cnt += 4; new = krealloc(work->iov, sizeof(struct kvec) * work->iov_alloc_cnt, - GFP_KERNEL | __GFP_ZERO); + KSMBD_DEFAULT_GFP | __GFP_ZERO); if (!new) { kfree(ar); work->iov_alloc_cnt -= 4; @@ -169,7 +169,7 @@ int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len, int allocate_interim_rsp_buf(struct ksmbd_work *work) { - work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL); + work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, KSMBD_DEFAULT_GFP); if (!work->response_buf) return -ENOMEM; work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; diff --git a/fs/smb/server/mgmt/ksmbd_ida.c b/fs/smb/server/mgmt/ksmbd_ida.c index a18e27e9e0cd93ecdec8781eb4663a2661c93513..0e2ae994ab52576b1cd7bc148b62683965bd39e9 100644 --- a/fs/smb/server/mgmt/ksmbd_ida.c +++ b/fs/smb/server/mgmt/ksmbd_ida.c @@ -4,31 +4,32 @@ */ #include "ksmbd_ida.h" +#include "../glob.h" int ksmbd_acquire_smb2_tid(struct ida *ida) { - return ida_alloc_range(ida, 1, 0xFFFFFFFE, GFP_KERNEL); + return ida_alloc_range(ida, 1, 0xFFFFFFFE, KSMBD_DEFAULT_GFP); } int ksmbd_acquire_smb2_uid(struct ida *ida) { int id; - id = ida_alloc_min(ida, 1, GFP_KERNEL); + id = ida_alloc_min(ida, 1, KSMBD_DEFAULT_GFP); if (id == 0xFFFE) - id = ida_alloc_min(ida, 1, GFP_KERNEL); + id = ida_alloc_min(ida, 1, KSMBD_DEFAULT_GFP); return id; } int ksmbd_acquire_async_msg_id(struct ida *ida) { - return ida_alloc_min(ida, 1, GFP_KERNEL); + return ida_alloc_min(ida, 1, KSMBD_DEFAULT_GFP); } int ksmbd_acquire_id(struct ida *ida) { - return ida_alloc(ida, GFP_KERNEL); + return ida_alloc(ida, KSMBD_DEFAULT_GFP); } void ksmbd_release_id(struct ida *ida, int id) diff --git a/fs/smb/server/mgmt/share_config.c b/fs/smb/server/mgmt/share_config.c index d8d03070ae44b46dab1505227f617218d09562e2..d3d5f99bdd34edcb318c47afa20f7041c64103a7 100644 --- a/fs/smb/server/mgmt/share_config.c +++ b/fs/smb/server/mgmt/share_config.c @@ -102,11 +102,11 @@ static int parse_veto_list(struct ksmbd_share_config *share, if (!sz) break; - p = kzalloc(sizeof(struct ksmbd_veto_pattern), GFP_KERNEL); + p = kzalloc(sizeof(struct ksmbd_veto_pattern), KSMBD_DEFAULT_GFP); if (!p) return -ENOMEM; - p->pattern = kstrdup(veto_list, GFP_KERNEL); + p->pattern = kstrdup(veto_list, KSMBD_DEFAULT_GFP); if (!p->pattern) { kfree(p); return -ENOMEM; @@ -150,14 +150,14 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, goto out; } - share = kzalloc(sizeof(struct ksmbd_share_config), GFP_KERNEL); + share = kzalloc(sizeof(struct ksmbd_share_config), KSMBD_DEFAULT_GFP); if (!share) goto out; share->flags = resp->flags; atomic_set(&share->refcount, 1); INIT_LIST_HEAD(&share->veto_list); - share->name = kstrdup(name, GFP_KERNEL); + share->name = kstrdup(name, KSMBD_DEFAULT_GFP); if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) { int path_len = PATH_MAX; @@ -166,7 +166,7 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, path_len = resp->payload_sz - resp->veto_list_sz; share->path = kstrndup(ksmbd_share_config_path(resp), path_len, - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (share->path) { share->path_sz = strlen(share->path); while (share->path_sz > 1 && diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c index 94a52a75014a4384fb80fbc461f3f558341c4f55..ecfc5750867124828c72d04624bc9d52a5d1d395 100644 --- a/fs/smb/server/mgmt/tree_connect.c +++ b/fs/smb/server/mgmt/tree_connect.c @@ -31,7 +31,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) if (!sc) return status; - tree_conn = kzalloc(sizeof(struct ksmbd_tree_connect), GFP_KERNEL); + tree_conn = kzalloc(sizeof(struct ksmbd_tree_connect), + KSMBD_DEFAULT_GFP); if (!tree_conn) { status.ret = -ENOMEM; goto out_error; @@ -80,7 +81,7 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) init_waitqueue_head(&tree_conn->refcount_q); ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, - GFP_KERNEL)); + KSMBD_DEFAULT_GFP)); if (ret) { status.ret = -ENOMEM; goto out_error; diff --git a/fs/smb/server/mgmt/user_config.c b/fs/smb/server/mgmt/user_config.c index 421a4a95e216aa5b1c2517c40fdc811a3da1014c..56c9a38ca878903535cec6e3761a173df6ffe988 100644 --- a/fs/smb/server/mgmt/user_config.c +++ b/fs/smb/server/mgmt/user_config.c @@ -36,16 +36,16 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp, { struct ksmbd_user *user; - user = kmalloc(sizeof(struct ksmbd_user), GFP_KERNEL); + user = kmalloc(sizeof(struct ksmbd_user), KSMBD_DEFAULT_GFP); if (!user) return NULL; - user->name = kstrdup(resp->account, GFP_KERNEL); + user->name = kstrdup(resp->account, KSMBD_DEFAULT_GFP); user->flags = resp->status; user->gid = resp->gid; user->uid = resp->uid; user->passkey_sz = resp->hash_sz; - user->passkey = kmalloc(resp->hash_sz, GFP_KERNEL); + user->passkey = kmalloc(resp->hash_sz, KSMBD_DEFAULT_GFP); if (user->passkey) memcpy(user->passkey, resp->hash, resp->hash_sz); @@ -64,7 +64,7 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp, user->sgid = kmemdup(resp_ext->____payload, resp_ext->ngroups * sizeof(gid_t), - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (!user->sgid) goto err_free; diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index ad02fe555fda7e404ed106bf3c7e9296cfdc0f39..df92d746e89cabf8a0d82f5d6ee495513582403e 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -98,7 +98,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) if (!method) return -EINVAL; - entry = kzalloc(sizeof(struct ksmbd_session_rpc), GFP_KERNEL); + entry = kzalloc(sizeof(struct ksmbd_session_rpc), KSMBD_DEFAULT_GFP); if (!entry) return -ENOMEM; @@ -106,7 +106,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) entry->id = ksmbd_ipc_id_alloc(); if (entry->id < 0) goto free_entry; - old = xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL); + old = xa_store(&sess->rpc_handle_list, entry->id, entry, KSMBD_DEFAULT_GFP); if (xa_is_err(old)) goto free_id; @@ -201,7 +201,7 @@ int ksmbd_session_register(struct ksmbd_conn *conn, sess->dialect = conn->dialect; memcpy(sess->ClientGUID, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE); ksmbd_expire_session(conn); - return xa_err(xa_store(&conn->sessions, sess->id, sess, GFP_KERNEL)); + return xa_err(xa_store(&conn->sessions, sess->id, sess, KSMBD_DEFAULT_GFP)); } static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess) @@ -314,7 +314,7 @@ struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn, { struct preauth_session *sess; - sess = kmalloc(sizeof(struct preauth_session), GFP_KERNEL); + sess = kmalloc(sizeof(struct preauth_session), KSMBD_DEFAULT_GFP); if (!sess) return NULL; @@ -398,7 +398,7 @@ static struct ksmbd_session *__session_create(int protocol) if (protocol != CIFDS_SESSION_FLAG_SMB2) return NULL; - sess = kzalloc(sizeof(struct ksmbd_session), GFP_KERNEL); + sess = kzalloc(sizeof(struct ksmbd_session), KSMBD_DEFAULT_GFP); if (!sess) return NULL; diff --git a/fs/smb/server/misc.c b/fs/smb/server/misc.c index 1a5faa6f6e7bc3ddb96bdaa1ce953ba06f3bf5a2..cb2a11ffb23fe3844c0d58416b2e714b68b0ed5f 100644 --- a/fs/smb/server/misc.c +++ b/fs/smb/server/misc.c @@ -165,7 +165,7 @@ char *convert_to_nt_pathname(struct ksmbd_share_config *share, char *pathname, *ab_pathname, *nt_pathname; int share_path_len = share->path_sz; - pathname = kmalloc(PATH_MAX, GFP_KERNEL); + pathname = kmalloc(PATH_MAX, KSMBD_DEFAULT_GFP); if (!pathname) return ERR_PTR(-EACCES); @@ -180,7 +180,8 @@ char *convert_to_nt_pathname(struct ksmbd_share_config *share, goto free_pathname; } - nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 2, GFP_KERNEL); + nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 2, + KSMBD_DEFAULT_GFP); if (!nt_pathname) { nt_pathname = ERR_PTR(-ENOMEM); goto free_pathname; @@ -232,7 +233,7 @@ char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name) char *cf_name; int cf_len; - cf_name = kzalloc(KSMBD_REQ_MAX_SHARE_NAME, GFP_KERNEL); + cf_name = kzalloc(KSMBD_REQ_MAX_SHARE_NAME, KSMBD_DEFAULT_GFP); if (!cf_name) return ERR_PTR(-ENOMEM); @@ -294,7 +295,7 @@ char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name) path_len = share->path_sz; name_len = strlen(name); - new_name = kmalloc(path_len + name_len + 2, GFP_KERNEL); + new_name = kmalloc(path_len + name_len + 2, KSMBD_DEFAULT_GFP); if (!new_name) return new_name; @@ -320,7 +321,7 @@ char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info, if (!sz) return NULL; - conv = kmalloc(sz, GFP_KERNEL); + conv = kmalloc(sz, KSMBD_DEFAULT_GFP); if (!conv) return NULL; diff --git a/fs/smb/server/ndr.c b/fs/smb/server/ndr.c index 3507d8f89074993a610606cebd150da8603538c7..58d71560f626b488392505d0a74ad093dee90045 100644 --- a/fs/smb/server/ndr.c +++ b/fs/smb/server/ndr.c @@ -18,7 +18,7 @@ static int try_to_realloc_ndr_blob(struct ndr *n, size_t sz) { char *data; - data = krealloc(n->data, n->offset + sz + 1024, GFP_KERNEL); + data = krealloc(n->data, n->offset + sz + 1024, KSMBD_DEFAULT_GFP); if (!data) return -ENOMEM; @@ -174,7 +174,7 @@ int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da) n->offset = 0; n->length = 1024; - n->data = kzalloc(n->length, GFP_KERNEL); + n->data = kzalloc(n->length, KSMBD_DEFAULT_GFP); if (!n->data) return -ENOMEM; @@ -350,7 +350,7 @@ int ndr_encode_posix_acl(struct ndr *n, n->offset = 0; n->length = 1024; - n->data = kzalloc(n->length, GFP_KERNEL); + n->data = kzalloc(n->length, KSMBD_DEFAULT_GFP); if (!n->data) return -ENOMEM; @@ -401,7 +401,7 @@ int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl) n->offset = 0; n->length = 2048; - n->data = kzalloc(n->length, GFP_KERNEL); + n->data = kzalloc(n->length, KSMBD_DEFAULT_GFP); if (!n->data) return -ENOMEM; @@ -505,7 +505,7 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl) return ret; acl->sd_size = n->length - n->offset; - acl->sd_buf = kzalloc(acl->sd_size, GFP_KERNEL); + acl->sd_buf = kzalloc(acl->sd_size, KSMBD_DEFAULT_GFP); if (!acl->sd_buf) return -ENOMEM; diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 4142c7ad5fa910cb5dce7375f108954756eece40..3a3fe4afbdf0df677a63a332a21a2d90567faf75 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -34,7 +34,7 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work, struct ksmbd_session *sess = work->sess; struct oplock_info *opinfo; - opinfo = kzalloc(sizeof(struct oplock_info), GFP_KERNEL); + opinfo = kzalloc(sizeof(struct oplock_info), KSMBD_DEFAULT_GFP); if (!opinfo) return NULL; @@ -94,7 +94,7 @@ static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) { struct lease *lease; - lease = kmalloc(sizeof(struct lease), GFP_KERNEL); + lease = kmalloc(sizeof(struct lease), KSMBD_DEFAULT_GFP); if (!lease) return -ENOMEM; @@ -709,7 +709,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo) if (!work) return -ENOMEM; - br_info = kmalloc(sizeof(struct oplock_break_info), GFP_KERNEL); + br_info = kmalloc(sizeof(struct oplock_break_info), KSMBD_DEFAULT_GFP); if (!br_info) { ksmbd_free_work_struct(work); return -ENOMEM; @@ -812,7 +812,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo) if (!work) return -ENOMEM; - br_info = kmalloc(sizeof(struct lease_break_info), GFP_KERNEL); + br_info = kmalloc(sizeof(struct lease_break_info), KSMBD_DEFAULT_GFP); if (!br_info) { ksmbd_free_work_struct(work); return -ENOMEM; @@ -1057,7 +1057,7 @@ static int add_lease_global_list(struct oplock_info *opinfo) } read_unlock(&lease_list_lock); - lb = kmalloc(sizeof(struct lease_table), GFP_KERNEL); + lb = kmalloc(sizeof(struct lease_table), KSMBD_DEFAULT_GFP); if (!lb) return -ENOMEM; @@ -1499,7 +1499,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req) if (IS_ERR_OR_NULL(cc)) return NULL; - lreq = kzalloc(sizeof(struct lease_ctx_info), GFP_KERNEL); + lreq = kzalloc(sizeof(struct lease_ctx_info), KSMBD_DEFAULT_GFP); if (!lreq) return NULL; diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c index e6cfedba99923231a8aa4668e8f67334b062656c..930d7566b52efdd624051b1cf0a0cc06be0254ce 100644 --- a/fs/smb/server/server.c +++ b/fs/smb/server/server.c @@ -47,7 +47,7 @@ static int ___server_conf_set(int idx, char *val) return -EINVAL; kfree(server_conf.conf[idx]); - server_conf.conf[idx] = kstrdup(val, GFP_KERNEL); + server_conf.conf[idx] = kstrdup(val, KSMBD_DEFAULT_GFP); if (!server_conf.conf[idx]) return -ENOMEM; return 0; @@ -276,8 +276,12 @@ static void handle_ksmbd_work(struct work_struct *wk) * disconnection. waitqueue_active is safe because it * uses atomic operation for condition. */ + atomic_inc(&conn->refcnt); if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q)) wake_up(&conn->r_count_q); + + if (atomic_dec_and_test(&conn->refcnt)) + kfree(conn); } /** @@ -415,7 +419,7 @@ static int __queue_ctrl_work(int type) { struct server_ctrl_struct *ctrl; - ctrl = kmalloc(sizeof(struct server_ctrl_struct), GFP_KERNEL); + ctrl = kmalloc(sizeof(struct server_ctrl_struct), KSMBD_DEFAULT_GFP); if (!ctrl) return -ENOMEM; diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 599118aed20539aeb35f6e5ff7dccb52fa2b66f3..416f7df4edef5d1da80cec845261a0a358813532 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -551,7 +551,7 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) if (le32_to_cpu(hdr->NextCommand) > 0) sz = large_sz; - work->response_buf = kvzalloc(sz, GFP_KERNEL); + work->response_buf = kvzalloc(sz, KSMBD_DEFAULT_GFP); if (!work->response_buf) return -ENOMEM; @@ -1147,7 +1147,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) case SMB311_PROT_ID: conn->preauth_info = kzalloc(sizeof(struct preauth_integrity_info), - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (!conn->preauth_info) { rc = -ENOMEM; rsp->hdr.Status = STATUS_INVALID_PARAMETER; @@ -1266,7 +1266,7 @@ static int alloc_preauth_hash(struct ksmbd_session *sess, return 0; sess->Preauth_HashValue = kmemdup(conn->preauth_info->Preauth_HashValue, - PREAUTH_HASHVALUE_SIZE, GFP_KERNEL); + PREAUTH_HASHVALUE_SIZE, KSMBD_DEFAULT_GFP); if (!sess->Preauth_HashValue) return -ENOMEM; @@ -1352,7 +1352,7 @@ static int ntlm_negotiate(struct ksmbd_work *work, sz = sizeof(struct challenge_message); sz += (strlen(ksmbd_netbios_name()) * 2 + 1 + 4) * 6; - neg_blob = kzalloc(sz, GFP_KERNEL); + neg_blob = kzalloc(sz, KSMBD_DEFAULT_GFP); if (!neg_blob) return -ENOMEM; @@ -1543,12 +1543,12 @@ binding_session: if (conn->dialect >= SMB30_PROT_ID) { chann = lookup_chann_list(sess, conn); if (!chann) { - chann = kmalloc(sizeof(struct channel), GFP_KERNEL); + chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP); if (!chann) return -ENOMEM; chann->conn = conn; - xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL); + xa_store(&sess->ksmbd_chann_list, (long)conn, chann, KSMBD_DEFAULT_GFP); } } @@ -1624,12 +1624,12 @@ static int krb5_authenticate(struct ksmbd_work *work, if (conn->dialect >= SMB30_PROT_ID) { chann = lookup_chann_list(sess, conn); if (!chann) { - chann = kmalloc(sizeof(struct channel), GFP_KERNEL); + chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP); if (!chann) return -ENOMEM; chann->conn = conn; - xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL); + xa_store(&sess->ksmbd_chann_list, (long)conn, chann, KSMBD_DEFAULT_GFP); } } @@ -1666,7 +1666,7 @@ int smb2_sess_setup(struct ksmbd_work *work) unsigned int negblob_len, negblob_off; int rc = 0; - ksmbd_debug(SMB, "Received request for session setup\n"); + ksmbd_debug(SMB, "Received smb2 session setup request\n"); WORK_BUFFERS(work, req, rsp); @@ -1940,6 +1940,8 @@ int smb2_tree_connect(struct ksmbd_work *work) struct ksmbd_share_config *share = NULL; int rc = -EINVAL; + ksmbd_debug(SMB, "Received smb2 tree connect request\n"); + WORK_BUFFERS(work, req, rsp); treename = smb_strndup_from_utf16((char *)req + le16_to_cpu(req->PathOffset), @@ -2136,9 +2138,9 @@ int smb2_tree_disconnect(struct ksmbd_work *work) struct ksmbd_tree_connect *tcon = work->tcon; int err; - WORK_BUFFERS(work, req, rsp); + ksmbd_debug(SMB, "Received smb2 tree disconnect request\n"); - ksmbd_debug(SMB, "request\n"); + WORK_BUFFERS(work, req, rsp); if (!tcon) { ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); @@ -2203,7 +2205,7 @@ int smb2_session_logoff(struct ksmbd_work *work) WORK_BUFFERS(work, req, rsp); - ksmbd_debug(SMB, "request\n"); + ksmbd_debug(SMB, "Received smb2 session logoff request\n"); ksmbd_conn_lock(conn); if (!ksmbd_conn_good(conn)) { @@ -2346,7 +2348,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, le16_to_cpu(eabuf->EaValueLength)) return -EINVAL; - attr_name = kmalloc(XATTR_NAME_MAX + 1, GFP_KERNEL); + attr_name = kmalloc(XATTR_NAME_MAX + 1, KSMBD_DEFAULT_GFP); if (!attr_name) return -ENOMEM; @@ -2849,6 +2851,8 @@ int smb2_open(struct ksmbd_work *work) __le32 daccess, maximal_access = 0; int iov_len = 0; + ksmbd_debug(SMB, "Received smb2 create request\n"); + WORK_BUFFERS(work, req, rsp); if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off && @@ -2897,7 +2901,7 @@ int smb2_open(struct ksmbd_work *work) goto err_out2; } } else { - name = kstrdup("", GFP_KERNEL); + name = kstrdup("", KSMBD_DEFAULT_GFP); if (!name) { rc = -ENOMEM; goto err_out2; @@ -3338,7 +3342,7 @@ int smb2_open(struct ksmbd_work *work) sizeof(struct smb_sid) * 3 + sizeof(struct smb_acl) + sizeof(struct smb_ace) * ace_num * 2, - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (!pntsd) { posix_acl_release(fattr.cf_acls); posix_acl_release(fattr.cf_dacls); @@ -4296,6 +4300,8 @@ int smb2_query_dir(struct ksmbd_work *work) int buffer_sz; struct smb2_query_dir_private query_dir_private = {NULL, }; + ksmbd_debug(SMB, "Received smb2 query directory request\n"); + WORK_BUFFERS(work, req, rsp); if (ksmbd_override_fsids(work)) { @@ -4946,7 +4952,7 @@ static int get_file_stream_info(struct ksmbd_work *work, /* plus : size */ streamlen += 1; - stream_buf = kmalloc(streamlen + 1, GFP_KERNEL); + stream_buf = kmalloc(streamlen + 1, KSMBD_DEFAULT_GFP); if (!stream_buf) break; @@ -5602,9 +5608,9 @@ int smb2_query_info(struct ksmbd_work *work) struct smb2_query_info_rsp *rsp; int rc = 0; - WORK_BUFFERS(work, req, rsp); + ksmbd_debug(SMB, "Received request smb2 query info request\n"); - ksmbd_debug(SMB, "GOT query info request\n"); + WORK_BUFFERS(work, req, rsp); if (ksmbd_override_fsids(work)) { rc = -ENOMEM; @@ -5709,6 +5715,8 @@ int smb2_close(struct ksmbd_work *work) u64 time; int err = 0; + ksmbd_debug(SMB, "Received smb2 close request\n"); + WORK_BUFFERS(work, req, rsp); if (test_share_config_flag(work->tcon->share_conf, @@ -5825,6 +5833,8 @@ int smb2_echo(struct ksmbd_work *work) { struct smb2_echo_rsp *rsp = smb2_get_msg(work->response_buf); + ksmbd_debug(SMB, "Received smb2 echo request\n"); + if (work->next_smb2_rcv_hdr_off) rsp = ksmbd_resp_buf_next(work); @@ -5921,7 +5931,7 @@ static int smb2_create_link(struct ksmbd_work *work, return -EINVAL; ksmbd_debug(SMB, "setting FILE_LINK_INFORMATION\n"); - pathname = kmalloc(PATH_MAX, GFP_KERNEL); + pathname = kmalloc(PATH_MAX, KSMBD_DEFAULT_GFP); if (!pathname) return -ENOMEM; @@ -6365,7 +6375,7 @@ int smb2_set_info(struct ksmbd_work *work) int rc = 0; unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; - ksmbd_debug(SMB, "Received set info request\n"); + ksmbd_debug(SMB, "Received smb2 set info request\n"); if (work->next_smb2_rcv_hdr_off) { req = ksmbd_req_buf_next(work); @@ -6485,7 +6495,7 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work) } aux_payload_buf = - kvmalloc(rpc_resp->payload_sz, GFP_KERNEL); + kvmalloc(rpc_resp->payload_sz, KSMBD_DEFAULT_GFP); if (!aux_payload_buf) { err = -ENOMEM; goto out; @@ -6591,6 +6601,8 @@ int smb2_read(struct ksmbd_work *work) unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; void *aux_payload_buf; + ksmbd_debug(SMB, "Received smb2 read request\n"); + if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) { ksmbd_debug(SMB, "IPC pipe read request\n"); @@ -6664,7 +6676,7 @@ int smb2_read(struct ksmbd_work *work) ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n", fp->filp, offset, length); - aux_payload_buf = kvzalloc(length, GFP_KERNEL); + aux_payload_buf = kvzalloc(length, KSMBD_DEFAULT_GFP); if (!aux_payload_buf) { err = -ENOMEM; goto out; @@ -6816,7 +6828,7 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work, int ret; ssize_t nbytes; - data_buf = kvzalloc(length, GFP_KERNEL); + data_buf = kvzalloc(length, KSMBD_DEFAULT_GFP); if (!data_buf) return -ENOMEM; @@ -6856,6 +6868,8 @@ int smb2_write(struct ksmbd_work *work) int err = 0; unsigned int max_write_size = work->conn->vals->max_write_size; + ksmbd_debug(SMB, "Received smb2 write request\n"); + WORK_BUFFERS(work, req, rsp); if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) { @@ -6994,7 +7008,7 @@ int smb2_flush(struct ksmbd_work *work) WORK_BUFFERS(work, req, rsp); - ksmbd_debug(SMB, "SMB2_FLUSH called for fid %llu\n", req->VolatileFileId); + ksmbd_debug(SMB, "Received smb2 flush request(fid : %llu)\n", req->VolatileFileId); err = ksmbd_vfs_fsync(work, req->VolatileFileId, req->PersistentFileId); if (err) @@ -7145,7 +7159,7 @@ static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock, { struct ksmbd_lock *lock; - lock = kzalloc(sizeof(struct ksmbd_lock), GFP_KERNEL); + lock = kzalloc(sizeof(struct ksmbd_lock), KSMBD_DEFAULT_GFP); if (!lock) return NULL; @@ -7206,7 +7220,7 @@ int smb2_lock(struct ksmbd_work *work) WORK_BUFFERS(work, req, rsp); - ksmbd_debug(SMB, "Received lock request\n"); + ksmbd_debug(SMB, "Received smb2 lock request\n"); fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId); if (!fp) { ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", req->VolatileFileId); @@ -7413,7 +7427,7 @@ skip: "would have to wait for getting lock\n"); list_add(&smb_lock->llist, &rollback_list); - argv = kmalloc(sizeof(void *), GFP_KERNEL); + argv = kmalloc(sizeof(void *), KSMBD_DEFAULT_GFP); if (!argv) { err = -ENOMEM; goto out; @@ -7973,6 +7987,8 @@ int smb2_ioctl(struct ksmbd_work *work) int ret = 0; char *buffer; + ksmbd_debug(SMB, "Received smb2 ioctl request\n"); + if (work->next_smb2_rcv_hdr_off) { req = ksmbd_req_buf_next(work); rsp = ksmbd_resp_buf_next(work); @@ -8599,6 +8615,8 @@ int smb2_oplock_break(struct ksmbd_work *work) struct smb2_oplock_break *req; struct smb2_oplock_break *rsp; + ksmbd_debug(SMB, "Received smb2 oplock break acknowledgment request\n"); + WORK_BUFFERS(work, req, rsp); switch (le16_to_cpu(req->StructureSize)) { @@ -8629,6 +8647,8 @@ int smb2_notify(struct ksmbd_work *work) struct smb2_change_notify_req *req; struct smb2_change_notify_rsp *rsp; + ksmbd_debug(SMB, "Received smb2 notify\n"); + WORK_BUFFERS(work, req, rsp); if (work->next_smb2_rcv_hdr_off && req->hdr.NextCommand) { @@ -8907,7 +8927,7 @@ int smb3_encrypt_resp(struct ksmbd_work *work) int rc = -ENOMEM; void *tr_buf; - tr_buf = kzalloc(sizeof(struct smb2_transform_hdr) + 4, GFP_KERNEL); + tr_buf = kzalloc(sizeof(struct smb2_transform_hdr) + 4, KSMBD_DEFAULT_GFP); if (!tr_buf) return rc; diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c index 75b4eb856d32f7ddc856ad5cf04906638cede0b5..4e6f169fcf83b7d5705339c603d832777a32656d 100644 --- a/fs/smb/server/smb_common.c +++ b/fs/smb/server/smb_common.c @@ -358,7 +358,7 @@ static int smb1_check_user_session(struct ksmbd_work *work) static int smb1_allocate_rsp_buf(struct ksmbd_work *work) { work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, - GFP_KERNEL); + KSMBD_DEFAULT_GFP); work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; if (!work->response_buf) { @@ -576,7 +576,7 @@ static int smb_handle_negotiate(struct ksmbd_work *work) ksmbd_debug(SMB, "Unsupported SMB1 protocol\n"); - if (ksmbd_iov_pin_rsp(work, (void *)neg_rsp, + if (ksmbd_iov_pin_rsp(work, (void *)neg_rsp + 4, sizeof(struct smb_negotiate_rsp) - 4)) return -ENOMEM; diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c index 1c9775f1efa56d2feb141669a65d36d9230238c3..d39d3e553366da73d50567d0ca3ebabe3c5097e2 100644 --- a/fs/smb/server/smbacl.c +++ b/fs/smb/server/smbacl.c @@ -345,10 +345,10 @@ int init_acl_state(struct posix_acl_state *state, int cnt) */ alloc = sizeof(struct posix_ace_state_array) + cnt * sizeof(struct posix_user_ace_state); - state->users = kzalloc(alloc, GFP_KERNEL); + state->users = kzalloc(alloc, KSMBD_DEFAULT_GFP); if (!state->users) return -ENOMEM; - state->groups = kzalloc(alloc, GFP_KERNEL); + state->groups = kzalloc(alloc, KSMBD_DEFAULT_GFP); if (!state->groups) { kfree(state->users); return -ENOMEM; @@ -410,7 +410,7 @@ static void parse_dacl(struct mnt_idmap *idmap, return; } - ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL); + ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), KSMBD_DEFAULT_GFP); if (!ppace) { free_acl_state(&default_acl_state); free_acl_state(&acl_state); @@ -553,7 +553,7 @@ static void parse_dacl(struct mnt_idmap *idmap, if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) { fattr->cf_acls = posix_acl_alloc(acl_state.users->n + - acl_state.groups->n + 4, GFP_KERNEL); + acl_state.groups->n + 4, KSMBD_DEFAULT_GFP); if (fattr->cf_acls) { cf_pace = fattr->cf_acls->a_entries; posix_state_to_acl(&acl_state, cf_pace); @@ -567,7 +567,7 @@ static void parse_dacl(struct mnt_idmap *idmap, if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) { fattr->cf_dacls = posix_acl_alloc(default_acl_state.users->n + - default_acl_state.groups->n + 4, GFP_KERNEL); + default_acl_state.groups->n + 4, KSMBD_DEFAULT_GFP); if (fattr->cf_dacls) { cf_pdace = fattr->cf_dacls->a_entries; posix_state_to_acl(&default_acl_state, cf_pdace); @@ -595,7 +595,7 @@ static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap, for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) { int flags = 0; - sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL); + sid = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); if (!sid) break; @@ -662,7 +662,7 @@ posix_default_acl: pace = fattr->cf_dacls->a_entries; for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) { - sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL); + sid = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); if (!sid) break; @@ -906,7 +906,7 @@ int build_sec_desc(struct mnt_idmap *idmap, gid_t gid; unsigned int sid_type = SIDOWNER; - nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL); + nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); if (!nowner_sid_ptr) return -ENOMEM; @@ -915,7 +915,7 @@ int build_sec_desc(struct mnt_idmap *idmap, sid_type = SIDUNIX_USER; id_to_sid(uid, sid_type, nowner_sid_ptr); - ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL); + ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); if (!ngroup_sid_ptr) { kfree(nowner_sid_ptr); return -ENOMEM; @@ -1032,7 +1032,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, goto free_parent_pntsd; } - aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL); + aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, + KSMBD_DEFAULT_GFP); if (!aces_base) { rc = -ENOMEM; goto free_parent_pntsd; @@ -1126,7 +1127,7 @@ pass: pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size + pgroup_sid_size + sizeof(struct smb_acl) + nt_size; - pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL); + pntsd = kzalloc(pntsd_alloc_size, KSMBD_DEFAULT_GFP); if (!pntsd) { rc = -ENOMEM; goto free_aces_base; diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c index 2f27afb695f62e5f081356139fb9968a73648dc0..48cda3350e5a22f403f512dfbe76e33998c1c9ad 100644 --- a/fs/smb/server/transport_ipc.c +++ b/fs/smb/server/transport_ipc.c @@ -244,7 +244,7 @@ static struct ksmbd_ipc_msg *ipc_msg_alloc(size_t sz) struct ksmbd_ipc_msg *msg; size_t msg_sz = sz + sizeof(struct ksmbd_ipc_msg); - msg = kvzalloc(msg_sz, GFP_KERNEL); + msg = kvzalloc(msg_sz, KSMBD_DEFAULT_GFP); if (msg) msg->sz = sz; return msg; @@ -283,7 +283,7 @@ static int handle_response(int type, void *payload, size_t sz) entry->type + 1, type); } - entry->response = kvzalloc(sz, GFP_KERNEL); + entry->response = kvzalloc(sz, KSMBD_DEFAULT_GFP); if (!entry->response) { ret = -ENOMEM; break; @@ -444,7 +444,7 @@ static int ipc_msg_send(struct ksmbd_ipc_msg *msg) if (!ksmbd_tools_pid) return ret; - skb = genlmsg_new(msg->sz, GFP_KERNEL); + skb = genlmsg_new(msg->sz, KSMBD_DEFAULT_GFP); if (!skb) return -ENOMEM; diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c index 17c76713c6d08617d0edea67543da3994328f58f..0ef3c9f0bfebd0b45131fe1b9333b4c1db299918 100644 --- a/fs/smb/server/transport_rdma.c +++ b/fs/smb/server/transport_rdma.c @@ -362,7 +362,7 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) struct smb_direct_transport *t; struct ksmbd_conn *conn; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc(sizeof(*t), KSMBD_DEFAULT_GFP); if (!t) return NULL; @@ -462,7 +462,7 @@ static struct smb_direct_sendmsg { struct smb_direct_sendmsg *msg; - msg = mempool_alloc(t->sendmsg_mempool, GFP_KERNEL); + msg = mempool_alloc(t->sendmsg_mempool, KSMBD_DEFAULT_GFP); if (!msg) return ERR_PTR(-ENOMEM); msg->transport = t; @@ -1406,7 +1406,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, desc_buf = buf; for (i = 0; i < desc_num; i++) { msg = kzalloc(struct_size(msg, sg_list, SG_CHUNK_SIZE), - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (!msg) { ret = -ENOMEM; goto out; @@ -1852,7 +1852,7 @@ static int smb_direct_create_pools(struct smb_direct_transport *t) INIT_LIST_HEAD(&t->recvmsg_queue); for (i = 0; i < t->recv_credit_max; i++) { - recvmsg = mempool_alloc(t->recvmsg_mempool, GFP_KERNEL); + recvmsg = mempool_alloc(t->recvmsg_mempool, KSMBD_DEFAULT_GFP); if (!recvmsg) goto err; recvmsg->transport = t; @@ -2144,7 +2144,7 @@ static int smb_direct_ib_client_add(struct ib_device *ib_dev) if (!rdma_frwr_is_supported(&ib_dev->attrs)) return 0; - smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL); + smb_dev = kzalloc(sizeof(*smb_dev), KSMBD_DEFAULT_GFP); if (!smb_dev) return -ENOMEM; smb_dev->ib_dev = ib_dev; @@ -2289,6 +2289,9 @@ out: } } + ksmbd_debug(RDMA, "netdev(%s) rdma capable : %s\n", + netdev->name, rdma_capable ? "true" : "false"); + return rdma_capable; } diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c index aaed9e293b2e0235a59677e8c1ffa19b336fc38f..0d9007285e30bbb0a6492595d370f4a75e44dc75 100644 --- a/fs/smb/server/transport_tcp.c +++ b/fs/smb/server/transport_tcp.c @@ -76,7 +76,7 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk) struct tcp_transport *t; struct ksmbd_conn *conn; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc(sizeof(*t), KSMBD_DEFAULT_GFP); if (!t) return NULL; t->sock = client_sk; @@ -151,7 +151,7 @@ static struct kvec *get_conn_iovec(struct tcp_transport *t, unsigned int nr_segs return t->iov; /* not big enough -- allocate a new one and release the old */ - new_iov = kmalloc_array(nr_segs, sizeof(*new_iov), GFP_KERNEL); + new_iov = kmalloc_array(nr_segs, sizeof(*new_iov), KSMBD_DEFAULT_GFP); if (new_iov) { kfree(t->iov); t->iov = new_iov; @@ -521,6 +521,8 @@ static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event, found = 1; if (iface->state != IFACE_STATE_DOWN) break; + ksmbd_debug(CONN, "netdev-up event: netdev(%s) is going up\n", + iface->name); ret = create_socket(iface); if (ret) return NOTIFY_OK; @@ -528,9 +530,11 @@ static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event, } } if (!found && bind_additional_ifaces) { - iface = alloc_iface(kstrdup(netdev->name, GFP_KERNEL)); + iface = alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP)); if (!iface) return NOTIFY_OK; + ksmbd_debug(CONN, "netdev-up event: netdev(%s) is going up\n", + iface->name); ret = create_socket(iface); if (ret) break; @@ -540,6 +544,8 @@ static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event, list_for_each_entry(iface, &iface_list, entry) { if (!strcmp(iface->name, netdev->name) && iface->state == IFACE_STATE_CONFIGURED) { + ksmbd_debug(CONN, "netdev-down event: netdev(%s) is going down\n", + iface->name); tcp_stop_kthread(iface->ksmbd_kthread); iface->ksmbd_kthread = NULL; mutex_lock(&iface->sock_release_lock); @@ -600,7 +606,7 @@ static struct interface *alloc_iface(char *ifname) if (!ifname) return NULL; - iface = kzalloc(sizeof(struct interface), GFP_KERNEL); + iface = kzalloc(sizeof(struct interface), KSMBD_DEFAULT_GFP); if (!iface) { kfree(ifname); return NULL; @@ -624,7 +630,7 @@ int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz) for_each_netdev(&init_net, netdev) { if (netif_is_bridge_port(netdev)) continue; - if (!alloc_iface(kstrdup(netdev->name, GFP_KERNEL))) { + if (!alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP))) { rtnl_unlock(); return -ENOMEM; } @@ -635,7 +641,7 @@ int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz) } while (ifc_list_sz > 0) { - if (!alloc_iface(kstrdup(ifc_list, GFP_KERNEL))) + if (!alloc_iface(kstrdup(ifc_list, KSMBD_DEFAULT_GFP))) return -ENOMEM; sz = strlen(ifc_list); diff --git a/fs/smb/server/unicode.c b/fs/smb/server/unicode.c index 217106ff7b8287a7e334c9235aae2d7ea397edd0..85e6791745ec8eb6baec2961bdd3eea0b0313124 100644 --- a/fs/smb/server/unicode.c +++ b/fs/smb/server/unicode.c @@ -297,7 +297,7 @@ char *smb_strndup_from_utf16(const char *src, const int maxlen, if (is_unicode) { len = smb_utf16_bytes((__le16 *)src, maxlen, codepage); len += nls_nullsize(codepage); - dst = kmalloc(len, GFP_KERNEL); + dst = kmalloc(len, KSMBD_DEFAULT_GFP); if (!dst) return ERR_PTR(-ENOMEM); ret = smb_from_utf16(dst, (__le16 *)src, len, maxlen, codepage, @@ -309,7 +309,7 @@ char *smb_strndup_from_utf16(const char *src, const int maxlen, } else { len = strnlen(src, maxlen); len++; - dst = kmalloc(len, GFP_KERNEL); + dst = kmalloc(len, KSMBD_DEFAULT_GFP); if (!dst) return ERR_PTR(-ENOMEM); strscpy(dst, src, len); diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 7cbd580120d129deb415cba8bf49830f35185d09..88d167a5f8b7b722e39809ffbbb4c6279d57faed 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -444,7 +444,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, } if (v_len < size) { - wbuf = kvzalloc(size, GFP_KERNEL); + wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP); if (!wbuf) { err = -ENOMEM; goto out; @@ -865,7 +865,7 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list) if (size <= 0) return size; - vlist = kvzalloc(size, GFP_KERNEL); + vlist = kvzalloc(size, KSMBD_DEFAULT_GFP); if (!vlist) return -ENOMEM; @@ -907,7 +907,7 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, if (xattr_len < 0) return xattr_len; - buf = kmalloc(xattr_len + 1, GFP_KERNEL); + buf = kmalloc(xattr_len + 1, KSMBD_DEFAULT_GFP); if (!buf) return -ENOMEM; @@ -1411,7 +1411,7 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id smb_acl = kzalloc(sizeof(struct xattr_smb_acl) + sizeof(struct xattr_acl_entry) * posix_acls->a_count, - GFP_KERNEL); + KSMBD_DEFAULT_GFP); if (!smb_acl) goto out; @@ -1767,7 +1767,7 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, else type = ":$DATA"; - buf = kasprintf(GFP_KERNEL, "%s%s%s", + buf = kasprintf(KSMBD_DEFAULT_GFP, "%s%s%s", XATTR_NAME_STREAM, stream_name, type); if (!buf) return -ENOMEM; @@ -1896,7 +1896,7 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap, acl_state.group.allow; acl_state.mask.allow = 0x07; - acls = posix_acl_alloc(6, GFP_KERNEL); + acls = posix_acl_alloc(6, KSMBD_DEFAULT_GFP); if (!acls) { free_acl_state(&acl_state); return -ENOMEM; diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index a19f4e563c7e54632aa2116fa7ace979c70bfe76..8d1f30dcba7e8eca86a19237a6417f1bea419abe 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -188,7 +188,7 @@ static struct ksmbd_inode *ksmbd_inode_get(struct ksmbd_file *fp) if (ci) return ci; - ci = kmalloc(sizeof(struct ksmbd_inode), GFP_KERNEL); + ci = kmalloc(sizeof(struct ksmbd_inode), KSMBD_DEFAULT_GFP); if (!ci) return NULL; @@ -577,7 +577,7 @@ static int __open_id(struct ksmbd_file_table *ft, struct ksmbd_file *fp, return -EMFILE; } - idr_preload(GFP_KERNEL); + idr_preload(KSMBD_DEFAULT_GFP); write_lock(&ft->lock); ret = idr_alloc_cyclic(ft->idr, fp, 0, INT_MAX - 1, GFP_NOWAIT); if (ret >= 0) { @@ -605,7 +605,7 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp) struct ksmbd_file *fp; int ret; - fp = kmem_cache_zalloc(filp_cache, GFP_KERNEL); + fp = kmem_cache_zalloc(filp_cache, KSMBD_DEFAULT_GFP); if (!fp) { pr_err("Failed to allocate memory\n"); return ERR_PTR(-ENOMEM); @@ -923,7 +923,7 @@ int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share, char *pathname, *ab_pathname; int ret = 0; - pathname = kmalloc(PATH_MAX, GFP_KERNEL); + pathname = kmalloc(PATH_MAX, KSMBD_DEFAULT_GFP); if (!pathname) return -EACCES; @@ -983,7 +983,7 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp) int ksmbd_init_file_table(struct ksmbd_file_table *ft) { - ft->idr = kzalloc(sizeof(struct idr), GFP_KERNEL); + ft->idr = kzalloc(sizeof(struct idr), KSMBD_DEFAULT_GFP); if (!ft->idr) return -ENOMEM; diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index d1995e2d6c943a644ff9f34cf2488864d57daf81..785408861c01c89fc84c787848243a13c1338367 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -91,9 +91,12 @@ static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf, count = size - pos; } - if (!battr->read) + if (!battr->read && !battr->read_new) return -EIO; + if (battr->read_new) + return battr->read_new(of->file, kobj, battr, buf, pos, count); + return battr->read(of->file, kobj, battr, buf, pos, count); } @@ -152,9 +155,12 @@ static ssize_t sysfs_kf_bin_write(struct kernfs_open_file *of, char *buf, if (!count) return 0; - if (!battr->write) + if (!battr->write && !battr->write_new) return -EIO; + if (battr->write_new) + return battr->write_new(of->file, kobj, battr, buf, pos, count); + return battr->write(of->file, kobj, battr, buf, pos, count); } @@ -315,7 +321,7 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, } int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent, - const struct bin_attribute *battr, umode_t mode, + const struct bin_attribute *battr, umode_t mode, size_t size, kuid_t uid, kgid_t gid, const void *ns) { const struct attribute *attr = &battr->attr; @@ -323,13 +329,19 @@ int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent, const struct kernfs_ops *ops; struct kernfs_node *kn; + if (battr->read && battr->read_new) + return -EINVAL; + + if (battr->write && battr->write_new) + return -EINVAL; + if (battr->mmap) ops = &sysfs_bin_kfops_mmap; - else if (battr->read && battr->write) + else if ((battr->read || battr->read_new) && (battr->write || battr->write_new)) ops = &sysfs_bin_kfops_rw; - else if (battr->read) + else if (battr->read || battr->read_new) ops = &sysfs_bin_kfops_ro; - else if (battr->write) + else if (battr->write || battr->write_new) ops = &sysfs_bin_kfops_wo; else ops = &sysfs_file_kfops_empty; @@ -340,7 +352,7 @@ int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent, #endif kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid, - battr->size, ops, (void *)attr, ns, key); + size, ops, (void *)attr, ns, key); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, attr->name); @@ -580,8 +592,8 @@ int sysfs_create_bin_file(struct kobject *kobj, return -EINVAL; kobject_get_ownership(kobj, &uid, &gid); - return sysfs_add_bin_file_mode_ns(kobj->sd, attr, attr->attr.mode, uid, - gid, NULL); + return sysfs_add_bin_file_mode_ns(kobj->sd, attr, attr->attr.mode, + attr->size, uid, gid, NULL); } EXPORT_SYMBOL_GPL(sysfs_create_bin_file); diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index d22ad67a0f3291f4702f494939528d5d13c31fae..8b01a7eda5fb3239e138372417d01967c7a3f122 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -87,6 +87,7 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, if (grp->bin_attrs) { for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) { umode_t mode = (*bin_attr)->attr.mode; + size_t size = (*bin_attr)->size; if (update) kernfs_remove_by_name(parent, @@ -97,6 +98,8 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, if (!mode) continue; } + if (grp->bin_size) + size = grp->bin_size(kobj, *bin_attr, i); WARN(mode & ~(SYSFS_PREALLOC | 0664), "Attribute %s: Invalid permissions 0%o\n", @@ -104,7 +107,7 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, mode &= SYSFS_PREALLOC | 0664; error = sysfs_add_bin_file_mode_ns(parent, *bin_attr, - mode, uid, gid, + mode, size, uid, gid, NULL); if (error) break; diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 3f28c9af57562f61a00a47935579f0939cbfd4dc..8e012f25e1c06e802c3138cc2715b46c1f67fa48 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -31,7 +31,7 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, const struct attribute *attr, umode_t amode, kuid_t uid, kgid_t gid, const void *ns); int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent, - const struct bin_attribute *battr, umode_t mode, + const struct bin_attribute *battr, umode_t mode, size_t size, kuid_t uid, kgid_t gid, const void *ns); /* diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index d79cabe193c34765ec1936d8f001f09d3c949733..2c99349cf537532a91f2f60e5825f5ca6310a89a 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c @@ -213,12 +213,6 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { - case FS_IOC32_GETFLAGS: - cmd = FS_IOC_GETFLAGS; - break; - case FS_IOC32_SETFLAGS: - cmd = FS_IOC_SETFLAGS; - break; case FS_IOC_SET_ENCRYPTION_POLICY: case FS_IOC_GET_ENCRYPTION_POLICY: case FS_IOC_GET_ENCRYPTION_POLICY_EX: diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 4a35f9e8f6681794740f1bbdf12fd8781188b28f..36ba79fbd2ff80ff3d5c1f0bf965e439d8c55ab2 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c @@ -981,6 +981,13 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); + if (kill_xattrs && ui->xattr_cnt > ubifs_xattr_max_cnt(c)) { + ubifs_err(c, "Cannot delete inode, it has too much xattrs!"); + err = -EPERM; + ubifs_ro_mode(c, err); + return err; + } + /* * If the inode is being deleted, do not write the attached data. No * need to synchronize the write-buffer either. @@ -1012,12 +1019,6 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) struct inode *xino; struct ubifs_dent_node *xent, *pxent = NULL; - if (ui->xattr_cnt > ubifs_xattr_max_cnt(c)) { - err = -EPERM; - ubifs_err(c, "Cannot delete inode, it has too much xattrs!"); - goto out_release; - } - lowest_xent_key(c, &key, inode->i_ino); while (1) { xent = ubifs_tnc_next_ent(c, &key, &nm); diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index 07351fdce72230f81d1caa48998741e09fe11722..aa8837e6247cf99ba5121a9d12c4078a653fd23b 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c @@ -577,7 +577,7 @@ static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, /* Go right */ nnode = ubifs_get_nnode(c, nnode, iip); if (IS_ERR(nnode)) - return (void *)nnode; + return ERR_CAST(nnode); /* Go down to level 1 */ while (nnode->level > 1) { @@ -594,7 +594,7 @@ static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, } nnode = ubifs_get_nnode(c, nnode, iip); if (IS_ERR(nnode)) - return (void *)nnode; + return ERR_CAST(nnode); } for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index fb957d963ba6c0edcb9a0a6eca2009309bbdb0da..5555dd740889479e34287949b0114efccf775a9a 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -76,7 +76,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) else if (inum > o->inum) p = &(*p)->rb_right; else { - ubifs_err(c, "orphaned twice"); + ubifs_err(c, "ino %lu orphaned twice", (unsigned long)inum); spin_unlock(&c->orphan_lock); kfree(orphan); return -EINVAL; diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 3fb308b6e16793a2d855463952e8404e12641700..f3e3b20686085e3b76adac5cff9b5ff3b956c204 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -773,10 +773,10 @@ static void init_constants_master(struct ubifs_info *c) * necessary to report something for the 'statfs()' call. * * Subtract the LEB reserved for GC, the LEB which is reserved for - * deletions, minimum LEBs for the index, and assume only one journal - * head is available. + * deletions, minimum LEBs for the index, the LEBs which are reserved + * for each journal head. */ - tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt + 1; + tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt; tmp64 *= (long long)c->leb_size - c->leb_overhead; tmp64 = ubifs_reported_space(c, tmp64); c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT; @@ -2206,6 +2206,8 @@ static int ubifs_fill_super(struct super_block *sb, struct fs_context *fc) } super_set_uuid(sb, c->uuid, sizeof(c->uuid)); + super_set_sysfs_name_generic(sb, UBIFS_DFS_DIR_NAME, + c->vi.ubi_num, c->vi.vol_id); mutex_unlock(&c->umount_mutex); return 0; diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 45cacdcd4746bcdc276eda7b4686cf09dbf6481a..33946b51814814ecd13815b01aa2637f38a3abdf 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -2930,8 +2930,6 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum) dbg_tnc("xent '%s', ino %lu", xent->name, (unsigned long)xattr_inum); - ubifs_evict_xattr_inode(c, xattr_inum); - fname_name(&nm) = xent->name; fname_len(&nm) = le16_to_cpu(xent->nlen); err = ubifs_tnc_remove_nm(c, &key1, &nm); diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index a55e04822d16e9a8e6139f02e0a9a8e677335a7d..7c43e0ccf6d47d6b87af7a8bc04208fc65de48f5 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c @@ -657,6 +657,8 @@ static int get_znodes_to_commit(struct ubifs_info *c) znode->alt = 0; cnext = find_next_dirty(znode); if (!cnext) { + ubifs_assert(c, !znode->parent); + znode->cparent = NULL; znode->cnext = c->cnext; break; } diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index d69a5a42d6936c32665496ab0a40a47c22365a5b..3375bbe0508c7248ec66dd6bb5a6ef8c3e950fd7 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -2040,13 +2040,10 @@ ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, #ifdef CONFIG_UBIFS_FS_XATTR extern const struct xattr_handler * const ubifs_xattr_handlers[]; ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); -void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); int ubifs_purge_xattrs(struct inode *host); #else #define ubifs_listxattr NULL #define ubifs_xattr_handlers NULL -static inline void ubifs_evict_xattr_inode(struct ubifs_info *c, - ino_t xattr_inum) { } static inline int ubifs_purge_xattrs(struct inode *host) { return 0; diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index f734588b224a31838cc9830093603c4dff9c377a..c21a0c2b3e907c1572780d4a3e48cc9d2a11b9d6 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -48,19 +48,6 @@ #include #include -/* - * Extended attribute type constants. - * - * USER_XATTR: user extended attribute ("user.*") - * TRUSTED_XATTR: trusted extended attribute ("trusted.*) - * SECURITY_XATTR: security extended attribute ("security.*") - */ -enum { - USER_XATTR, - TRUSTED_XATTR, - SECURITY_XATTR, -}; - static const struct inode_operations empty_iops; static const struct file_operations empty_fops; @@ -532,8 +519,6 @@ int ubifs_purge_xattrs(struct inode *host) ubifs_err(c, "dead directory entry '%s', error %d", xent->name, err); ubifs_ro_mode(c, err); - kfree(pxent); - kfree(xent); goto out_err; } @@ -541,16 +526,12 @@ int ubifs_purge_xattrs(struct inode *host) clear_nlink(xino); err = remove_xattr(c, host, xino, &nm); + iput(xino); if (err) { - kfree(pxent); - kfree(xent); - iput(xino); ubifs_err(c, "cannot remove xattr, error %d", err); goto out_err; } - iput(xino); - kfree(pxent); pxent = xent; key_read(c, &xent->key, &key); @@ -566,32 +547,12 @@ int ubifs_purge_xattrs(struct inode *host) return 0; out_err: + kfree(pxent); + kfree(xent); up_write(&ubifs_inode(host)->xattr_sem); return err; } -/** - * ubifs_evict_xattr_inode - Evict an xattr inode. - * @c: UBIFS file-system description object - * @xattr_inum: xattr inode number - * - * When an inode that hosts xattrs is being removed we have to make sure - * that cached inodes of the xattrs also get removed from the inode cache - * otherwise we'd waste memory. This function looks up an inode from the - * inode cache and clears the link counter such that iput() will evict - * the inode. - */ -void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum) -{ - struct inode *inode; - - inode = ilookup(c->vfs_sb, xattr_inum); - if (inode) { - clear_nlink(inode); - iput(inode); - } -} - static int ubifs_xattr_remove(struct inode *host, const char *name) { struct inode *inode; diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 78a603129dd583dd12170330df668a690f018590..2cb49b6b07168a8195ce10391546c2e8bc110983 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -517,7 +517,11 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) inode->i_nlink); clear_nlink(inode); inode->i_size = 0; - inode_dec_link_count(dir); + if (dir->i_nlink >= 3) + inode_dec_link_count(dir); + else + udf_warn(inode->i_sb, "parent dir link count too low (%u)\n", + dir->i_nlink); udf_add_fid_counter(dir->i_sb, true, -1); inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_set_ctime_current(inode))); @@ -787,8 +791,18 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, retval = -ENOTEMPTY; if (!empty_dir(new_inode)) goto out_oiter; + retval = -EFSCORRUPTED; + if (new_inode->i_nlink != 2) + goto out_oiter; } + retval = -EFSCORRUPTED; + if (old_dir->i_nlink < 3) + goto out_oiter; is_dir = true; + } else if (new_inode) { + retval = -EFSCORRUPTED; + if (new_inode->i_nlink < 1) + goto out_oiter; } if (is_dir && old_dir != new_dir) { retval = udf_fiiter_find_entry(old_inode, &dotdot_name, diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 9052839305e2caa52734295931ab4ac3b7340020..5255f93bae31f39371b09ac5bf66ad859b313b93 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -2620,8 +2620,7 @@ xfs_bmap_add_extent_hole_delay( */ if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) && left.br_startoff + left.br_blockcount == new->br_startoff && - left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN && - xfs_bmap_same_rtgroup(ip, whichfork, &left, new)) + left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN) state |= BMAP_LEFT_CONTIG; if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) && @@ -2629,8 +2628,7 @@ xfs_bmap_add_extent_hole_delay( new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN && (!(state & BMAP_LEFT_CONTIG) || (left.br_blockcount + new->br_blockcount + - right.br_blockcount <= XFS_MAX_BMBT_EXTLEN)) && - xfs_bmap_same_rtgroup(ip, whichfork, new, &right)) + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN))) state |= BMAP_RIGHT_CONTIG; /* diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 8b84e2cf711b19b3bb01576a07ac71430f808d05..f3a840a425f5101982cba9fd902333143814b027 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -853,7 +853,8 @@ sparse_alloc: * the end of the AG. */ args.min_agbno = args.mp->m_sb.sb_inoalignmt; - args.max_agbno = round_down(args.mp->m_sb.sb_agblocks, + args.max_agbno = round_down(xfs_ag_block_count(args.mp, + pag_agno(pag)), args.mp->m_sb.sb_inoalignmt) - igeo->ialloc_blks; @@ -2349,9 +2350,9 @@ xfs_difree( return -EINVAL; } agbno = XFS_AGINO_TO_AGBNO(mp, agino); - if (agbno >= mp->m_sb.sb_agblocks) { - xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).", - __func__, agbno, mp->m_sb.sb_agblocks); + if (agbno >= xfs_ag_block_count(mp, pag_agno(pag))) { + xfs_warn(mp, "%s: agbno >= xfs_ag_block_count (%d >= %d).", + __func__, agbno, xfs_ag_block_count(mp, pag_agno(pag))); ASSERT(0); return -EINVAL; } @@ -2474,7 +2475,7 @@ xfs_imap( */ agino = XFS_INO_TO_AGINO(mp, ino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); - if (agbno >= mp->m_sb.sb_agblocks || + if (agbno >= xfs_ag_block_count(mp, pag_agno(pag)) || ino != xfs_agino_to_ino(pag, agino)) { error = -EINVAL; #ifdef DEBUG @@ -2484,11 +2485,12 @@ xfs_imap( */ if (flags & XFS_IGET_UNTRUSTED) return error; - if (agbno >= mp->m_sb.sb_agblocks) { + if (agbno >= xfs_ag_block_count(mp, pag_agno(pag))) { xfs_alert(mp, "%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)", __func__, (unsigned long long)agbno, - (unsigned long)mp->m_sb.sb_agblocks); + (unsigned long)xfs_ag_block_count(mp, + pag_agno(pag))); } if (ino != xfs_agino_to_ino(pag, agino)) { xfs_alert(mp, diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index e81b240b71583e7940806badb0c0f37a9b708802..a809513a290cf4a4d150a7dc8d3a374f79b3ea7e 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -326,13 +326,6 @@ xfs_validate_sb_write( * the kernel cannot support since we checked for unsupported bits in * the read verifier, which means that memory is corrupt. */ - if (xfs_sb_has_compat_feature(sbp, XFS_SB_FEAT_COMPAT_UNKNOWN)) { - xfs_warn(mp, -"Corruption detected in superblock compatible features (0x%x)!", - (sbp->sb_features_compat & XFS_SB_FEAT_COMPAT_UNKNOWN)); - return -EFSCORRUPTED; - } - if (!xfs_is_readonly(mp) && xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { xfs_alert(mp, diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 7db38630487514d553facdc3421e37349c561e3d..379b48d015d2541d10618a7eab1db09e9e581270 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -114,7 +114,8 @@ xfs_attr_shortform_list( * It didn't all fit, so we have to sort everything on hashval. */ sbsize = sf->count * sizeof(*sbuf); - sbp = sbuf = kmalloc(sbsize, GFP_KERNEL | __GFP_NOFAIL); + sbp = sbuf = kmalloc(sbsize, + GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); /* * Scan the attribute list for the rest of the entries, storing diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 26b2f5887b88193175e8abafa12b17a9bd370f31..05daad8a8d34dfc635eb6ac0dd2d79cf31b30b94 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -3455,6 +3455,16 @@ xlog_force_shutdown( if (!log) return false; + /* + * Ensure that there is only ever one log shutdown being processed. + * If we allow the log force below on a second pass after shutting + * down the log, we risk deadlocking the CIL push as it may require + * locks on objects the current shutdown context holds (e.g. taking + * buffer locks to abort buffers on last unpin of buf log items). + */ + if (test_and_set_bit(XLOG_SHUTDOWN_STARTED, &log->l_opstate)) + return false; + /* * Flush all the completed transactions to disk before marking the log * being shut down. We need to do this first as shutting down the log @@ -3487,6 +3497,7 @@ xlog_force_shutdown( spin_lock(&log->l_icloglock); if (test_and_set_bit(XLOG_IO_ERROR, &log->l_opstate)) { spin_unlock(&log->l_icloglock); + ASSERT(0); return false; } spin_unlock(&log->l_icloglock); diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 2e9157b650e647215e16a81a3ec335abe6d2746c..1ca406ec1b40b324e31ebaab49c9d38d87aa1adc 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -171,11 +171,8 @@ xlog_cil_insert_pcp_aggregate( */ for_each_cpu(cpu, &ctx->cil_pcpmask) { struct xlog_cil_pcp *cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); - int old = READ_ONCE(cilpcp->space_used); - while (!try_cmpxchg(&cilpcp->space_used, &old, 0)) - ; - count += old; + count += xchg(&cilpcp->space_used, 0); } atomic_add(count, &ctx->space_used); } diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index b8778a4fd6b64e3a2ab9a09f2ab0dd916f2c6487..f3d78869e5e5a3c6c51839fd1244dd0d5b72e2d3 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -458,6 +458,7 @@ struct xlog { #define XLOG_IO_ERROR 2 /* log hit an I/O error, and being shutdown */ #define XLOG_TAIL_WARN 3 /* log tail verify warning issued */ +#define XLOG_SHUTDOWN_STARTED 4 /* xlog_force_shutdown() exclusion */ static inline bool xlog_recovery_needed(struct xlog *log) diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 4eda50ae2d1cb26bfe204b6826e2dc66ae8750c7..0c78f30fa4a3ff5b76f3d388b3f7fcbec6072982 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -427,19 +427,6 @@ xfs_qm_scall_getquota_fill_qc( dst->d_ino_timer = 0; dst->d_rt_spc_timer = 0; } - -#ifdef DEBUG - if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) { - if ((dst->d_space > dst->d_spc_softlimit) && - (dst->d_spc_softlimit > 0)) { - ASSERT(dst->d_spc_timer != 0); - } - if ((dst->d_ino_count > dqp->q_ino.softlimit) && - (dqp->q_ino.softlimit > 0)) { - ASSERT(dst->d_ino_timer != 0); - } - } -#endif } /* Return the quota information for the dquot matching id. */ diff --git a/include/asm-generic/delay.h b/include/asm-generic/delay.h index 76cf237b6e4cb590544e84edc9984c153741f63f..03b0ec7afca6f774a54edf232c55129b00227992 100644 --- a/include/asm-generic/delay.h +++ b/include/asm-generic/delay.h @@ -75,11 +75,11 @@ static __always_inline void ndelay(unsigned long nsec) { if (__builtin_constant_p(nsec)) { if (nsec >= DELAY_CONST_MAX) - __bad_udelay(); + __bad_ndelay(); else __const_udelay(nsec * NDELAY_CONST_MULT); } else { - __udelay(nsec); + __ndelay(nsec); } } #define ndelay(x) ndelay(x) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index eeadbaeccf88b73af40efe5221760a7cb37058d2..54504013c74915c2ed923fb3afde024a69cdae6b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -95,18 +95,25 @@ * With LTO_CLANG, the linker also splits sections by default, so we need * these macros to combine the sections during the final link. * + * With AUTOFDO_CLANG and PROPELLER_CLANG, by default, the linker splits + * text sections and regroups functions into subsections. + * * RODATA_MAIN is not used because existing code already defines .rodata.x * sections to be brought in with rodata. */ -#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) +#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) || \ +defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) #define TEXT_MAIN .text .text.[0-9a-zA-Z_]* +#else +#define TEXT_MAIN .text +#endif +#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) #define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$L* #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* #define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L* #define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..L* .bss..compoundliteral* #define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]* #else -#define TEXT_MAIN .text #define DATA_MAIN .data #define SDATA_MAIN .sdata #define RODATA_MAIN .rodata @@ -350,9 +357,9 @@ *(.data..decrypted) \ *(.ref.data) \ *(.data..shared_aligned) /* percpu related */ \ - *(.data.unlikely) \ + *(.data..unlikely) \ __start_once = .; \ - *(.data.once) \ + *(.data..once) \ __end_once = .; \ STRUCT_ALIGN(); \ *(__tracepoints) \ @@ -549,24 +556,44 @@ __cpuidle_text_end = .; \ __noinstr_text_end = .; +#define TEXT_SPLIT \ + __split_text_start = .; \ + *(.text.split .text.split.[0-9a-zA-Z_]*) \ + __split_text_end = .; + +#define TEXT_UNLIKELY \ + __unlikely_text_start = .; \ + *(.text.unlikely .text.unlikely.*) \ + __unlikely_text_end = .; + +#define TEXT_HOT \ + __hot_text_start = .; \ + *(.text.hot .text.hot.*) \ + __hot_text_end = .; + /* * .text section. Map to function alignment to avoid address changes * during second ld run in second ld pass when generating System.map * - * TEXT_MAIN here will match .text.fixup and .text.unlikely if dead - * code elimination is enabled, so these sections should be converted - * to use ".." first. + * TEXT_MAIN here will match symbols with a fixed pattern (for example, + * .text.hot or .text.unlikely) if dead code elimination or + * function-section is enabled. Match these symbols first before + * TEXT_MAIN to ensure they are grouped together. + * + * Also placing .text.hot section at the beginning of a page, this + * would help the TLB performance. */ #define TEXT_TEXT \ ALIGN_FUNCTION(); \ - *(.text.hot .text.hot.*) \ - *(TEXT_MAIN .text.fixup) \ - *(.text.unlikely .text.unlikely.*) \ + *(.text.asan.* .text.tsan.*) \ *(.text.unknown .text.unknown.*) \ + TEXT_SPLIT \ + TEXT_UNLIKELY \ + . = ALIGN(PAGE_SIZE); \ + TEXT_HOT \ + *(TEXT_MAIN .text.fixup) \ NOINSTR_TEXT \ - *(.ref.text) \ - *(.text.asan.* .text.tsan.*) - + *(.ref.text) /* sched.text is aling to function alignment to secure we have same * address even at second ld pass when generating System.map */ diff --git a/include/dt-bindings/iio/adc/gehc,pmc-adc.h b/include/dt-bindings/iio/adc/gehc,pmc-adc.h new file mode 100644 index 0000000000000000000000000000000000000000..2f291e3c76aec445db1d39d1a8c5fc5be1eebb2e --- /dev/null +++ b/include/dt-bindings/iio/adc/gehc,pmc-adc.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ + +#ifndef _DT_BINDINGS_IIO_ADC_GEHC_PMC_ADC_H +#define _DT_BINDINGS_IIO_ADC_GEHC_PMC_ADC_H + +/* ADC channel type */ +#define GEHC_PMC_ADC_VOLTAGE 0 +#define GEHC_PMC_ADC_CURRENT 1 + +#endif diff --git a/include/dt-bindings/interconnect/qcom,qcs615-rpmh.h b/include/dt-bindings/interconnect/qcom,qcs615-rpmh.h new file mode 100644 index 0000000000000000000000000000000000000000..84ae0d39e73ccacfd9d2ceb3d53667d89f878e98 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,qcs615-rpmh.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_QCS615_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_QCS615_H + +#define MASTER_A1NOC_CFG 1 +#define MASTER_QDSS_BAM 2 +#define MASTER_QSPI 3 +#define MASTER_QUP_0 4 +#define MASTER_BLSP_1 5 +#define MASTER_CNOC_A2NOC 6 +#define MASTER_CRYPTO 7 +#define MASTER_IPA 8 +#define MASTER_EMAC_EVB 9 +#define MASTER_PCIE 10 +#define MASTER_QDSS_ETR 11 +#define MASTER_SDCC_1 12 +#define MASTER_SDCC_2 13 +#define MASTER_UFS_MEM 14 +#define MASTER_USB2 15 +#define MASTER_USB3_0 16 +#define SLAVE_A1NOC_SNOC 17 +#define SLAVE_LPASS_SNOC 18 +#define SLAVE_ANOC_PCIE_SNOC 19 +#define SLAVE_SERVICE_A2NOC 20 + +#define MASTER_CAMNOC_HF0_UNCOMP 1 +#define MASTER_CAMNOC_HF1_UNCOMP 2 +#define MASTER_CAMNOC_SF_UNCOMP 3 +#define SLAVE_CAMNOC_UNCOMP 4 + +#define MASTER_SPDM 1 +#define MASTER_SNOC_CNOC 2 +#define MASTER_QDSS_DAP 3 +#define SLAVE_A1NOC_CFG 4 +#define SLAVE_AHB2PHY_EAST 5 +#define SLAVE_AHB2PHY_WEST 6 +#define SLAVE_AOP 7 +#define SLAVE_AOSS 8 +#define SLAVE_CAMERA_CFG 9 +#define SLAVE_CLK_CTL 10 +#define SLAVE_RBCPR_CX_CFG 11 +#define SLAVE_RBCPR_MX_CFG 12 +#define SLAVE_CRYPTO_0_CFG 13 +#define SLAVE_CNOC_DDRSS 14 +#define SLAVE_DISPLAY_CFG 15 +#define SLAVE_EMAC_AVB_CFG 16 +#define SLAVE_GLM 17 +#define SLAVE_GFX3D_CFG 18 +#define SLAVE_IMEM_CFG 19 +#define SLAVE_IPA_CFG 20 +#define SLAVE_CNOC_MNOC_CFG 21 +#define SLAVE_PCIE_CFG 22 +#define SLAVE_PIMEM_CFG 23 +#define SLAVE_PRNG 24 +#define SLAVE_QDSS_CFG 25 +#define SLAVE_QSPI 26 +#define SLAVE_QUP_0 27 +#define SLAVE_QUP_1 28 +#define SLAVE_SDCC_1 29 +#define SLAVE_SDCC_2 30 +#define SLAVE_SNOC_CFG 31 +#define SLAVE_SPDM_WRAPPER 32 +#define SLAVE_TCSR 33 +#define SLAVE_TLMM_EAST 34 +#define SLAVE_TLMM_SOUTH 35 +#define SLAVE_TLMM_WEST 36 +#define SLAVE_UFS_MEM_CFG 37 +#define SLAVE_USB2 38 +#define SLAVE_USB3 39 +#define SLAVE_VENUS_CFG 40 +#define SLAVE_VSENSE_CTRL_CFG 41 +#define SLAVE_CNOC_A2NOC 42 +#define SLAVE_SERVICE_CNOC 43 + +#define MASTER_CNOC_DC_NOC 1 +#define SLAVE_DC_NOC_GEMNOC 2 +#define SLAVE_LLCC_CFG 3 + +#define MASTER_APPSS_PROC 1 +#define MASTER_GPU_TCU 2 +#define MASTER_SYS_TCU 3 +#define MASTER_GEM_NOC_CFG 4 +#define MASTER_GFX3D 5 +#define MASTER_MNOC_HF_MEM_NOC 6 +#define MASTER_MNOC_SF_MEM_NOC 7 +#define MASTER_SNOC_GC_MEM_NOC 8 +#define MASTER_SNOC_SF_MEM_NOC 9 +#define SLAVE_MSS_PROC_MS_MPU_CFG 10 +#define SLAVE_GEM_NOC_SNOC 11 +#define SLAVE_LLCC 12 +#define SLAVE_MEM_NOC_PCIE_SNOC 13 +#define SLAVE_SERVICE_GEM_NOC 14 + +#define MASTER_IPA_CORE 1 +#define SLAVE_IPA_CORE 2 + +#define MASTER_LLCC 1 +#define SLAVE_EBI1 2 + +#define MASTER_CNOC_MNOC_CFG 1 +#define MASTER_CAMNOC_HF0 2 +#define MASTER_CAMNOC_HF1 3 +#define MASTER_CAMNOC_SF 4 +#define MASTER_MDP0 5 +#define MASTER_ROTATOR 6 +#define MASTER_VIDEO_P0 7 +#define MASTER_VIDEO_PROC 8 +#define SLAVE_MNOC_SF_MEM_NOC 9 +#define SLAVE_MNOC_HF_MEM_NOC 10 +#define SLAVE_SERVICE_MNOC 11 + +#define MASTER_SNOC_CFG 1 +#define MASTER_A1NOC_SNOC 2 +#define MASTER_GEM_NOC_SNOC 3 +#define MASTER_GEM_NOC_PCIE_SNOC 4 +#define MASTER_LPASS_ANOC 5 +#define MASTER_ANOC_PCIE_SNOC 6 +#define MASTER_PIMEM 7 +#define MASTER_GIC 8 +#define SLAVE_APPSS 9 +#define SLAVE_SNOC_CNOC 10 +#define SLAVE_SNOC_GEM_NOC_SF 11 +#define SLAVE_SNOC_MEM_NOC_GC 12 +#define SLAVE_IMEM 13 +#define SLAVE_PIMEM 14 +#define SLAVE_SERVICE_SNOC 15 +#define SLAVE_PCIE_0 16 +#define SLAVE_QDSS_STM 17 +#define SLAVE_TCU 18 + +#endif + diff --git a/include/dt-bindings/interconnect/qcom,qcs8300-rpmh.h b/include/dt-bindings/interconnect/qcom,qcs8300-rpmh.h new file mode 100644 index 0000000000000000000000000000000000000000..c5eeafa1b1dda784146510c24f879ad9a803f08a --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,qcs8300-rpmh.h @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_QCS8300_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_QCS8300_H + +#define MASTER_QUP_3 0 +#define MASTER_EMAC 1 +#define MASTER_SDC 2 +#define MASTER_UFS_MEM 3 +#define MASTER_USB2 4 +#define MASTER_USB3_0 5 +#define SLAVE_A1NOC_SNOC 6 + +#define MASTER_QDSS_BAM 0 +#define MASTER_QUP_0 1 +#define MASTER_QUP_1 2 +#define MASTER_CNOC_A2NOC 3 +#define MASTER_CRYPTO_CORE0 4 +#define MASTER_CRYPTO_CORE1 5 +#define MASTER_IPA 6 +#define MASTER_QDSS_ETR_0 7 +#define MASTER_QDSS_ETR_1 8 +#define SLAVE_A2NOC_SNOC 9 + +#define MASTER_QUP_CORE_0 0 +#define MASTER_QUP_CORE_1 1 +#define MASTER_QUP_CORE_3 2 +#define SLAVE_QUP_CORE_0 3 +#define SLAVE_QUP_CORE_1 4 +#define SLAVE_QUP_CORE_3 5 + +#define MASTER_GEM_NOC_CNOC 0 +#define MASTER_GEM_NOC_PCIE_SNOC 1 +#define SLAVE_AHB2PHY_2 2 +#define SLAVE_AHB2PHY_3 3 +#define SLAVE_ANOC_THROTTLE_CFG 4 +#define SLAVE_AOSS 5 +#define SLAVE_APPSS 6 +#define SLAVE_BOOT_ROM 7 +#define SLAVE_CAMERA_CFG 8 +#define SLAVE_CAMERA_NRT_THROTTLE_CFG 9 +#define SLAVE_CAMERA_RT_THROTTLE_CFG 10 +#define SLAVE_CLK_CTL 11 +#define SLAVE_CDSP_CFG 12 +#define SLAVE_RBCPR_CX_CFG 13 +#define SLAVE_RBCPR_MMCX_CFG 14 +#define SLAVE_RBCPR_MX_CFG 15 +#define SLAVE_CPR_NSPCX 16 +#define SLAVE_CPR_NSPHMX 17 +#define SLAVE_CRYPTO_0_CFG 18 +#define SLAVE_CX_RDPM 19 +#define SLAVE_DISPLAY_CFG 20 +#define SLAVE_DISPLAY_RT_THROTTLE_CFG 21 +#define SLAVE_EMAC_CFG 22 +#define SLAVE_GP_DSP0_CFG 23 +#define SLAVE_GPDSP0_THROTTLE_CFG 24 +#define SLAVE_GPU_TCU_THROTTLE_CFG 25 +#define SLAVE_GFX3D_CFG 26 +#define SLAVE_HWKM 27 +#define SLAVE_IMEM_CFG 28 +#define SLAVE_IPA_CFG 29 +#define SLAVE_IPC_ROUTER_CFG 30 +#define SLAVE_LPASS 31 +#define SLAVE_LPASS_THROTTLE_CFG 32 +#define SLAVE_MX_RDPM 33 +#define SLAVE_MXC_RDPM 34 +#define SLAVE_PCIE_0_CFG 35 +#define SLAVE_PCIE_1_CFG 36 +#define SLAVE_PCIE_TCU_THROTTLE_CFG 37 +#define SLAVE_PCIE_THROTTLE_CFG 38 +#define SLAVE_PDM 39 +#define SLAVE_PIMEM_CFG 40 +#define SLAVE_PKA_WRAPPER_CFG 41 +#define SLAVE_QDSS_CFG 42 +#define SLAVE_QM_CFG 43 +#define SLAVE_QM_MPU_CFG 44 +#define SLAVE_QUP_0 45 +#define SLAVE_QUP_1 46 +#define SLAVE_QUP_3 47 +#define SLAVE_SAIL_THROTTLE_CFG 48 +#define SLAVE_SDC1 49 +#define SLAVE_SECURITY 50 +#define SLAVE_SNOC_THROTTLE_CFG 51 +#define SLAVE_TCSR 52 +#define SLAVE_TLMM 53 +#define SLAVE_TSC_CFG 54 +#define SLAVE_UFS_MEM_CFG 55 +#define SLAVE_USB2 56 +#define SLAVE_USB3_0 57 +#define SLAVE_VENUS_CFG 58 +#define SLAVE_VENUS_CVP_THROTTLE_CFG 59 +#define SLAVE_VENUS_V_CPU_THROTTLE_CFG 60 +#define SLAVE_VENUS_VCODEC_THROTTLE_CFG 61 +#define SLAVE_DDRSS_CFG 62 +#define SLAVE_GPDSP_NOC_CFG 63 +#define SLAVE_CNOC_MNOC_HF_CFG 64 +#define SLAVE_CNOC_MNOC_SF_CFG 65 +#define SLAVE_PCIE_ANOC_CFG 66 +#define SLAVE_SNOC_CFG 67 +#define SLAVE_BOOT_IMEM 68 +#define SLAVE_IMEM 69 +#define SLAVE_PIMEM 70 +#define SLAVE_PCIE_0 71 +#define SLAVE_PCIE_1 72 +#define SLAVE_QDSS_STM 73 +#define SLAVE_TCU 74 + +#define MASTER_CNOC_DC_NOC 0 +#define SLAVE_LLCC_CFG 1 +#define SLAVE_GEM_NOC_CFG 2 + +#define MASTER_GPU_TCU 0 +#define MASTER_PCIE_TCU 1 +#define MASTER_SYS_TCU 2 +#define MASTER_APPSS_PROC 3 +#define MASTER_COMPUTE_NOC 4 +#define MASTER_GEM_NOC_CFG 5 +#define MASTER_GPDSP_SAIL 6 +#define MASTER_GFX3D 7 +#define MASTER_MNOC_HF_MEM_NOC 8 +#define MASTER_MNOC_SF_MEM_NOC 9 +#define MASTER_ANOC_PCIE_GEM_NOC 10 +#define MASTER_SNOC_GC_MEM_NOC 11 +#define MASTER_SNOC_SF_MEM_NOC 12 +#define SLAVE_GEM_NOC_CNOC 13 +#define SLAVE_LLCC 14 +#define SLAVE_GEM_NOC_PCIE_CNOC 15 +#define SLAVE_SERVICE_GEM_NOC_1 16 +#define SLAVE_SERVICE_GEM_NOC_2 17 +#define SLAVE_SERVICE_GEM_NOC 18 +#define SLAVE_SERVICE_GEM_NOC2 19 + +#define MASTER_SAILSS_MD0 0 +#define MASTER_DSP0 1 +#define SLAVE_GP_DSP_SAIL_NOC 2 + +#define MASTER_CNOC_LPASS_AG_NOC 0 +#define MASTER_LPASS_PROC 1 +#define SLAVE_LPASS_CORE_CFG 2 +#define SLAVE_LPASS_LPI_CFG 3 +#define SLAVE_LPASS_MPU_CFG 4 +#define SLAVE_LPASS_TOP_CFG 5 +#define SLAVE_LPASS_SNOC 6 +#define SLAVE_SERVICES_LPASS_AML_NOC 7 +#define SLAVE_SERVICE_LPASS_AG_NOC 8 + +#define MASTER_LLCC 0 +#define SLAVE_EBI1 1 + +#define MASTER_CAMNOC_HF 0 +#define MASTER_CAMNOC_ICP 1 +#define MASTER_CAMNOC_SF 2 +#define MASTER_MDP0 3 +#define MASTER_MDP1 4 +#define MASTER_CNOC_MNOC_HF_CFG 5 +#define MASTER_CNOC_MNOC_SF_CFG 6 +#define MASTER_VIDEO_P0 7 +#define MASTER_VIDEO_PROC 8 +#define MASTER_VIDEO_V_PROC 9 +#define SLAVE_MNOC_HF_MEM_NOC 10 +#define SLAVE_MNOC_SF_MEM_NOC 11 +#define SLAVE_SERVICE_MNOC_HF 12 +#define SLAVE_SERVICE_MNOC_SF 13 + +#define MASTER_CDSP_NOC_CFG 0 +#define MASTER_CDSP_PROC 1 +#define SLAVE_HCP_A 2 +#define SLAVE_CDSP_MEM_NOC 3 +#define SLAVE_SERVICE_NSP_NOC 4 + +#define MASTER_PCIE_0 0 +#define MASTER_PCIE_1 1 +#define SLAVE_ANOC_PCIE_GEM_NOC 2 + +#define MASTER_GIC_AHB 0 +#define MASTER_A1NOC_SNOC 1 +#define MASTER_A2NOC_SNOC 2 +#define MASTER_LPASS_ANOC 3 +#define MASTER_SNOC_CFG 4 +#define MASTER_PIMEM 5 +#define MASTER_GIC 6 +#define SLAVE_SNOC_GEM_NOC_GC 7 +#define SLAVE_SNOC_GEM_NOC_SF 8 +#define SLAVE_SERVICE_SNOC 9 + +#endif diff --git a/include/dt-bindings/interconnect/qcom,sar2130p-rpmh.h b/include/dt-bindings/interconnect/qcom,sar2130p-rpmh.h new file mode 100644 index 0000000000000000000000000000000000000000..aec7cbb7cd7050ae669bdf655ad97241555b00b5 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,sar2130p-rpmh.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024, Linaro Ltd. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_SAR2130P_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_SAR2130P_H + +#define MASTER_QUP_CORE_0 0 +#define MASTER_QUP_CORE_1 1 +#define SLAVE_QUP_CORE_0 2 +#define SLAVE_QUP_CORE_1 3 + +#define MASTER_GEM_NOC_CNOC 0 +#define MASTER_GEM_NOC_PCIE_SNOC 1 +#define MASTER_QDSS_DAP 2 +#define SLAVE_AHB2PHY_SOUTH 3 +#define SLAVE_AOSS 4 +#define SLAVE_CAMERA_CFG 5 +#define SLAVE_CLK_CTL 6 +#define SLAVE_CDSP_CFG 7 +#define SLAVE_RBCPR_CX_CFG 8 +#define SLAVE_RBCPR_MMCX_CFG 9 +#define SLAVE_RBCPR_MXA_CFG 10 +#define SLAVE_RBCPR_MXC_CFG 11 +#define SLAVE_CPR_NSPCX 12 +#define SLAVE_CRYPTO_0_CFG 13 +#define SLAVE_CX_RDPM 14 +#define SLAVE_DISPLAY_CFG 15 +#define SLAVE_GFX3D_CFG 16 +#define SLAVE_IMEM_CFG 17 +#define SLAVE_IPC_ROUTER_CFG 18 +#define SLAVE_LPASS 19 +#define SLAVE_MX_RDPM 20 +#define SLAVE_PCIE_0_CFG 21 +#define SLAVE_PCIE_1_CFG 22 +#define SLAVE_PDM 23 +#define SLAVE_PIMEM_CFG 24 +#define SLAVE_PRNG 25 +#define SLAVE_QDSS_CFG 26 +#define SLAVE_QSPI_0 27 +#define SLAVE_QUP_0 28 +#define SLAVE_QUP_1 29 +#define SLAVE_SDCC_1 30 +#define SLAVE_TCSR 31 +#define SLAVE_TLMM 32 +#define SLAVE_TME_CFG 33 +#define SLAVE_USB3_0 34 +#define SLAVE_VENUS_CFG 35 +#define SLAVE_VSENSE_CTRL_CFG 36 +#define SLAVE_WLAN_Q6_CFG 37 +#define SLAVE_DDRSS_CFG 38 +#define SLAVE_CNOC_MNOC_CFG 39 +#define SLAVE_SNOC_CFG 40 +#define SLAVE_IMEM 41 +#define SLAVE_PIMEM 42 +#define SLAVE_SERVICE_CNOC 43 +#define SLAVE_PCIE_0 44 +#define SLAVE_PCIE_1 45 +#define SLAVE_QDSS_STM 46 +#define SLAVE_TCU 47 + +#define MASTER_GPU_TCU 0 +#define MASTER_SYS_TCU 1 +#define MASTER_APPSS_PROC 2 +#define MASTER_GFX3D 3 +#define MASTER_MNOC_HF_MEM_NOC 4 +#define MASTER_MNOC_SF_MEM_NOC 5 +#define MASTER_COMPUTE_NOC 6 +#define MASTER_ANOC_PCIE_GEM_NOC 7 +#define MASTER_SNOC_GC_MEM_NOC 8 +#define MASTER_SNOC_SF_MEM_NOC 9 +#define MASTER_WLAN_Q6 10 +#define SLAVE_GEM_NOC_CNOC 11 +#define SLAVE_LLCC 12 +#define SLAVE_MEM_NOC_PCIE_SNOC 13 + +#define MASTER_CNOC_LPASS_AG_NOC 0 +#define MASTER_LPASS_PROC 1 +#define SLAVE_LPASS_CORE_CFG 2 +#define SLAVE_LPASS_LPI_CFG 3 +#define SLAVE_LPASS_MPU_CFG 4 +#define SLAVE_LPASS_TOP_CFG 5 +#define SLAVE_LPASS_SNOC 6 +#define SLAVE_SERVICES_LPASS_AML_NOC 7 +#define SLAVE_SERVICE_LPASS_AG_NOC 8 + +#define MASTER_LLCC 0 +#define SLAVE_EBI1 1 + +#define MASTER_CAMNOC_HF 0 +#define MASTER_CAMNOC_ICP 1 +#define MASTER_CAMNOC_SF 2 +#define MASTER_LSR 3 +#define MASTER_MDP 4 +#define MASTER_CNOC_MNOC_CFG 5 +#define MASTER_VIDEO 6 +#define MASTER_VIDEO_CV_PROC 7 +#define MASTER_VIDEO_PROC 8 +#define MASTER_VIDEO_V_PROC 9 +#define SLAVE_MNOC_HF_MEM_NOC 10 +#define SLAVE_MNOC_SF_MEM_NOC 11 +#define SLAVE_SERVICE_MNOC 12 + +#define MASTER_CDSP_NOC_CFG 0 +#define MASTER_CDSP_PROC 1 +#define SLAVE_CDSP_MEM_NOC 2 +#define SLAVE_SERVICE_NSP_NOC 3 + +#define MASTER_PCIE_0 0 +#define MASTER_PCIE_1 1 +#define SLAVE_ANOC_PCIE_GEM_NOC 2 + +#define MASTER_GIC_AHB 0 +#define MASTER_QDSS_BAM 1 +#define MASTER_QSPI_0 2 +#define MASTER_QUP_0 3 +#define MASTER_QUP_1 4 +#define MASTER_A2NOC_SNOC 5 +#define MASTER_CNOC_DATAPATH 6 +#define MASTER_LPASS_ANOC 7 +#define MASTER_SNOC_CFG 8 +#define MASTER_CRYPTO 9 +#define MASTER_PIMEM 10 +#define MASTER_GIC 11 +#define MASTER_QDSS_ETR 12 +#define MASTER_QDSS_ETR_1 13 +#define MASTER_SDCC_1 14 +#define MASTER_USB3_0 15 +#define SLAVE_A2NOC_SNOC 16 +#define SLAVE_SNOC_GEM_NOC_GC 17 +#define SLAVE_SNOC_GEM_NOC_SF 18 +#define SLAVE_SERVICE_SNOC 19 + +#endif diff --git a/include/kunit/visibility.h b/include/kunit/visibility.h index efff77b58dd6fb8b07b9d3b26b8272e590628b48..7c34c8ffcf3b2378054db6e2148c2389b3d75111 100644 --- a/include/kunit/visibility.h +++ b/include/kunit/visibility.h @@ -20,12 +20,11 @@ /** * EXPORT_SYMBOL_IF_KUNIT(symbol) - Exports symbol into * EXPORTED_FOR_KUNIT_TESTING namespace only if CONFIG_KUNIT is - * enabled. Must use MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING) + * enabled. Must use MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING") * in test file in order to use symbols. * @symbol: the symbol identifier to export */ - #define EXPORT_SYMBOL_IF_KUNIT(symbol) EXPORT_SYMBOL_NS(symbol, \ - EXPORTED_FOR_KUNIT_TESTING) + #define EXPORT_SYMBOL_IF_KUNIT(symbol) EXPORT_SYMBOL_NS(symbol, "EXPORTED_FOR_KUNIT_TESTING") #else #define VISIBLE_IF_KUNIT static #define EXPORT_SYMBOL_IF_KUNIT(symbol) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index f5172549f9ba0114430fd62a5c849f26a192e5b0..3a8ccfda34d29571d2d6f110f6bf7c002c996297 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -26,7 +26,6 @@ #define VGIC_NR_SGIS 16 #define VGIC_NR_PPIS 16 #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) -#define VGIC_MAX_PRIVATE (VGIC_NR_PRIVATE_IRQS - 1) #define VGIC_MAX_SPI 1019 #define VGIC_MAX_RESERVED 1023 #define VGIC_MIN_LPI 8192 diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 05f39fbfa4856d2e6b7d45d9580cc82963764d55..6adcd1b92b20681fdd93952dc45a51fe336711e7 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -40,7 +40,7 @@ struct irq_domain_ops; #include #ifdef CONFIG_ACPI_TABLE_LIB -#define EXPORT_SYMBOL_ACPI_LIB(x) EXPORT_SYMBOL_NS_GPL(x, ACPI) +#define EXPORT_SYMBOL_ACPI_LIB(x) EXPORT_SYMBOL_NS_GPL(x, "ACPI") #define __init_or_acpilib #define __initdata_or_acpilib #else diff --git a/include/linux/alcor_pci.h b/include/linux/alcor_pci.h index c4a0b23846d8ddbe8f4bf6cd7b1e7a6546234d09..dcb1d37dabc293a31256ba5efd0338416aa630af 100644 --- a/include/linux/alcor_pci.h +++ b/include/linux/alcor_pci.h @@ -11,6 +11,7 @@ #define ALCOR_SD_CARD 0 #define ALCOR_MS_CARD 1 +#define DRV_NAME_ALCOR_PCI "alcor_pci" #define DRV_NAME_ALCOR_PCI_SDMMC "alcor_sdmmc" #define DRV_NAME_ALCOR_PCI_MS "alcor_ms" diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index dda2f3ea89cb5d7a9b2f8189c6c740b0c4b20532..9946276aff73779435fc42b7a44f0717944e3e1a 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -121,6 +121,7 @@ extern const struct bus_type amba_bustype; #ifdef CONFIG_ARM_AMBA int __amba_driver_register(struct amba_driver *, struct module *); void amba_driver_unregister(struct amba_driver *); +bool dev_is_amba(const struct device *dev); #else static inline int __amba_driver_register(struct amba_driver *drv, struct module *owner) @@ -130,6 +131,10 @@ static inline int __amba_driver_register(struct amba_driver *drv, static inline void amba_driver_unregister(struct amba_driver *drv) { } +static inline bool dev_is_amba(const struct device *dev) +{ + return false; +} #endif struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t); diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h index 31762324bcc9b55810b3d4e4da1ea7eaf8920c02..65dd7f15437474468acf0e28f6932a7ff2cfff2c 100644 --- a/include/linux/auxiliary_bus.h +++ b/include/linux/auxiliary_bus.h @@ -269,8 +269,4 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv); #define module_auxiliary_driver(__auxiliary_driver) \ module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister) -struct auxiliary_device *auxiliary_find_device(struct device *start, - const void *data, - device_match_t match); - #endif /* _AUXILIARY_BUS_H_ */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a1fd0ddce5cf7649ba8a448d6f60ed2e23239c4e..08a727b408164712c2180a911a2574cf0b3446f1 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -333,6 +333,10 @@ typedef unsigned int __bitwise blk_features_t; #define BLK_FEAT_RAID_PARTIAL_STRIPES_EXPENSIVE \ ((__force blk_features_t)(1u << 15)) +/* stacked device can/does support atomic writes */ +#define BLK_FEAT_ATOMIC_WRITES_STACKED \ + ((__force blk_features_t)(1u << 16)) + /* * Flags automatically inherited when stacking limits. */ @@ -775,13 +779,13 @@ static inline void bdev_clear_flag(struct block_device *bdev, unsigned flag) atomic_andnot(flag, &bdev->__bd_flags); } -static inline int get_disk_ro(struct gendisk *disk) +static inline bool get_disk_ro(struct gendisk *disk) { return bdev_test_flag(disk->part0, BD_READ_ONLY) || test_bit(GD_READ_ONLY, &disk->state); } -static inline int bdev_read_only(struct block_device *bdev) +static inline bool bdev_read_only(struct block_device *bdev) { return bdev_test_flag(bdev, BD_READ_ONLY) || get_disk_ro(bdev->bd_disk); } @@ -1261,7 +1265,7 @@ static inline unsigned int queue_io_min(const struct request_queue *q) return q->limits.io_min; } -static inline int bdev_io_min(struct block_device *bdev) +static inline unsigned int bdev_io_min(struct block_device *bdev) { return queue_io_min(bdev_get_queue(bdev)); } @@ -1271,7 +1275,7 @@ static inline unsigned int queue_io_opt(const struct request_queue *q) return q->limits.io_opt; } -static inline int bdev_io_opt(struct block_device *bdev) +static inline unsigned int bdev_io_opt(struct block_device *bdev) { return queue_io_opt(bdev_get_queue(bdev)); } @@ -1417,7 +1421,7 @@ static inline bool bdev_zone_is_seq(struct block_device *bdev, sector_t sector) return is_seq; } -static inline int queue_dma_alignment(const struct request_queue *q) +static inline unsigned int queue_dma_alignment(const struct request_queue *q) { return q->limits.dma_alignment; } @@ -1458,12 +1462,13 @@ static inline bool bdev_iter_is_aligned(struct block_device *bdev, bdev_logical_block_size(bdev) - 1); } -static inline int blk_lim_dma_alignment_and_pad(struct queue_limits *lim) +static inline unsigned int +blk_lim_dma_alignment_and_pad(struct queue_limits *lim) { return lim->dma_alignment | lim->dma_pad_mask; } -static inline int blk_rq_aligned(struct request_queue *q, unsigned long addr, +static inline bool blk_rq_aligned(struct request_queue *q, unsigned long addr, unsigned int len) { unsigned int alignment = blk_lim_dma_alignment_and_pad(&q->limits); @@ -1581,7 +1586,6 @@ static inline void bio_end_io_acct(struct bio *bio, unsigned long start_time) return bio_end_io_acct_remapped(bio, start_time, bio->bi_bdev); } -int bdev_read_only(struct block_device *bdev); int set_blocksize(struct file *file, int size); int lookup_bdev(const char *pathname, dev_t *dev); diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h index ee1d0e5f9789f2bd1672721c304cd6cae56245b7..2d7d86f0290d98c1b60b0d1e52d6c0dbac0636a2 100644 --- a/include/linux/ceph/ceph_fs.h +++ b/include/linux/ceph/ceph_fs.h @@ -808,7 +808,7 @@ struct ceph_mds_caps { struct ceph_mds_cap_peer { __le64 cap_id; - __le32 seq; + __le32 issue_seq; __le32 mseq; __le32 mds; __u8 flags; @@ -822,7 +822,7 @@ struct ceph_mds_cap_release { struct ceph_mds_cap_item { __le64 ino; __le64 cap_id; - __le32 migrate_seq, seq; + __le32 migrate_seq, issue_seq; } __attribute__ ((packed)); #define CEPH_MDS_LEASE_REVOKE 1 /* mds -> client */ diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 15fb566d3f46ab021a99d56edf1693ea616ef9e6..733e7f93db66a7a29a4a8eba97e9ebf2c49da1f9 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -317,12 +317,6 @@ extern void ceph_release_page_vector(struct page **pages, int num_pages); extern void ceph_put_page_vector(struct page **pages, int num_pages, bool dirty); extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); -extern int ceph_copy_user_to_page_vector(struct page **pages, - const void __user *data, - loff_t off, size_t len); -extern void ceph_copy_to_page_vector(struct page **pages, - const void *data, - loff_t off, size_t len); extern void ceph_copy_from_page_vector(struct page **pages, void *data, loff_t off, size_t len); diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index d7941478158cdf0bf6c9bbfa1e1e149b2d24d7b8..d55b30057a4555fdae870f9ad245eba7fe93bba0 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -626,8 +626,6 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc, u32 timeout, struct page ***preply_pages, size_t *preply_len); -int ceph_osdc_watch_check(struct ceph_osd_client *osdc, - struct ceph_osd_linger_request *lreq); int ceph_osdc_list_watchers(struct ceph_osd_client *osdc, struct ceph_object_id *oid, struct ceph_object_locator *oloc, diff --git a/include/linux/ceph/pagelist.h b/include/linux/ceph/pagelist.h index 5dead8486fd8f38e9ac2c9333374b6da2b1d21f7..879bec0863aa16e884b20df21273f4efdf637a65 100644 --- a/include/linux/ceph/pagelist.h +++ b/include/linux/ceph/pagelist.h @@ -17,12 +17,6 @@ struct ceph_pagelist { refcount_t refcnt; }; -struct ceph_pagelist_cursor { - struct ceph_pagelist *pl; /* pagelist, for error checking */ - struct list_head *page_lru; /* page in list */ - size_t room; /* room remaining to reset to */ -}; - struct ceph_pagelist *ceph_pagelist_alloc(gfp_t gfp_flags); extern void ceph_pagelist_release(struct ceph_pagelist *pl); @@ -33,12 +27,6 @@ extern int ceph_pagelist_reserve(struct ceph_pagelist *pl, size_t space); extern int ceph_pagelist_free_reserve(struct ceph_pagelist *pl); -extern void ceph_pagelist_set_cursor(struct ceph_pagelist *pl, - struct ceph_pagelist_cursor *c); - -extern int ceph_pagelist_truncate(struct ceph_pagelist *pl, - struct ceph_pagelist_cursor *c); - static inline int ceph_pagelist_encode_64(struct ceph_pagelist *pl, u64 v) { __le64 ev = cpu_to_le64(v); diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h index c860c72a921d03af86d1fe995d2a778da6f817b6..3a485cc0e0fa0b6ddeafe2ed8113314fc2bd3e98 100644 --- a/include/linux/eeprom_93cx6.h +++ b/include/linux/eeprom_93cx6.h @@ -11,6 +11,8 @@ Supported chipsets: 93c46, 93c56 and 93c66. */ +#include + /* * EEPROM operation defines. */ @@ -34,6 +36,7 @@ * @register_write(struct eeprom_93cx6 *eeprom): handler to * write to the eeprom register by using all reg_* fields. * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines + * @quirks: eeprom or controller quirks * @drive_data: Set if we're driving the data line. * @reg_data_in: register field to indicate data input * @reg_data_out: register field to indicate data output @@ -50,6 +53,9 @@ struct eeprom_93cx6 { void (*register_write)(struct eeprom_93cx6 *eeprom); int width; + unsigned int quirks; +/* Some EEPROMs require an extra clock cycle before reading */ +#define PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE BIT(0) char drive_data; char reg_data_in; @@ -71,3 +77,8 @@ extern void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable); extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, u8 addr, u16 data); + +static inline bool has_quirk_extra_read_cycle(struct eeprom_93cx6 *eeprom) +{ + return eeprom->quirks & PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE; +} diff --git a/include/linux/export.h b/include/linux/export.h index 0bbd02fd351db9239cfd39709e945c649582fb52..2633df4d31e622a4be7dfa5a183db39fa09051ee 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -60,14 +60,14 @@ #endif #ifdef DEFAULT_SYMBOL_NAMESPACE -#define _EXPORT_SYMBOL(sym, license) __EXPORT_SYMBOL(sym, license, __stringify(DEFAULT_SYMBOL_NAMESPACE)) +#define _EXPORT_SYMBOL(sym, license) __EXPORT_SYMBOL(sym, license, DEFAULT_SYMBOL_NAMESPACE) #else #define _EXPORT_SYMBOL(sym, license) __EXPORT_SYMBOL(sym, license, "") #endif #define EXPORT_SYMBOL(sym) _EXPORT_SYMBOL(sym, "") #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") -#define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL(sym, "", __stringify(ns)) -#define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "GPL", __stringify(ns)) +#define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL(sym, "", ns) +#define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "GPL", ns) #endif /* _LINUX_EXPORT_H */ diff --git a/include/linux/fw_table.h b/include/linux/fw_table.h index 3ff4c277296fb6e9fbdd83923acaaa50384ddd5c..9bd605b87c4c79ff4fa315085d84d03fe1423a23 100644 --- a/include/linux/fw_table.h +++ b/include/linux/fw_table.h @@ -54,7 +54,7 @@ int cdat_table_parse(enum acpi_cdat_type type, #define EXPORT_SYMBOL_FWTBL_LIB(x) EXPORT_SYMBOL_ACPI_LIB(x) #define __init_or_fwtbl_lib __init_or_acpilib #else -#define EXPORT_SYMBOL_FWTBL_LIB(x) EXPORT_SYMBOL_NS_GPL(x, CXL) +#define EXPORT_SYMBOL_FWTBL_LIB(x) EXPORT_SYMBOL_NS_GPL(x, "CXL") #define __init_or_fwtbl_lib #endif diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h index 6730ee900ee1c9559eabe48bb278ea2ecedb1d5c..8a03d9696b1c9d2456028665ae9488f4bae7f64f 100644 --- a/include/linux/hid-sensor-ids.h +++ b/include/linux/hid-sensor-ids.h @@ -30,6 +30,8 @@ #define HID_USAGE_SENSOR_PROX 0x200011 #define HID_USAGE_SENSOR_DATA_PRESENCE 0x2004b0 #define HID_USAGE_SENSOR_HUMAN_PRESENCE 0x2004b1 +#define HID_USAGE_SENSOR_HUMAN_PROXIMITY 0x2004b2 +#define HID_USAGE_SENSOR_HUMAN_ATTENTION 0x2004bd /* Pressure (200031) */ #define HID_USAGE_SENSOR_PRESSURE 0x200031 diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index a6876ab29004892b78eb32135ec52cd0417503fe..a2e47dbcf82c8bbbc547ebc18c82e11bfe8c6236 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -78,7 +78,7 @@ struct hid_ops { const struct bus_type *bus_type; }; -extern struct hid_ops *hid_ops; +extern const struct hid_ops *hid_ops; /** * struct hid_bpf_ops - A BPF struct_ops of callbacks allowing to attach HID-BPF diff --git a/include/linux/i2c-of-prober.h b/include/linux/i2c-of-prober.h new file mode 100644 index 0000000000000000000000000000000000000000..bb6d47f50ee5977ae4f028814d660e8b55458a52 --- /dev/null +++ b/include/linux/i2c-of-prober.h @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Definitions for the Linux I2C OF component prober + * + * Copyright (C) 2024 Google LLC + */ + +#ifndef _LINUX_I2C_OF_PROBER_H +#define _LINUX_I2C_OF_PROBER_H + +#include +#include + +struct device; +struct device_node; + +/** + * struct i2c_of_probe_ops - I2C OF component prober callbacks + * + * A set of callbacks to be used by i2c_of_probe_component(). + * + * All callbacks are optional. Callbacks are called only once per run, and are + * used in the order they are defined in this structure. + * + * All callbacks that have return values shall return %0 on success, + * or a negative error number on failure. + * + * The @dev parameter passed to the callbacks is the same as @dev passed to + * i2c_of_probe_component(). It should only be used for dev_printk() calls + * and nothing else, especially not managed device resource (devres) APIs. + */ +struct i2c_of_probe_ops { + /** + * @enable: Retrieve and enable resources so that the components respond to probes. + * + * It is OK for this callback to return -EPROBE_DEFER since the intended use includes + * retrieving resources and enables them. Resources should be reverted to their initial + * state and released before returning if this fails. + */ + int (*enable)(struct device *dev, struct device_node *bus_node, void *data); + + /** + * @cleanup_early: Release exclusive resources prior to calling probe() on a + * detected component. + * + * Only called if a matching component is actually found. If none are found, + * resources that would have been released in this callback should be released in + * @free_resourcs_late instead. + */ + void (*cleanup_early)(struct device *dev, void *data); + + /** + * @cleanup: Opposite of @enable to balance refcounts and free resources after probing. + * + * Should check if resources were already freed by @cleanup_early. + */ + void (*cleanup)(struct device *dev, void *data); +}; + +/** + * struct i2c_of_probe_cfg - I2C OF component prober configuration + * @ops: Callbacks for the prober to use. + * @type: A string to match the device node name prefix to probe for. + */ +struct i2c_of_probe_cfg { + const struct i2c_of_probe_ops *ops; + const char *type; +}; + +#if IS_ENABLED(CONFIG_OF_DYNAMIC) + +int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cfg, void *ctx); + +/** + * DOC: I2C OF component prober simple helpers + * + * Components such as trackpads are commonly connected to a devices baseboard + * with a 6-pin ribbon cable. That gives at most one voltage supply and one + * GPIO (commonly a "enable" or "reset" line) besides the I2C bus, interrupt + * pin, and common ground. Touchscreens, while integrated into the display + * panel's connection, typically have the same set of connections. + * + * A simple set of helpers are provided here for use with the I2C OF component + * prober. This implementation targets such components, allowing for at most + * one regulator supply. + * + * The following helpers are provided: + * * i2c_of_probe_simple_enable() + * * i2c_of_probe_simple_cleanup_early() + * * i2c_of_probe_simple_cleanup() + */ + +/** + * struct i2c_of_probe_simple_opts - Options for simple I2C component prober callbacks + * @res_node_compatible: Compatible string of device node to retrieve resources from. + * @supply_name: Name of regulator supply. + * @gpio_name: Name of GPIO. NULL if no GPIO line is used. Empty string ("") if GPIO + * line is unnamed. + * @post_power_on_delay_ms: Delay after regulators are powered on. Passed to msleep(). + * @post_gpio_config_delay_ms: Delay after GPIO is configured. Passed to msleep(). + * @gpio_assert_to_enable: %true if GPIO should be asserted, i.e. set to logical high, + * to enable the component. + * + * This describes power sequences common for the class of components supported by the + * simple component prober: + * * @gpio_name is configured to the non-active setting according to @gpio_assert_to_enable. + * * @supply_name regulator supply is enabled. + * * Wait for @post_power_on_delay_ms to pass. + * * @gpio_name is configured to the active setting according to @gpio_assert_to_enable. + * * Wait for @post_gpio_config_delay_ms to pass. + */ +struct i2c_of_probe_simple_opts { + const char *res_node_compatible; + const char *supply_name; + const char *gpio_name; + unsigned int post_power_on_delay_ms; + unsigned int post_gpio_config_delay_ms; + bool gpio_assert_to_enable; +}; + +struct gpio_desc; +struct regulator; + +struct i2c_of_probe_simple_ctx { + /* public: provided by user before helpers are used. */ + const struct i2c_of_probe_simple_opts *opts; + /* private: internal fields for helpers. */ + struct regulator *supply; + struct gpio_desc *gpiod; +}; + +int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node, void *data); +void i2c_of_probe_simple_cleanup_early(struct device *dev, void *data); +void i2c_of_probe_simple_cleanup(struct device *dev, void *data); + +extern struct i2c_of_probe_ops i2c_of_probe_simple_ops; + +#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ + +#endif /* _LINUX_I2C_OF_PROBER_H */ diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h index 37d56914d4857f77958800968241a3cde00656af..10be00f3b1206e8a58ddf4f0267c8bcb05269f33 100644 --- a/include/linux/iio/backend.h +++ b/include/linux/iio/backend.h @@ -14,12 +14,14 @@ struct iio_dev; enum iio_backend_data_type { IIO_BACKEND_TWOS_COMPLEMENT, IIO_BACKEND_OFFSET_BINARY, + IIO_BACKEND_DATA_UNSIGNED, IIO_BACKEND_DATA_TYPE_MAX }; enum iio_backend_data_source { IIO_BACKEND_INTERNAL_CONTINUOUS_WAVE, IIO_BACKEND_EXTERNAL, + IIO_BACKEND_INTERNAL_RAMP_16BIT, IIO_BACKEND_DATA_SOURCE_MAX }; @@ -89,6 +91,11 @@ enum iio_backend_sample_trigger { * @read_raw: Read a channel attribute from a backend device * @debugfs_print_chan_status: Print channel status into a buffer. * @debugfs_reg_access: Read or write register value of backend. + * @ddr_enable: Enable interface DDR (Double Data Rate) mode. + * @ddr_disable: Disable interface DDR (Double Data Rate) mode. + * @data_stream_enable: Enable data stream. + * @data_stream_disable: Disable data stream. + * @data_transfer_addr: Set data address. **/ struct iio_backend_ops { int (*enable)(struct iio_backend *back); @@ -129,6 +136,11 @@ struct iio_backend_ops { size_t len); int (*debugfs_reg_access)(struct iio_backend *back, unsigned int reg, unsigned int writeval, unsigned int *readval); + int (*ddr_enable)(struct iio_backend *back); + int (*ddr_disable)(struct iio_backend *back); + int (*data_stream_enable)(struct iio_backend *back); + int (*data_stream_disable)(struct iio_backend *back); + int (*data_transfer_addr)(struct iio_backend *back, u32 address); }; /** @@ -164,6 +176,11 @@ int iio_backend_data_sample_trigger(struct iio_backend *back, int devm_iio_backend_request_buffer(struct device *dev, struct iio_backend *back, struct iio_dev *indio_dev); +int iio_backend_ddr_enable(struct iio_backend *back); +int iio_backend_ddr_disable(struct iio_backend *back); +int iio_backend_data_stream_enable(struct iio_backend *back); +int iio_backend_data_stream_disable(struct iio_backend *back); +int iio_backend_data_transfer_addr(struct iio_backend *back, u32 address); ssize_t iio_backend_ext_info_set(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, const char *buf, size_t len); diff --git a/include/linux/iio/driver.h b/include/linux/iio/driver.h index 7a157ed218f602885470883e3cccaaeeca73fba3..7f8b55551ed017f8e78a25a055f86bbb65aa76e1 100644 --- a/include/linux/iio/driver.h +++ b/include/linux/iio/driver.h @@ -18,7 +18,7 @@ struct iio_map; * @map: array of mappings specifying association of channel with client */ int iio_map_array_register(struct iio_dev *indio_dev, - struct iio_map *map); + const struct iio_map *map); /** * iio_map_array_unregister() - tell the core to remove consumer mappings for @@ -38,6 +38,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev); * handle de-registration of the IIO map object when the device's refcount goes to * zero. */ -int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev, struct iio_map *maps); +int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev, + const struct iio_map *maps); #endif diff --git a/include/linux/iio/events.h b/include/linux/iio/events.h index a4558c45a548834e33702927609ca9ad447c67de..72062a0c7c879aa6940da33bb0067790aa73cd86 100644 --- a/include/linux/iio/events.h +++ b/include/linux/iio/events.h @@ -10,7 +10,7 @@ #include /** - * IIO_EVENT_CODE() - create event identifier + * _IIO_EVENT_CODE() - create event identifier * @chan_type: Type of the channel. Should be one of enum iio_chan_type. * @diff: Whether the event is for an differential channel or not. * @modifier: Modifier for the channel. Should be one of enum iio_modifier. @@ -19,10 +19,13 @@ * @chan: Channel number for non-differential channels. * @chan1: First channel number for differential channels. * @chan2: Second channel number for differential channels. + * + * Drivers should use the specialized macros below instead of using this one + * directly. */ -#define IIO_EVENT_CODE(chan_type, diff, modifier, direction, \ - type, chan, chan1, chan2) \ +#define _IIO_EVENT_CODE(chan_type, diff, modifier, direction, \ + type, chan, chan1, chan2) \ (((u64)type << 56) | ((u64)diff << 55) | \ ((u64)direction << 48) | ((u64)modifier << 40) | \ ((u64)chan_type << 32) | (((u16)chan2) << 16) | ((u16)chan1) | \ @@ -30,7 +33,8 @@ /** - * IIO_MOD_EVENT_CODE() - create event identifier for modified channels + * IIO_MOD_EVENT_CODE() - create event identifier for modified (non + * differential) channels * @chan_type: Type of the channel. Should be one of enum iio_chan_type. * @number: Channel number. * @modifier: Modifier for the channel. Should be one of enum iio_modifier. @@ -40,10 +44,11 @@ #define IIO_MOD_EVENT_CODE(chan_type, number, modifier, \ type, direction) \ - IIO_EVENT_CODE(chan_type, 0, modifier, direction, type, number, 0, 0) + _IIO_EVENT_CODE(chan_type, 0, modifier, direction, type, number, 0, 0) /** - * IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified channels + * IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified (non + * differential) channels * @chan_type: Type of the channel. Should be one of enum iio_chan_type. * @number: Channel number. * @type: Type of the event. Should be one of enum iio_event_type. @@ -51,6 +56,18 @@ */ #define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction) \ - IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0) + _IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0) + +/** + * IIO_DIFF_EVENT_CODE() - create event identifier for differential channels + * @chan_type: Type of the channel. Should be one of enum iio_chan_type. + * @chan1: First channel number for differential channels. + * @chan2: Second channel number for differential channels. + * @type: Type of the event. Should be one of enum iio_event_type. + * @direction: Direction of the event. One of enum iio_event_direction. + */ + +#define IIO_DIFF_EVENT_CODE(chan_type, chan1, chan2, type, direction) \ + _IIO_EVENT_CODE(chan_type, 1, 0, direction, type, 0, chan1, chan2) #endif diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 5aec3945555bf4bc720244585229bccc2681dd5e..a89e7e43e4418484f1da5665b386d3d359d661a1 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -70,7 +70,7 @@ struct iio_dev_opaque { #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_dentry; - unsigned cached_reg_addr; + unsigned int cached_reg_addr; char read_buf[20]; unsigned int read_buf_len; #endif diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 18779b631e9071801958fc9d50b941b548fab940..ae65890d456772f11eee76bd1a2cafbc5f16b7ec 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -282,11 +282,11 @@ struct iio_chan_spec { const struct iio_chan_spec_ext_info *ext_info; const char *extend_name; const char *datasheet_name; - unsigned modified:1; - unsigned indexed:1; - unsigned output:1; - unsigned differential:1; - unsigned has_ext_scan_type:1; + unsigned int modified:1; + unsigned int indexed:1; + unsigned int output:1; + unsigned int differential:1; + unsigned int has_ext_scan_type:1; }; @@ -514,7 +514,7 @@ struct iio_info { const struct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, - int state); + bool state); int (*read_event_value)(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, @@ -541,13 +541,13 @@ struct iio_info { int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask); int (*debugfs_reg_access)(struct iio_dev *indio_dev, - unsigned reg, unsigned writeval, - unsigned *readval); + unsigned int reg, unsigned int writeval, + unsigned int *readval); int (*fwnode_xlate)(struct iio_dev *indio_dev, const struct fwnode_reference_args *iiospec); - int (*hwfifo_set_watermark)(struct iio_dev *indio_dev, unsigned val); + int (*hwfifo_set_watermark)(struct iio_dev *indio_dev, unsigned int val); int (*hwfifo_flush_to_buffer)(struct iio_dev *indio_dev, - unsigned count); + unsigned int count); }; /** @@ -609,7 +609,7 @@ struct iio_dev { int scan_bytes; const unsigned long *available_scan_masks; - unsigned __private masklength; + unsigned int __private masklength; const unsigned long *active_scan_mask; bool scan_timestamp; struct iio_trigger *trig; @@ -624,7 +624,7 @@ struct iio_dev { const struct iio_info *info; const struct iio_buffer_setup_ops *setup_ops; - void *priv; + void *__private priv; }; int iio_device_id(struct iio_dev *indio_dev); @@ -785,7 +785,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv); /* The information at the returned address is guaranteed to be cacheline aligned */ static inline void *iio_priv(const struct iio_dev *indio_dev) { - return indio_dev->priv; + return ACCESS_PRIVATE(indio_dev, priv); } void iio_device_free(struct iio_dev *indio_dev); @@ -831,6 +831,7 @@ int iio_device_resume_triggering(struct iio_dev *indio_dev); bool iio_read_acpi_mount_matrix(struct device *dev, struct iio_mount_matrix *orientation, char *acpi_method); +const char *iio_get_acpi_device_name_and_data(struct device *dev, const void **data); #else static inline bool iio_read_acpi_mount_matrix(struct device *dev, struct iio_mount_matrix *orientation, @@ -838,7 +839,16 @@ static inline bool iio_read_acpi_mount_matrix(struct device *dev, { return false; } +static inline const char * +iio_get_acpi_device_name_and_data(struct device *dev, const void **data) +{ + return NULL; +} #endif +static inline const char *iio_get_acpi_device_name(struct device *dev) +{ + return iio_get_acpi_device_name_and_data(dev, NULL); +} /** * iio_get_current_scan_type - Get the current scan type for a channel diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 593c10a02144e6e695f6538a4dc945ff7548a451..011860ade268e75af64c7c85e713014b16251fc8 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -336,6 +336,7 @@ struct io_ring_ctx { */ struct { struct llist_head work_llist; + struct llist_head retry_llist; unsigned long check_cq; atomic_t cq_wait_nr; atomic_t cq_timeouts; diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 564868bdce898b92da33b6b7b8e07128ccb0f972..fd743d4c4b4bdc50f40ff34275bc39ea49244f3b 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -37,7 +37,6 @@ */ #include -#include #include #include #include diff --git a/include/linux/list.h b/include/linux/list.h index 5f4b0a39cf46a3784a22e0319aa213551d7f4b2c..29a375889fb8fad3d999706f2f3a2ef51af2e6ab 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -686,14 +686,6 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_for_each(pos, head) \ for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) -/** - * list_for_each_reverse - iterate backwards over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each_reverse(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) - /** * list_for_each_rcu - Iterate over a list in an RCU-safe fashion * @pos: the &struct list_head to use as a loop cursor. diff --git a/include/linux/mfd/88pm886.h b/include/linux/mfd/88pm886.h index 133aa302e49297fd923d0eb41146da69f5f2c5eb..85eca44f39ab58ba4cb9ec4216118ee9604d021f 100644 --- a/include/linux/mfd/88pm886.h +++ b/include/linux/mfd/88pm886.h @@ -31,6 +31,15 @@ #define PM886_INT_WC BIT(1) #define PM886_INT_MASK_MODE BIT(2) +#define PM886_REG_RTC_CNT1 0xd1 +#define PM886_REG_RTC_CNT2 0xd2 +#define PM886_REG_RTC_CNT3 0xd3 +#define PM886_REG_RTC_CNT4 0xd4 +#define PM886_REG_RTC_SPARE1 0xea +#define PM886_REG_RTC_SPARE2 0xeb +#define PM886_REG_RTC_SPARE3 0xec +#define PM886_REG_RTC_SPARE4 0xed +#define PM886_REG_RTC_SPARE5 0xee #define PM886_REG_RTC_SPARE6 0xef #define PM886_REG_BUCK_EN 0x08 diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h index 8db52324f416957804fbc22af4c61ca8a8889dba..eae82f421414ec63da5c1a9cf5a04a0f496f48fd 100644 --- a/include/linux/mfd/da9063/core.h +++ b/include/linux/mfd/da9063/core.h @@ -78,6 +78,7 @@ struct da9063 { enum da9063_type type; unsigned char variant_code; unsigned int flags; + bool use_sw_pm; /* Control interface */ struct regmap *regmap; diff --git a/include/linux/misc/keba.h b/include/linux/misc/keba.h index 323b31a847c5b307830d34aa5fd9414e33d30dc9..a81d6fa7085189478800dea0c87bb27a8f22d84e 100644 --- a/include/linux/misc/keba.h +++ b/include/linux/misc/keba.h @@ -7,6 +7,7 @@ #include struct i2c_board_info; +struct spi_board_info; /** * struct keba_i2c_auxdev - KEBA I2C auxiliary device @@ -22,4 +23,50 @@ struct keba_i2c_auxdev { struct i2c_board_info *info; }; +/** + * struct keba_spi_auxdev - KEBA SPI auxiliary device + * @auxdev: auxiliary device object + * @io: address range of SPI controller IO memory + * @info_size: number of SPI devices to be probed + * @info: SPI devices to be probed + */ +struct keba_spi_auxdev { + struct auxiliary_device auxdev; + struct resource io; + int info_size; + struct spi_board_info *info; +}; + +/** + * struct keba_fan_auxdev - KEBA fan auxiliary device + * @auxdev: auxiliary device object + * @io: address range of fan controller IO memory + */ +struct keba_fan_auxdev { + struct auxiliary_device auxdev; + struct resource io; +}; + +/** + * struct keba_batt_auxdev - KEBA battery auxiliary device + * @auxdev: auxiliary device object + * @io: address range of battery controller IO memory + */ +struct keba_batt_auxdev { + struct auxiliary_device auxdev; + struct resource io; +}; + +/** + * struct keba_uart_auxdev - KEBA UART auxiliary device + * @auxdev: auxiliary device object + * @io: address range of UART controller IO memory + * @irq: number of UART controller interrupt + */ +struct keba_uart_auxdev { + struct auxiliary_device auxdev; + struct resource io; + unsigned int irq; +}; + #endif /* _LINUX_MISC_KEBA_H */ diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 39a7714605a7965d1792f557e3ee40a6cf73c4e2..d7cb1e5ecbda9d6881566e3d0841b9973ffac560 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -46,7 +46,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); } \ } while (0) #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \ @@ -66,7 +66,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); unlikely(__ret_warn); \ }) #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \ @@ -77,7 +77,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi); unlikely(__ret_warn_once); \ }) #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(__ret_warn_once && !__warned)) { \ diff --git a/include/linux/module.h b/include/linux/module.h index 2a9386cbdf8502d9eb05bcc6cc981d577cc107ed..94acbacdcdf189e27013088de2202bccac9717e0 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -247,7 +247,7 @@ extern void cleanup_module(void); #ifdef MODULE /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ -extern typeof(name) __mod_##type##__##name##_device_table \ +extern typeof(name) __mod_device_table__##type##__##name \ __attribute__ ((unused, alias(__stringify(name)))) #else /* !MODULE */ #define MODULE_DEVICE_TABLE(type, name) @@ -296,7 +296,7 @@ extern typeof(name) __mod_##type##__##name##_device_table \ * files require multiple MODULE_FIRMWARE() specifiers */ #define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) -#define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, __stringify(ns)) +#define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns) struct notifier_block; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 12d8e47bc5a38863b2831fb16056f742fa81612e..559273a0f16d81ef93b66c088cc0c5f86ab3109c 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1336,7 +1336,7 @@ struct pnfs_commit_array { struct rcu_head rcu; refcount_t refcount; unsigned int nbuckets; - struct pnfs_commit_bucket buckets[]; + struct pnfs_commit_bucket buckets[] __counted_by(nbuckets); }; struct pnfs_ds_commit_info { diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 0a6e22038ce361e678326d16677045c2b9b6fcc5..13377dde4527b296dae0e00d3ea61f2be97bd5cb 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -389,6 +389,11 @@ enum { NVME_CTRL_CTRATT_PREDICTABLE_LAT = 1 << 5, NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY = 1 << 7, NVME_CTRL_CTRATT_UUID_LIST = 1 << 9, + NVME_CTRL_SGLS_BYTE_ALIGNED = 1, + NVME_CTRL_SGLS_DWORD_ALIGNED = 2, + NVME_CTRL_SGLS_KSDBDS = 1 << 2, + NVME_CTRL_SGLS_MSDS = 1 << 19, + NVME_CTRL_SGLS_SAOS = 1 << 20, }; struct nvme_lbaf { @@ -2166,4 +2171,13 @@ enum nvme_pr_release_action { NVME_PR_RELEASE_ACT_CLEAR = 1, }; +enum nvme_pr_change_ptpl { + NVME_PR_CPTPL_NO_CHANGE = 0, + NVME_PR_CPTPL_RESV = 1 << 30, + NVME_PR_CPTPL_CLEARED = 2 << 30, + NVME_PR_CPTPL_PERSIST = 3 << 30, +}; + +#define NVME_PR_IGNORE_KEY (1 << 3) + #endif /* _LINUX_NVME_H */ diff --git a/include/linux/of.h b/include/linux/of.h index 086a60f3b8a6da1452f27757361af91d6c5c8bbd..f921786cb8ac782286ed5ff4425a35668204d050 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -289,6 +289,9 @@ extern struct device_node *of_get_parent(const struct device_node *node); extern struct device_node *of_get_next_parent(struct device_node *node); extern struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev); +extern struct device_node *of_get_next_child_with_prefix(const struct device_node *node, + struct device_node *prev, + const char *prefix); extern struct device_node *of_get_next_available_child( const struct device_node *node, struct device_node *prev); extern struct device_node *of_get_next_reserved_child( @@ -1468,6 +1471,12 @@ static inline int of_property_read_s32(const struct device_node *np, child != NULL; \ child = of_get_next_child(parent, child)) +#define for_each_child_of_node_with_prefix(parent, child, prefix) \ + for (struct device_node *child __free(device_node) = \ + of_get_next_child_with_prefix(parent, NULL, prefix); \ + child != NULL; \ + child = of_get_next_child_with_prefix(parent, child, prefix)) + #define for_each_available_child_of_node(parent, child) \ for (child = of_get_next_available_child(parent, NULL); child != NULL; \ child = of_get_next_available_child(parent, child)) @@ -1651,6 +1660,10 @@ static inline int of_changeset_add_prop_u32(struct of_changeset *ocs, return of_changeset_add_prop_u32_array(ocs, np, prop_name, &val, 1); } +int of_changeset_update_prop_string(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, const char *str); + int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np, const char *prop_name); diff --git a/include/linux/once.h b/include/linux/once.h index bc714d414448a7ab982f14d4ab76512170a4689f..30346fcdc7995d465e34162845718387a9258fd4 100644 --- a/include/linux/once.h +++ b/include/linux/once.h @@ -46,7 +46,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, #define DO_ONCE(func, ...) \ ({ \ bool ___ret = false; \ - static bool __section(".data.once") ___done = false; \ + static bool __section(".data..once") ___done = false; \ static DEFINE_STATIC_KEY_TRUE(___once_key); \ if (static_branch_unlikely(&___once_key)) { \ unsigned long ___flags; \ @@ -64,7 +64,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, #define DO_ONCE_SLEEPABLE(func, ...) \ ({ \ bool ___ret = false; \ - static bool __section(".data.once") ___done = false; \ + static bool __section(".data..once") ___done = false; \ static DEFINE_STATIC_KEY_TRUE(___once_key); \ if (static_branch_unlikely(&___once_key)) { \ ___ret = __do_once_sleepable_start(&___done); \ diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h index b7bce4983638f8c7d14388142e048f4ddde8b187..27de7bc32a0610afe39ad2d920d1adc141370f51 100644 --- a/include/linux/once_lite.h +++ b/include/linux/once_lite.h @@ -12,7 +12,7 @@ #define __ONCE_LITE_IF(condition) \ ({ \ - static bool __section(".data.once") __already_done; \ + static bool __section(".data..once") __already_done; \ bool __ret_cond = !!(condition); \ bool __ret_once = false; \ \ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e4bddb92779564ec268059c4d91465383974807f..d2402bf4aea2d10ec6a8db33d2ec86912cc560b4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -121,6 +121,7 @@ #define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 #define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 #define PCI_CLASS_SERIAL_USB_XHCI 0x0c0330 +#define PCI_CLASS_SERIAL_USB_CDNS 0x0c0380 #define PCI_CLASS_SERIAL_USB_DEVICE 0x0c03fe #define PCI_CLASS_SERIAL_FIBER 0x0c04 #define PCI_CLASS_SERIAL_SMBUS 0x0c05 @@ -2421,6 +2422,9 @@ #define PCI_VENDOR_ID_QCOM 0x17cb #define PCI_VENDOR_ID_CDNS 0x17cd +#define PCI_DEVICE_ID_CDNS_USBSS 0x0100 +#define PCI_DEVICE_ID_CDNS_USB 0x0120 +#define PCI_DEVICE_ID_CDNS_USBSSP 0x0200 #define PCI_VENDOR_ID_ARECA 0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 diff --git a/include/linux/platform_data/sa11x0-serial.h b/include/linux/platform_data/sa11x0-serial.h index 8b79ab08af45e95c43e42d7c84dab2805dad5a62..a88096bc74e423673d833f43c323f692f9055607 100644 --- a/include/linux/platform_data/sa11x0-serial.h +++ b/include/linux/platform_data/sa11x0-serial.h @@ -10,7 +10,6 @@ #define SA11X0_SERIAL_H struct uart_port; -struct uart_info; /* * This is a temporary structure for registering these diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 7132623e4658576f0be2a80b493e445e0c9d4de6..074754c23d330c9a099e20eecfeb6cbd5025e04f 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -235,17 +235,7 @@ extern void platform_device_put(struct platform_device *pdev); struct platform_driver { int (*probe)(struct platform_device *); - - /* - * .remove_new() is a relic from a prototype conversion of .remove(). - * New drivers are supposed to implement .remove(). Once all drivers are - * converted to not use .remove_new any more, it will be dropped. - */ - union { - void (*remove)(struct platform_device *); - void (*remove_new)(struct platform_device *); - }; - + void (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*resume)(struct platform_device *); diff --git a/include/linux/pm.h b/include/linux/pm.h index 97b0e23363c8283f53c361d8129ef90d7a2b9350..e7f0260f15ad5f76dd6b5aeeb152ede4c0812bac 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -385,7 +385,7 @@ const struct dev_pm_ops name = { \ #ifdef CONFIG_PM #define _EXPORT_DEV_PM_OPS(name, license, ns) _EXPORT_PM_OPS(name, license, ns) #define EXPORT_PM_FN_GPL(name) EXPORT_SYMBOL_GPL(name) -#define EXPORT_PM_FN_NS_GPL(name, ns) EXPORT_SYMBOL_NS_GPL(name, ns) +#define EXPORT_PM_FN_NS_GPL(name, ns) EXPORT_SYMBOL_NS_GPL(name, "ns") #else #define _EXPORT_DEV_PM_OPS(name, license, ns) _DISCARD_PM_OPS(name, license, ns) #define EXPORT_PM_FN_GPL(name) diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 78827f31240745a31338f1e1deae2b2d5e002d38..6853e29d9674134a6fc9a7e0a2b64c1c31b5cc1e 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -8,7 +8,7 @@ #include #include -MODULE_IMPORT_NS(PWM); +MODULE_IMPORT_NS("PWM"); struct pwm_chip; diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 58d84c59f3ddae9bc242c16aa7e8ee6678d56ecd..48e5c03df1dd83c246a61d0fcc8aa638adcd7654 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -401,7 +401,7 @@ static inline int debug_lockdep_rcu_enabled(void) */ #define RCU_LOCKDEP_WARN(c, s) \ do { \ - static bool __section(".data.unlikely") __warned; \ + static bool __section(".data..unlikely") __warned; \ if (debug_lockdep_rcu_enabled() && (c) && \ debug_lockdep_rcu_enabled() && !__warned) { \ __warned = true; \ diff --git a/include/linux/rcupdate_trace.h b/include/linux/rcupdate_trace.h index eda493200663faf15780bff26c9ddc797afe9434..e6c44eb428ab63c2523fb12e97446b89ddffb480 100644 --- a/include/linux/rcupdate_trace.h +++ b/include/linux/rcupdate_trace.h @@ -10,6 +10,7 @@ #include #include +#include extern struct lockdep_map rcu_trace_lock_map; @@ -98,4 +99,8 @@ static inline void rcu_read_lock_trace(void) { BUG(); } static inline void rcu_read_unlock_trace(void) { BUG(); } #endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ +DEFINE_LOCK_GUARD_0(rcu_tasks_trace, + rcu_read_lock_trace(), + rcu_read_unlock_trace()) + #endif /* __LINUX_RCUPDATE_TRACE_H */ diff --git a/include/linux/rtc/m48t59.h b/include/linux/rtc/m48t59.h index 9465d5405fe28be2b9f82747c792dd16e3bc57fc..373ba77071c6b27a80ac0ec7d434bb2866e5263c 100644 --- a/include/linux/rtc/m48t59.h +++ b/include/linux/rtc/m48t59.h @@ -56,6 +56,9 @@ struct m48t59_plat_data { void __iomem *ioaddr; /* offset to RTC registers, automatically set according to the type */ unsigned int offset; + + /* YY digits (in RTC) are offset, i.e. year is 1900 + yy_offset + YY */ + int yy_offset; }; #endif /* _LINUX_RTC_M48T59_H_ */ diff --git a/include/linux/rtsx_common.h b/include/linux/rtsx_common.h index bf290ad14c57f038df6dac520191359547c0603c..da9c8c6b5d50f04bc08f7af7c48e90e15e96d0b4 100644 --- a/include/linux/rtsx_common.h +++ b/include/linux/rtsx_common.h @@ -12,7 +12,6 @@ #define DRV_NAME_RTSX_PCI "rtsx_pci" #define DRV_NAME_RTSX_PCI_SDMMC "rtsx_pci_sdmmc" -#define DRV_NAME_RTSX_PCI_MS "rtsx_pci_ms" #define RTSX_REG_PAIR(addr, val) (((u32)(addr) << 16) | (u8)(val)) diff --git a/include/linux/rtsx_usb.h b/include/linux/rtsx_usb.h index 3247ed8e9ff0fb2c5571d6dd55e1845b3125fc0c..f267a06c6b1e7ef3c5b87684fe32182fd28caa80 100644 --- a/include/linux/rtsx_usb.h +++ b/include/linux/rtsx_usb.h @@ -12,6 +12,10 @@ #include +#define DRV_NAME_RTSX_USB "rtsx_usb" +#define DRV_NAME_RTSX_USB_SDMMC "rtsx_usb_sdmmc" +#define DRV_NAME_RTSX_USB_MS "rtsx_usb_ms" + /* related module names */ #define RTSX_USB_SD_CARD 0 #define RTSX_USB_MS_CARD 1 diff --git a/include/linux/string.h b/include/linux/string.h index 0dd27afcfaf76b507ccb72ee8508534ae2fb903f..493ac4862c77771ada8f12737277204e475eecc3 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -335,7 +335,6 @@ int __sysfs_match_string(const char * const *array, size_t n, const char *s); #ifdef CONFIG_BINARY_PRINTF int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args); int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf); -int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4); #endif extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index c4e64dc112063f7cb89bf66059d0338716089e87..0f2fcd244523f050c5286f19d4fe1846506f9214 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -87,6 +87,11 @@ do { \ * SYSFS_GROUP_VISIBLE() when assigning this callback to * specify separate _group_visible() and _attr_visible() * handlers. + * @bin_size: + * Optional: Function to return the size of a binary attribute + * of the group. Will be called repeatedly for each binary + * attribute in the group. Overwrites the size field embedded + * inside the attribute itself. * @attrs: Pointer to NULL terminated list of attributes. * @bin_attrs: Pointer to NULL terminated list of binary attributes. * Either attrs or bin_attrs or both must be provided. @@ -96,9 +101,15 @@ struct attribute_group { umode_t (*is_visible)(struct kobject *, struct attribute *, int); umode_t (*is_bin_visible)(struct kobject *, - struct bin_attribute *, int); + const struct bin_attribute *, int); + size_t (*bin_size)(struct kobject *, + const struct bin_attribute *, + int); struct attribute **attrs; - struct bin_attribute **bin_attrs; + union { + struct bin_attribute **bin_attrs; + const struct bin_attribute *const *bin_attrs_new; + }; }; #define SYSFS_PREALLOC 010000 @@ -191,22 +202,22 @@ struct attribute_group { * attributes, the group visibility is determined by the function * specified to is_visible() not is_bin_visible() */ -#define DEFINE_SYSFS_BIN_GROUP_VISIBLE(name) \ - static inline umode_t sysfs_group_visible_##name( \ - struct kobject *kobj, struct bin_attribute *attr, int n) \ - { \ - if (n == 0 && !name##_group_visible(kobj)) \ - return SYSFS_GROUP_INVISIBLE; \ - return name##_attr_visible(kobj, attr, n); \ +#define DEFINE_SYSFS_BIN_GROUP_VISIBLE(name) \ + static inline umode_t sysfs_group_visible_##name( \ + struct kobject *kobj, const struct bin_attribute *attr, int n) \ + { \ + if (n == 0 && !name##_group_visible(kobj)) \ + return SYSFS_GROUP_INVISIBLE; \ + return name##_attr_visible(kobj, attr, n); \ } -#define DEFINE_SIMPLE_SYSFS_BIN_GROUP_VISIBLE(name) \ - static inline umode_t sysfs_group_visible_##name( \ - struct kobject *kobj, struct bin_attribute *a, int n) \ - { \ - if (n == 0 && !name##_group_visible(kobj)) \ - return SYSFS_GROUP_INVISIBLE; \ - return a->mode; \ +#define DEFINE_SIMPLE_SYSFS_BIN_GROUP_VISIBLE(name) \ + static inline umode_t sysfs_group_visible_##name( \ + struct kobject *kobj, const struct bin_attribute *a, int n) \ + { \ + if (n == 0 && !name##_group_visible(kobj)) \ + return SYSFS_GROUP_INVISIBLE; \ + return a->mode; \ } #define SYSFS_GROUP_VISIBLE(fn) sysfs_group_visible_##fn @@ -297,11 +308,15 @@ struct bin_attribute { struct address_space *(*f_mapping)(void); ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); + ssize_t (*read_new)(struct file *, struct kobject *, const struct bin_attribute *, + char *, loff_t, size_t); ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); - loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *, + ssize_t (*write_new)(struct file *, struct kobject *, + const struct bin_attribute *, char *, loff_t, size_t); + loff_t (*llseek)(struct file *, struct kobject *, const struct bin_attribute *, loff_t, int); - int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, + int (*mmap)(struct file *, struct kobject *, const struct bin_attribute *attr, struct vm_area_struct *vma); }; @@ -317,25 +332,36 @@ struct bin_attribute { */ #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr) +typedef ssize_t __sysfs_bin_rw_handler_new(struct file *, struct kobject *, + const struct bin_attribute *, char *, loff_t, size_t); + /* macros to create static binary attributes easier */ #define __BIN_ATTR(_name, _mode, _read, _write, _size) { \ .attr = { .name = __stringify(_name), .mode = _mode }, \ - .read = _read, \ - .write = _write, \ + .read = _Generic(_read, \ + __sysfs_bin_rw_handler_new * : NULL, \ + default : _read \ + ), \ + .read_new = _Generic(_read, \ + __sysfs_bin_rw_handler_new * : _read, \ + default : NULL \ + ), \ + .write = _Generic(_write, \ + __sysfs_bin_rw_handler_new * : NULL, \ + default : _write \ + ), \ + .write_new = _Generic(_write, \ + __sysfs_bin_rw_handler_new * : _write, \ + default : NULL \ + ), \ .size = _size, \ } -#define __BIN_ATTR_RO(_name, _size) { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .read = _name##_read, \ - .size = _size, \ -} +#define __BIN_ATTR_RO(_name, _size) \ + __BIN_ATTR(_name, 0444, _name##_read, NULL, _size) -#define __BIN_ATTR_WO(_name, _size) { \ - .attr = { .name = __stringify(_name), .mode = 0200 }, \ - .write = _name##_write, \ - .size = _size, \ -} +#define __BIN_ATTR_WO(_name, _size) \ + __BIN_ATTR(_name, 0200, NULL, _name##_write, _size) #define __BIN_ATTR_RW(_name, _size) \ __BIN_ATTR(_name, 0644, _name##_read, _name##_write, _size) @@ -356,11 +382,8 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_WO(_name, _size) struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size) -#define __BIN_ATTR_ADMIN_RO(_name, _size) { \ - .attr = { .name = __stringify(_name), .mode = 0400 }, \ - .read = _name##_read, \ - .size = _size, \ -} +#define __BIN_ATTR_ADMIN_RO(_name, _size) \ + __BIN_ATTR(_name, 0400, _name##_read, NULL, _size) #define __BIN_ATTR_ADMIN_RW(_name, _size) \ __BIN_ATTR(_name, 0600, _name##_read, _name##_write, _size) @@ -371,10 +394,8 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RO(_name, _size) #define BIN_ATTR_ADMIN_RW(_name, _size) \ struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RW(_name, _size) -#define __BIN_ATTR_SIMPLE_RO(_name, _mode) { \ - .attr = { .name = __stringify(_name), .mode = _mode }, \ - .read = sysfs_bin_attr_simple_read, \ -} +#define __BIN_ATTR_SIMPLE_RO(_name, _mode) \ + __BIN_ATTR(_name, _mode, sysfs_bin_attr_simple_read, NULL, 0) #define BIN_ATTR_SIMPLE_RO(_name) \ struct bin_attribute bin_attr_##_name = __BIN_ATTR_SIMPLE_RO(_name, 0444) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 016b29a56c875f9e97bea918b0f229d95891a77d..2a5df5b62cfc709a3502ad254328b20a227f86bf 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -184,6 +184,7 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status); enum trace_flag_type { TRACE_FLAG_IRQS_OFF = 0x01, + TRACE_FLAG_NEED_RESCHED_LAZY = 0x02, TRACE_FLAG_NEED_RESCHED = 0x04, TRACE_FLAG_HARDIRQ = 0x08, TRACE_FLAG_SOFTIRQ = 0x10, diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 6073a8c7e38ce2ad9400365c9a1155dd25d388f8..76d9055b2cff1cadaf402895524b8adeca090a15 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -209,36 +209,6 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) #define __DO_TRACE_CALL(name, args) __traceiter_##name(NULL, args) #endif /* CONFIG_HAVE_STATIC_CALL */ -/* - * it_func[0] is never NULL because there is at least one element in the array - * when the array itself is non NULL. - * - * With @syscall=0, the tracepoint callback array dereference is - * protected by disabling preemption. - * With @syscall=1, the tracepoint callback array dereference is - * protected by Tasks Trace RCU, which allows probes to handle page - * faults. - */ -#define __DO_TRACE(name, args, cond, syscall) \ - do { \ - int __maybe_unused __idx = 0; \ - \ - if (!(cond)) \ - return; \ - \ - if (syscall) \ - rcu_read_lock_trace(); \ - else \ - preempt_disable_notrace(); \ - \ - __DO_TRACE_CALL(name, TP_ARGS(args)); \ - \ - if (syscall) \ - rcu_read_unlock_trace(); \ - else \ - preempt_enable_notrace(); \ - } while (0) - /* * Declare an exported function that Rust code can call to trigger this * tracepoint. This function does not include the static branch; that is done @@ -262,7 +232,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) * site if it is not watching, as it will need to be active when the * tracepoint is enabled. */ -#define __DECLARE_TRACE_COMMON(name, proto, args, cond, data_proto) \ +#define __DECLARE_TRACE_COMMON(name, proto, args, data_proto) \ extern int __traceiter_##name(data_proto); \ DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \ extern struct tracepoint __tracepoint_##name; \ @@ -297,41 +267,43 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) } #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ - __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \ + __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \ static inline void __rust_do_trace_##name(proto) \ { \ - __DO_TRACE(name, \ - TP_ARGS(args), \ - TP_CONDITION(cond), 0); \ + if (cond) { \ + guard(preempt_notrace)(); \ + __DO_TRACE_CALL(name, TP_ARGS(args)); \ + } \ } \ static inline void trace_##name(proto) \ { \ - if (static_branch_unlikely(&__tracepoint_##name.key)) \ - __DO_TRACE(name, \ - TP_ARGS(args), \ - TP_CONDITION(cond), 0); \ + if (static_branch_unlikely(&__tracepoint_##name.key)) { \ + if (cond) { \ + guard(preempt_notrace)(); \ + __DO_TRACE_CALL(name, TP_ARGS(args)); \ + } \ + } \ if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ WARN_ONCE(!rcu_is_watching(), \ "RCU not watching for tracepoint"); \ } \ } -#define __DECLARE_TRACE_SYSCALL(name, proto, args, cond, data_proto) \ - __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \ +#define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \ + __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \ static inline void __rust_do_trace_##name(proto) \ { \ - __DO_TRACE(name, \ - TP_ARGS(args), \ - TP_CONDITION(cond), 1); \ + guard(rcu_tasks_trace)(); \ + __DO_TRACE_CALL(name, TP_ARGS(args)); \ } \ static inline void trace_##name(proto) \ { \ might_fault(); \ - if (static_branch_unlikely(&__tracepoint_##name.key)) \ - __DO_TRACE(name, \ - TP_ARGS(args), \ - TP_CONDITION(cond), 1); \ - if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ + if (static_branch_unlikely(&__tracepoint_##name.key)) { \ + guard(rcu_tasks_trace)(); \ + __DO_TRACE_CALL(name, TP_ARGS(args)); \ + } \ + if (IS_ENABLED(CONFIG_LOCKDEP)) { \ WARN_ONCE(!rcu_is_watching(), \ "RCU not watching for tracepoint"); \ } \ @@ -341,6 +313,9 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) * We have no guarantee that gcc and the linker won't up-align the tracepoint * structures, so we create an array of pointers that will be used for iteration * on the tracepoints. + * + * it_func[0] is never NULL because there is at least one element in the array + * when the array itself is non NULL. */ #define __DEFINE_TRACE_EXT(_name, _ext, proto, args) \ static const char __tpstrtab_##_name[] \ @@ -412,7 +387,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) #else /* !TRACEPOINTS_ENABLED */ -#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ +#define __DECLARE_TRACE_COMMON(name, proto, args, data_proto) \ static inline void trace_##name(proto) \ { } \ static inline int \ @@ -436,7 +411,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) return false; \ } -#define __DECLARE_TRACE_SYSCALL __DECLARE_TRACE +#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ + __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) + +#define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \ + __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) #define DEFINE_TRACE_FN(name, reg, unreg, proto, args) #define DEFINE_TRACE_SYSCALL(name, reg, unreg, proto, args) @@ -502,7 +481,6 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) #define DECLARE_TRACE_SYSCALL(name, proto, args) \ __DECLARE_TRACE_SYSCALL(name, PARAMS(proto), PARAMS(args), \ - cpu_online(raw_smp_processor_id()), \ PARAMS(void *__data, proto)) #define TRACE_EVENT_FLAGS(event, flag) diff --git a/include/linux/types.h b/include/linux/types.h index 2bc8766ba20cab014a380f02e5644bd0d772ec67..2d7b9ae8714ce5224d7c669226d7fe021c98076b 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -115,8 +115,9 @@ typedef u64 u_int64_t; typedef s64 int64_t; #endif -/* this is a special 64bit data type that is 8-byte aligned */ +/* These are the special 64-bit data types that are 8-byte aligned */ #define aligned_u64 __aligned_u64 +#define aligned_s64 __aligned_s64 #define aligned_be64 __aligned_be64 #define aligned_le64 __aligned_le64 diff --git a/include/linux/usb.h b/include/linux/usb.h index 672d8fc2abdb02149c6a2bcbf4eb090075cf839f..cfa8005e24f9fe7bc823e37250e1743969778731 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1129,8 +1129,8 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size) /* ----------------------------------------------------------------------- */ /* Stuff for dynamic usb ids */ +extern struct mutex usb_dynids_lock; struct usb_dynids { - spinlock_t lock; struct list_head list; }; @@ -1243,7 +1243,7 @@ struct usb_driver { unsigned int disable_hub_initiated_lpm:1; unsigned int soft_unbind:1; }; -#define to_usb_driver(d) container_of(d, struct usb_driver, driver) +#define to_usb_driver(d) container_of_const(d, struct usb_driver, driver) /** * struct usb_device_driver - identifies USB device driver to usbcore @@ -1294,8 +1294,7 @@ struct usb_device_driver { unsigned int supports_autosuspend:1; unsigned int generic_subclass:1; }; -#define to_usb_device_driver(d) container_of(d, struct usb_device_driver, \ - driver) +#define to_usb_device_driver(d) container_of_const(d, struct usb_device_driver, driver) /** * struct usb_class_driver - identifies a USB driver that wants to use the USB major number diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 5a7f96684ea226e2de0512e7f3246f1712dc6cd7..ebdfef124b2bc02433b45c27d032f56eba704263 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -65,6 +65,7 @@ struct ci_hdrc_platform_data { #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) #define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) #define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS BIT(18) +#define CI_HDRC_HAS_SHORT_PKT_LIMIT BIT(19) enum usb_dr_mode dr_mode; #define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 diff --git a/include/linux/usb/storage.h b/include/linux/usb/storage.h index 2827ce72e5025ca25c419d5ecf0507dcb6b1729b..8539956bc2be1c81ffa0b5919017b1d1521a5e56 100644 --- a/include/linux/usb/storage.h +++ b/include/linux/usb/storage.h @@ -53,7 +53,7 @@ struct bulk_cb_wrap { __le32 Signature; /* contains 'USBC' */ __u32 Tag; /* unique per command id */ __le32 DataTransferLength; /* size of data */ - __u8 Flags; /* direction in bit 0 */ + __u8 Flags; /* direction in bit 7 */ __u8 Lun; /* LUN normally 0 */ __u8 Length; /* length of the CDB */ __u8 CDB[16]; /* max command */ diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 549275f8ac1b385cf6ead37a06566cd2e6a4ba44..d616b8807000612232019214cfd655e12c0cf5f2 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -87,6 +87,17 @@ enum typec_orientation { TYPEC_ORIENTATION_REVERSE, }; +enum usb_mode { + USB_MODE_NONE, + USB_MODE_USB2, + USB_MODE_USB3, + USB_MODE_USB4 +}; + +#define USB_CAPABILITY_USB2 BIT(0) +#define USB_CAPABILITY_USB3 BIT(1) +#define USB_CAPABILITY_USB4 BIT(2) + /* * struct enter_usb_data - Enter_USB Message details * @eudo: Enter_USB Data Object @@ -209,6 +220,7 @@ struct typec_cable_desc { * @accessory: Audio, Debug or none. * @identity: Discover Identity command data * @pd_revision: USB Power Delivery Specification Revision if supported + * @usb_capability: Supported USB Modes * @attach: Notification about attached USB device * @deattach: Notification about removed USB device * @@ -226,6 +238,7 @@ struct typec_partner_desc { enum typec_accessory accessory; struct usb_pd_identity *identity; u16 pd_revision; /* 0300H = "3.0" */ + u8 usb_capability; void (*attach)(struct typec_partner *partner, struct device *dev); void (*deattach)(struct typec_partner *partner, struct device *dev); @@ -240,6 +253,8 @@ struct typec_partner_desc { * @port_type_set: Set port type * @pd_get: Get available USB Power Delivery Capabilities. * @pd_set: Set USB Power Delivery Capabilities. + * @default_usb_mode_set: USB Mode to be used by default with Enter_USB Message + * @enter_usb_mode: Change the active USB Mode */ struct typec_operations { int (*try_role)(struct typec_port *port, int role); @@ -250,6 +265,8 @@ struct typec_operations { enum typec_port_type type); struct usb_power_delivery **(*pd_get)(struct typec_port *port); int (*pd_set)(struct typec_port *port, struct usb_power_delivery *pd); + int (*default_usb_mode_set)(struct typec_port *port, enum usb_mode mode); + int (*enter_usb_mode)(struct typec_port *port, enum usb_mode mode); }; enum usb_pd_svdm_ver { @@ -267,6 +284,7 @@ enum usb_pd_svdm_ver { * @svdm_version: USB PD Structured VDM version if supported * @prefer_role: Initial role preference (DRP ports). * @accessory: Supported Accessory Modes + * @usb_capability: Supported USB Modes * @fwnode: Optional fwnode of the port * @driver_data: Private pointer for driver specific info * @pd: Optional USB Power Delivery Support @@ -283,6 +301,7 @@ struct typec_capability { int prefer_role; enum typec_accessory accessory[TYPEC_MAX_ACCESSORY]; unsigned int orientation_aware:1; + u8 usb_capability; struct fwnode_handle *fwnode; void *driver_data; @@ -350,6 +369,9 @@ int typec_port_set_usb_power_delivery(struct typec_port *port, struct usb_power_ int typec_partner_set_usb_power_delivery(struct typec_partner *partner, struct usb_power_delivery *pd); +void typec_partner_set_usb_mode(struct typec_partner *partner, enum usb_mode usb_mode); +void typec_port_set_usb_mode(struct typec_port *port, enum usb_mode mode); + /** * struct typec_connector - Representation of Type-C port for external drivers * @attach: notification about device removal diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index beb533a0e88098a95a1365b51bdc2d9e9dfd1d07..62c0a7e65d6bdf4c71a8ea90586b985f9fd30229 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -45,6 +45,8 @@ struct inet_timewait_sock { #define tw_node __tw_common.skc_nulls_node #define tw_bind_node __tw_common.skc_bind_node #define tw_refcnt __tw_common.skc_refcnt +#define tw_tx_queue_mapping __tw_common.skc_tx_queue_mapping +#define tw_rx_queue_mapping __tw_common.skc_rx_queue_mapping #define tw_hash __tw_common.skc_hash #define tw_prot __tw_common.skc_prot #define tw_net __tw_common.skc_net diff --git a/include/net/net_debug.h b/include/net/net_debug.h index 9fecb1496be3f0fca4da9ce83f6b69b27077483a..47f7a4a878b9f3f52d6c55a13e8c19bbd7f8edcf 100644 --- a/include/net/net_debug.h +++ b/include/net/net_debug.h @@ -27,7 +27,7 @@ void netdev_info(const struct net_device *dev, const char *format, ...); #define netdev_level_once(level, dev, fmt, ...) \ do { \ - static bool __section(".data.once") __print_once; \ + static bool __section(".data..once") __print_once; \ \ if (!__print_once) { \ __print_once = true; \ diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 873c0f9fdac66397152dcc66dfffe02c82661b21..f943bd79ef03825fcf7c753cea470839c59b902d 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -325,6 +325,11 @@ static inline int check_net(const struct net *net) #define net_drop_ns NULL #endif +/* Returns true if the netns initialization is completed successfully */ +static inline bool net_initialized(const struct net *net) +{ + return READ_ONCE(net->list.next); +} static inline void __netns_tracker_alloc(struct net *net, netns_tracker *tracker, diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h index ff27cb2e166207cf8b58a96944d9b07a1779afe3..03b6165756fc5db03ef589e1b23f72bc48f7046d 100644 --- a/include/net/netfilter/nf_tables_core.h +++ b/include/net/netfilter/nf_tables_core.h @@ -161,6 +161,7 @@ enum { }; struct nft_inner_tun_ctx { + unsigned long cookie; u16 type; u16 inner_tunoff; u16 inner_lloff; diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 8cd6da0480b79486f076f630c19cae80e49dc7db..72d2060904f6a94c4d5cc34a6543808bbd2ffe0a 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -156,6 +156,7 @@ struct tasdevice_priv { struct tasdevice_rca rcabin; struct calidata cali_data; struct tasdevice_fw *fmw; + struct gpio_desc *speaker_id; struct gpio_desc *reset; struct mutex codec_lock; struct regmap *regmap; diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 5e8495216689549f1c0bb377911eac4a7bb7b1a8..b13dc275ef4a79940a940dd463b7a3eef5ca428b 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -719,7 +719,7 @@ TRACE_EVENT(rpc_xdr_overflow, ), TP_printk(SUNRPC_TRACE_TASK_SPECIFIER - " %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u\n", + " %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u", __entry->task_id, __entry->client_id, __get_str(progname), __entry->version, __get_str(procedure), __entry->requested, __entry->p, __entry->end, @@ -777,7 +777,7 @@ TRACE_EVENT(rpc_xdr_alignment, ), TP_printk(SUNRPC_TRACE_TASK_SPECIFIER - " %sv%d %s offset=%zu copied=%u xdr=[%p,%zu]/%u/[%p,%zu]/%u\n", + " %sv%d %s offset=%zu copied=%u xdr=[%p,%zu]/%u/[%p,%zu]/%u", __entry->task_id, __entry->client_id, __get_str(progname), __entry->version, __get_str(procedure), __entry->offset, __entry->copied, diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index f2e0b2d50e6b5ffadd52ced37e8a1e36999c9d97..12886d4465e4896aedce837c2df63c78f83a5496 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -51,6 +51,7 @@ enum iio_chan_type { IIO_DELTA_VELOCITY, IIO_COLORTEMP, IIO_CHROMATICITY, + IIO_ATTENTION, }; enum iio_modifier { diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 4418d019295919b35ee49b33e08413bd3192d805..aac9a4f8fa9a60e97ef2ac5ffe8066f23634c84a 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -873,20 +873,6 @@ enum { IORING_REG_WAIT_TS = (1U << 0), }; -/* - * Argument for IORING_REGISTER_CQWAIT_REG, registering a region of - * struct io_uring_reg_wait that can be indexed when io_uring_enter(2) is - * called rather than pass in a wait argument structure separately. - */ -struct io_uring_cqwait_reg_arg { - __u32 flags; - __u32 struct_size; - __u32 nr_entries; - __u32 pad; - __u64 user_addr; - __u64 pad2[3]; -}; - /* * Argument for io_uring_enter(2) with * IORING_GETEVENTS | IORING_ENTER_EXT_ARG_REG set, where the actual argument diff --git a/include/uapi/linux/types.h b/include/uapi/linux/types.h index 6375a06840520da2d161a2873bb782200365ec64..48b933938877d95d6c2a412ed2d7b2e62ace2797 100644 --- a/include/uapi/linux/types.h +++ b/include/uapi/linux/types.h @@ -53,6 +53,7 @@ typedef __u32 __bitwise __wsum; * No conversions are necessary between 32-bit user-space and a 64-bit kernel. */ #define __aligned_u64 __u64 __attribute__((aligned(8))) +#define __aligned_s64 __s64 __attribute__((aligned(8))) #define __aligned_be64 __be64 __attribute__((aligned(8))) #define __aligned_le64 __le64 __attribute__((aligned(8))) diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h index 2ff0e8a3a683dcd0dec4d2269041096831d88ea9..526b5155e23c502584e44a0710ca6197697ed769 100644 --- a/include/uapi/linux/usb/video.h +++ b/include/uapi/linux/usb/video.h @@ -597,5 +597,63 @@ struct UVC_FRAME_MJPEG(n) { \ __le32 dwFrameInterval[n]; \ } __attribute__ ((packed)) +/* Frame Based Payload - 3.1.1. Frame Based Video Format Descriptor */ +struct uvc_format_framebased { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bFormatIndex; + __u8 bNumFrameDescriptors; + __u8 guidFormat[16]; + __u8 bBitsPerPixel; + __u8 bDefaultFrameIndex; + __u8 bAspectRatioX; + __u8 bAspectRatioY; + __u8 bmInterfaceFlags; + __u8 bCopyProtect; + __u8 bVariableSize; +} __attribute__((__packed__)); + +#define UVC_DT_FORMAT_FRAMEBASED_SIZE 28 + +/* Frame Based Payload - 3.1.2. Frame Based Video Frame Descriptor */ +struct uvc_frame_framebased { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bFrameIndex; + __u8 bmCapabilities; + __u16 wWidth; + __u16 wHeight; + __u32 dwMinBitRate; + __u32 dwMaxBitRate; + __u32 dwDefaultFrameInterval; + __u8 bFrameIntervalType; + __u32 dwBytesPerLine; + __u32 dwFrameInterval[]; +} __attribute__((__packed__)); + +#define UVC_DT_FRAME_FRAMEBASED_SIZE(n) (26+4*(n)) + +#define UVC_FRAME_FRAMEBASED(n) \ + uvc_frame_framebased_##n + +#define DECLARE_UVC_FRAME_FRAMEBASED(n) \ +struct UVC_FRAME_FRAMEBASED(n) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u8 bFrameIndex; \ + __u8 bmCapabilities; \ + __u16 wWidth; \ + __u16 wHeight; \ + __u32 dwMinBitRate; \ + __u32 dwMaxBitRate; \ + __u32 dwDefaultFrameInterval; \ + __u8 bFrameIntervalType; \ + __u32 dwBytesPerLine; \ + __u32 dwFrameInterval[n]; \ +} __attribute__ ((packed)) + #endif /* __LINUX_USB_VIDEO_H */ diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 8012933998837ddcef45c14f1dfe543947a9eaec..06ff41484e29c6e7d8779bd7ff8317ebae003a8d 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -121,6 +121,7 @@ #define IO_COMPL_BATCH 32 #define IO_REQ_ALLOC_BATCH 8 +#define IO_LOCAL_TW_DEFAULT_MAX 20 struct io_defer_entry { struct list_head list; @@ -1255,12 +1256,14 @@ static void __cold io_move_task_work_from_local(struct io_ring_ctx *ctx) struct llist_node *node = llist_del_all(&ctx->work_llist); __io_fallback_tw(node, false); + node = llist_del_all(&ctx->retry_llist); + __io_fallback_tw(node, false); } static bool io_run_local_work_continue(struct io_ring_ctx *ctx, int events, int min_events) { - if (llist_empty(&ctx->work_llist)) + if (!io_local_work_pending(ctx)) return false; if (events < min_events) return true; @@ -1269,8 +1272,29 @@ static bool io_run_local_work_continue(struct io_ring_ctx *ctx, int events, return false; } +static int __io_run_local_work_loop(struct llist_node **node, + struct io_tw_state *ts, + int events) +{ + int ret = 0; + + while (*node) { + struct llist_node *next = (*node)->next; + struct io_kiocb *req = container_of(*node, struct io_kiocb, + io_task_work.node); + INDIRECT_CALL_2(req->io_task_work.func, + io_poll_task_func, io_req_rw_complete, + req, ts); + *node = next; + if (++ret >= events) + break; + } + + return ret; +} + static int __io_run_local_work(struct io_ring_ctx *ctx, struct io_tw_state *ts, - int min_events) + int min_events, int max_events) { struct llist_node *node; unsigned int loops = 0; @@ -1281,25 +1305,23 @@ static int __io_run_local_work(struct io_ring_ctx *ctx, struct io_tw_state *ts, if (ctx->flags & IORING_SETUP_TASKRUN_FLAG) atomic_andnot(IORING_SQ_TASKRUN, &ctx->rings->sq_flags); again: + min_events -= ret; + ret = __io_run_local_work_loop(&ctx->retry_llist.first, ts, max_events); + if (ctx->retry_llist.first) + goto retry_done; + /* * llists are in reverse order, flip it back the right way before * running the pending items. */ node = llist_reverse_order(llist_del_all(&ctx->work_llist)); - while (node) { - struct llist_node *next = node->next; - struct io_kiocb *req = container_of(node, struct io_kiocb, - io_task_work.node); - INDIRECT_CALL_2(req->io_task_work.func, - io_poll_task_func, io_req_rw_complete, - req, ts); - ret++; - node = next; - } + ret += __io_run_local_work_loop(&node, ts, max_events - ret); + ctx->retry_llist.first = node; loops++; if (io_run_local_work_continue(ctx, ret, min_events)) goto again; +retry_done: io_submit_flush_completions(ctx); if (io_run_local_work_continue(ctx, ret, min_events)) goto again; @@ -1313,18 +1335,20 @@ static inline int io_run_local_work_locked(struct io_ring_ctx *ctx, { struct io_tw_state ts = {}; - if (llist_empty(&ctx->work_llist)) + if (!io_local_work_pending(ctx)) return 0; - return __io_run_local_work(ctx, &ts, min_events); + return __io_run_local_work(ctx, &ts, min_events, + max(IO_LOCAL_TW_DEFAULT_MAX, min_events)); } -static int io_run_local_work(struct io_ring_ctx *ctx, int min_events) +static int io_run_local_work(struct io_ring_ctx *ctx, int min_events, + int max_events) { struct io_tw_state ts = {}; int ret; mutex_lock(&ctx->uring_lock); - ret = __io_run_local_work(ctx, &ts, min_events); + ret = __io_run_local_work(ctx, &ts, min_events, max_events); mutex_unlock(&ctx->uring_lock); return ret; } @@ -2328,9 +2352,9 @@ static int io_wake_function(struct wait_queue_entry *curr, unsigned int mode, int io_run_task_work_sig(struct io_ring_ctx *ctx) { - if (!llist_empty(&ctx->work_llist)) { + if (io_local_work_pending(ctx)) { __set_current_state(TASK_RUNNING); - if (io_run_local_work(ctx, INT_MAX) > 0) + if (io_run_local_work(ctx, INT_MAX, IO_LOCAL_TW_DEFAULT_MAX) > 0) return 0; } if (io_run_task_work() > 0) @@ -2459,7 +2483,7 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx, { if (unlikely(READ_ONCE(ctx->check_cq))) return 1; - if (unlikely(!llist_empty(&ctx->work_llist))) + if (unlikely(io_local_work_pending(ctx))) return 1; if (unlikely(task_work_pending(current))) return 1; @@ -2493,8 +2517,9 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, u32 flags, if (!io_allowed_run_tw(ctx)) return -EEXIST; - if (!llist_empty(&ctx->work_llist)) - io_run_local_work(ctx, min_events); + if (io_local_work_pending(ctx)) + io_run_local_work(ctx, min_events, + max(IO_LOCAL_TW_DEFAULT_MAX, min_events)); io_run_task_work(); if (unlikely(test_bit(IO_CHECK_CQ_OVERFLOW_BIT, &ctx->check_cq))) @@ -2564,8 +2589,8 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, u32 flags, * If we got woken because of task_work being processed, run it * now rather than let the caller do another wait loop. */ - if (!llist_empty(&ctx->work_llist)) - io_run_local_work(ctx, nr_wait); + if (io_local_work_pending(ctx)) + io_run_local_work(ctx, nr_wait, nr_wait); io_run_task_work(); /* @@ -3077,7 +3102,7 @@ static __cold bool io_uring_try_cancel_requests(struct io_ring_ctx *ctx, if ((ctx->flags & IORING_SETUP_DEFER_TASKRUN) && io_allowed_defer_tw_run(ctx)) - ret |= io_run_local_work(ctx, INT_MAX) > 0; + ret |= io_run_local_work(ctx, INT_MAX, INT_MAX) > 0; ret |= io_cancel_defer_files(ctx, tctx, cancel_all); mutex_lock(&ctx->uring_lock); ret |= io_poll_remove_all(ctx, tctx, cancel_all); @@ -3158,7 +3183,7 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd) io_run_task_work(); io_uring_drop_tctx_refs(current); xa_for_each(&tctx->xa, index, node) { - if (!llist_empty(&node->ctx->work_llist)) { + if (io_local_work_pending(node->ctx)) { WARN_ON_ONCE(node->ctx->submitter_task && node->ctx->submitter_task != current); goto end_wait; diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h index 4070d4c8ef9713ed1baa6b4bc28e63dc10255cf2..12abee607e4aa245257e0b70ded3642341c87d4a 100644 --- a/io_uring/io_uring.h +++ b/io_uring/io_uring.h @@ -347,9 +347,14 @@ static inline int io_run_task_work(void) return ret; } +static inline bool io_local_work_pending(struct io_ring_ctx *ctx) +{ + return !llist_empty(&ctx->work_llist) || !llist_empty(&ctx->retry_llist); +} + static inline bool io_task_work_pending(struct io_ring_ctx *ctx) { - return task_work_pending(current) || !llist_empty(&ctx->work_llist); + return task_work_pending(current) || io_local_work_pending(ctx); } static inline void io_tw_lock(struct io_ring_ctx *ctx, struct io_tw_state *ts) @@ -484,6 +489,6 @@ enum { static inline bool io_has_work(struct io_ring_ctx *ctx) { return test_bit(IO_CHECK_CQ_OVERFLOW_BIT, &ctx->check_cq) || - !llist_empty(&ctx->work_llist); + io_local_work_pending(ctx); } #endif diff --git a/io_uring/memmap.c b/io_uring/memmap.c index 6e6ee79ba94fcd97a57811a4bf98fd3a0abf0bdb..57de9bccbf508b8820fd3120d3a8d08b5437527f 100644 --- a/io_uring/memmap.c +++ b/io_uring/memmap.c @@ -73,6 +73,8 @@ void *io_pages_map(struct page ***out_pages, unsigned short *npages, ret = io_mem_alloc_compound(pages, nr_pages, size, gfp); if (!IS_ERR(ret)) goto done; + if (nr_pages == 1) + goto fail; ret = io_mem_alloc_single(pages, nr_pages, size, gfp); if (!IS_ERR(ret)) { @@ -81,7 +83,7 @@ done: *npages = nr_pages; return ret; } - +fail: kvfree(pages); *out_pages = NULL; *npages = 0; @@ -136,7 +138,12 @@ struct page **io_pin_pages(unsigned long uaddr, unsigned long len, int *npages) struct page **pages; int ret; - end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (check_add_overflow(uaddr, len, &end)) + return ERR_PTR(-EOVERFLOW); + if (check_add_overflow(end, PAGE_SIZE - 1, &end)) + return ERR_PTR(-EOVERFLOW); + + end = end >> PAGE_SHIFT; start = uaddr >> PAGE_SHIFT; nr_pages = end - start; if (WARN_ON_ONCE(!nr_pages)) @@ -229,7 +236,7 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr, if (!reg->size || reg->mmap_offset || reg->id) return -EINVAL; if ((reg->size >> PAGE_SHIFT) > INT_MAX) - return E2BIG; + return -E2BIG; if ((reg->user_addr | reg->size) & ~PAGE_MASK) return -EINVAL; if (check_add_overflow(reg->user_addr, reg->size, &end)) diff --git a/io_uring/nop.c b/io_uring/nop.c index 6d470d4251eef96ecf9e3b77c44388d3112901f4..5e5196df650a19e032e53594db6f1d1bea71c5f2 100644 --- a/io_uring/nop.c +++ b/io_uring/nop.c @@ -35,10 +35,14 @@ int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) nop->result = READ_ONCE(sqe->len); else nop->result = 0; - if (nop->flags & IORING_NOP_FIXED_FILE) + if (nop->flags & IORING_NOP_FILE) nop->fd = READ_ONCE(sqe->fd); + else + nop->fd = -1; if (nop->flags & IORING_NOP_FIXED_BUFFER) nop->buffer = READ_ONCE(sqe->buf_index); + else + nop->buffer = -1; return 0; } diff --git a/io_uring/register.c b/io_uring/register.c index 1a60f491664991aaca00f7ad1c8e202ab622cb61..1e99c783abdf6e0bd066e6f0da873f316e5bf130 100644 --- a/io_uring/register.c +++ b/io_uring/register.c @@ -905,9 +905,10 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode, mutex_lock(&ctx->uring_lock); ret = __io_uring_register(ctx, opcode, arg, nr_args); - mutex_unlock(&ctx->uring_lock); + trace_io_uring_register(ctx, opcode, ctx->file_table.data.nr, ctx->buf_table.nr, ret); + mutex_unlock(&ctx->uring_lock); if (!use_registered_ring) fput(file); return ret; diff --git a/io_uring/tctx.c b/io_uring/tctx.c index 503f3ff8bc4f90e891e3e06b2cd0bed536606be8..adc6e42c14df6c0152b6f97ee908e7797f489b95 100644 --- a/io_uring/tctx.c +++ b/io_uring/tctx.c @@ -47,8 +47,19 @@ static struct io_wq *io_init_wq_offload(struct io_ring_ctx *ctx, void __io_uring_free(struct task_struct *tsk) { struct io_uring_task *tctx = tsk->io_uring; + struct io_tctx_node *node; + unsigned long index; - WARN_ON_ONCE(!xa_empty(&tctx->xa)); + /* + * Fault injection forcing allocation errors in the xa_store() path + * can lead to xa_empty() returning false, even though no actual + * node is stored in the xarray. Until that gets sorted out, attempt + * an iteration here and warn if any entries are found. + */ + xa_for_each(&tctx->xa, index, node) { + WARN_ON_ONCE(1); + break; + } WARN_ON_ONCE(tctx->io_wq); WARN_ON_ONCE(tctx->cached_refs); diff --git a/kernel/cpu.c b/kernel/cpu.c index 6e34b52cb5ce714571bb5778648b9720df39ddb1..b605334f8ee6a39b628479d89f6363827cbd6064 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -2866,7 +2866,6 @@ static struct attribute *cpuhp_cpu_attrs[] = { static const struct attribute_group cpuhp_cpu_attr_group = { .attrs = cpuhp_cpu_attrs, .name = "hotplug", - NULL }; static ssize_t states_show(struct device *dev, @@ -2898,7 +2897,6 @@ static struct attribute *cpuhp_cpu_root_attrs[] = { static const struct attribute_group cpuhp_cpu_root_attr_group = { .attrs = cpuhp_cpu_root_attrs, .name = "hotplug", - NULL }; #ifdef CONFIG_HOTPLUG_SMT @@ -3020,7 +3018,6 @@ static struct attribute *cpuhp_smt_attrs[] = { static const struct attribute_group cpuhp_smt_attr_group = { .attrs = cpuhp_smt_attrs, .name = "smt", - NULL }; static int __init cpu_smt_sysfs_init(void) diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index 295396226f318b6ffa6f1899b29cbe9b54e45a1a..e43c6de2bce4e7d3e58f8d9601a7637d8f6da767 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -1219,7 +1219,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, entry->dev = dev; entry->type = dma_debug_single; - entry->paddr = page_to_phys(page); + entry->paddr = page_to_phys(page) + offset; entry->dev_addr = dma_addr; entry->size = size; entry->direction = direction; @@ -1377,6 +1377,18 @@ void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, } } +static phys_addr_t virt_to_paddr(void *virt) +{ + struct page *page; + + if (is_vmalloc_addr(virt)) + page = vmalloc_to_page(virt); + else + page = virt_to_page(virt); + + return page_to_phys(page) + offset_in_page(virt); +} + void debug_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t dma_addr, void *virt, unsigned long attrs) @@ -1399,8 +1411,7 @@ void debug_dma_alloc_coherent(struct device *dev, size_t size, entry->type = dma_debug_coherent; entry->dev = dev; - entry->paddr = page_to_phys((is_vmalloc_addr(virt) ? - vmalloc_to_page(virt) : virt_to_page(virt))); + entry->paddr = virt_to_paddr(virt); entry->size = size; entry->dev_addr = dma_addr; entry->direction = DMA_BIDIRECTIONAL; @@ -1423,8 +1434,7 @@ void debug_dma_free_coherent(struct device *dev, size_t size, if (!is_vmalloc_addr(virt) && !virt_addr_valid(virt)) return; - ref.paddr = page_to_phys((is_vmalloc_addr(virt) ? - vmalloc_to_page(virt) : virt_to_page(virt))); + ref.paddr = virt_to_paddr(virt); if (unlikely(dma_debug_disabled())) return; diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index 7c6588148d42d351b787b8336400cff25558136d..7b329057997ad2ec310133ca84617d9bfcdb7e9f 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -349,7 +349,7 @@ config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS help Symbols exported with EXPORT_SYMBOL_NS*() are considered exported in a namespace. A module that makes use of a symbol exported with such a - namespace is required to import the namespace via MODULE_IMPORT_NS(). + namespace is required to import the namespace via MODULE_IMPORT_NS(""). There is no technical reason to enforce correct namespace imports, but it creates consistency between symbols defining namespaces and users importing namespaces they make use of. This option relaxes this diff --git a/kernel/resource.c b/kernel/resource.c index c9fd26c06345453472f4325860d40fd2e8b9c01b..b7c0e24d93980101f3598a5b4725aa5c0e2c07d5 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -998,7 +998,7 @@ void insert_resource_expand_to_fit(struct resource *root, struct resource *new) * to use this interface. The former are built-in and only the latter, * CXL, is a module. */ -EXPORT_SYMBOL_NS_GPL(insert_resource_expand_to_fit, CXL); +EXPORT_SYMBOL_NS_GPL(insert_resource_expand_to_fit, "CXL"); /** * remove_resource - Remove a resource in the resource tree diff --git a/kernel/signal.c b/kernel/signal.c index 98b65cb358306836525a66ea83d77c3369c672f6..989b1cc9116a2868bda685c8a164801172ce4559 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1959,14 +1959,15 @@ static void posixtimer_queue_sigqueue(struct sigqueue *q, struct task_struct *t, * * Where type is not PIDTYPE_PID, signals must be delivered to the * process. In this case, prefer to deliver to current if it is in - * the same thread group as the target process, which avoids - * unnecessarily waking up a potentially idle task. + * the same thread group as the target process and its sighand is + * stable, which avoids unnecessarily waking up a potentially idle task. */ static inline struct task_struct *posixtimer_get_target(struct k_itimer *tmr) { struct task_struct *t = pid_task(tmr->it_pid, tmr->it_pid_type); - if (t && tmr->it_pid_type != PIDTYPE_PID && same_thread_group(t, current)) + if (t && tmr->it_pid_type != PIDTYPE_PID && + same_thread_group(t, current) && !current->exit_state) t = current; return t; } diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index b550ebe0f03b2205479f5343e11afe1fadd70185..163e7a2033b624f3f023c25968cd17e624ea831d 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -798,7 +798,7 @@ int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts, txc->offset = shift_right(ntpdata->time_offset * NTP_INTERVAL_FREQ, NTP_SCALE_SHIFT); if (!(ntpdata->time_status & STA_NANO)) - txc->offset = (u32)txc->offset / NSEC_PER_USEC; + txc->offset = div_s64(txc->offset, NSEC_PER_USEC); } result = ntpdata->time_state; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3ef047ed9705574a11256369a98d6da9e0fe273a..be62f0ea1814d2a9f7440a1c8bcdabc430f08925 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2552,6 +2552,8 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status) trace_flags |= TRACE_FLAG_NEED_RESCHED; if (test_preempt_need_resched()) trace_flags |= TRACE_FLAG_PREEMPT_RESCHED; + if (IS_ENABLED(CONFIG_ARCH_HAS_PREEMPT_LAZY) && tif_test_bit(TIF_NEED_RESCHED_LAZY)) + trace_flags |= TRACE_FLAG_NEED_RESCHED_LAZY; return (trace_flags << 16) | (min_t(unsigned int, pc & 0xff, 0xf)) | (min_t(unsigned int, migration_disable_value(), 0xf)) << 4; } diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index e08aee34ef63de4cebef5e991d95aff1aa513f62..da748b7cbc4d53e0eb5fef075891f41d23361cb2 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -462,17 +462,29 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) bh_off ? 'b' : '.'; - switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | + switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY | TRACE_FLAG_PREEMPT_RESCHED)) { + case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY | TRACE_FLAG_PREEMPT_RESCHED: + need_resched = 'B'; + break; case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED: need_resched = 'N'; break; + case TRACE_FLAG_NEED_RESCHED_LAZY | TRACE_FLAG_PREEMPT_RESCHED: + need_resched = 'L'; + break; + case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY: + need_resched = 'b'; + break; case TRACE_FLAG_NEED_RESCHED: need_resched = 'n'; break; case TRACE_FLAG_PREEMPT_RESCHED: need_resched = 'p'; break; + case TRACE_FLAG_NEED_RESCHED_LAZY: + need_resched = 'l'; + break; default: need_resched = '.'; break; diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c index 5c03633316a666b09b4a70d71ccf5fe3b718d452..0c42b15c380047b44efdd4b2c6395d6b77b9ccf7 100644 --- a/kernel/trace/trace_preemptirq.c +++ b/kernel/trace/trace_preemptirq.c @@ -10,11 +10,42 @@ #include #include #include +#include #include "trace.h" #define CREATE_TRACE_POINTS #include +/* + * Use regular trace points on architectures that implement noinstr + * tooling: these calls will only happen with RCU enabled, which can + * use a regular tracepoint. + * + * On older architectures, RCU may not be watching in idle. In that + * case, wake up RCU to watch while calling the tracepoint. These + * aren't NMI-safe - so exclude NMI contexts: + */ +#ifdef CONFIG_ARCH_WANTS_NO_INSTR +#define trace(point, args) trace_##point(args) +#else +#define trace(point, args) \ + do { \ + if (trace_##point##_enabled()) { \ + bool exit_rcu = false; \ + if (in_nmi()) \ + break; \ + if (!IS_ENABLED(CONFIG_TINY_RCU) && \ + is_idle_task(current)) { \ + ct_irq_enter(); \ + exit_rcu = true; \ + } \ + trace_##point(args); \ + if (exit_rcu) \ + ct_irq_exit(); \ + } \ + } while (0) +#endif + #ifdef CONFIG_TRACE_IRQFLAGS /* Per-cpu variable to prevent redundant calls when IRQs already off */ static DEFINE_PER_CPU(int, tracing_irq_cpu); @@ -28,7 +59,7 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu); void trace_hardirqs_on_prepare(void) { if (this_cpu_read(tracing_irq_cpu)) { - trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1); + trace(irq_enable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1)); tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); this_cpu_write(tracing_irq_cpu, 0); } @@ -39,7 +70,7 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare); void trace_hardirqs_on(void) { if (this_cpu_read(tracing_irq_cpu)) { - trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1); + trace(irq_enable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1)); tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); this_cpu_write(tracing_irq_cpu, 0); } @@ -61,7 +92,7 @@ void trace_hardirqs_off_finish(void) if (!this_cpu_read(tracing_irq_cpu)) { this_cpu_write(tracing_irq_cpu, 1); tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); - trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1); + trace(irq_disable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1)); } } @@ -75,7 +106,7 @@ void trace_hardirqs_off(void) if (!this_cpu_read(tracing_irq_cpu)) { this_cpu_write(tracing_irq_cpu, 1); tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); - trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1); + trace(irq_disable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1)); } } EXPORT_SYMBOL(trace_hardirqs_off); @@ -86,13 +117,13 @@ NOKPROBE_SYMBOL(trace_hardirqs_off); void trace_preempt_on(unsigned long a0, unsigned long a1) { - trace_preempt_enable(a0, a1); + trace(preempt_enable, TP_ARGS(a0, a1)); tracer_preempt_on(a0, a1); } void trace_preempt_off(unsigned long a0, unsigned long a1) { - trace_preempt_disable(a0, a1); + trace(preempt_disable, TP_ARGS(a0, a1)); tracer_preempt_off(a0, a1); } #endif diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c index 3a56e7c8aa4f67281e57bb6538dc961c4b65c670..1921ade45be38b27600e3b055e81b9050a566826 100644 --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c @@ -845,15 +845,11 @@ int tracing_map_init(struct tracing_map *map) static int cmp_entries_dup(const void *A, const void *B) { const struct tracing_map_sort_entry *a, *b; - int ret = 0; a = *(const struct tracing_map_sort_entry **)A; b = *(const struct tracing_map_sort_entry **)B; - if (memcmp(a->key, b->key, a->elt->map->key_size)) - ret = 1; - - return ret; + return memcmp(a->key, b->key, a->elt->map->key_size); } static int cmp_entries_sum(const void *A, const void *B) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index f340017585c54a91332956ad101b600e4e0462d2..f3d72370587936fa373129cc9b246f15dac907be 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3003,9 +3003,39 @@ config TEST_KALLSYMS_D tristate depends on m +choice + prompt "Kallsym test range" + default TEST_KALLSYMS_LARGE + help + Selecting something other than "Fast" will enable tests which slow + down the build and may crash your build. + +config TEST_KALLSYMS_FAST + bool "Fast builds" + help + You won't really be testing kallsysms, so this just helps fast builds + when allmodconfig is used.. + +config TEST_KALLSYMS_LARGE + bool "Enable testing kallsyms with large exports" + help + This will enable larger number of symbols. This will slow down + your build considerably. + +config TEST_KALLSYMS_MAX + bool "Known kallsysms limits" + help + This will enable exports to the point we know we'll start crashing + builds. + +endchoice + config TEST_KALLSYMS_NUMSYMS int "test kallsyms number of symbols" - default 100 + range 2 10000 + default 2 if TEST_KALLSYMS_FAST + default 100 if TEST_KALLSYMS_LARGE + default 10000 if TEST_KALLSYMS_MAX help The number of symbols to create on TEST_KALLSYMS_A, only one of which module TEST_KALLSYMS_B will use. This also will be used diff --git a/lib/devres.c b/lib/devres.c index 4fc152de6d8bb1232aeca382a313bd9ff56b8f60..73901160197eb3588b97b80310654f394666b1ac 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -115,9 +115,8 @@ EXPORT_SYMBOL(devm_ioremap_wc); */ void devm_iounmap(struct device *dev, void __iomem *addr) { - WARN_ON(devres_destroy(dev, devm_ioremap_release, devm_ioremap_match, + WARN_ON(devres_release(dev, devm_ioremap_release, devm_ioremap_match, (__force void *)addr)); - iounmap(addr); } EXPORT_SYMBOL(devm_iounmap); @@ -308,8 +307,7 @@ EXPORT_SYMBOL(devm_ioport_map); */ void devm_ioport_unmap(struct device *dev, void __iomem *addr) { - ioport_unmap(addr); - WARN_ON(devres_destroy(dev, devm_ioport_map_release, + WARN_ON(devres_release(dev, devm_ioport_map_release, devm_ioport_map_match, (__force void *)addr)); } EXPORT_SYMBOL(devm_ioport_unmap); diff --git a/lib/kunit/user_alloc.c b/lib/kunit/user_alloc.c index ae935df09a5eb6018c8c22b1bc432136c68021e6..46951be018be27776f8369322fe8be0d63f376ca 100644 --- a/lib/kunit/user_alloc.c +++ b/lib/kunit/user_alloc.c @@ -114,4 +114,4 @@ unsigned long kunit_vm_mmap(struct kunit *test, struct file *file, } EXPORT_SYMBOL_GPL(kunit_vm_mmap); -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); diff --git a/lib/string.c b/lib/string.c index 76327b51e36f25fffae386d2b8016d1f2586688f..eb4486ed40d259e43dfb63d76c2bd57ef74e2fd1 100644 --- a/lib/string.c +++ b/lib/string.c @@ -104,6 +104,12 @@ char *strncpy(char *dest, const char *src, size_t count) EXPORT_SYMBOL(strncpy); #endif +#ifdef __BIG_ENDIAN +# define ALLBUTLAST_BYTE_MASK (~255ul) +#else +# define ALLBUTLAST_BYTE_MASK (~0ul >> 8) +#endif + ssize_t sized_strscpy(char *dest, const char *src, size_t count) { const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; @@ -147,13 +153,18 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count) *(unsigned long *)(dest+res) = c & zero_bytemask(data); return res + find_zero(data); } + count -= sizeof(unsigned long); + if (unlikely(!count)) { + c &= ALLBUTLAST_BYTE_MASK; + *(unsigned long *)(dest+res) = c; + return -E2BIG; + } *(unsigned long *)(dest+res) = c; res += sizeof(unsigned long); - count -= sizeof(unsigned long); max -= sizeof(unsigned long); } - while (count) { + while (count > 1) { char c; c = src[res]; @@ -164,11 +175,11 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count) count--; } - /* Hit buffer length without finding a NUL; force NUL-termination. */ - if (res) - dest[res-1] = '\0'; + /* Force NUL-termination. */ + dest[res] = '\0'; - return -E2BIG; + /* Return E2BIG if the source didn't stop */ + return src[res] ? -E2BIG : res; } EXPORT_SYMBOL(sized_strscpy); diff --git a/lib/test_firmware.c b/lib/test_firmware.c index bcb32cbff1885217cd6e70d40e52841e4575b6cb..211222e63328f970228920f5662ee80cc7f51215 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -27,7 +27,7 @@ #include #include -MODULE_IMPORT_NS(TEST_FIRMWARE); +MODULE_IMPORT_NS("TEST_FIRMWARE"); #define TEST_FIRMWARE_NAME "test-firmware.bin" #define TEST_FIRMWARE_NUM_REQS 4 diff --git a/lib/tests/module/Makefile b/lib/tests/module/Makefile index af5c27b996cb15d2f48218755b3ea3d81ffd7280..2f3e1a772c2c4a4205a10825a408eb98227e989d 100644 --- a/lib/tests/module/Makefile +++ b/lib/tests/module/Makefile @@ -3,13 +3,12 @@ obj-$(CONFIG_TEST_KALLSYMS_B) += test_kallsyms_b.o obj-$(CONFIG_TEST_KALLSYMS_C) += test_kallsyms_c.o obj-$(CONFIG_TEST_KALLSYMS_D) += test_kallsyms_d.o -$(obj)/%.c: FORCE - @$(kecho) " GEN $@" - $(Q)$(srctree)/lib/tests/module/gen_test_kallsyms.sh $@\ - $(CONFIG_TEST_KALLSYMS_NUMSYMS) \ - $(CONFIG_TEST_KALLSYMS_SCALE_FACTOR) +quiet_cmd_gen_test_kallsyms = GEN $@ + cmd_gen_test_kallsyms = $< $@ \ + $(CONFIG_TEST_KALLSYMS_NUMSYMS) \ + $(CONFIG_TEST_KALLSYMS_SCALE_FACTOR) -clean-files += test_kallsyms_a.c -clean-files += test_kallsyms_b.c -clean-files += test_kallsyms_c.c -clean-files += test_kallsyms_d.c +$(obj)/%.c: $(src)/gen_test_kallsyms.sh FORCE + $(call if_changed,gen_test_kallsyms) + +targets += $(foreach x, a b c d, test_kallsyms_$(x).c) diff --git a/lib/tests/module/gen_test_kallsyms.sh b/lib/tests/module/gen_test_kallsyms.sh index 3f2c626350ad1b2bc653b60e5d6e3abe9cb7d334..561dcac0f359c1305fe92e0db8853b9288ecc602 100755 --- a/lib/tests/module/gen_test_kallsyms.sh +++ b/lib/tests/module/gen_test_kallsyms.sh @@ -7,6 +7,11 @@ NUM_SYMS=$2 SCALE_FACTOR=$3 TEST_TYPE=$(echo $TARGET | sed -e 's|lib/tests/module/test_kallsyms_||g') TEST_TYPE=$(echo $TEST_TYPE | sed -e 's|.c||g') +FIRST_B_LOOKUP=1 + +if [[ $NUM_SYMS -gt 2 ]]; then + FIRST_B_LOOKUP=$((NUM_SYMS/2)) +fi gen_template_module_header() { @@ -52,10 +57,10 @@ ____END_MODULE gen_template_module_data_b() { - printf "\nextern int auto_test_a_%010d;\n\n" 28 + printf "\nextern int auto_test_a_%010d;\n\n" $FIRST_B_LOOKUP echo "static int auto_runtime_test(void)" echo "{" - printf "\nreturn auto_test_a_%010d;\n" 28 + printf "\nreturn auto_test_a_%010d;\n" $FIRST_B_LOOKUP echo "}" } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6ac02bbb7df14e432699c70c2f2ac6479407728f..9d3dac38a3f4a0f046b0f94d89d1a83f4e46c51f 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -3428,29 +3428,6 @@ out: } EXPORT_SYMBOL_GPL(bstr_printf); -/** - * bprintf - Parse a format string and place args' binary value in a buffer - * @bin_buf: The buffer to place args' binary value - * @size: The size of the buffer(by words(32bits), not characters) - * @fmt: The format string to use - * @...: Arguments for the format string - * - * The function returns the number of words(u32) written - * into @bin_buf. - */ -int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) -{ - va_list args; - int ret; - - va_start(args, fmt); - ret = vbin_printf(bin_buf, size, fmt, args); - va_end(args); - - return ret; -} -EXPORT_SYMBOL_GPL(bprintf); - #endif /* CONFIG_BINARY_PRINTF */ /** diff --git a/mm/internal.h b/mm/internal.h index 5a7302baeed7ccbae6a6fc827e1599e179161a88..cb8d8e8e3ffa5f7fec34d8498a9aad1808232748 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -49,7 +49,7 @@ struct folio_batch; * when we specify __GFP_NOWARN. */ #define WARN_ON_ONCE_GFP(cond, gfp) ({ \ - static bool __section(".data.once") __warned; \ + static bool __section(".data..once") __warned; \ int __ret_warn_once = !!(cond); \ \ if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \ diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c index e0ec5a6d15be134eea6361e85c236e5cf4bf9375..99d4ff0ed57a1c2c4513b72bd0c705f09abae4ae 100644 --- a/mm/kasan/kasan_test_c.c +++ b/mm/kasan/kasan_test_c.c @@ -33,7 +33,7 @@ #define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_GRANULE_SIZE) -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static bool multishot; diff --git a/net/9p/Kconfig b/net/9p/Kconfig index ee967fd25312cbe3999044700d71a756cf21eb74..22f8c167845d11062e37ad6e608a4de7f5186af0 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -41,8 +41,8 @@ config NET_9P_XEN two Xen domains. config NET_9P_USBG - bool "9P USB Gadget Transport" - depends on USB_GADGET=y || USB_GADGET=NET_9P + tristate "9P USB Gadget Transport" + depends on USB_GADGET select CONFIGFS_FS select USB_LIBCOMPOSITE help diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c index 975b76839dca1a851105f59d8c3471bc4cc24e12..6b694f117aef296a66419fed5252305e7a1d0936 100644 --- a/net/9p/trans_usbg.c +++ b/net/9p/trans_usbg.c @@ -909,9 +909,9 @@ static struct usb_function_instance *usb9pfs_alloc_instance(void) usb9pfs_opts->buflen = DEFAULT_BUFLEN; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (IS_ERR(dev)) { + if (!dev) { kfree(usb9pfs_opts); - return ERR_CAST(dev); + return ERR_PTR(-ENOMEM); } usb9pfs_opts->dev = dev; diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index dfdbe1ca533872ce189e64ff5f4a083c5261ddee..b9ff69c7522a19c53906b0dc0cfa0998a9063826 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -286,7 +286,7 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv) if (!priv->rings[i].intf) break; if (priv->rings[i].irq > 0) - unbind_from_irqhandler(priv->rings[i].irq, priv->dev); + unbind_from_irqhandler(priv->rings[i].irq, ring); if (priv->rings[i].data.in) { for (j = 0; j < (1 << priv->rings[i].intf->ring_order); @@ -465,6 +465,7 @@ static int xen_9pfs_front_init(struct xenbus_device *dev) goto error; } + xenbus_switch_state(dev, XenbusStateInitialised); return 0; error_xenbus: @@ -512,8 +513,10 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev, break; case XenbusStateInitWait: - if (!xen_9pfs_front_init(dev)) - xenbus_switch_state(dev, XenbusStateInitialised); + if (dev->state != XenbusStateInitialising) + break; + + xen_9pfs_front_init(dev); break; case XenbusStateConnected: diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 319f47df33300cb2a96e646bccbc700e89dd384e..95f7a7e65a73fa74243ddf5141d0fe81c7c6734d 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -1505,7 +1505,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv, session->state = J1939_SESSION_NEW; skb_queue_head_init(&session->skb_queue); - skb_queue_tail(&session->skb_queue, skb); + skb_queue_tail(&session->skb_queue, skb_get(skb)); skcb = j1939_skb_to_cb(skb); memcpy(&session->skcb, skcb, sizeof(session->skcb)); diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 051d22c0e4ad4bbbc41746f9b986f150d8e6aba8..01b2ce1e8fc06eec7cfdc2aa9c6cde5398a40fc3 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -74,18 +74,6 @@ int ceph_crypto_key_clone(struct ceph_crypto_key *dst, return set_secret(dst, src->key); } -int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end) -{ - if (*p + sizeof(u16) + sizeof(key->created) + - sizeof(u16) + key->len > end) - return -ERANGE; - ceph_encode_16(p, key->type); - ceph_encode_copy(p, &key->created, sizeof(key->created)); - ceph_encode_16(p, key->len); - ceph_encode_copy(p, key->key, key->len); - return 0; -} - int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end) { int ret; diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h index 13bd526349fa1b63b71f84fb4ab1076fc1d2a7f2..23de29fc613cf1909096c222cdda1d3e10ad2d0a 100644 --- a/net/ceph/crypto.h +++ b/net/ceph/crypto.h @@ -21,7 +21,6 @@ struct ceph_crypto_key { int ceph_crypto_key_clone(struct ceph_crypto_key *dst, const struct ceph_crypto_key *src); -int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end); int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end); int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in); void ceph_crypto_key_destroy(struct ceph_crypto_key *key); diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 9d078b37fe0b9b085894be86db17053227de9a18..9b1168eb77abb3707ab162953fa9cf380ec1795f 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -4999,40 +4999,6 @@ out_put_lreq: } EXPORT_SYMBOL(ceph_osdc_notify); -/* - * Return the number of milliseconds since the watch was last - * confirmed, or an error. If there is an error, the watch is no - * longer valid, and should be destroyed with ceph_osdc_unwatch(). - */ -int ceph_osdc_watch_check(struct ceph_osd_client *osdc, - struct ceph_osd_linger_request *lreq) -{ - unsigned long stamp, age; - int ret; - - down_read(&osdc->lock); - mutex_lock(&lreq->lock); - stamp = lreq->watch_valid_thru; - if (!list_empty(&lreq->pending_lworks)) { - struct linger_work *lwork = - list_first_entry(&lreq->pending_lworks, - struct linger_work, - pending_item); - - if (time_before(lwork->queued_stamp, stamp)) - stamp = lwork->queued_stamp; - } - age = jiffies - stamp; - dout("%s lreq %p linger_id %llu age %lu last_error %d\n", __func__, - lreq, lreq->linger_id, age, lreq->last_error); - /* we are truncating to msecs, so return a safe upper bound */ - ret = lreq->last_error ?: 1 + jiffies_to_msecs(age); - - mutex_unlock(&lreq->lock); - up_read(&osdc->lock); - return ret; -} - static int decode_watcher(void **p, void *end, struct ceph_watch_item *item) { u8 struct_v; diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c index 74622b278d5766bd57803d9e160ac9c390b9b287..5a9c4be5f222106c8b372affd115b8f899a920a9 100644 --- a/net/ceph/pagelist.c +++ b/net/ceph/pagelist.c @@ -131,41 +131,3 @@ int ceph_pagelist_free_reserve(struct ceph_pagelist *pl) return 0; } EXPORT_SYMBOL(ceph_pagelist_free_reserve); - -/* Create a truncation point. */ -void ceph_pagelist_set_cursor(struct ceph_pagelist *pl, - struct ceph_pagelist_cursor *c) -{ - c->pl = pl; - c->page_lru = pl->head.prev; - c->room = pl->room; -} -EXPORT_SYMBOL(ceph_pagelist_set_cursor); - -/* Truncate a pagelist to the given point. Move extra pages to reserve. - * This won't sleep. - * Returns: 0 on success, - * -EINVAL if the pagelist doesn't match the trunc point pagelist - */ -int ceph_pagelist_truncate(struct ceph_pagelist *pl, - struct ceph_pagelist_cursor *c) -{ - struct page *page; - - if (pl != c->pl) - return -EINVAL; - ceph_pagelist_unmap_tail(pl); - while (pl->head.prev != c->page_lru) { - page = list_entry(pl->head.prev, struct page, lru); - /* move from pagelist to reserve */ - list_move_tail(&page->lru, &pl->free_list); - ++pl->num_pages_free; - } - pl->room = c->room; - if (!list_empty(&pl->head)) { - page = list_entry(pl->head.prev, struct page, lru); - pl->mapped_tail = kmap(page); - } - return 0; -} -EXPORT_SYMBOL(ceph_pagelist_truncate); diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c index 64305e7056a1c738ef178d59544822af8ce49ea4..4509757d8b3be6ff49554d4110a25fc4ad991ad6 100644 --- a/net/ceph/pagevec.c +++ b/net/ceph/pagevec.c @@ -55,58 +55,6 @@ struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags) } EXPORT_SYMBOL(ceph_alloc_page_vector); -/* - * copy user data into a page vector - */ -int ceph_copy_user_to_page_vector(struct page **pages, - const void __user *data, - loff_t off, size_t len) -{ - int i = 0; - int po = off & ~PAGE_MASK; - int left = len; - int l, bad; - - while (left > 0) { - l = min_t(int, PAGE_SIZE-po, left); - bad = copy_from_user(page_address(pages[i]) + po, data, l); - if (bad == l) - return -EFAULT; - data += l - bad; - left -= l - bad; - po += l - bad; - if (po == PAGE_SIZE) { - po = 0; - i++; - } - } - return len; -} -EXPORT_SYMBOL(ceph_copy_user_to_page_vector); - -void ceph_copy_to_page_vector(struct page **pages, - const void *data, - loff_t off, size_t len) -{ - int i = 0; - size_t po = off & ~PAGE_MASK; - size_t left = len; - - while (left > 0) { - size_t l = min_t(size_t, PAGE_SIZE-po, left); - - memcpy(page_address(pages[i]) + po, data, l); - data += l; - left -= l; - po += l; - if (po == PAGE_SIZE) { - po = 0; - i++; - } - } -} -EXPORT_SYMBOL(ceph_copy_to_page_vector); - void ceph_copy_from_page_vector(struct page **pages, void *data, loff_t off, size_t len) diff --git a/net/core/dev.c b/net/core/dev.c index 13d00fc10f55998077cb643a2f6e3c171974589d..45a8c3dd4a64839c403dec5e3f763dfa2f591415 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6557,18 +6557,22 @@ static void __napi_hash_add_with_id(struct napi_struct *napi, static void napi_hash_add_with_id(struct napi_struct *napi, unsigned int napi_id) { - spin_lock(&napi_hash_lock); + unsigned long flags; + + spin_lock_irqsave(&napi_hash_lock, flags); WARN_ON_ONCE(napi_by_id(napi_id)); __napi_hash_add_with_id(napi, napi_id); - spin_unlock(&napi_hash_lock); + spin_unlock_irqrestore(&napi_hash_lock, flags); } static void napi_hash_add(struct napi_struct *napi) { + unsigned long flags; + if (test_bit(NAPI_STATE_NO_BUSY_POLL, &napi->state)) return; - spin_lock(&napi_hash_lock); + spin_lock_irqsave(&napi_hash_lock, flags); /* 0..NR_CPUS range is reserved for sender_cpu use */ do { @@ -6578,7 +6582,7 @@ static void napi_hash_add(struct napi_struct *napi) __napi_hash_add_with_id(napi, napi_gen_id); - spin_unlock(&napi_hash_lock); + spin_unlock_irqrestore(&napi_hash_lock, flags); } /* Warning : caller is responsible to make sure rcu grace period @@ -6586,11 +6590,13 @@ static void napi_hash_add(struct napi_struct *napi) */ static void napi_hash_del(struct napi_struct *napi) { - spin_lock(&napi_hash_lock); + unsigned long flags; + + spin_lock_irqsave(&napi_hash_lock, flags); hlist_del_init_rcu(&napi->napi_hash_node); - spin_unlock(&napi_hash_lock); + spin_unlock_irqrestore(&napi_hash_lock, flags); } static enum hrtimer_restart napi_watchdog(struct hrtimer *timer) diff --git a/net/core/link_watch.c b/net/core/link_watch.c index ab150641142aa1545c71fc5d3b11db33c70cf437..1b4d39e38084272269a51503c217fc1e5a1326eb 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c @@ -45,9 +45,14 @@ static unsigned int default_operstate(const struct net_device *dev) int iflink = dev_get_iflink(dev); struct net_device *peer; - if (iflink == dev->ifindex) + /* If called from netdev_run_todo()/linkwatch_sync_dev(), + * dev_net(dev) can be already freed, and RTNL is not held. + */ + if (dev->reg_state == NETREG_UNREGISTERED || + iflink == dev->ifindex) return IF_OPER_DOWN; + ASSERT_RTNL(); peer = __dev_get_by_index(dev_net(dev), iflink); if (!peer) return IF_OPER_DOWN; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 58df76fe408a4677db52a3c1f94674119dc4c925..ab5f201bf0ab41b463175f501e8560b4d64d9b0a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -3746,6 +3746,7 @@ static int rtnl_group_changelink(const struct sk_buff *skb, static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm, const struct rtnl_link_ops *ops, struct net *tgt_net, struct net *link_net, + struct net *peer_net, const struct nlmsghdr *nlh, struct nlattr **tb, struct nlattr **data, struct netlink_ext_ack *extack) @@ -3776,8 +3777,13 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm, dev->ifindex = ifm->ifi_index; + if (link_net) + net = link_net; + if (peer_net) + net = peer_net; + if (ops->newlink) - err = ops->newlink(link_net ? : net, dev, tb, data, extack); + err = ops->newlink(net, dev, tb, data, extack); else err = register_netdevice(dev); if (err < 0) { @@ -3812,40 +3818,33 @@ out_unregister: goto out; } -static int rtnl_add_peer_net(struct rtnl_nets *rtnl_nets, - const struct rtnl_link_ops *ops, - struct nlattr *data[], - struct netlink_ext_ack *extack) +static struct net *rtnl_get_peer_net(const struct rtnl_link_ops *ops, + struct nlattr *data[], + struct netlink_ext_ack *extack) { struct nlattr *tb[IFLA_MAX + 1]; - struct net *net; int err; if (!data || !data[ops->peer_type]) - return 0; + return NULL; err = rtnl_nla_parse_ifinfomsg(tb, data[ops->peer_type], extack); if (err < 0) - return err; + return ERR_PTR(err); if (ops->validate) { err = ops->validate(tb, NULL, extack); if (err < 0) - return err; + return ERR_PTR(err); } - net = rtnl_link_get_net_ifla(tb); - if (IS_ERR(net)) - return PTR_ERR(net); - if (net) - rtnl_nets_add(rtnl_nets, net); - - return 0; + return rtnl_link_get_net_ifla(tb); } static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, const struct rtnl_link_ops *ops, struct net *tgt_net, struct net *link_net, + struct net *peer_net, struct rtnl_newlink_tbs *tbs, struct nlattr **data, struct netlink_ext_ack *extack) @@ -3894,14 +3893,15 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, return -EOPNOTSUPP; } - return rtnl_newlink_create(skb, ifm, ops, tgt_net, link_net, nlh, tb, data, extack); + return rtnl_newlink_create(skb, ifm, ops, tgt_net, link_net, peer_net, nlh, + tb, data, extack); } static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack) { + struct net *tgt_net, *link_net = NULL, *peer_net = NULL; struct nlattr **tb, **linkinfo, **data = NULL; - struct net *tgt_net, *link_net = NULL; struct rtnl_link_ops *ops = NULL; struct rtnl_newlink_tbs *tbs; struct rtnl_nets rtnl_nets; @@ -3971,9 +3971,11 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, } if (ops->peer_type) { - ret = rtnl_add_peer_net(&rtnl_nets, ops, data, extack); - if (ret < 0) + peer_net = rtnl_get_peer_net(ops, data, extack); + if (IS_ERR(peer_net)) goto put_ops; + if (peer_net) + rtnl_nets_add(&rtnl_nets, peer_net); } } @@ -4004,7 +4006,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, } rtnl_nets_lock(&rtnl_nets); - ret = __rtnl_newlink(skb, nlh, ops, tgt_net, link_net, tbs, data, extack); + ret = __rtnl_newlink(skb, nlh, ops, tgt_net, link_net, peer_net, tbs, data, extack); rtnl_nets_unlock(&rtnl_nets); put_net: diff --git a/net/dccp/feat.c b/net/dccp/feat.c index 54086bb05c42cd02692d4f7cf6cf63a5d1d6b006..f7554dcdaaba932111bf27069897031b0121a229 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -1166,8 +1166,12 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt, goto not_valid_or_not_known; } - return dccp_feat_push_confirm(fn, feat, local, &fval); + if (dccp_feat_push_confirm(fn, feat, local, &fval)) { + kfree(fval.sp.vec); + return DCCP_RESET_CODE_TOO_BUSY; + } + return 0; } else if (entry->state == FEAT_UNSTABLE) { /* 6.6.2 */ return 0; } diff --git a/net/ethtool/bitset.c b/net/ethtool/bitset.c index 0515d6604b3b9d641e96e1ad688d217c123c997b..f0883357d12e52745fc74b301342fde41f07d92b 100644 --- a/net/ethtool/bitset.c +++ b/net/ethtool/bitset.c @@ -425,12 +425,32 @@ static int ethnl_parse_bit(unsigned int *index, bool *val, unsigned int nbits, return 0; } +/** + * ethnl_bitmap32_equal() - Compare two bitmaps + * @map1: first bitmap + * @map2: second bitmap + * @nbits: bit size to compare + * + * Return: true if first @nbits are equal, false if not + */ +static bool ethnl_bitmap32_equal(const u32 *map1, const u32 *map2, + unsigned int nbits) +{ + if (memcmp(map1, map2, nbits / 32 * sizeof(u32))) + return false; + if (nbits % 32 == 0) + return true; + return !((map1[nbits / 32] ^ map2[nbits / 32]) & + ethnl_lower_bits(nbits % 32)); +} + static int ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, const struct nlattr *attr, struct nlattr **tb, ethnl_string_array_t names, struct netlink_ext_ack *extack, bool *mod) { + u32 *saved_bitmap = NULL; struct nlattr *bit_attr; bool no_mask; int rem; @@ -448,8 +468,20 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, } no_mask = tb[ETHTOOL_A_BITSET_NOMASK]; - if (no_mask) - ethnl_bitmap32_clear(bitmap, 0, nbits, mod); + if (no_mask) { + unsigned int nwords = DIV_ROUND_UP(nbits, 32); + unsigned int nbytes = nwords * sizeof(u32); + bool dummy; + + /* The bitmap size is only the size of the map part without + * its mask part. + */ + saved_bitmap = kcalloc(nwords, sizeof(u32), GFP_KERNEL); + if (!saved_bitmap) + return -ENOMEM; + memcpy(saved_bitmap, bitmap, nbytes); + ethnl_bitmap32_clear(bitmap, 0, nbits, &dummy); + } nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) { bool old_val, new_val; @@ -458,22 +490,30 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, if (nla_type(bit_attr) != ETHTOOL_A_BITSET_BITS_BIT) { NL_SET_ERR_MSG_ATTR(extack, bit_attr, "only ETHTOOL_A_BITSET_BITS_BIT allowed in ETHTOOL_A_BITSET_BITS"); + kfree(saved_bitmap); return -EINVAL; } ret = ethnl_parse_bit(&idx, &new_val, nbits, bit_attr, no_mask, names, extack); - if (ret < 0) + if (ret < 0) { + kfree(saved_bitmap); return ret; + } old_val = bitmap[idx / 32] & ((u32)1 << (idx % 32)); if (new_val != old_val) { if (new_val) bitmap[idx / 32] |= ((u32)1 << (idx % 32)); else bitmap[idx / 32] &= ~((u32)1 << (idx % 32)); - *mod = true; + if (!no_mask) + *mod = true; } } + if (no_mask && !ethnl_bitmap32_equal(saved_bitmap, bitmap, nbits)) + *mod = true; + + kfree(saved_bitmap); return 0; } diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 61df8ce44379de8ba54c9818eec6c35c7fe80a48..7bb94875a7ec87b3e2d882cb5df2416b9fad9d9d 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -993,7 +993,8 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, return rc; /* Nonzero ring with RSS only makes sense if NIC adds them together */ - if (info.flow_type & FLOW_RSS && !ops->cap_rss_rxnfc_adds && + if (cmd == ETHTOOL_SRXCLSRLINS && info.flow_type & FLOW_RSS && + !ops->cap_rss_rxnfc_adds && ethtool_get_flow_spec_ring(info.fs.ring_cookie)) return -EINVAL; diff --git a/net/handshake/handshake-test.c b/net/handshake/handshake-test.c index 34fd1d9b2db861de15f7ce68828abedbf6bc771c..55442b2f518afbc2a845b4108cbcabd27f8d17fc 100644 --- a/net/handshake/handshake-test.c +++ b/net/handshake/handshake-test.c @@ -17,7 +17,7 @@ #include #include "handshake.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static int test_accept_func(struct handshake_req *req, struct genl_info *info, int fd) diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 31a416ee21ad904f68c9f1c99110153b9236ab07..03eadd6c51fd1f80f8c2fd0889625d5da79d11f6 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -246,20 +246,22 @@ static const struct header_ops hsr_header_ops = { .parse = eth_header_parse, }; -static struct sk_buff *hsr_init_skb(struct hsr_port *master) +static struct sk_buff *hsr_init_skb(struct hsr_port *master, int extra) { struct hsr_priv *hsr = master->hsr; struct sk_buff *skb; int hlen, tlen; + int len; hlen = LL_RESERVED_SPACE(master->dev); tlen = master->dev->needed_tailroom; + len = sizeof(struct hsr_sup_tag) + sizeof(struct hsr_sup_payload); /* skb size is same for PRP/HSR frames, only difference * being, for PRP it is a trailer and for HSR it is a - * header + * header. + * RedBox might use @extra more bytes. */ - skb = dev_alloc_skb(sizeof(struct hsr_sup_tag) + - sizeof(struct hsr_sup_payload) + hlen + tlen); + skb = dev_alloc_skb(len + extra + hlen + tlen); if (!skb) return skb; @@ -295,6 +297,7 @@ static void send_hsr_supervision_frame(struct hsr_port *port, struct hsr_sup_tlv *hsr_stlv; struct hsr_sup_tag *hsr_stag; struct sk_buff *skb; + int extra = 0; *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); if (hsr->announce_count < 3 && hsr->prot_version == 0) { @@ -303,7 +306,11 @@ static void send_hsr_supervision_frame(struct hsr_port *port, hsr->announce_count++; } - skb = hsr_init_skb(port); + if (hsr->redbox) + extra = sizeof(struct hsr_sup_tlv) + + sizeof(struct hsr_sup_payload); + + skb = hsr_init_skb(port, extra); if (!skb) { netdev_warn_once(port->dev, "HSR: Could not send supervision frame\n"); return; @@ -362,7 +369,7 @@ static void send_prp_supervision_frame(struct hsr_port *master, struct hsr_sup_tag *hsr_stag; struct sk_buff *skb; - skb = hsr_init_skb(master); + skb = hsr_init_skb(master, 0); if (!skb) { netdev_warn_once(master->dev, "PRP: Could not send supervision frame\n"); return; diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index aa6acebc7c1ef6547451329fa23dafdc5443a5ba..87bb3a91598ee96b825f7aaff53aafb32ffe4f95 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -700,6 +700,8 @@ static int fill_frame_info(struct hsr_frame_info *frame, frame->is_vlan = true; if (frame->is_vlan) { + if (skb->mac_len < offsetofend(struct hsr_vlan_ethhdr, vlanhdr)) + return -EINVAL; vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; } diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 4f088fa1c2f2cbb5a6e5c13de3f47847baa04d66..963a89ae9c26e8b462de57e4af981c6c46061052 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -517,6 +517,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4, if (!IS_ERR(dst)) { if (rt != rt2) return rt; + if (inet_addr_type_dev_table(net, route_lookup_dev, + fl4->daddr) == RTN_LOCAL) + return rt; } else if (PTR_ERR(dst) == -EPERM) { rt = NULL; } else { diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index c5b8ec5c0a8c041e67554a3736ef624a155f6a99..99d8faa508e5325c653c920855a52f24b661618c 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -122,7 +122,7 @@ static void ipmr_expire_process(struct timer_list *t); static bool ipmr_can_free_table(struct net *net) { - return !check_net(net) || !net->ipv4.mr_rules_ops; + return !check_net(net) || !net_initialized(net); } static struct mr_table *ipmr_mr_table_iter(struct net *net, diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index bb1fe1ba867ac3ed8610ceb9fef7e74cd465b3ea..7121d8573928cbf6840b3361b62f4812d365a30b 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -326,6 +326,10 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) tcptw->tw_last_oow_ack_time = 0; tcptw->tw_tx_delay = tp->tcp_tx_delay; tw->tw_txhash = sk->sk_txhash; + tw->tw_tx_queue_mapping = sk->sk_tx_queue_mapping; +#ifdef CONFIG_SOCK_RX_QUEUE_MAPPING + tw->tw_rx_queue_mapping = sk->sk_rx_queue_mapping; +#endif #if IS_ENABLED(CONFIG_IPV6) if (tw->tw_family == PF_INET6) { struct ipv6_pinfo *np = inet6_sk(sk); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 6a01905d379fdd5c1815c3a71694071f6e5e06d3..e8953e88efef987c5125094b3c7c7385fd7444ab 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1674,7 +1674,6 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb) struct sk_buff_head *list = &sk->sk_receive_queue; int rmem, err = -ENOMEM; spinlock_t *busy = NULL; - bool becomes_readable; int size, rcvbuf; /* Immediately drop when the receive queue is full. @@ -1715,19 +1714,12 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb) */ sock_skb_set_dropcount(sk, skb); - becomes_readable = skb_queue_empty(list); __skb_queue_tail(list, skb); spin_unlock(&list->lock); - if (!sock_flag(sk, SOCK_DEAD)) { - if (becomes_readable || - sk->sk_data_ready != sock_def_readable || - READ_ONCE(sk->sk_peek_off) >= 0) - INDIRECT_CALL_1(sk->sk_data_ready, - sock_def_readable, sk); - else - sk_wake_async_rcu(sk, SOCK_WAKE_WAITD, POLL_IN); - } + if (!sock_flag(sk, SOCK_DEAD)) + INDIRECT_CALL_1(sk->sk_data_ready, sock_def_readable, sk); + busylock_release(busy); return 0; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c489a1e6aec9a8b05a46bcf36424c30d73ebc8f0..0e765466d7f79ecc13316204c4ffc29c7ea3a71b 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4821,7 +4821,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, ifm->ifa_prefixlen, extack); } -static int modify_prefix_route(struct inet6_ifaddr *ifp, +static int modify_prefix_route(struct net *net, struct inet6_ifaddr *ifp, unsigned long expires, u32 flags, bool modify_peer) { @@ -4845,7 +4845,9 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, ifp->prefix_len, ifp->rt_priority, ifp->idev->dev, expires, flags, GFP_KERNEL); - } else { + return 0; + } + if (f6i != net->ipv6.fib6_null_entry) { table = f6i->fib6_table; spin_lock_bh(&table->tb6_lock); @@ -4858,9 +4860,8 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, } spin_unlock_bh(&table->tb6_lock); - - fib6_info_release(f6i); } + fib6_info_release(f6i); return 0; } @@ -4939,7 +4940,7 @@ static int inet6_addr_modify(struct net *net, struct inet6_ifaddr *ifp, int rc = -ENOENT; if (had_prefixroute) - rc = modify_prefix_route(ifp, expires, flags, false); + rc = modify_prefix_route(net, ifp, expires, flags, false); /* prefix route could have been deleted; if so restore it */ if (rc == -ENOENT) { @@ -4949,7 +4950,7 @@ static int inet6_addr_modify(struct net *net, struct inet6_ifaddr *ifp, } if (had_prefixroute && !ipv6_addr_any(&ifp->peer_addr)) - rc = modify_prefix_route(ifp, expires, flags, true); + rc = modify_prefix_route(net, ifp, expires, flags, true); if (rc == -ENOENT && !ipv6_addr_any(&ifp->peer_addr)) { addrconf_prefix_route(&ifp->peer_addr, ifp->prefix_len, diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 7f1902ac35862c96397e82eda0ee78d8748d88ef..578ff1336afeff7a9f468d54c8fc47fddcaedbbb 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -110,7 +110,7 @@ static void ipmr_expire_process(struct timer_list *t); static bool ip6mr_can_free_table(struct net *net) { - return !check_net(net) || !net->ipv6.mr6_rules_ops; + return !check_net(net) || !net_initialized(net); } static struct mr_table *ip6mr_mr_table_iter(struct net *net, diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 63d7681c929fca8f176f9f46f6365342150b26cc..67ff16c047180bfb3928d16226f5bf864e2361fb 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2780,10 +2780,10 @@ static void ip6_negative_advice(struct sock *sk, if (rt->rt6i_flags & RTF_CACHE) { rcu_read_lock(); if (rt6_check_expired(rt)) { - /* counteract the dst_release() in sk_dst_reset() */ - dst_hold(dst); + /* rt/dst can not be destroyed yet, + * because of rcu_read_lock() + */ sk_dst_reset(sk); - rt6_remove_exception_rt(rt); } rcu_read_unlock(); diff --git a/net/mac80211/tests/elems.c b/net/mac80211/tests/elems.c index a413ba29f7592398b526ee7befae664464bcb266..a53c55a879a8e930e2f812a01863b6ec88f55dd0 100644 --- a/net/mac80211/tests/elems.c +++ b/net/mac80211/tests/elems.c @@ -7,7 +7,7 @@ #include #include "../ieee80211_i.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static void mle_defrag(struct kunit *test) { diff --git a/net/mac80211/tests/mfp.c b/net/mac80211/tests/mfp.c index a8dc1601da6080b985ffba831e8b229ee067995d..58e675e0ed91c16c6adde91bb9920c29d153eecf 100644 --- a/net/mac80211/tests/mfp.c +++ b/net/mac80211/tests/mfp.c @@ -9,7 +9,7 @@ #include "../ieee80211_i.h" #include "../sta_info.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static const struct mfp_test_case { const char *desc; diff --git a/net/mac80211/tests/tpe.c b/net/mac80211/tests/tpe.c index dd63303a2985b96372957711cf3119094574d82d..c73b6c66bd5a4f0e9cd152252af96d94d3f9a6c1 100644 --- a/net/mac80211/tests/tpe.c +++ b/net/mac80211/tests/tpe.c @@ -7,7 +7,7 @@ #include #include "../ieee80211_i.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static struct ieee80211_channel chan6g_1 = { .band = NL80211_BAND_6GHZ, diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 61431690cbd5f195ca27a90661c3838189e2330d..cc20e6d56807c6b31d8beabc7f7d2617cad76c8a 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -104,14 +104,19 @@ find_set_type(const char *name, u8 family, u8 revision) static bool load_settype(const char *name) { + if (!try_module_get(THIS_MODULE)) + return false; + nfnl_unlock(NFNL_SUBSYS_IPSET); pr_debug("try to load ip_set_%s\n", name); if (request_module("ip_set_%s", name) < 0) { pr_warn("Can't find ip_set type %s\n", name); nfnl_lock(NFNL_SUBSYS_IPSET); + module_put(THIS_MODULE); return false; } nfnl_lock(NFNL_SUBSYS_IPSET); + module_put(THIS_MODULE); return true; } diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c index f100da4ba3bc3c6922547292dca47558ffcda066..a9fd1d3fc2cbfe1b2c00b0e62d0bba97ae85d919 100644 --- a/net/netfilter/ipvs/ip_vs_proto.c +++ b/net/netfilter/ipvs/ip_vs_proto.c @@ -340,7 +340,7 @@ void __net_exit ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs) int __init ip_vs_protocol_init(void) { - char protocols[64]; + char protocols[64] = { 0 }; #define REGISTER_PROTOCOL(p) \ do { \ register_ip_vs_protocol(p); \ @@ -348,8 +348,6 @@ int __init ip_vs_protocol_init(void) strcat(protocols, (p)->name); \ } while (0) - protocols[0] = '\0'; - protocols[2] = '\0'; #ifdef CONFIG_IP_VS_PROTO_TCP REGISTER_PROTOCOL(&ip_vs_protocol_tcp); #endif diff --git a/net/netfilter/nft_inner.c b/net/netfilter/nft_inner.c index 928312d01eb1d6028a2e5098a2044df0cafbefce..817ab978d24a19c32904a1861c390dc1dd99938d 100644 --- a/net/netfilter/nft_inner.c +++ b/net/netfilter/nft_inner.c @@ -210,35 +210,66 @@ static int nft_inner_parse(const struct nft_inner *priv, struct nft_pktinfo *pkt, struct nft_inner_tun_ctx *tun_ctx) { - struct nft_inner_tun_ctx ctx = {}; u32 off = pkt->inneroff; if (priv->flags & NFT_INNER_HDRSIZE && - nft_inner_parse_tunhdr(priv, pkt, &ctx, &off) < 0) + nft_inner_parse_tunhdr(priv, pkt, tun_ctx, &off) < 0) return -1; if (priv->flags & (NFT_INNER_LL | NFT_INNER_NH)) { - if (nft_inner_parse_l2l3(priv, pkt, &ctx, off) < 0) + if (nft_inner_parse_l2l3(priv, pkt, tun_ctx, off) < 0) return -1; } else if (priv->flags & NFT_INNER_TH) { - ctx.inner_thoff = off; - ctx.flags |= NFT_PAYLOAD_CTX_INNER_TH; + tun_ctx->inner_thoff = off; + tun_ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH; } - *tun_ctx = ctx; tun_ctx->type = priv->type; + tun_ctx->cookie = (unsigned long)pkt->skb; pkt->flags |= NFT_PKTINFO_INNER_FULL; return 0; } +static bool nft_inner_restore_tun_ctx(const struct nft_pktinfo *pkt, + struct nft_inner_tun_ctx *tun_ctx) +{ + struct nft_inner_tun_ctx *this_cpu_tun_ctx; + + local_bh_disable(); + this_cpu_tun_ctx = this_cpu_ptr(&nft_pcpu_tun_ctx); + if (this_cpu_tun_ctx->cookie != (unsigned long)pkt->skb) { + local_bh_enable(); + return false; + } + *tun_ctx = *this_cpu_tun_ctx; + local_bh_enable(); + + return true; +} + +static void nft_inner_save_tun_ctx(const struct nft_pktinfo *pkt, + const struct nft_inner_tun_ctx *tun_ctx) +{ + struct nft_inner_tun_ctx *this_cpu_tun_ctx; + + local_bh_disable(); + this_cpu_tun_ctx = this_cpu_ptr(&nft_pcpu_tun_ctx); + if (this_cpu_tun_ctx->cookie != tun_ctx->cookie) + *this_cpu_tun_ctx = *tun_ctx; + local_bh_enable(); +} + static bool nft_inner_parse_needed(const struct nft_inner *priv, const struct nft_pktinfo *pkt, - const struct nft_inner_tun_ctx *tun_ctx) + struct nft_inner_tun_ctx *tun_ctx) { if (!(pkt->flags & NFT_PKTINFO_INNER_FULL)) return true; + if (!nft_inner_restore_tun_ctx(pkt, tun_ctx)) + return true; + if (priv->type != tun_ctx->type) return true; @@ -248,27 +279,29 @@ static bool nft_inner_parse_needed(const struct nft_inner *priv, static void nft_inner_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { - struct nft_inner_tun_ctx *tun_ctx = this_cpu_ptr(&nft_pcpu_tun_ctx); const struct nft_inner *priv = nft_expr_priv(expr); + struct nft_inner_tun_ctx tun_ctx = {}; if (nft_payload_inner_offset(pkt) < 0) goto err; - if (nft_inner_parse_needed(priv, pkt, tun_ctx) && - nft_inner_parse(priv, (struct nft_pktinfo *)pkt, tun_ctx) < 0) + if (nft_inner_parse_needed(priv, pkt, &tun_ctx) && + nft_inner_parse(priv, (struct nft_pktinfo *)pkt, &tun_ctx) < 0) goto err; switch (priv->expr_type) { case NFT_INNER_EXPR_PAYLOAD: - nft_payload_inner_eval((struct nft_expr *)&priv->expr, regs, pkt, tun_ctx); + nft_payload_inner_eval((struct nft_expr *)&priv->expr, regs, pkt, &tun_ctx); break; case NFT_INNER_EXPR_META: - nft_meta_inner_eval((struct nft_expr *)&priv->expr, regs, pkt, tun_ctx); + nft_meta_inner_eval((struct nft_expr *)&priv->expr, regs, pkt, &tun_ctx); break; default: WARN_ON_ONCE(1); goto err; } + nft_inner_save_tun_ctx(pkt, &tun_ctx); + return; err: regs->verdict.code = NFT_BREAK; diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c index 65bd291318f2ac4a813feaadbf06e09bbca044e3..8bfac4185ac797fa69a0e5c92e690d92db4c097a 100644 --- a/net/netfilter/nft_set_hash.c +++ b/net/netfilter/nft_set_hash.c @@ -24,11 +24,13 @@ struct nft_rhash { struct rhashtable ht; struct delayed_work gc_work; + u32 wq_gc_seq; }; struct nft_rhash_elem { struct nft_elem_priv priv; struct rhash_head node; + u32 wq_gc_seq; struct nft_set_ext ext; }; @@ -338,6 +340,10 @@ static void nft_rhash_gc(struct work_struct *work) if (!gc) goto done; + /* Elements never collected use a zero gc worker sequence number. */ + if (unlikely(++priv->wq_gc_seq == 0)) + priv->wq_gc_seq++; + rhashtable_walk_enter(&priv->ht, &hti); rhashtable_walk_start(&hti); @@ -355,6 +361,14 @@ static void nft_rhash_gc(struct work_struct *work) goto try_later; } + /* rhashtable walk is unstable, already seen in this gc run? + * Then, skip this element. In case of (unlikely) sequence + * wraparound and stale element wq_gc_seq, next gc run will + * just find this expired element. + */ + if (he->wq_gc_seq == priv->wq_gc_seq) + continue; + if (nft_set_elem_is_dead(&he->ext)) goto dead_elem; @@ -371,6 +385,8 @@ dead_elem: if (!gc) goto try_later; + /* annotate gc sequence for this attempt. */ + he->wq_gc_seq = priv->wq_gc_seq; nft_trans_gc_elem_add(gc, he); } diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c index f5da0c1775f2e7fd5ba108b70facc06cbf7180e1..35d0409b009501661d8b668889efeb100b0db737 100644 --- a/net/netfilter/nft_socket.c +++ b/net/netfilter/nft_socket.c @@ -68,7 +68,7 @@ static noinline int nft_socket_cgroup_subtree_level(void) cgroup_put(cgrp); - if (WARN_ON_ONCE(level > 255)) + if (level > 255) return -ERANGE; if (WARN_ON_ONCE(level < 0)) diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c index f7b0286d106ac1368baceb7809348213c266f34f..8a80fd76fe45b20e703321c106baf2fc8fe92756 100644 --- a/net/netfilter/xt_LED.c +++ b/net/netfilter/xt_LED.c @@ -96,7 +96,9 @@ static int led_tg_check(const struct xt_tgchk_param *par) struct xt_led_info_internal *ledinternal; int err; - if (ledinfo->id[0] == '\0') + /* Bail out if empty string or not a string at all. */ + if (ledinfo->id[0] == '\0' || + !memchr(ledinfo->id, '\0', sizeof(ledinfo->id))) return -EINVAL; mutex_lock(&xt_led_mutex); diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index a8e21060112ffdd162676aaa483d4ede71a1efda..9fa019e0dcadd475825921339d35905e047ff540 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c @@ -203,7 +203,7 @@ MODULE_DEVICE_TABLE(of, rfkill_of_match); static struct platform_driver rfkill_gpio_driver = { .probe = rfkill_gpio_probe, - .remove_new = rfkill_gpio_remove, + .remove = rfkill_gpio_remove, .driver = { .name = "rfkill_gpio", .acpi_match_table = ACPI_PTR(rfkill_acpi_match), diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index e280c27cb9f9af455fa049bab237942f2266d026..1008ec8a464c9333a3d978083aa40f91733cb89e 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1369,7 +1369,6 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key, int err; md = (struct erspan_metadata *)&key->enc_opts.data[key->enc_opts.len]; - memset(md, 0xff, sizeof(*md)); md->version = 1; if (!depth) @@ -1398,9 +1397,9 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key, NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index"); return -EINVAL; } + memset(&md->u.index, 0xff, sizeof(md->u.index)); if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]; - memset(&md->u, 0x00, sizeof(md->u)); md->u.index = nla_get_be32(nla); } } else if (md->version == 2) { @@ -1409,10 +1408,12 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key, NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid"); return -EINVAL; } + md->u.md2.dir = 1; if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]; md->u.md2.dir = nla_get_u8(nla); } + set_hwid(&md->u.md2, 0xff); if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]; set_hwid(&md->u.md2, nla_get_u8(nla)); diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index f2f9b75008bb059d17ced6c405dbc5071da392a3..8d8b2db4653c0c9f271f9c1953e8c61175d8f76b 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -1525,7 +1525,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) b->backlogs[idx] -= len; b->tin_backlog -= len; sch->qstats.backlog -= len; - qdisc_tree_reduce_backlog(sch, 1, len); flow->dropped++; b->tin_dropped++; @@ -1536,6 +1535,7 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) __qdisc_drop(skb, to_free); sch->q.qlen--; + qdisc_tree_reduce_backlog(sch, 1, len); cake_heapify(q, 0); diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 1e940ad0d2fad122508fdc178fb7a5bcd6b80c6e..59e7bdf5063e8ce75d69b3127512985ae8cc499a 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -123,10 +123,10 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx, if (idx == q->tail) choke_zap_tail_holes(q); + --sch->q.qlen; qdisc_qstats_backlog_dec(sch, skb); qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb)); qdisc_drop(skb, sch, to_free); - --sch->q.qlen; } struct choke_skb_cb { diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index f1d09183ae632d2e950608877fcbdb9e86d0ec8e..dc26b22d53c73461c6f6d64f768136ad3f334143 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -208,7 +208,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch, struct tbf_sched_data *q = qdisc_priv(sch); struct sk_buff *segs, *nskb; netdev_features_t features = netif_skb_features(skb); - unsigned int len = 0, prev_len = qdisc_pkt_len(skb); + unsigned int len = 0, prev_len = qdisc_pkt_len(skb), seg_len; int ret, nb; segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); @@ -219,21 +219,27 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch, nb = 0; skb_list_walk_safe(segs, segs, nskb) { skb_mark_not_on_list(segs); - qdisc_skb_cb(segs)->pkt_len = segs->len; - len += segs->len; + seg_len = segs->len; + qdisc_skb_cb(segs)->pkt_len = seg_len; ret = qdisc_enqueue(segs, q->qdisc, to_free); if (ret != NET_XMIT_SUCCESS) { if (net_xmit_drop_count(ret)) qdisc_qstats_drop(sch); } else { nb++; + len += seg_len; } } sch->q.qlen += nb; - if (nb > 1) + sch->qstats.backlog += len; + if (nb > 0) { qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len); - consume_skb(skb); - return nb > 0 ? NET_XMIT_SUCCESS : NET_XMIT_DROP; + consume_skb(skb); + return NET_XMIT_SUCCESS; + } + + kfree_skb(skb); + return NET_XMIT_DROP; } static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch, diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 9d76e902fd770f5b10d9cd8ae977f1d80552066f..9e6c69d18581ce6c31d3d357ed2cb29bde6e13a7 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -383,6 +383,7 @@ void smc_sk_init(struct net *net, struct sock *sk, int protocol) smc->limit_smc_hs = net->smc.limit_smc_hs; smc->use_fallback = false; /* assume rdma capability first */ smc->fallback_rsn = 0; + smc_close_init(smc); } static struct sock *smc_sock_alloc(struct net *net, struct socket *sock, @@ -1299,7 +1300,6 @@ static int smc_connect_rdma(struct smc_sock *smc, goto connect_abort; } - smc_close_init(smc); smc_rx_init(smc); if (ini->first_contact_local) { @@ -1435,7 +1435,6 @@ static int smc_connect_ism(struct smc_sock *smc, goto connect_abort; } } - smc_close_init(smc); smc_rx_init(smc); smc_tx_init(smc); @@ -1901,6 +1900,7 @@ static void smc_listen_out(struct smc_sock *new_smc) if (tcp_sk(new_smc->clcsock->sk)->syn_smc) atomic_dec(&lsmc->queued_smc_hs); + release_sock(newsmcsk); /* lock in smc_listen_work() */ if (lsmc->sk.sk_state == SMC_LISTEN) { lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING); smc_accept_enqueue(&lsmc->sk, newsmcsk); @@ -2422,6 +2422,7 @@ static void smc_listen_work(struct work_struct *work) u8 accept_version; int rc = 0; + lock_sock(&new_smc->sk); /* release in smc_listen_out() */ if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN) return smc_listen_out_err(new_smc); @@ -2479,7 +2480,6 @@ static void smc_listen_work(struct work_struct *work) goto out_decl; mutex_lock(&smc_server_lgr_pending); - smc_close_init(new_smc); smc_rx_init(new_smc); smc_tx_init(new_smc); diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index 85625e3f3814e07639e614517226ce9d2b572088..a5bff02cd7ba48c75a6d270b6584c0f23cb71380 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -17,7 +17,7 @@ #include "gss_krb5_internal.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); struct gss_krb5_test_param { const char *desc; diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index b785425c33151445252510fd3a428dd0bf7976aa..95397677673bb0cb4a2ffc5402d196b3227818ac 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1551,6 +1551,10 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, newlen = error; if (protocol == IPPROTO_TCP) { + __netns_tracker_free(net, &sock->sk->ns_tracker, false); + sock->sk->sk_net_refcnt = 1; + get_net_track(net, &sock->sk->ns_tracker, GFP_KERNEL); + sock_inuse_add(net, 1); if ((error = kernel_listen(sock, 64)) < 0) goto bummer; } diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 1326fbf45a3479b5b3668487842f945ca5f2cc84..c60936d8cef71b3eb7937a3ec8dd8a4edbaaff10 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1198,6 +1198,7 @@ static void xs_sock_reset_state_flags(struct rpc_xprt *xprt) clear_bit(XPRT_SOCK_WAKE_WRITE, &transport->sock_state); clear_bit(XPRT_SOCK_WAKE_DISCONNECT, &transport->sock_state); clear_bit(XPRT_SOCK_NOSPACE, &transport->sock_state); + clear_bit(XPRT_SOCK_UPD_TIMEOUT, &transport->sock_state); } static void xs_run_error_worker(struct sock_xprt *transport, unsigned int nr) @@ -1278,6 +1279,7 @@ static void xs_reset_transport(struct sock_xprt *transport) transport->file = NULL; sk->sk_user_data = NULL; + sk->sk_sndtimeo = 0; xs_restore_old_callbacks(transport, sk); xprt_clear_connected(xprt); @@ -1939,6 +1941,13 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt, goto out; } + if (protocol == IPPROTO_TCP) { + __netns_tracker_free(xprt->xprt_net, &sock->sk->ns_tracker, false); + sock->sk->sk_net_refcnt = 1; + get_net_track(xprt->xprt_net, &sock->sk->ns_tracker, GFP_KERNEL); + sock_inuse_add(xprt->xprt_net, 1); + } + filp = sock_alloc_file(sock, O_NONBLOCK, NULL); if (IS_ERR(filp)) return ERR_CAST(filp); @@ -2614,11 +2623,10 @@ static int xs_tls_handshake_sync(struct rpc_xprt *lower_xprt, struct xprtsec_par rc = wait_for_completion_interruptible_timeout(&lower_transport->handshake_done, XS_TLS_HANDSHAKE_TO); if (rc <= 0) { - if (!tls_handshake_cancel(sk)) { - if (rc == 0) - rc = -ETIMEDOUT; - goto out_put_xprt; - } + tls_handshake_cancel(sk); + if (rc == 0) + rc = -ETIMEDOUT; + goto out_put_xprt; } rc = lower_transport->xprt_err; diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index 439f7553997728ae8d264d370178f5bdd8b7aaf8..b7e25e7e9933b69aa6a3364e3287c358b7ac9421 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c @@ -814,10 +814,10 @@ static void cleanup_bearer(struct work_struct *work) kfree_rcu(rcast, rcu); } - atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); dst_cache_destroy(&ub->rcast.dst_cache); udp_tunnel_sock_release(ub->ubsock); synchronize_net(); + atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); kfree(ub); } diff --git a/net/wireless/tests/chan.c b/net/wireless/tests/chan.c index 74bbee25085f8d98690c5aed52810d56c10b0d3c..7b97b731993ca72bcd4efed7cc6eeb407fcec6dd 100644 --- a/net/wireless/tests/chan.c +++ b/net/wireless/tests/chan.c @@ -7,7 +7,7 @@ #include #include -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); static struct ieee80211_channel chan_6ghz_1 = { .band = NL80211_BAND_6GHZ, diff --git a/net/wireless/tests/scan.c b/net/wireless/tests/scan.c index 9f458be71659518fb77d3c4feecbdc89cc6bacd0..e12f620b5f424140e58f1a7b5236ba7dc2e2d209 100644 --- a/net/wireless/tests/scan.c +++ b/net/wireless/tests/scan.c @@ -14,7 +14,7 @@ /* mac80211 helpers for element building */ #include "../../mac80211/ieee80211_i.h" -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); struct test_elem { u8 id; diff --git a/rust/Makefile b/rust/Makefile index 01cf8e6ba3b3bdf711ac7c8e1c4dc24e44de059a..9da9042fd62796ddb852f4bf7cf46d70f0b8ca97 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -372,8 +372,8 @@ rust-analyzer: $(Q)$(srctree)/scripts/generate_rust_analyzer.py \ --cfgs='core=$(core-cfgs)' \ $(realpath $(srctree)) $(realpath $(objtree)) \ - $(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \ - $(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json + $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ + > rust-project.json redirect-intrinsics = \ __addsf3 __eqsf2 __extendsfdf2 __gesf2 __lesf2 __ltsf2 __mulsf3 __nesf2 __truncdfsf2 __unordsf2 \ diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index 54bc8a8c5c88a84996f0bd980fb26e8b3f85cbed..5c4dfe22f41a5a106330e8c43ffbd342c69c4e0b 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_disk.rs index 708125dce96a934f32caab44d5e6cff14c4321a9..798c4ae0bdedd58221b5851a630c0e1052e0face 100644 --- a/rust/kernel/block/mq/gen_disk.rs +++ b/rust/kernel/block/mq/gen_disk.rs @@ -45,7 +45,7 @@ impl GenDiskBuilder { /// Validate block size by verifying that it is between 512 and `PAGE_SIZE`, /// and that it is a power of two. - fn validate_block_size(size: u32) -> Result<()> { + fn validate_block_size(size: u32) -> Result { if !(512..=bindings::PAGE_SIZE as u32).contains(&size) || !size.is_power_of_two() { Err(error::code::EINVAL) } else { diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index c8199ee079eff10db8ae26793be6e3410c123197..c926e0c2b8528c289ebd0f9849c04e1b6eec30a4 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -8,7 +8,10 @@ use crate::{ bindings, types::{ARef, Opaque}, }; -use core::ptr; +use core::{fmt, ptr}; + +#[cfg(CONFIG_PRINTK)] +use crate::c_str; /// A reference-counted device. /// @@ -73,6 +76,110 @@ impl Device { // SAFETY: Guaranteed by the safety requirements of the function. unsafe { &*ptr.cast() } } + + /// Prints an emergency-level message (level 0) prefixed with device information. + /// + /// More details are available from [`dev_emerg`]. + /// + /// [`dev_emerg`]: crate::dev_emerg + pub fn pr_emerg(&self, args: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_EMERG, args) }; + } + + /// Prints an alert-level message (level 1) prefixed with device information. + /// + /// More details are available from [`dev_alert`]. + /// + /// [`dev_alert`]: crate::dev_alert + pub fn pr_alert(&self, args: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_ALERT, args) }; + } + + /// Prints a critical-level message (level 2) prefixed with device information. + /// + /// More details are available from [`dev_crit`]. + /// + /// [`dev_crit`]: crate::dev_crit + pub fn pr_crit(&self, args: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_CRIT, args) }; + } + + /// Prints an error-level message (level 3) prefixed with device information. + /// + /// More details are available from [`dev_err`]. + /// + /// [`dev_err`]: crate::dev_err + pub fn pr_err(&self, args: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_ERR, args) }; + } + + /// Prints a warning-level message (level 4) prefixed with device information. + /// + /// More details are available from [`dev_warn`]. + /// + /// [`dev_warn`]: crate::dev_warn + pub fn pr_warn(&self, args: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_WARNING, args) }; + } + + /// Prints a notice-level message (level 5) prefixed with device information. + /// + /// More details are available from [`dev_notice`]. + /// + /// [`dev_notice`]: crate::dev_notice + pub fn pr_notice(&self, args: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_NOTICE, args) }; + } + + /// Prints an info-level message (level 6) prefixed with device information. + /// + /// More details are available from [`dev_info`]. + /// + /// [`dev_info`]: crate::dev_info + pub fn pr_info(&self, args: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_INFO, args) }; + } + + /// Prints a debug-level message (level 7) prefixed with device information. + /// + /// More details are available from [`dev_dbg`]. + /// + /// [`dev_dbg`]: crate::dev_dbg + pub fn pr_dbg(&self, args: fmt::Arguments<'_>) { + if cfg!(debug_assertions) { + // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. + unsafe { self.printk(bindings::KERN_DEBUG, args) }; + } + } + + /// Prints the provided message to the console. + /// + /// # Safety + /// + /// Callers must ensure that `klevel` is null-terminated; in particular, one of the + /// `KERN_*`constants, for example, `KERN_CRIT`, `KERN_ALERT`, etc. + #[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))] + unsafe fn printk(&self, klevel: &[u8], msg: fmt::Arguments<'_>) { + // SAFETY: `klevel` is null-terminated and one of the kernel constants. `self.as_raw` + // is valid because `self` is valid. The "%pA" format string expects a pointer to + // `fmt::Arguments`, which is what we're passing as the last argument. + #[cfg(CONFIG_PRINTK)] + unsafe { + bindings::_dev_printk( + klevel as *const _ as *const core::ffi::c_char, + self.as_raw(), + c_str!("%pA").as_char_ptr(), + &msg as *const _ as *const core::ffi::c_void, + ) + }; + } } // SAFETY: Instances of `Device` are always reference-counted. @@ -94,3 +201,213 @@ unsafe impl Send for Device {} // SAFETY: `Device` can be shared among threads because all immutable methods are protected by the // synchronization in `struct device`. unsafe impl Sync for Device {} + +#[doc(hidden)] +#[macro_export] +macro_rules! dev_printk { + ($method:ident, $dev:expr, $($f:tt)*) => { + { + ($dev).$method(core::format_args!($($f)*)); + } + } +} + +/// Prints an emergency-level message (level 0) prefixed with device information. +/// +/// This level should be used if the system is unusable. +/// +/// Equivalent to the kernel's `dev_emerg` macro. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_emerg!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_emerg { + ($($f:tt)*) => { $crate::dev_printk!(pr_emerg, $($f)*); } +} + +/// Prints an alert-level message (level 1) prefixed with device information. +/// +/// This level should be used if action must be taken immediately. +/// +/// Equivalent to the kernel's `dev_alert` macro. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_alert!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_alert { + ($($f:tt)*) => { $crate::dev_printk!(pr_alert, $($f)*); } +} + +/// Prints a critical-level message (level 2) prefixed with device information. +/// +/// This level should be used in critical conditions. +/// +/// Equivalent to the kernel's `dev_crit` macro. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_crit!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_crit { + ($($f:tt)*) => { $crate::dev_printk!(pr_crit, $($f)*); } +} + +/// Prints an error-level message (level 3) prefixed with device information. +/// +/// This level should be used in error conditions. +/// +/// Equivalent to the kernel's `dev_err` macro. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_err!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_err { + ($($f:tt)*) => { $crate::dev_printk!(pr_err, $($f)*); } +} + +/// Prints a warning-level message (level 4) prefixed with device information. +/// +/// This level should be used in warning conditions. +/// +/// Equivalent to the kernel's `dev_warn` macro. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_warn!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_warn { + ($($f:tt)*) => { $crate::dev_printk!(pr_warn, $($f)*); } +} + +/// Prints a notice-level message (level 5) prefixed with device information. +/// +/// This level should be used in normal but significant conditions. +/// +/// Equivalent to the kernel's `dev_notice` macro. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_notice!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_notice { + ($($f:tt)*) => { $crate::dev_printk!(pr_notice, $($f)*); } +} + +/// Prints an info-level message (level 6) prefixed with device information. +/// +/// This level should be used for informational messages. +/// +/// Equivalent to the kernel's `dev_info` macro. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_info!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_info { + ($($f:tt)*) => { $crate::dev_printk!(pr_info, $($f)*); } +} + +/// Prints a debug-level message (level 7) prefixed with device information. +/// +/// This level should be used for debug messages. +/// +/// Equivalent to the kernel's `dev_dbg` macro, except that it doesn't support dynamic debug yet. +/// +/// Mimics the interface of [`std::print!`]. More information about the syntax is available from +/// [`core::fmt`] and `alloc::format!`. +/// +/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html +/// +/// # Examples +/// +/// ``` +/// # use kernel::device::Device; +/// +/// fn example(dev: &Device) { +/// dev_dbg!(dev, "hello {}\n", "there"); +/// } +/// ``` +#[macro_export] +macro_rules! dev_dbg { + ($($f:tt)*) => { $crate::dev_printk!(pr_dbg, $($f)*); } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 04dbee70d3e66a256240c4fb5c36b2a05d07db03..e1065a7551a39e68d6379031d80d4be336e652a3 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -45,6 +45,7 @@ pub mod jump_label; #[cfg(CONFIG_KUNIT)] pub mod kunit; pub mod list; +pub mod miscdevice; #[cfg(CONFIG_NET)] pub mod net; pub mod page; @@ -92,6 +93,29 @@ pub trait Module: Sized + Sync + Send { fn init(module: &'static ThisModule) -> error::Result; } +/// A module that is pinned and initialised in-place. +pub trait InPlaceModule: Sync + Send { + /// Creates an initialiser for the module. + /// + /// It is called when the module is loaded. + fn init(module: &'static ThisModule) -> impl init::PinInit; +} + +impl InPlaceModule for T { + fn init(module: &'static ThisModule) -> impl init::PinInit { + let initer = move |slot: *mut Self| { + let m = ::init(module)?; + + // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`. + unsafe { slot.write(m) }; + Ok(()) + }; + + // SAFETY: On success, `initer` always fully initialises an instance of `Self`. + unsafe { init::pin_init_from_closure(initer) } + } +} + /// Equivalent to `THIS_MODULE` in the C API. /// /// C header: [`include/linux/init.h`](srctree/include/linux/init.h) diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs new file mode 100644 index 0000000000000000000000000000000000000000..7e2a79b3ae263659b7e0781c05cb130d10c8accb --- /dev/null +++ b/rust/kernel/miscdevice.rs @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Miscdevice support. +//! +//! C headers: [`include/linux/miscdevice.h`](srctree/include/linux/miscdevice.h). +//! +//! Reference: + +use crate::{ + bindings, + error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, + prelude::*, + str::CStr, + types::{ForeignOwnable, Opaque}, +}; +use core::{ + ffi::{c_int, c_long, c_uint, c_ulong}, + marker::PhantomData, + mem::MaybeUninit, + pin::Pin, +}; + +/// Options for creating a misc device. +#[derive(Copy, Clone)] +pub struct MiscDeviceOptions { + /// The name of the miscdevice. + pub name: &'static CStr, +} + +impl MiscDeviceOptions { + /// Create a raw `struct miscdev` ready for registration. + pub const fn into_raw(self) -> bindings::miscdevice { + // SAFETY: All zeros is valid for this C type. + let mut result: bindings::miscdevice = unsafe { MaybeUninit::zeroed().assume_init() }; + result.minor = bindings::MISC_DYNAMIC_MINOR as _; + result.name = self.name.as_char_ptr(); + result.fops = create_vtable::(); + result + } +} + +/// A registration of a miscdevice. +/// +/// # Invariants +/// +/// `inner` is a registered misc device. +#[repr(transparent)] +#[pin_data(PinnedDrop)] +pub struct MiscDeviceRegistration { + #[pin] + inner: Opaque, + _t: PhantomData, +} + +// SAFETY: It is allowed to call `misc_deregister` on a different thread from where you called +// `misc_register`. +unsafe impl Send for MiscDeviceRegistration {} +// SAFETY: All `&self` methods on this type are written to ensure that it is safe to call them in +// parallel. +unsafe impl Sync for MiscDeviceRegistration {} + +impl MiscDeviceRegistration { + /// Register a misc device. + pub fn register(opts: MiscDeviceOptions) -> impl PinInit { + try_pin_init!(Self { + inner <- Opaque::try_ffi_init(move |slot: *mut bindings::miscdevice| { + // SAFETY: The initializer can write to the provided `slot`. + unsafe { slot.write(opts.into_raw::()) }; + + // SAFETY: We just wrote the misc device options to the slot. The miscdevice will + // get unregistered before `slot` is deallocated because the memory is pinned and + // the destructor of this type deallocates the memory. + // INVARIANT: If this returns `Ok(())`, then the `slot` will contain a registered + // misc device. + to_result(unsafe { bindings::misc_register(slot) }) + }), + _t: PhantomData, + }) + } + + /// Returns a raw pointer to the misc device. + pub fn as_raw(&self) -> *mut bindings::miscdevice { + self.inner.get() + } +} + +#[pinned_drop] +impl PinnedDrop for MiscDeviceRegistration { + fn drop(self: Pin<&mut Self>) { + // SAFETY: We know that the device is registered by the type invariants. + unsafe { bindings::misc_deregister(self.inner.get()) }; + } +} + +/// Trait implemented by the private data of an open misc device. +#[vtable] +pub trait MiscDevice { + /// What kind of pointer should `Self` be wrapped in. + type Ptr: ForeignOwnable + Send + Sync; + + /// Called when the misc device is opened. + /// + /// The returned pointer will be stored as the private data for the file. + fn open() -> Result; + + /// Called when the misc device is released. + fn release(device: Self::Ptr) { + drop(device); + } + + /// Handler for ioctls. + /// + /// The `cmd` argument is usually manipulated using the utilties in [`kernel::ioctl`]. + /// + /// [`kernel::ioctl`]: mod@crate::ioctl + fn ioctl( + _device: ::Borrowed<'_>, + _cmd: u32, + _arg: usize, + ) -> Result { + kernel::build_error(VTABLE_DEFAULT_ERROR) + } + + /// Handler for ioctls. + /// + /// Used for 32-bit userspace on 64-bit platforms. + /// + /// This method is optional and only needs to be provided if the ioctl relies on structures + /// that have different layout on 32-bit and 64-bit userspace. If no implementation is + /// provided, then `compat_ptr_ioctl` will be used instead. + #[cfg(CONFIG_COMPAT)] + fn compat_ioctl( + _device: ::Borrowed<'_>, + _cmd: u32, + _arg: usize, + ) -> Result { + kernel::build_error(VTABLE_DEFAULT_ERROR) + } +} + +const fn create_vtable() -> &'static bindings::file_operations { + const fn maybe_fn(check: bool, func: T) -> Option { + if check { + Some(func) + } else { + None + } + } + + struct VtableHelper { + _t: PhantomData, + } + impl VtableHelper { + const VTABLE: bindings::file_operations = bindings::file_operations { + open: Some(fops_open::), + release: Some(fops_release::), + unlocked_ioctl: maybe_fn(T::HAS_IOCTL, fops_ioctl::), + #[cfg(CONFIG_COMPAT)] + compat_ioctl: if T::HAS_COMPAT_IOCTL { + Some(fops_compat_ioctl::) + } else if T::HAS_IOCTL { + Some(bindings::compat_ptr_ioctl) + } else { + None + }, + // SAFETY: All zeros is a valid value for `bindings::file_operations`. + ..unsafe { MaybeUninit::zeroed().assume_init() } + }; + } + + &VtableHelper::::VTABLE +} + +/// # Safety +/// +/// `file` and `inode` must be the file and inode for a file that is undergoing initialization. +/// The file must be associated with a `MiscDeviceRegistration`. +unsafe extern "C" fn fops_open( + inode: *mut bindings::inode, + file: *mut bindings::file, +) -> c_int { + // SAFETY: The pointers are valid and for a file being opened. + let ret = unsafe { bindings::generic_file_open(inode, file) }; + if ret != 0 { + return ret; + } + + let ptr = match T::open() { + Ok(ptr) => ptr, + Err(err) => return err.to_errno(), + }; + + // SAFETY: The open call of a file owns the private data. + unsafe { (*file).private_data = ptr.into_foreign().cast_mut() }; + + 0 +} + +/// # Safety +/// +/// `file` and `inode` must be the file and inode for a file that is being released. The file must +/// be associated with a `MiscDeviceRegistration`. +unsafe extern "C" fn fops_release( + _inode: *mut bindings::inode, + file: *mut bindings::file, +) -> c_int { + // SAFETY: The release call of a file owns the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: The release call of a file owns the private data. + let ptr = unsafe { ::from_foreign(private) }; + + T::release(ptr); + + 0 +} + +/// # Safety +/// +/// `file` must be a valid file that is associated with a `MiscDeviceRegistration`. +unsafe extern "C" fn fops_ioctl( + file: *mut bindings::file, + cmd: c_uint, + arg: c_ulong, +) -> c_long { + // SAFETY: The ioctl call of a file can access the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: Ioctl calls can borrow the private data of the file. + let device = unsafe { ::borrow(private) }; + + match T::ioctl(device, cmd, arg as usize) { + Ok(ret) => ret as c_long, + Err(err) => err.to_errno() as c_long, + } +} + +/// # Safety +/// +/// `file` must be a valid file that is associated with a `MiscDeviceRegistration`. +#[cfg(CONFIG_COMPAT)] +unsafe extern "C" fn fops_compat_ioctl( + file: *mut bindings::file, + cmd: c_uint, + arg: c_ulong, +) -> c_long { + // SAFETY: The compat ioctl call of a file can access the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: Ioctl calls can borrow the private data of the file. + let device = unsafe { ::borrow(private) }; + + match T::compat_ioctl(device, cmd, arg as usize) { + Ok(ret) => ret as c_long, + Err(err) => err.to_errno() as c_long, + } +} diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index 8bdab9aa0d16bf85fcd303afafed96bacffe5f2f..9ab4e0b6cbc912531c8f3155720c2df5d037f97e 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -24,6 +24,8 @@ pub use super::build_assert; // `super::std_vendor` is hidden, which makes the macro inline for some reason. #[doc(no_inline)] pub use super::dbg; +pub use super::fmt; +pub use super::{dev_alert, dev_crit, dev_dbg, dev_emerg, dev_err, dev_info, dev_notice, dev_warn}; pub use super::{pr_alert, pr_crit, pr_debug, pr_emerg, pr_err, pr_info, pr_notice, pr_warn}; pub use super::{init, pin_init, try_init, try_pin_init}; diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 7a133d938551f95c9768c7fe2e592bc867c9ea0d..ec6457bb3084ae327c38ba4ba79b1601aef38244 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -300,6 +300,22 @@ impl Opaque { } } + /// Creates a fallible pin-initializer from the given initializer closure. + /// + /// The returned initializer calls the given closure with the pointer to the inner `T` of this + /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it. + /// + /// This function is safe, because the `T` inside of an `Opaque` is allowed to be + /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs + /// to verify at that point that the inner value is valid. + pub fn try_ffi_init( + init_func: impl FnOnce(*mut T) -> Result<(), E>, + ) -> impl PinInit { + // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully + // initialize the `T`. + unsafe { init::pin_init_from_closure::<_, E>(move |slot| init_func(Self::raw_get(slot))) } + } + /// Returns a raw pointer to the opaque data. pub const fn get(&self) -> *mut T { UnsafeCell::get(&self.value).cast::() diff --git a/rust/macros/module.rs b/rust/macros/module.rs index e7a087b7e88494103c35b1ac7b499df77f2639b1..2587f41b0d3929af7ceac5f42b4711f70b4f8749 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -232,6 +232,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { mod __module_init {{ mod __module_init {{ use super::super::{type_}; + use kernel::init::PinInit; /// The \"Rust loadable module\" mark. // @@ -242,7 +243,8 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[used] static __IS_RUST_MODULE: () = (); - static mut __MOD: Option<{type_}> = None; + static mut __MOD: core::mem::MaybeUninit<{type_}> = + core::mem::MaybeUninit::uninit(); // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. /// # Safety @@ -331,20 +333,14 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { /// /// This function must only be called once. unsafe fn __init() -> kernel::ffi::c_int {{ - match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{ - Ok(m) => {{ - // SAFETY: No data race, since `__MOD` can only be accessed by this - // module and there only `__init` and `__exit` access it. These - // functions are only called once and `__exit` cannot be called - // before or during `__init`. - unsafe {{ - __MOD = Some(m); - }} - return 0; - }} - Err(e) => {{ - return e.to_errno(); - }} + let initer = + <{type_} as kernel::InPlaceModule>::init(&super::super::THIS_MODULE); + // SAFETY: No data race, since `__MOD` can only be accessed by this module + // and there only `__init` and `__exit` access it. These functions are only + // called once and `__exit` cannot be called before or during `__init`. + match unsafe {{ initer.__pinned_init(__MOD.as_mut_ptr()) }} {{ + Ok(m) => 0, + Err(e) => e.to_errno(), }} }} @@ -359,7 +355,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { // called once and `__init` was already called. unsafe {{ // Invokes `drop()` on `__MOD`, which should be used for cleanup. - __MOD = None; + __MOD.assume_init_drop(); }} }} diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index 48df719dac8c6d6fbdcf52bc58e76330f3772ce4..8076ac410161a3af8d77ef8930eb1fe15db9b979 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c @@ -9,6 +9,7 @@ #include #include #include +#include /* * This module shows how to handle fifo dma operations. diff --git a/samples/qmi/qmi_sample_client.c b/samples/qmi/qmi_sample_client.c index a42892523d3bfa9e065bd9e4c08c152bcd36b683..b27d861f354f5a6aa326100afb0823e822aaa97c 100644 --- a/samples/qmi/qmi_sample_client.c +++ b/samples/qmi/qmi_sample_client.c @@ -524,7 +524,7 @@ static void qmi_sample_remove(struct platform_device *pdev) static struct platform_driver qmi_sample_driver = { .probe = qmi_sample_probe, - .remove_new = qmi_sample_remove, + .remove = qmi_sample_remove, .driver = { .name = "qmi_sample_client", }, diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 83645683799703a98a5d5936eaee631c382a15b5..18623ba666e33f9407a620c8a7a5601a86c0c5fc 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1469,6 +1469,6 @@ static void __exit mbochs_dev_exit(void) class_unregister(&mbochs_class); } -MODULE_IMPORT_NS(DMA_BUF); +MODULE_IMPORT_NS("DMA_BUF"); module_init(mbochs_dev_init) module_exit(mbochs_dev_exit) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index ed8a7493524b299321d66a3fe61797f83c751e05..8c311b997e246319d8118de2796de96c8d1ab68d 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -205,7 +205,7 @@ if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:) cmd_and_fixdep = \ $(cmd); \ - scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\ + $(objtree)/scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\ rm -f $(depfile) # Usage: $(call if_changed_rule,foo) diff --git a/scripts/Makefile.autofdo b/scripts/Makefile.autofdo new file mode 100644 index 0000000000000000000000000000000000000000..1caf2457e585c03123929fdade53cd1768c0fb82 --- /dev/null +++ b/scripts/Makefile.autofdo @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Enable available and selected Clang AutoFDO features. + +CFLAGS_AUTOFDO_CLANG := -fdebug-info-for-profiling -mllvm -enable-fs-discriminator=true -mllvm -improved-fs-discriminator=true + +ifndef CONFIG_DEBUG_INFO + CFLAGS_AUTOFDO_CLANG += -gmlt +endif + +ifdef CLANG_AUTOFDO_PROFILE + CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) -ffunction-sections + CFLAGS_AUTOFDO_CLANG += -fsplit-machine-functions +endif + +ifdef CONFIG_LTO_CLANG_THIN + ifdef CLANG_AUTOFDO_PROFILE + KBUILD_LDFLAGS += --lto-sample-profile=$(CLANG_AUTOFDO_PROFILE) + endif + KBUILD_LDFLAGS += --mllvm=-enable-fs-discriminator=true --mllvm=-improved-fs-discriminator=true -plugin-opt=thinlto + KBUILD_LDFLAGS += -plugin-opt=-split-machine-functions +endif + +export CFLAGS_AUTOFDO_CLANG diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f483a54380e71b460c1d54f2c2380e89de491f71..c16e4cf54d770fd2cf585a65dc4ad9b6a6bd6e42 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -3,7 +3,7 @@ # Building # ========================================================================== -src := $(if $(VPATH),$(VPATH)/)$(obj) +src := $(srcroot)/$(obj) PHONY := $(obj)/ $(obj)/: @@ -34,7 +34,7 @@ subdir-asflags-y := subdir-ccflags-y := # Read auto.conf if it exists, otherwise ignore --include include/config/auto.conf +-include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include include $(srctree)/scripts/Makefile.compiler @@ -107,20 +107,14 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(obj)/%.c FORCE $(call if_changed_dep,cpp_i_c) -genksyms = scripts/genksyms/genksyms \ - $(if $(1), -T $(2)) \ - $(if $(KBUILD_PRESERVE), -p) \ - -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) +genksyms = $(objtree)/scripts/genksyms/genksyms \ + $(if $(KBUILD_SYMTYPES), -T $(@:.o=.symtypes)) \ + $(if $(KBUILD_PRESERVE), -p) \ + $(addprefix -r , $(wildcard $(@:.o=.symref))) # These mirror gensymtypes_S and co below, keep them in synch. cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) -quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ - cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null - -$(obj)/%.symtypes : $(obj)/%.c FORCE - $(call cmd,cc_symtypes_c) - # LLVM assembly # Generate .ll files from .c quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@ @@ -135,17 +129,6 @@ $(obj)/%.ll: $(obj)/%.c FORCE is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y) -# When a module consists of a single object, there is no reason to keep LLVM IR. -# Make $(LD) covert LLVM IR to ELF here. -ifdef CONFIG_LTO_CLANG -cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) -endif - -quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ - $(cmd_ld_single_m) \ - $(cmd_objtool) - ifdef CONFIG_MODVERSIONS # When module versioning is enabled the following steps are executed: # o compile a .o from .c @@ -158,8 +141,7 @@ ifdef CONFIG_MODVERSIONS gen_symversions = \ if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then \ - $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ - >> $(dot-target).cmd; \ + $(cmd_gensymtypes_$1) >> $(dot-target).cmd; \ fi cmd_gen_symversions_c = $(call gen_symversions,c) @@ -207,23 +189,6 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi))) endif -define rule_cc_o_c - $(call cmd_and_fixdep,cc_o_c) - $(call cmd,checksrc) - $(call cmd,checkdoc) - $(call cmd,gen_objtooldep) - $(call cmd,gen_symversions_c) - $(call cmd,record_mcount) - $(call cmd,warn_shared_object) -endef - -define rule_as_o_S - $(call cmd_and_fixdep,as_o_S) - $(call cmd,gen_objtooldep) - $(call cmd,gen_symversions_S) - $(call cmd,warn_shared_object) -endef - # Built-in and composite module parts $(obj)/%.o: $(obj)/%.c $(recordmcount_source) FORCE $(call if_changed_rule,cc_o_c) @@ -330,22 +295,12 @@ cmd_gensymtypes_S = \ $(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/EXPORT_SYMBOL(\1);/p' ; } | \ $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) -quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ - cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null - -$(obj)/%.symtypes : $(obj)/%.S FORCE - $(call cmd,cc_symtypes_S) - - quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< $(obj)/%.s: $(obj)/%.S FORCE $(call if_changed_dep,cpp_s_S) -quiet_cmd_as_o_S = AS $(quiet_modtag) $@ - cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) - ifdef CONFIG_ASM_MODVERSIONS # versioning matches the C process described above, with difference that diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang index 6c23c6af797fb016232914589c948208345417ad..2435efae67f53a26d55a1c0f1bf254a49d9fc731 100644 --- a/scripts/Makefile.clang +++ b/scripts/Makefile.clang @@ -10,6 +10,7 @@ CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu +CLANG_TARGET_FLAGS_sparc := sparc64-linux-gnu CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu CLANG_TARGET_FLAGS_um := $(CLANG_TARGET_FLAGS_$(SUBARCH)) CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH)) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 4fcfab40ed61a8fa148601272c8bb3ab24122907..6ead00ec7313b3e4330a8de5f1342f2da1d6eb84 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -3,7 +3,7 @@ # Cleaning up # ========================================================================== -src := $(if $(VPATH),$(VPATH)/)$(obj) +src := $(srcroot)/$(obj) PHONY := __clean __clean: diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index e0842496d26ed773cba4cf9e6a0df50e9713705b..8c1029687e2e4f67743dc28710a4abf81d7c6d85 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -13,7 +13,7 @@ cc-cross-prefix = $(firstword $(foreach c, $(1), \ $(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c)))) # output directory for tests below -TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ +TMPOUT = .tmp_$$$$ # try-run # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index e01c13a588ddd9257902b6d8e772574394189c1f..c1dedf646a39f708030d37b5d50170d241c9484c 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -96,12 +96,10 @@ hostrust_flags = --out-dir $(dir $@) --emit=dep-info=$(depfile) \ $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \ $(HOSTRUSTFLAGS_$(target-stem)) -# $(objtree)/$(obj) for including generated headers from checkin source files -ifeq ($(KBUILD_EXTMOD),) +# $(obj) for including generated headers from checkin source files ifdef building_out_of_srctree -hostc_flags += -I $(objtree)/$(obj) -hostcxx_flags += -I $(objtree)/$(obj) -endif +hostc_flags += -I $(obj) +hostcxx_flags += -I $(obj) endif ##### diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 01a9f567d5af4869ec518d3186ecb27fa5c991a5..7395200538da89a2f6e6d21f8959f3f60d291d79 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -191,15 +191,33 @@ _c_flags += $(if $(patsubst n%,, \ -D__KCSAN_INSTRUMENT_BARRIERS__) endif +# +# Enable AutoFDO build flags except some files or directories we don't want to +# enable (depends on variables AUTOFDO_PROFILE_obj.o and AUTOFDO_PROFILE). +# +ifeq ($(CONFIG_AUTOFDO_CLANG),y) +_c_flags += $(if $(patsubst n%,, \ + $(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(is-kernel-object)), \ + $(CFLAGS_AUTOFDO_CLANG)) +endif + +# +# Enable Propeller build flags except some files or directories we don't want to +# enable (depends on variables AUTOFDO_PROPELLER_obj.o and PROPELLER_PROFILE). +# +ifdef CONFIG_PROPELLER_CLANG +_c_flags += $(if $(patsubst n%,, \ + $(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(PROPELLER_PROFILE))$(is-kernel-object), \ + $(CFLAGS_PROPELLER_CLANG)) +endif + # $(src) for including checkin headers from generated source files # $(obj) for including generated headers from checkin source files -ifeq ($(KBUILD_EXTMOD),) ifdef building_out_of_srctree _c_flags += $(addprefix -I, $(src) $(obj)) _a_flags += $(addprefix -I, $(src) $(obj)) _cpp_flags += $(addprefix -I, $(src) $(obj)) endif -endif # If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules is-kernel-object = $(or $(part-of-builtin),$(part-of-module)) @@ -280,6 +298,42 @@ $(foreach m, $1, \ $(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3)))) endef +# Build commands +# =========================================================================== +# These are shared by some Makefile.* files. + +objtool-enabled := y + +ifdef CONFIG_LTO_CLANG +# objtool cannot process LLVM IR. Make $(LD) covert LLVM IR to ELF here. +cmd_ld_single = $(if $(objtool-enabled), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) +endif + +quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ + $(cmd_ld_single) \ + $(cmd_objtool) + +define rule_cc_o_c + $(call cmd_and_fixdep,cc_o_c) + $(call cmd,checksrc) + $(call cmd,checkdoc) + $(call cmd,gen_objtooldep) + $(call cmd,gen_symversions_c) + $(call cmd,record_mcount) + $(call cmd,warn_shared_object) +endef + +quiet_cmd_as_o_S = AS $(quiet_modtag) $@ + cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) + +define rule_as_o_S + $(call cmd_and_fixdep,as_o_S) + $(call cmd,gen_objtooldep) + $(call cmd,gen_symversions_S) + $(call cmd,warn_shared_object) +endef + # Copy a file # =========================================================================== # 'cp' preserves permissions. If you use it to copy a file in read-only srctree, @@ -371,10 +425,10 @@ quiet_cmd_lzo_with_size = LZO $@ cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ quiet_cmd_lz4 = LZ4 $@ - cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@ + cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -9 - - > $@ quiet_cmd_lz4_with_size = LZ4 $@ - cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \ + cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -9 - -; \ $(size_append); } > $@ # U-Boot mkimage diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 1482884ec3ca820c0a1dbd4d25c5463985561a49..542ba462ed3ec9607e0df10e26613a4c7ac318e8 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -6,14 +6,12 @@ PHONY := __modfinal __modfinal: -include include/config/auto.conf +include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include - -# for c_flags include $(srctree)/scripts/Makefile.lib # find all modules listed in modules.order -modules := $(call read-file, $(MODORDER)) +modules := $(call read-file, modules.order) __modfinal: $(modules:%.o=%.ko) @: @@ -22,30 +20,27 @@ __modfinal: $(modules:%.o=%.ko) modname = $(notdir $(@:.mod.o=)) part-of-module = y GCOV_PROFILE := n -KCSAN_SANITIZE := n - -quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< +ccflags-remove-y := $(CC_FLAGS_CFI) %.mod.o: %.mod.c FORCE - $(call if_changed_dep,cc_o_c) + $(call if_changed_rule,cc_o_c) -$(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE - $(call if_changed_dep,cc_o_c) +.module-common.o: $(srctree)/scripts/module-common.c FORCE + $(call if_changed_rule,cc_o_c) quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ - -T scripts/module.lds -o $@ $(filter %.o, $^) + -T $(objtree)/scripts/module.lds -o $@ $(filter %.o, $^) quiet_cmd_btf_ko = BTF [M] $@ cmd_btf_ko = \ - if [ ! -f vmlinux ]; then \ + if [ ! -f $(objtree)/vmlinux ]; then \ printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ else \ - LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base vmlinux $@; \ - $(RESOLVE_BTFIDS) -b vmlinux $@; \ + LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $(objtree)/vmlinux $@; \ + $(RESOLVE_BTFIDS) -b $(objtree)/vmlinux $@; \ fi; # Same as newer-prereqs, but allows to exclude specified extra dependencies @@ -57,13 +52,13 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) # Re-generate module BTFs if either module's .ko or vmlinux changed -%.ko: %.o %.mod.o $(extmod_prefix).module-common.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE - +$(call if_changed_except,ld_ko_o,vmlinux) +%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE + +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif -targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) $(extmod_prefix).module-common.o +targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.o # Add FORCE to the prerequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index d977209431898befac99a4a4ec937b036c33f3f2..f97c9926ed31b2b14601ff7773a2ea48b225628b 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -6,7 +6,7 @@ PHONY := __modinst __modinst: -include include/config/auto.conf +include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include install-y := @@ -40,7 +40,7 @@ $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo modules.builtin. endif -modules := $(call read-file, $(MODORDER)) +modules := $(call read-file, modules.order) ifeq ($(KBUILD_EXTMOD),) dst := $(MODLIB)/kernel @@ -59,7 +59,7 @@ suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst endif -modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules)) +modules := $(patsubst %.o, $(dst)/%.ko$(suffix-y), $(modules)) install-$(CONFIG_MODULES) += $(modules) __modinst: $(install-y) @@ -119,7 +119,7 @@ endif # Create necessary directories $(foreach dir, $(sort $(dir $(install-y))), $(shell mkdir -p $(dir))) -$(dst)/%.ko: $(extmod_prefix)%.ko FORCE +$(dst)/%.ko: %.ko FORCE $(call cmd,install) $(call cmd,strip) $(call cmd,sign) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 44936ebad161e914cbcc40ac74a2d651596d7b07..ab0e94ea62496e11dbaa3ffc289ce546862795ca 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -35,10 +35,10 @@ PHONY := __modpost __modpost: -include include/config/auto.conf +include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include -MODPOST = scripts/mod/modpost +MODPOST = $(objtree)/scripts/mod/modpost modpost-args = \ $(if $(CONFIG_MODULES),-M) \ @@ -46,7 +46,7 @@ modpost-args = \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ $(if $(KBUILD_MODPOST_WARN),-w) \ - $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ + $(if $(KBUILD_NSDEPS),-d modules.nsdeps) \ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ $(if $(findstring 1, $(KBUILD_EXTRA_WARN)),-W) \ -o $@ @@ -61,8 +61,8 @@ endif # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". ifdef KBUILD_MODULES -modpost-args += -T $(MODORDER) -modpost-deps += $(MODORDER) +modpost-args += -T modules.order +modpost-deps += modules.order endif ifeq ($(KBUILD_EXTMOD),) @@ -111,19 +111,19 @@ endif else # set src + obj - they may be used in the modules's Makefile -obj := $(KBUILD_EXTMOD) -src := $(if $(VPATH),$(VPATH)/)$(obj) +obj := . +src := $(srcroot) # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS include $(kbuild-file) -output-symdump := $(KBUILD_EXTMOD)/Module.symvers +output-symdump := Module.symvers -ifeq ($(wildcard Module.symvers),) -missing-input := Module.symvers +ifeq ($(wildcard $(objtree)/Module.symvers),) +missing-input := $(objtree)/Module.symvers else -modpost-args += -i Module.symvers -modpost-deps += Module.symvers +modpost-args += -i $(objtree)/Module.symvers +modpost-deps += $(objtree)/Module.symvers endif modpost-args += -e $(addprefix -i , $(KBUILD_EXTRA_SYMBOLS)) diff --git a/scripts/Makefile.propeller b/scripts/Makefile.propeller new file mode 100644 index 0000000000000000000000000000000000000000..48a660128e256dcd7fea51ef5c8504a3870a62a4 --- /dev/null +++ b/scripts/Makefile.propeller @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Enable available and selected Clang Propeller features. +ifdef CLANG_PROPELLER_PROFILE_PREFIX + CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=list=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt -ffunction-sections + KBUILD_LDFLAGS += --symbol-ordering-file=$(CLANG_PROPELLER_PROFILE_PREFIX)_ld_profile.txt --no-warn-symbol-ordering +else + # Starting with Clang v20, the '-fbasic-block-sections=labels' option is + # deprecated. Use the recommended '-fbasic-block-address-map' option. + # Link: https://github.com/llvm/llvm-project/pull/110039 + ifeq ($(call clang-min-version, 200000),y) + CFLAGS_PROPELLER_CLANG := -fbasic-block-address-map + else + CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=labels + endif +endif + +# Propeller requires debug information to embed module names in the profiles. +# If CONFIG_DEBUG_INFO is not enabled, set -gmlt option. Skip this for AutoFDO, +# as the option should already be set. +ifndef CONFIG_DEBUG_INFO + ifndef CONFIG_AUTOFDO_CLANG + CFLAGS_PROPELLER_CLANG += -gmlt + endif +endif + +ifdef CONFIG_LTO_CLANG_THIN + ifdef CLANG_PROPELLER_PROFILE_PREFIX + KBUILD_LDFLAGS += --lto-basic-block-sections=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt + else + ifeq ($(call test-ge, $(CONFIG_LLD_VERSION), 200000),y) + KBUILD_LDFLAGS += --lto-basic-block-address-map + else + KBUILD_LDFLAGS += --lto-basic-block-sections=labels + endif + endif +endif + +export CFLAGS_PROPELLER_CLANG diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index dddad554e91274be801c80f57f6b0b4ff16664ea..873caaa553134e09d034e0c4e0ac7f07c9e3f31b 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -5,17 +5,53 @@ __default: vmlinux include include/config/auto.conf include $(srctree)/scripts/Kbuild.include - -# for c_flags include $(srctree)/scripts/Makefile.lib targets := -quiet_cmd_cc_o_c = CC $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< - %.o: %.c FORCE - $(call if_changed_dep,cc_o_c) + $(call if_changed_rule,cc_o_c) + +%.o: %.S FORCE + $(call if_changed_rule,as_o_S) + +# Built-in dtb +# --------------------------------------------------------------------------- + +quiet_cmd_wrap_dtbs = WRAP $@ + cmd_wrap_dtbs = { \ + echo '\#include '; \ + echo '.section .dtb.init.rodata,"a"'; \ + while read dtb; do \ + symbase=__dtb_$$(basename -s .dtb "$${dtb}" | tr - _); \ + echo '.balign STRUCT_ALIGNMENT'; \ + echo ".global $${symbase}_begin"; \ + echo "$${symbase}_begin:"; \ + echo '.incbin "'$$dtb'" '; \ + echo ".global $${symbase}_end"; \ + echo "$${symbase}_end:"; \ + done < $<; \ + } > $@ + +.builtin-dtbs.S: .builtin-dtbs-list FORCE + $(call if_changed,wrap_dtbs) + +quiet_cmd_gen_dtbs_list = GEN $@ + cmd_gen_dtbs_list = \ + $(if $(CONFIG_BUILTIN_DTB_NAME), echo "arch/$(SRCARCH)/boot/dts/$(CONFIG_BUILTIN_DTB_NAME).dtb",:) > $@ + +.builtin-dtbs-list: arch/$(SRCARCH)/boot/dts/dtbs-list FORCE + $(call if_changed,$(if $(CONFIG_BUILTIN_DTB_ALL),copy,gen_dtbs_list)) + +targets += .builtin-dtbs-list + +ifdef CONFIG_GENERIC_BUILTIN_DTB +targets += .builtin-dtbs.S .builtin-dtbs.o +vmlinux: .builtin-dtbs.o +endif + +# vmlinux +# --------------------------------------------------------------------------- ifdef CONFIG_MODULES targets += .vmlinux.export.o @@ -39,6 +75,9 @@ cmd_link_vmlinux = \ targets += vmlinux vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) +ifdef CONFIG_DEBUG_INFO_BTF +vmlinux: $(RESOLVE_BTFIDS) +endif # module.builtin.ranges # --------------------------------------------------------------------------- diff --git a/scripts/coccicheck b/scripts/coccicheck index e52cb43fede60fe1be7eea170b63a6c0d54b6e0b..0e6bc5a10320c9926f3a611bf71911c102d25ea2 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -80,11 +80,7 @@ command results in a shift count error.' NPROC=1 else ONLINE=0 - if [ "$KBUILD_EXTMOD" = "" ] ; then - OPTIONS="--dir $srctree $COCCIINCLUDE" - else - OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" - fi + OPTIONS="--dir $srcroot $COCCIINCLUDE" # Use only one thread per core by default if hyperthreading is enabled THREADS_PER_CORE=$(LANG=C lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]") diff --git a/scripts/depmod.sh b/scripts/depmod.sh index e22da27fe13eb35fccb3a34cfc90b558e3adc31f..3c34fecacbc82e297fd4919e98ab70f0283c6b10 100755 --- a/scripts/depmod.sh +++ b/scripts/depmod.sh @@ -12,7 +12,7 @@ KERNELRELEASE=$1 : ${DEPMOD:=depmod} -if ! test -r System.map ; then +if ! test -r "${objtree}/System.map" ; then echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2 exit 0 fi @@ -25,7 +25,7 @@ if [ -z $(command -v $DEPMOD) ]; then exit 0 fi -set -- -ae -F System.map +set -- -ae -F "${objtree}/System.map" if test -n "$INSTALL_MOD_PATH"; then set -- "$@" -b "$INSTALL_MOD_PATH" fi diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index f3901c55df239df5a7d88e974bae8e388d2c00ae..07f9b8cfb23370b385a03ada2becee0e8a2cb3b1 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -632,54 +632,55 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) void export_symbol(const char *name) { struct symbol *sym; + unsigned long crc; + int has_changed = 0; sym = find_symbol(name, SYM_NORMAL, 0); - if (!sym) + if (!sym) { error_with_pos("export undefined symbol %s", name); - else { - unsigned long crc; - int has_changed = 0; + return; + } - if (flag_dump_defs) - fprintf(debugfile, "Export %s == <", name); + if (flag_dump_defs) + fprintf(debugfile, "Export %s == <", name); - expansion_trail = (struct symbol *)-1L; + expansion_trail = (struct symbol *)-1L; - sym->expansion_trail = expansion_trail; - expansion_trail = sym; - crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; + sym->expansion_trail = expansion_trail; + expansion_trail = sym; + crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; - sym = expansion_trail; - while (sym != (struct symbol *)-1L) { - struct symbol *n = sym->expansion_trail; + sym = expansion_trail; + while (sym != (struct symbol *)-1L) { + struct symbol *n = sym->expansion_trail; - if (sym->status != STATUS_UNCHANGED) { - if (!has_changed) { - print_location(); - fprintf(stderr, "%s: %s: modversion " - "changed because of changes " - "in ", flag_preserve ? "error" : - "warning", name); - } else - fprintf(stderr, ", "); - print_type_name(sym->type, sym->name); - if (sym->status == STATUS_DEFINED) - fprintf(stderr, " (became defined)"); - has_changed = 1; - if (flag_preserve) - errors++; + if (sym->status != STATUS_UNCHANGED) { + if (!has_changed) { + print_location(); + fprintf(stderr, + "%s: %s: modversion changed because of changes in ", + flag_preserve ? "error" : "warning", + name); + } else { + fprintf(stderr, ", "); } - sym->expansion_trail = 0; - sym = n; + print_type_name(sym->type, sym->name); + if (sym->status == STATUS_DEFINED) + fprintf(stderr, " (became defined)"); + has_changed = 1; + if (flag_preserve) + errors++; } - if (has_changed) - fprintf(stderr, "\n"); + sym->expansion_trail = 0; + sym = n; + } + if (has_changed) + fprintf(stderr, "\n"); - if (flag_dump_defs) - fputs(">\n", debugfile); + if (flag_dump_defs) + fputs(">\n", debugfile); - printf("#SYMVER %s 0x%08lx\n", name, crc); - } + printf("#SYMVER %s 0x%08lx\n", name, crc); } /*----------------------------------------------------------------------*/ diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt index fd5d00bac447dae9f4aa20380565b15ab3fe5d25..f12b4a7b8406beef69dc24f14c9c448c319b3806 100644 --- a/scripts/head-object-list.txt +++ b/scripts/head-object-list.txt @@ -23,7 +23,6 @@ arch/m68k/coldfire/head.o arch/m68k/kernel/head.o arch/m68k/kernel/sun3-head.o arch/microblaze/kernel/head.o -arch/mips/kernel/head.o arch/nios2/kernel/head.o arch/openrisc/kernel/head.o arch/parisc/kernel/head.o diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 3d7d454c54da3c01df7a4a0b488b114be132e7b1..8abe570419552fa8d59038ac98725dfd413a4c46 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -628,7 +628,7 @@ static const struct option long_opts[] = { static void conf_usage(const char *progname) { - printf("Usage: %s [options] \n", progname); + printf("Usage: %s [options] kconfig_file\n", progname); printf("\n"); printf("Generic options:\n"); printf(" -h, --help Print this message and exit.\n"); @@ -653,6 +653,9 @@ static void conf_usage(const char *progname) printf(" --mod2yesconfig Change answers from mod to yes if possible\n"); printf(" --mod2noconfig Change answers from mod to no if possible\n"); printf(" (If none of the above is given, --oldaskconfig is the default)\n"); + printf("\n"); + printf("Arguments:\n"); + printf(" kconfig_file Top-level Kconfig file.\n"); } int main(int ac, char **av) diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 63519cd24bc7fa8e30c03b712e85e1a22fe0984d..8914b4e8f2a81161844aace81ece38fb97d7ce7e 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -34,6 +34,7 @@ bool sym_string_valid(struct symbol *sym, const char *newval); bool sym_string_within_range(struct symbol *sym, const char *str); bool sym_set_string_value(struct symbol *sym, const char *newval); bool sym_is_changeable(const struct symbol *sym); +struct menu *sym_get_prompt_menu(const struct symbol *sym); struct menu *sym_get_choice_menu(const struct symbol *sym); const char * sym_get_string_value(struct symbol *sym); diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 063b4f7ccbdb369b96a01a9413f8ade5393beea9..c0b2dabf6c894fcdf6ac1fa651e5506bb7ac1c77 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -467,7 +467,7 @@ static void handle_f9(int *key, struct menu *current_item) return; } -/* return != 0 to indicate the key was handles */ +/* return != 0 to indicate the key was handled */ static int process_special_keys(int *key, struct menu *menu) { int i; diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 72b605efe549d9d82b2e8a0f29bf47036ea07e67..4bfdf8ac2a9a34d077d6ba470ff233ec947d638b 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -277,6 +277,15 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) case KEY_RIGHT: menu_driver(menu, REQ_RIGHT_ITEM); break; + case 9: /* TAB */ + if (btn_num > 1) { + /* cycle through buttons */ + if (item_index(current_item(menu)) == btn_num - 1) + menu_driver(menu, REQ_FIRST_ITEM); + else + menu_driver(menu, REQ_NEXT_ITEM); + } + break; case 10: /* ENTER */ case 27: /* ESCAPE */ case ' ': diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index bc43fb67c7c41e6db263a636ae165dbfa22e99d5..68372d3ff32539cb5460807ca4369343eff4481d 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -24,7 +24,6 @@ int cdebug = PRINTD; static void yyerror(const char *err); -static void zconfprint(const char *err, ...); static void zconf_error(const char *err, ...); static bool zconf_endtoken(const char *tokenname, const char *expected_tokenname); @@ -183,7 +182,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list if (current_entry->prompt) current_entry->prompt->type = P_MENU; else - zconfprint("warning: menuconfig statement without prompt"); + zconf_error("menuconfig statement without prompt"); printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno); }; @@ -293,12 +292,6 @@ choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno); }; -choice_option: T_BOOL T_WORD_QUOTE if_expr T_EOL -{ - menu_add_prompt(P_PROMPT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:bool\n", cur_filename, cur_lineno); -}; - choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL { menu_add_symbol(P_DEFAULT, $2, $3); @@ -408,14 +401,14 @@ help: help_start T_HELPTEXT { if (current_entry->help) { free(current_entry->help); - zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used", - current_entry->sym->name ?: ""); + zconf_error("'%s' defined with more than one help text", + current_entry->sym->name ?: ""); } /* Is the help text empty or all whitespace? */ if ($2[strspn($2, " \f\n\r\t\v")] == '\0') - zconfprint("warning: '%s' defined with blank help text", - current_entry->sym->name ?: ""); + zconf_error("'%s' defined with blank help text", + current_entry->sym->name ?: ""); current_entry->help = $2; }; @@ -598,17 +591,6 @@ static bool zconf_endtoken(const char *tokenname, return true; } -static void zconfprint(const char *err, ...) -{ - va_list ap; - - fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno); - va_start(ap, err); - vfprintf(stderr, err, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - static void zconf_error(const char *err, ...) { va_list ap; diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index e260cab1c2afff347aa6e8d773c6058f11a3a7b6..6c92ef1e16efb175324c554c56dcebdfb74e9036 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -110,7 +110,7 @@ void ConfigItem::updateMenu(void) if (prop) switch (prop->type) { case P_MENU: - if (list->mode == singleMode || list->mode == symbolMode) { + if (list->mode == singleMode) { /* a menuconfig entry is displayed differently * depending whether it's at the view root or a child. */ @@ -159,7 +159,7 @@ void ConfigItem::updateMenu(void) ch = 'M'; break; default: - if (sym_is_choice_value(sym) && type == S_BOOLEAN) + if (sym_is_choice_value(sym)) setIcon(promptColIdx, choiceNoIcon); else setIcon(promptColIdx, symbolNoIcon); @@ -175,17 +175,16 @@ void ConfigItem::updateMenu(void) setText(dataColIdx, sym_get_string_value(sym)); break; } - if (!sym_has_value(sym) && visible) + if (!sym_has_value(sym)) prompt += " (NEW)"; set_prompt: setText(promptColIdx, prompt); } -void ConfigItem::testUpdateMenu(bool v) +void ConfigItem::testUpdateMenu(void) { ConfigItem* i; - visible = v; if (!menu) return; @@ -307,7 +306,6 @@ ConfigList::ConfigList(QWidget *parent, const char *name) { setObjectName(name); setSortingEnabled(false); - setRootIsDecorated(true); setVerticalScrollMode(ScrollPerPixel); setHorizontalScrollMode(ScrollPerPixel); @@ -430,27 +428,26 @@ void ConfigList::updateList() item = (ConfigItem*)(*it); if (!item->menu) continue; - item->testUpdateMenu(menu_is_visible(item->menu)); + item->testUpdateMenu(); ++it; } return; } - if (rootEntry != &rootmenu && (mode == singleMode || - (mode == symbolMode && rootEntry->parent != &rootmenu))) { + if (rootEntry != &rootmenu && mode == singleMode) { item = (ConfigItem *)topLevelItem(0); if (!item) - item = new ConfigItem(this, 0, true); + item = new ConfigItem(this, 0); last = item; } if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && rootEntry->sym && rootEntry->prompt) { item = last ? last->nextSibling() : nullptr; if (!item) - item = new ConfigItem(this, last, rootEntry, true); + item = new ConfigItem(this, last, rootEntry); else - item->testUpdateMenu(true); + item->testUpdateMenu(); updateMenuList(item, rootEntry); update(); @@ -599,7 +596,6 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) struct menu* child; ConfigItem* item; ConfigItem* last; - bool visible; enum prop_type type; if (!menu) { @@ -631,14 +627,13 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) break; } - visible = menu_is_visible(child); if (!menuSkip(child)) { if (!child->sym && !child->list && !child->prompt) continue; if (!item || item->menu != child) - item = new ConfigItem(parent, last, child, visible); + item = new ConfigItem(parent, last, child); else - item->testUpdateMenu(visible); + item->testUpdateMenu(); if (mode == fullMode || mode == menuMode || type != P_MENU) updateMenuList(item, child); @@ -664,7 +659,6 @@ void ConfigList::updateMenuList(struct menu *menu) struct menu* child; ConfigItem* item; ConfigItem* last; - bool visible; enum prop_type type; if (!menu) { @@ -696,14 +690,13 @@ void ConfigList::updateMenuList(struct menu *menu) break; } - visible = menu_is_visible(child); if (!menuSkip(child)) { if (!child->sym && !child->list && !child->prompt) continue; if (!item || item->menu != child) - item = new ConfigItem(this, last, child, visible); + item = new ConfigItem(this, last, child); else - item->testUpdateMenu(visible); + item->testUpdateMenu(); if (mode == fullMode || mode == menuMode || type != P_MENU) updateMenuList(item, child); @@ -731,7 +724,7 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) struct menu *menu; enum prop_type type; - if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) { + if (ev->key() == Qt::Key_Escape && mode == singleMode) { emit parentSelected(); ev->accept(); return; @@ -781,13 +774,6 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) ev->accept(); } -void ConfigList::mousePressEvent(QMouseEvent* e) -{ - //QPoint p(contentsToViewport(e->pos())); - //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); - Parent::mousePressEvent(e); -} - void ConfigList::mouseReleaseEvent(QMouseEvent* e) { QPoint p = e->pos(); @@ -834,13 +820,6 @@ skip: Parent::mouseReleaseEvent(e); } -void ConfigList::mouseMoveEvent(QMouseEvent* e) -{ - //QPoint p(contentsToViewport(e->pos())); - //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); - Parent::mouseMoveEvent(e); -} - void ConfigList::mouseDoubleClickEvent(QMouseEvent* e) { QPoint p = e->pos(); @@ -1022,7 +1001,7 @@ void ConfigInfoView::menuInfo(void) if (sym->name) { stream << " ("; if (showDebug()) - stream << "name << "\">"; + stream << "name << "\">"; stream << print_filter(sym->name); if (showDebug()) stream << ""; @@ -1031,7 +1010,7 @@ void ConfigInfoView::menuInfo(void) } else if (sym->name) { stream << ""; if (showDebug()) - stream << "name << "\">"; + stream << "name << "\">"; stream << print_filter(sym->name); if (showDebug()) stream << ""; @@ -1086,9 +1065,9 @@ QString ConfigInfoView::debug_info(struct symbol *sym) switch (prop->type) { case P_PROMPT: case P_MENU: - stream << "prompt: name << "\">"; + stream << "prompt: "; stream << print_filter(prop->text); - stream << "
"; + stream << "
"; break; case P_DEFAULT: case P_SELECT: @@ -1122,28 +1101,19 @@ QString ConfigInfoView::print_filter(const QString &str) { QRegularExpression re("[<>&\"\\n]"); QString res = str; + + QHash patterns; + patterns['<'] = "<"; + patterns['>'] = ">"; + patterns['&'] = "&"; + patterns['"'] = """; + patterns['\n'] = "
"; + for (int i = 0; (i = res.indexOf(re, i)) >= 0;) { - switch (res[i].toLatin1()) { - case '<': - res.replace(i, 1, "<"); - i += 4; - break; - case '>': - res.replace(i, 1, ">"); - i += 4; - break; - case '&': - res.replace(i, 1, "&"); - i += 5; - break; - case '"': - res.replace(i, 1, """); - i += 6; - break; - case '\n': - res.replace(i, 1, "
"); - i += 4; - break; + const QString n = patterns.value(res[i], QString()); + if (!n.isEmpty()) { + res.replace(i, 1, n); + i += n.length(); } } return res; @@ -1154,7 +1124,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char QTextStream *stream = reinterpret_cast(data); if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { - *stream << "name << "\">"; + *stream << "name << "\">"; *stream << print_filter(str); *stream << ""; } else { @@ -1164,39 +1134,11 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char void ConfigInfoView::clicked(const QUrl &url) { - QByteArray str = url.toEncoded(); - const std::size_t count = str.size(); - char *data = new char[count + 2]; // '$' + '\0' - struct symbol **result; - struct menu *m = NULL; - - if (count < 1) { - delete[] data; - return; - } - - memcpy(data, str.constData(), count); - data[count] = '\0'; - - /* Seek for exact match */ - data[0] = '^'; - strcat(data, "$"); - result = sym_re_search(data); - if (!result) { - delete[] data; - return; - } + struct menu *m; - sym = *result; - - /* Seek for the menu which holds the symbol */ - for (struct property *prop = sym->prop; prop; prop = prop->next) { - if (prop->type != P_PROMPT && prop->type != P_MENU) - continue; - m = prop->menu; - break; - } + sym = sym_find(url.toEncoded().constData()); + m = sym_get_prompt_menu(sym); if (!m) { /* Symbol is not visible as a menu */ symbolInfo(); @@ -1204,9 +1146,6 @@ void ConfigInfoView::clicked(const QUrl &url) } else { emit menuSelected(m); } - - free(result); - delete[] data; } void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event) @@ -1240,8 +1179,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) layout2->addWidget(searchButton); layout1->addLayout(layout2); - split = new QSplitter(this); - split->setOrientation(Qt::Vertical); + split = new QSplitter(Qt::Vertical, this); list = new ConfigList(split, "search"); list->mode = listMode; info = new ConfigInfoView(split, "search"); @@ -1300,8 +1238,7 @@ void ConfigSearchWindow::search(void) return; for (p = result; *p; p++) { for_all_prompts((*p), prop) - lastItem = new ConfigItem(list, lastItem, prop->menu, - menu_is_visible(prop->menu)); + lastItem = new ConfigItem(list, lastItem, prop->menu); } } @@ -1341,61 +1278,56 @@ ConfigMainWindow::ConfigMainWindow(void) ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); QWidget *widget = new QWidget(this); - QVBoxLayout *layout = new QVBoxLayout(widget); setCentralWidget(widget); - split1 = new QSplitter(widget); - split1->setOrientation(Qt::Horizontal); - split1->setChildrenCollapsible(false); - - menuList = new ConfigList(widget, "menu"); + QVBoxLayout *layout = new QVBoxLayout(widget); - split2 = new QSplitter(widget); + split2 = new QSplitter(Qt::Vertical, widget); + layout->addWidget(split2); split2->setChildrenCollapsible(false); - split2->setOrientation(Qt::Vertical); - // create config tree - configList = new ConfigList(widget, "config"); + split1 = new QSplitter(Qt::Horizontal, split2); + split1->setChildrenCollapsible(false); - helpText = new ConfigInfoView(widget, "help"); + configList = new ConfigList(split1, "config"); - layout->addWidget(split2); - split2->addWidget(split1); - split1->addWidget(configList); - split1->addWidget(menuList); - split2->addWidget(helpText); + menuList = new ConfigList(split1, "menu"); + helpText = new ConfigInfoView(split2, "help"); setTabOrder(configList, helpText); + configList->setFocus(); backAction = new QAction(QPixmap(xpm_back), "Back", this); + backAction->setShortcut(QKeySequence::Back); connect(backAction, &QAction::triggered, this, &ConfigMainWindow::goBack); QAction *quitAction = new QAction("&Quit", this); - quitAction->setShortcut(Qt::CTRL | Qt::Key_Q); + quitAction->setShortcut(QKeySequence::Quit); connect(quitAction, &QAction::triggered, this, &ConfigMainWindow::close); - QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); - loadAction->setShortcut(Qt::CTRL | Qt::Key_L); + QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); + loadAction->setShortcut(QKeySequence::Open); connect(loadAction, &QAction::triggered, this, &ConfigMainWindow::loadConfig); saveAction = new QAction(QPixmap(xpm_save), "&Save", this); - saveAction->setShortcut(Qt::CTRL | Qt::Key_S); + saveAction->setShortcut(QKeySequence::Save); connect(saveAction, &QAction::triggered, this, &ConfigMainWindow::saveConfig); conf_set_changed_callback(conf_changed); - configname = xstrdup(conf_get_configname()); + configname = conf_get_configname(); QAction *saveAsAction = new QAction("Save &As...", this); + saveAsAction->setShortcut(QKeySequence::SaveAs); connect(saveAsAction, &QAction::triggered, this, &ConfigMainWindow::saveConfigAs); QAction *searchAction = new QAction("&Find", this); - searchAction->setShortcut(Qt::CTRL | Qt::Key_F); + searchAction->setShortcut(QKeySequence::Find); connect(searchAction, &QAction::triggered, this, &ConfigMainWindow::searchConfig); singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); @@ -1505,6 +1437,9 @@ ConfigMainWindow::ConfigMainWindow(void) connect(helpText, &ConfigInfoView::menuSelected, this, &ConfigMainWindow::setMenuLink); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigMainWindow::saveSettings); + conf_read(NULL); QString listMode = configSettings->value("/listMode", "symbol").toString(); @@ -1528,28 +1463,22 @@ ConfigMainWindow::ConfigMainWindow(void) void ConfigMainWindow::loadConfig(void) { QString str; - QByteArray ba; - const char *name; str = QFileDialog::getOpenFileName(this, "", configname); if (str.isNull()) return; - ba = str.toLocal8Bit(); - name = ba.data(); - - if (conf_read(name)) + if (conf_read(str.toLocal8Bit().constData())) QMessageBox::information(this, "qconf", "Unable to load configuration!"); - free(configname); - configname = xstrdup(name); + configname = str; ConfigList::updateListAllForAll(); } bool ConfigMainWindow::saveConfig(void) { - if (conf_write(configname)) { + if (conf_write(configname.toLocal8Bit().constData())) { QMessageBox::information(this, "qconf", "Unable to save configuration!"); return false; } @@ -1561,23 +1490,17 @@ bool ConfigMainWindow::saveConfig(void) void ConfigMainWindow::saveConfigAs(void) { QString str; - QByteArray ba; - const char *name; str = QFileDialog::getSaveFileName(this, "", configname); if (str.isNull()) return; - ba = str.toLocal8Bit(); - name = ba.data(); - - if (conf_write(name)) { + if (conf_write(str.toLocal8Bit().constData())) { QMessageBox::information(this, "qconf", "Unable to save configuration!"); } conf_write_autoconf(0); - free(configname); - configname = xstrdup(name); + configname = str; } void ConfigMainWindow::searchConfig(void) @@ -1662,9 +1585,6 @@ void ConfigMainWindow::listFocusChanged(void) void ConfigMainWindow::goBack(void) { - if (configList->rootEntry == &rootmenu) - return; - configList->setParentMenu(); } @@ -1905,8 +1825,6 @@ int main(int ac, char** av) v = new ConfigMainWindow(); //zconfdump(stdout); - configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); - configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); v->show(); configApp->exec(); diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 53373064d90ace9cc779482b16004897c93d0519..62ab3286d04f753b93a086a74e98eb2d3af88884 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -55,9 +55,7 @@ public: protected: void keyPressEvent(QKeyEvent *e); - void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); - void mouseMoveEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e); void focusInEvent(QFocusEvent *e); void contextMenuEvent(QContextMenuEvent *e); @@ -116,25 +114,25 @@ public: class ConfigItem : public QTreeWidgetItem { typedef class QTreeWidgetItem Parent; public: - ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v) - : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false) + ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m) + : Parent(parent, after), nextItem(0), menu(m), goParent(false) { init(); } - ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) - : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false) + ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m) + : Parent(parent, after), nextItem(0), menu(m), goParent(false) { init(); } - ConfigItem(ConfigList *parent, ConfigItem *after, bool v) - : Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true) + ConfigItem(ConfigList *parent, ConfigItem *after) + : Parent(parent, after), nextItem(0), menu(0), goParent(true) { init(); } ~ConfigItem(void); void init(void); void updateMenu(void); - void testUpdateMenu(bool v); + void testUpdateMenu(void); ConfigList* listView() const { return (ConfigList*)Parent::treeWidget(); @@ -161,7 +159,6 @@ public: ConfigItem* nextItem; struct menu *menu; - bool visible; bool goParent; static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon; @@ -237,7 +234,7 @@ protected: class ConfigMainWindow : public QMainWindow { Q_OBJECT - char *configname; + QString configname; static QAction *saveAction; static void conf_changed(bool); public: diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index d51cd7ac15d2ce062eb78d07c6fc6316b5755a8b..8e23faab5d2277cdfc0d913c20daac02cb2782d2 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -144,6 +144,7 @@ my %selects; my %prompts; my %objects; my %config2kfile; +my %defaults; my $var; my $iflevel = 0; my @ifdeps; @@ -220,8 +221,9 @@ sub read_kconfig { $depends{$config} = $1; } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { $depends{$config} .= " " . $1; - } elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { + } elsif ($state ne "NONE" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { my $dep = $3; + $defaults{$config} = 1; if ($dep !~ /^\s*(y|m|n)\s*$/) { $dep =~ s/.*\sif\s+//; $depends{$config} .= " " . $dep; @@ -503,7 +505,7 @@ sub parse_config_selects # Check if something other than a module selects this config if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") { - dprint "$conf (non module) selects config, we are good\n"; + dprint "$conf (non module) selects $config, we are good\n"; # we are good with this return; } @@ -523,8 +525,16 @@ sub parse_config_selects # If no possible config selected this, then something happened. if (!defined($next_config)) { - print STDERR "WARNING: $config is required, but nothing in the\n"; - print STDERR " current config selects it.\n"; + + # Some config options have no prompt, and nothing selects them, but + # they stay turned on once the final checks for the configs + # are done. These configs have a default option, so turn off the + # warnings for configs with default options. + if (!defined($defaults{$config})) { + print STDERR "WARNING: $config is required, but nothing in the\n"; + print STDERR " current config selects it.\n"; + } + return; } diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index a3af93aaaf32af1e1a1a62433888303b30bd7182..89b84bf8e21fa63e6ca2482561017c8508910717 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -70,6 +70,24 @@ const char *sym_type_name(enum symbol_type type) return "???"; } +/** + * sym_get_prompt_menu - get the menu entry with a prompt + * + * @sym: a symbol pointer + * + * Return: the menu entry with a prompt. + */ +struct menu *sym_get_prompt_menu(const struct symbol *sym) +{ + struct menu *m; + + list_for_each_entry(m, &sym->menus, link) + if (m->prompt) + return m; + + return NULL; +} + /** * sym_get_choice_menu - get the parent choice menu if present * @@ -80,18 +98,12 @@ const char *sym_type_name(enum symbol_type type) struct menu *sym_get_choice_menu(const struct symbol *sym) { struct menu *menu = NULL; - struct menu *m; /* * Choice members must have a prompt. Find a menu entry with a prompt, * and assume it resides inside a choice block. */ - list_for_each_entry(m, &sym->menus, link) - if (m->prompt) { - menu = m; - break; - } - + menu = sym_get_prompt_menu(sym); if (!menu) return NULL; diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index a3c634b2f348f9c976cff9693caf290db7f31666..d853ddb3b28c1238ec9079ebbbe77df26980a0a1 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -68,6 +68,10 @@ vmlinux_link() libs="${KBUILD_VMLINUX_LIBS}" fi + if is_enabled CONFIG_GENERIC_BUILTIN_DTB; then + objs="${objs} .builtin-dtbs.o" + fi + if is_enabled CONFIG_MODULES; then objs="${objs} .vmlinux.export.o" fi @@ -208,8 +212,8 @@ kallsymso= strip_debug= if is_enabled CONFIG_KALLSYMS; then - true > .tmp_vmlinux.kallsyms0.syms - kallsyms .tmp_vmlinux.kallsyms0.syms .tmp_vmlinux0.kallsyms + true > .tmp_vmlinux0.syms + kallsyms .tmp_vmlinux0.syms .tmp_vmlinux0.kallsyms fi if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then @@ -236,14 +240,14 @@ if is_enabled CONFIG_KALLSYMS; then # Generate section listing all symbols and add it into vmlinux # It's a four step process: # 0) Generate a dummy __kallsyms with empty symbol list. - # 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections, + # 1) Link .tmp_vmlinux1.kallsyms so it has all symbols and sections, # with a dummy __kallsyms. - # Running kallsyms on that gives us .tmp_kallsyms1.o with + # Running kallsyms on that gives us .tmp_vmlinux1.kallsyms.o with # the right size - # 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of + # 2) Link .tmp_vmlinux2.kallsyms so it now has a __kallsyms section of # the right size, but due to the added section, some # addresses have shifted. - # From here, we generate a correct .tmp_vmlinux.kallsyms2.o + # From here, we generate a correct .tmp_vmlinux2.kallsyms.o # 3) That link may have expanded the kernel image enough that # more linker branch stubs / trampolines had to be added, which # introduces new names, which further expands kallsyms. Do another diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index c4cc11aa558f5f5dc4ef3a78475cbbe827f48308..5b5745f00eb306a93247c7bc1e33bf837bc3a152 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -10,6 +10,12 @@ * of the GNU General Public License, incorporated herein by reference. */ +#include +#include + +#include "list.h" +#include "xalloc.h" + #include "modpost.h" #include "devicetable-offsets.h" @@ -31,6 +37,66 @@ typedef Elf64_Addr kernel_ulong_t; #include #include +/** + * module_alias_printf - add auto-generated MODULE_ALIAS() + * + * @mod: module + * @append_wildcard: append '*' for future extension if not exist yet + * @fmt: printf(3)-like format + */ +static void __attribute__((format (printf, 3, 4))) +module_alias_printf(struct module *mod, bool append_wildcard, + const char *fmt, ...) +{ + struct module_alias *new, *als; + size_t len; + int n; + va_list ap; + + /* Determine required size. */ + va_start(ap, fmt); + n = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + if (n < 0) { + error("vsnprintf failed\n"); + return; + } + + len = n + 1; /* extra byte for '\0' */ + + if (append_wildcard) + len++; /* extra byte for '*' */ + + new = xmalloc(sizeof(*new) + len); + + /* Now, really print it to the allocated buffer */ + va_start(ap, fmt); + n = vsnprintf(new->str, len, fmt, ap); + va_end(ap); + + if (n < 0) { + error("vsnprintf failed\n"); + free(new); + return; + } + + if (append_wildcard && (n == 0 || new->str[n - 1] != '*')) { + new->str[n] = '*'; + new->str[n + 1] = '\0'; + } + + /* avoid duplication */ + list_for_each_entry(als, &mod->aliases, node) { + if (!strcmp(als->str, new->str)) { + free(new); + return; + } + } + + list_add_tail(&new->node, &mod->aliases); +} + typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; @@ -56,35 +122,24 @@ typedef struct { * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" -/* This array collects all instances that use the generic do_table */ struct devtable { - const char *device_id; /* name of table, __mod___*_device_table. */ + const char *device_id; unsigned long id_size; - int (*do_entry)(const char *filename, void *symval, char *alias); + void (*do_entry)(struct module *mod, void *symval); }; -/* Size of alias provided to do_entry functions */ -#define ALIAS_SIZE 500 - /* Define a variable f that holds the value of field f of struct devid * based at address m. */ #define DEF_FIELD(m, devid, f) \ typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f)) -/* Define a variable v that holds the address of field f of struct devid - * based at address m. Due to the way typeof works, for a field of type - * T[N] the variable has type T(*)[N], _not_ T*. - */ -#define DEF_FIELD_ADDR_VAR(m, devid, f, v) \ - typeof(((struct devid *)0)->f) *v = ((m) + OFF_##devid##_##f) - /* Define a variable f that holds the address of field f of struct devid * based at address m. Due to the way typeof works, for a field of type * T[N] the variable has type T(*)[N], _not_ T*. */ #define DEF_FIELD_ADDR(m, devid, f) \ - DEF_FIELD_ADDR_VAR(m, devid, f, f) + typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f) #define ADD(str, sep, cond, field) \ do { \ @@ -99,15 +154,6 @@ do { \ sprintf(str + strlen(str), "*"); \ } while(0) -/* End in a wildcard, for future extension */ -static inline void add_wildcard(char *str) -{ - int len = strlen(str); - - if (str[len - 1] != '*') - strcat(str + len, "*"); -} - static inline void add_uuid(char *str, uuid_le uuid) { int len = strlen(str); @@ -130,40 +176,6 @@ static inline void add_guid(char *str, guid_t guid) guid.b[12], guid.b[13], guid.b[14], guid.b[15]); } -/** - * Check that sizeof(device_id type) are consistent with size of section - * in .o file. If in-consistent then userspace and kernel does not agree - * on actual size which is a bug. - * Also verify that the final entry in the table is all zeros. - * Ignore both checks if build host differ from target host and size differs. - **/ -static void device_id_check(const char *modname, const char *device_id, - unsigned long size, unsigned long id_size, - void *symval) -{ - int i; - - if (size % id_size || size < id_size) { - fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_%s___device_table=%lu.\n" - "Fix definition of struct %s_device_id in mod_devicetable.h\n", - modname, device_id, id_size, device_id, size, device_id); - } - /* Verify last one is a terminator */ - for (i = 0; i < id_size; i++ ) { - if (*(uint8_t*)(symval+size-id_size+i)) { - fprintf(stderr, - "%s: struct %s_device_id is %lu bytes. The last of %lu is:\n", - modname, device_id, id_size, size / id_size); - for (i = 0; i < id_size; i++ ) - fprintf(stderr,"0x%02x ", - *(uint8_t*)(symval+size-id_size+i) ); - fprintf(stderr,"\n"); - fatal("%s: struct %s_device_id is not terminated with a NULL entry!\n", - modname, device_id); - } - } -} - /* USB is special because the bcdDevice can be matched against a numeric range */ /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ static void do_usb_entry(void *symval, @@ -229,9 +241,7 @@ static void do_usb_entry(void *symval, ADD(alias, "in", match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER, bInterfaceNumber); - add_wildcard(alias); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"%s\");\n", alias); + module_alias_printf(mod, true, "%s", alias); } /* Handles increment/decrement of BCD formatted integers */ @@ -273,7 +283,7 @@ static unsigned int incbcd(unsigned int *bcd, return init; } -static void do_usb_entry_multi(void *symval, struct module *mod) +static void do_usb_entry_multi(struct module *mod, void *symval) { unsigned int devlo, devhi; unsigned char chi, clo, max; @@ -338,22 +348,7 @@ static void do_usb_entry_multi(void *symval, struct module *mod) } } -static void do_usb_table(void *symval, unsigned long size, - struct module *mod) -{ - unsigned int i; - const unsigned long id_size = SIZE_usb_device_id; - - device_id_check(mod->name, "usb", size, id_size, symval); - - /* Leave last one: it's the terminator. */ - size -= id_size; - - for (i = 0; i < size; i += id_size) - do_usb_entry_multi(symval + i, mod); -} - -static void do_of_entry_multi(void *symval, struct module *mod) +static void do_of_entry(struct module *mod, void *symval) { char alias[500]; int len; @@ -375,56 +370,39 @@ static void do_of_entry_multi(void *symval, struct module *mod) if (isspace(*tmp)) *tmp = '_'; - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); - strcat(alias, "C"); - add_wildcard(alias); - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); -} - -static void do_of_table(void *symval, unsigned long size, - struct module *mod) -{ - unsigned int i; - const unsigned long id_size = SIZE_of_device_id; - - device_id_check(mod->name, "of", size, id_size, symval); - - /* Leave last one: it's the terminator. */ - size -= id_size; - - for (i = 0; i < size; i += id_size) - do_of_entry_multi(symval + i, mod); + module_alias_printf(mod, false, "%s", alias); + module_alias_printf(mod, false, "%sC*", alias); } /* Looks like: hid:bNvNpN */ -static int do_hid_entry(const char *filename, - void *symval, char *alias) +static void do_hid_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, hid_device_id, bus); DEF_FIELD(symval, hid_device_id, group); DEF_FIELD(symval, hid_device_id, vendor); DEF_FIELD(symval, hid_device_id, product); - sprintf(alias, "hid:"); ADD(alias, "b", bus != HID_BUS_ANY, bus); ADD(alias, "g", group != HID_GROUP_ANY, group); ADD(alias, "v", vendor != HID_ANY_ID, vendor); ADD(alias, "p", product != HID_ANY_ID, product); - return 1; + module_alias_printf(mod, false, "hid:%s", alias); } /* Looks like: ieee1394:venNmoNspNverN */ -static int do_ieee1394_entry(const char *filename, - void *symval, char *alias) +static void do_ieee1394_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ieee1394_device_id, match_flags); DEF_FIELD(symval, ieee1394_device_id, vendor_id); DEF_FIELD(symval, ieee1394_device_id, model_id); DEF_FIELD(symval, ieee1394_device_id, specifier_id); DEF_FIELD(symval, ieee1394_device_id, version); - strcpy(alias, "ieee1394:"); ADD(alias, "ven", match_flags & IEEE1394_MATCH_VENDOR_ID, vendor_id); ADD(alias, "mo", match_flags & IEEE1394_MATCH_MODEL_ID, @@ -434,14 +412,13 @@ static int do_ieee1394_entry(const char *filename, ADD(alias, "ver", match_flags & IEEE1394_MATCH_VERSION, version); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "ieee1394:%s", alias); } /* Looks like: pci:vNdNsvNsdNbcNscNiN or _pci:vNdNsvNsdNbcNscNiN. */ -static int do_pci_entry(const char *filename, - void *symval, char *alias) +static void do_pci_entry(struct module *mod, void *symval) { + char alias[256]; /* Class field can be divided into these three. */ unsigned char baseclass, subclass, interface, baseclass_mask, subclass_mask, interface_mask; @@ -464,7 +441,6 @@ static int do_pci_entry(const char *filename, default: warn("Unknown PCI driver_override alias %08X\n", override_only); - return 0; } ADD(alias, "v", vendor != PCI_ANY_ID, vendor); @@ -483,28 +459,28 @@ static int do_pci_entry(const char *filename, || (subclass_mask != 0 && subclass_mask != 0xFF) || (interface_mask != 0 && interface_mask != 0xFF)) { warn("Can't handle masks in %s:%04X\n", - filename, class_mask); - return 0; + mod->name, class_mask); + return; } ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); ADD(alias, "sc", subclass_mask == 0xFF, subclass); ADD(alias, "i", interface_mask == 0xFF, interface); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "%s", alias); } /* looks like: "ccw:tNmNdtNdmN" */ -static int do_ccw_entry(const char *filename, - void *symval, char *alias) +static void do_ccw_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ccw_device_id, match_flags); DEF_FIELD(symval, ccw_device_id, cu_type); DEF_FIELD(symval, ccw_device_id, cu_model); DEF_FIELD(symval, ccw_device_id, dev_type); DEF_FIELD(symval, ccw_device_id, dev_model); - strcpy(alias, "ccw:"); ADD(alias, "t", match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE, cu_type); ADD(alias, "m", match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL, @@ -513,47 +489,42 @@ static int do_ccw_entry(const char *filename, dev_type); ADD(alias, "dm", match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, dev_model); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ccw:%s", alias); } /* looks like: "ap:tN" */ -static int do_ap_entry(const char *filename, - void *symval, char *alias) +static void do_ap_entry(struct module *mod, void *symval) { DEF_FIELD(symval, ap_device_id, dev_type); - sprintf(alias, "ap:t%02X*", dev_type); - return 1; + module_alias_printf(mod, false, "ap:t%02X*", dev_type); } /* looks like: "css:tN" */ -static int do_css_entry(const char *filename, - void *symval, char *alias) +static void do_css_entry(struct module *mod, void *symval) { DEF_FIELD(symval, css_device_id, type); - sprintf(alias, "css:t%01X", type); - return 1; + module_alias_printf(mod, false, "css:t%01X", type); } /* Looks like: "serio:tyNprNidNexN" */ -static int do_serio_entry(const char *filename, - void *symval, char *alias) +static void do_serio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, serio_device_id, type); DEF_FIELD(symval, serio_device_id, proto); DEF_FIELD(symval, serio_device_id, id); DEF_FIELD(symval, serio_device_id, extra); - strcpy(alias, "serio:"); ADD(alias, "ty", type != SERIO_ANY, type); ADD(alias, "pr", proto != SERIO_ANY, proto); ADD(alias, "id", id != SERIO_ANY, id); ADD(alias, "ex", extra != SERIO_ANY, extra); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "serio:%s", alias); } /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or @@ -563,21 +534,19 @@ static int do_serio_entry(const char *filename, * or _CLS. Also, bb, ss, and pp can be substituted with ?? * as don't care byte. */ -static int do_acpi_entry(const char *filename, - void *symval, char *alias) +static void do_acpi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, acpi_device_id, id); DEF_FIELD(symval, acpi_device_id, cls); DEF_FIELD(symval, acpi_device_id, cls_msk); - if (id && strlen((const char *)*id)) - sprintf(alias, "acpi*:%s:*", *id); + if ((*id)[0]) + module_alias_printf(mod, false, "acpi*:%s:*", *id); else { + char alias[256]; int i, byte_shift, cnt = 0; unsigned int msk; - sprintf(&alias[cnt], "acpi*:"); - cnt = 6; for (i = 1; i <= 3; i++) { byte_shift = 8 * (3-i); msk = (cls_msk >> byte_shift) & 0xFF; @@ -588,101 +557,49 @@ static int do_acpi_entry(const char *filename, sprintf(&alias[cnt], "??"); cnt += 2; } - sprintf(&alias[cnt], ":*"); + module_alias_printf(mod, false, "acpi*:%s:*", alias); } - return 1; } /* looks like: "pnp:dD" */ -static void do_pnp_device_entry(void *symval, unsigned long size, - struct module *mod) +static void do_pnp_device_entry(struct module *mod, void *symval) { - const unsigned long id_size = SIZE_pnp_device_id; - const unsigned int count = (size / id_size)-1; - unsigned int i; - - device_id_check(mod->name, "pnp", size, id_size, symval); + DEF_FIELD_ADDR(symval, pnp_device_id, id); + char acpi_id[sizeof(*id)]; - for (i = 0; i < count; i++) { - DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id); - char acpi_id[sizeof(*id)]; - int j; - - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"pnp:d%s*\");\n", *id); - - /* fix broken pnp bus lowercasing */ - for (j = 0; j < sizeof(acpi_id); j++) - acpi_id[j] = toupper((*id)[j]); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); - } + /* fix broken pnp bus lowercasing */ + for (unsigned int i = 0; i < sizeof(acpi_id); i++) + acpi_id[i] = toupper((*id)[i]); + module_alias_printf(mod, false, "pnp:d%s*", *id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } /* looks like: "pnp:dD" for every device of the card */ -static void do_pnp_card_entries(void *symval, unsigned long size, - struct module *mod) +static void do_pnp_card_entry(struct module *mod, void *symval) { - const unsigned long id_size = SIZE_pnp_card_device_id; - const unsigned int count = (size / id_size)-1; - unsigned int i; - - device_id_check(mod->name, "pnp", size, id_size, symval); - - for (i = 0; i < count; i++) { - unsigned int j; - DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs); - - for (j = 0; j < PNP_MAX_DEVICES; j++) { - const char *id = (char *)(*devs)[j].id; - int i2, j2; - int dup = 0; - - if (!id[0]) - break; + DEF_FIELD_ADDR(symval, pnp_card_device_id, devs); - /* find duplicate, already added value */ - for (i2 = 0; i2 < i && !dup; i2++) { - DEF_FIELD_ADDR_VAR(symval + i2 * id_size, - pnp_card_device_id, - devs, devs_dup); + for (unsigned int i = 0; i < PNP_MAX_DEVICES; i++) { + const char *id = (char *)(*devs)[i].id; + char acpi_id[PNP_ID_LEN]; - for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) { - const char *id2 = - (char *)(*devs_dup)[j2].id; - - if (!id2[0]) - break; - - if (!strcmp(id, id2)) { - dup = 1; - break; - } - } - } - - /* add an individual alias for every device entry */ - if (!dup) { - char acpi_id[PNP_ID_LEN]; - int k; + if (!id[0]) + break; - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"pnp:d%s*\");\n", id); + /* fix broken pnp bus lowercasing */ + for (unsigned int j = 0; j < sizeof(acpi_id); j++) + acpi_id[j] = toupper(id[j]); - /* fix broken pnp bus lowercasing */ - for (k = 0; k < sizeof(acpi_id); k++) - acpi_id[k] = toupper(id[k]); - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); - } - } + /* add an individual alias for every device entry */ + module_alias_printf(mod, false, "pnp:d%s*", id); + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); } } /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */ -static int do_pcmcia_entry(const char *filename, - void *symval, char *alias) +static void do_pcmcia_entry(struct module *mod, void *symval) { + char alias[256] = {}; unsigned int i; DEF_FIELD(symval, pcmcia_device_id, match_flags); DEF_FIELD(symval, pcmcia_device_id, manf_id); @@ -696,7 +613,6 @@ static int do_pcmcia_entry(const char *filename, (*prod_id_hash)[i] = TO_NATIVE((*prod_id_hash)[i]); } - strcpy(alias, "pcmcia:"); ADD(alias, "m", match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID, manf_id); ADD(alias, "c", match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID, @@ -712,13 +628,12 @@ static int do_pcmcia_entry(const char *filename, ADD(alias, "pc", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, (*prod_id_hash)[2]); ADD(alias, "pd", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, (*prod_id_hash)[3]); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "pcmcia:%s", alias); } -static int do_vio_entry(const char *filename, void *symval, - char *alias) +static void do_vio_entry(struct module *mod, void *symval) { + char alias[256]; char *tmp; DEF_FIELD_ADDR(symval, vio_device_id, type); DEF_FIELD_ADDR(symval, vio_device_id, compat); @@ -731,8 +646,7 @@ static int do_vio_entry(const char *filename, void *symval, if (isspace (*tmp)) *tmp = '_'; - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "%s", alias); } static void do_input(char *alias, @@ -748,9 +662,10 @@ static void do_input(char *alias, } /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ -static int do_input_entry(const char *filename, void *symval, - char *alias) +static void do_input_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, input_device_id, flags); DEF_FIELD(symval, input_device_id, bustype); DEF_FIELD(symval, input_device_id, vendor); @@ -766,8 +681,6 @@ static int do_input_entry(const char *filename, void *symval, DEF_FIELD_ADDR(symval, input_device_id, ffbit); DEF_FIELD_ADDR(symval, input_device_id, swbit); - sprintf(alias, "input:"); - ADD(alias, "b", flags & INPUT_DEVICE_ID_MATCH_BUS, bustype); ADD(alias, "v", flags & INPUT_DEVICE_ID_MATCH_VENDOR, vendor); ADD(alias, "p", flags & INPUT_DEVICE_ID_MATCH_PRODUCT, product); @@ -802,102 +715,96 @@ static int do_input_entry(const char *filename, void *symval, sprintf(alias + strlen(alias), "w*"); if (flags & INPUT_DEVICE_ID_MATCH_SWBIT) do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX); - return 1; + + module_alias_printf(mod, false, "input:%s", alias); } -static int do_eisa_entry(const char *filename, void *symval, - char *alias) +static void do_eisa_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, eisa_device_id, sig); - if (sig[0]) - sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig); - else - strcat(alias, "*"); - return 1; + module_alias_printf(mod, false, EISA_DEVICE_MODALIAS_FMT "*", *sig); } /* Looks like: parisc:tNhvNrevNsvN */ -static int do_parisc_entry(const char *filename, void *symval, - char *alias) +static void do_parisc_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, parisc_device_id, hw_type); DEF_FIELD(symval, parisc_device_id, hversion); DEF_FIELD(symval, parisc_device_id, hversion_rev); DEF_FIELD(symval, parisc_device_id, sversion); - strcpy(alias, "parisc:"); ADD(alias, "t", hw_type != PA_HWTYPE_ANY_ID, hw_type); ADD(alias, "hv", hversion != PA_HVERSION_ANY_ID, hversion); ADD(alias, "rev", hversion_rev != PA_HVERSION_REV_ANY_ID, hversion_rev); ADD(alias, "sv", sversion != PA_SVERSION_ANY_ID, sversion); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "parisc:%s", alias); } /* Looks like: sdio:cNvNdN. */ -static int do_sdio_entry(const char *filename, - void *symval, char *alias) +static void do_sdio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, sdio_device_id, class); DEF_FIELD(symval, sdio_device_id, vendor); DEF_FIELD(symval, sdio_device_id, device); - strcpy(alias, "sdio:"); ADD(alias, "c", class != (__u8)SDIO_ANY_ID, class); ADD(alias, "v", vendor != (__u16)SDIO_ANY_ID, vendor); ADD(alias, "d", device != (__u16)SDIO_ANY_ID, device); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "sdio:%s", alias); } /* Looks like: ssb:vNidNrevN. */ -static int do_ssb_entry(const char *filename, - void *symval, char *alias) +static void do_ssb_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ssb_device_id, vendor); DEF_FIELD(symval, ssb_device_id, coreid); DEF_FIELD(symval, ssb_device_id, revision); - strcpy(alias, "ssb:"); ADD(alias, "v", vendor != SSB_ANY_VENDOR, vendor); ADD(alias, "id", coreid != SSB_ANY_ID, coreid); ADD(alias, "rev", revision != SSB_ANY_REV, revision); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ssb:%s", alias); } /* Looks like: bcma:mNidNrevNclN. */ -static int do_bcma_entry(const char *filename, - void *symval, char *alias) +static void do_bcma_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, bcma_device_id, manuf); DEF_FIELD(symval, bcma_device_id, id); DEF_FIELD(symval, bcma_device_id, rev); DEF_FIELD(symval, bcma_device_id, class); - strcpy(alias, "bcma:"); ADD(alias, "m", manuf != BCMA_ANY_MANUF, manuf); ADD(alias, "id", id != BCMA_ANY_ID, id); ADD(alias, "rev", rev != BCMA_ANY_REV, rev); ADD(alias, "cl", class != BCMA_ANY_CLASS, class); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "bcma:%s", alias); } /* Looks like: virtio:dNvN */ -static int do_virtio_entry(const char *filename, void *symval, - char *alias) +static void do_virtio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, virtio_device_id, device); DEF_FIELD(symval, virtio_device_id, vendor); - strcpy(alias, "virtio:"); ADD(alias, "d", device != VIRTIO_DEV_ANY_ID, device); ADD(alias, "v", vendor != VIRTIO_DEV_ANY_ID, vendor); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "virtio:%s", alias); } /* @@ -906,8 +813,7 @@ static int do_virtio_entry(const char *filename, void *symval, * in the name. */ -static int do_vmbus_entry(const char *filename, void *symval, - char *alias) +static void do_vmbus_entry(struct module *mod, void *symval) { int i; DEF_FIELD_ADDR(symval, hv_vmbus_device_id, guid); @@ -916,68 +822,57 @@ static int do_vmbus_entry(const char *filename, void *symval, for (i = 0; i < (sizeof(*guid) * 2); i += 2) sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); - strcpy(alias, "vmbus:"); - strcat(alias, guid_name); - - return 1; + module_alias_printf(mod, false, "vmbus:%s", guid_name); } /* Looks like: rpmsg:S */ -static int do_rpmsg_entry(const char *filename, void *symval, - char *alias) +static void do_rpmsg_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, rpmsg_device_id, name); - sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name); - return 1; + module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name); } /* Looks like: i2c:S */ -static int do_i2c_entry(const char *filename, void *symval, - char *alias) +static void do_i2c_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, i2c_device_id, name); - sprintf(alias, I2C_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, I2C_MODULE_PREFIX "%s", *name); } -static int do_i3c_entry(const char *filename, void *symval, - char *alias) +static void do_i3c_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, i3c_device_id, match_flags); DEF_FIELD(symval, i3c_device_id, dcr); DEF_FIELD(symval, i3c_device_id, manuf_id); DEF_FIELD(symval, i3c_device_id, part_id); DEF_FIELD(symval, i3c_device_id, extra_info); - strcpy(alias, "i3c:"); ADD(alias, "dcr", match_flags & I3C_MATCH_DCR, dcr); ADD(alias, "manuf", match_flags & I3C_MATCH_MANUF, manuf_id); ADD(alias, "part", match_flags & I3C_MATCH_PART, part_id); ADD(alias, "ext", match_flags & I3C_MATCH_EXTRA_INFO, extra_info); - return 1; + module_alias_printf(mod, false, "i3c:%s", alias); } -static int do_slim_entry(const char *filename, void *symval, char *alias) +static void do_slim_entry(struct module *mod, void *symval) { DEF_FIELD(symval, slim_device_id, manf_id); DEF_FIELD(symval, slim_device_id, prod_code); - sprintf(alias, "slim:%x:%x:*", manf_id, prod_code); - - return 1; + module_alias_printf(mod, false, "slim:%x:%x:*", manf_id, prod_code); } /* Looks like: spi:S */ -static int do_spi_entry(const char *filename, void *symval, - char *alias) +static void do_spi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, spi_device_id, name); - sprintf(alias, SPI_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, SPI_MODULE_PREFIX "%s", *name); } static const struct dmifield { @@ -1012,12 +907,11 @@ static void dmi_ascii_filter(char *d, const char *s) } -static int do_dmi_entry(const char *filename, void *symval, - char *alias) +static void do_dmi_entry(struct module *mod, void *symval) { + char alias[256] = {}; int i, j; DEF_FIELD_ADDR(symval, dmi_system_id, matches); - sprintf(alias, "dmi*"); for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) { for (j = 0; j < 4; j++) { @@ -1032,80 +926,75 @@ static int do_dmi_entry(const char *filename, void *symval, } } - strcat(alias, ":"); - return 1; + module_alias_printf(mod, false, "dmi*%s:", alias); } -static int do_platform_entry(const char *filename, - void *symval, char *alias) +static void do_platform_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, platform_device_id, name); - sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name); - return 1; + + module_alias_printf(mod, false, PLATFORM_MODULE_PREFIX "%s", *name); } -static int do_mdio_entry(const char *filename, - void *symval, char *alias) +static void do_mdio_entry(struct module *mod, void *symval) { + char id[33]; int i; DEF_FIELD(symval, mdio_device_id, phy_id); DEF_FIELD(symval, mdio_device_id, phy_id_mask); - alias += sprintf(alias, MDIO_MODULE_PREFIX); - for (i = 0; i < 32; i++) { if (!((phy_id_mask >> (31-i)) & 1)) - *(alias++) = '?'; + id[i] = '?'; else if ((phy_id >> (31-i)) & 1) - *(alias++) = '1'; + id[i] = '1'; else - *(alias++) = '0'; + id[i] = '0'; } /* Terminate the string */ - *alias = 0; + id[32] = '\0'; - return 1; + module_alias_printf(mod, false, MDIO_MODULE_PREFIX "%s", id); } /* Looks like: zorro:iN. */ -static int do_zorro_entry(const char *filename, void *symval, - char *alias) +static void do_zorro_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD(symval, zorro_device_id, id); - strcpy(alias, "zorro:"); + ADD(alias, "i", id != ZORRO_WILDCARD, id); - return 1; + + module_alias_printf(mod, false, "zorro:%s", alias); } /* looks like: "pnp:dD" */ -static int do_isapnp_entry(const char *filename, - void *symval, char *alias) +static void do_isapnp_entry(struct module *mod, void *symval) { DEF_FIELD(symval, isapnp_device_id, vendor); DEF_FIELD(symval, isapnp_device_id, function); - sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", + module_alias_printf(mod, false, "pnp:d%c%c%c%x%x%x%x*", 'A' + ((vendor >> 2) & 0x3f) - 1, 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, 'A' + ((vendor >> 8) & 0x1f) - 1, (function >> 4) & 0x0f, function & 0x0f, (function >> 12) & 0x0f, (function >> 8) & 0x0f); - return 1; } /* Looks like: "ipack:fNvNdN". */ -static int do_ipack_entry(const char *filename, - void *symval, char *alias) +static void do_ipack_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD(symval, ipack_device_id, format); DEF_FIELD(symval, ipack_device_id, vendor); DEF_FIELD(symval, ipack_device_id, device); - strcpy(alias, "ipack:"); + ADD(alias, "f", format != IPACK_ANY_FORMAT, format); ADD(alias, "v", vendor != IPACK_ANY_ID, vendor); ADD(alias, "d", device != IPACK_ANY_ID, device); - add_wildcard(alias); - return 1; + + module_alias_printf(mod, true, "ipack:%s", alias); } /* @@ -1156,9 +1045,9 @@ static void append_nibble_mask(char **outp, * N is exactly 8 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_amba_entry(const char *filename, - void *symval, char *alias) +static void do_amba_entry(struct module *mod, void *symval) { + char alias[256]; unsigned int digit; char *p = alias; DEF_FIELD(symval, amba_id, id); @@ -1166,15 +1055,14 @@ static int do_amba_entry(const char *filename, if ((id & mask) != id) fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: id=0x%08X, mask=0x%08X. Please fix this driver.\n", - filename, id, mask); + mod->name, id, mask); - p += sprintf(alias, "amba:d"); for (digit = 0; digit < 8; digit++) append_nibble_mask(&p, (id >> (4 * (7 - digit))) & 0xf, (mask >> (4 * (7 - digit))) & 0xf); - return 1; + module_alias_printf(mod, false, "amba:d%s", alias); } /* @@ -1183,13 +1071,11 @@ static int do_amba_entry(const char *filename, * N is exactly 2 digits, where each is an upper-case hex digit, or * a ? or [] pattern matching exactly one digit. */ -static int do_mips_cdmm_entry(const char *filename, - void *symval, char *alias) +static void do_mips_cdmm_entry(struct module *mod, void *symval) { DEF_FIELD(symval, mips_cdmm_device_id, type); - sprintf(alias, "mipscdmm:t%02X*", type); - return 1; + module_alias_printf(mod, false, "mipscdmm:t%02X*", type); } /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* @@ -1198,137 +1084,130 @@ static int do_mips_cdmm_entry(const char *filename, * complicated. */ -static int do_x86cpu_entry(const char *filename, void *symval, - char *alias) +static void do_x86cpu_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, x86_cpu_id, feature); DEF_FIELD(symval, x86_cpu_id, family); DEF_FIELD(symval, x86_cpu_id, model); DEF_FIELD(symval, x86_cpu_id, vendor); - strcpy(alias, "cpu:type:x86,"); ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor); ADD(alias, "fam", family != X86_FAMILY_ANY, family); ADD(alias, "mod", model != X86_MODEL_ANY, model); strcat(alias, ":feature:*"); if (feature != X86_FEATURE_ANY) sprintf(alias + strlen(alias), "%04X*", feature); - return 1; + + module_alias_printf(mod, false, "cpu:type:x86,%s", alias); } /* LOOKS like cpu:type:*:feature:*FEAT* */ -static int do_cpu_entry(const char *filename, void *symval, char *alias) +static void do_cpu_entry(struct module *mod, void *symval) { DEF_FIELD(symval, cpu_feature, feature); - sprintf(alias, "cpu:type:*:feature:*%04X*", feature); - return 1; + module_alias_printf(mod, false, "cpu:type:*:feature:*%04X*", feature); } /* Looks like: mei:S:uuid:N:* */ -static int do_mei_entry(const char *filename, void *symval, - char *alias) +static void do_mei_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD_ADDR(symval, mei_cl_device_id, name); DEF_FIELD_ADDR(symval, mei_cl_device_id, uuid); DEF_FIELD(symval, mei_cl_device_id, version); - sprintf(alias, MEI_CL_MODULE_PREFIX); - sprintf(alias + strlen(alias), "%s:", (*name)[0] ? *name : "*"); add_uuid(alias, *uuid); ADD(alias, ":", version != MEI_CL_VERSION_ANY, version); - strcat(alias, ":*"); - - return 1; + module_alias_printf(mod, false, MEI_CL_MODULE_PREFIX "%s:%s:*", + (*name)[0] ? *name : "*", alias); } /* Looks like: rapidio:vNdNavNadN */ -static int do_rio_entry(const char *filename, - void *symval, char *alias) +static void do_rio_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, rio_device_id, did); DEF_FIELD(symval, rio_device_id, vid); DEF_FIELD(symval, rio_device_id, asm_did); DEF_FIELD(symval, rio_device_id, asm_vid); - strcpy(alias, "rapidio:"); ADD(alias, "v", vid != RIO_ANY_ID, vid); ADD(alias, "d", did != RIO_ANY_ID, did); ADD(alias, "av", asm_vid != RIO_ANY_ID, asm_vid); ADD(alias, "ad", asm_did != RIO_ANY_ID, asm_did); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "rapidio:%s", alias); } /* Looks like: ulpi:vNpN */ -static int do_ulpi_entry(const char *filename, void *symval, - char *alias) +static void do_ulpi_entry(struct module *mod, void *symval) { DEF_FIELD(symval, ulpi_device_id, vendor); DEF_FIELD(symval, ulpi_device_id, product); - sprintf(alias, "ulpi:v%04xp%04x", vendor, product); - - return 1; + module_alias_printf(mod, false, "ulpi:v%04xp%04x", vendor, product); } /* Looks like: hdaudio:vNrNaN */ -static int do_hda_entry(const char *filename, void *symval, char *alias) +static void do_hda_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, hda_device_id, vendor_id); DEF_FIELD(symval, hda_device_id, rev_id); DEF_FIELD(symval, hda_device_id, api_version); - strcpy(alias, "hdaudio:"); ADD(alias, "v", vendor_id != 0, vendor_id); ADD(alias, "r", rev_id != 0, rev_id); ADD(alias, "a", api_version != 0, api_version); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "hdaudio:%s", alias); } /* Looks like: sdw:mNpNvNcN */ -static int do_sdw_entry(const char *filename, void *symval, char *alias) +static void do_sdw_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, sdw_device_id, mfg_id); DEF_FIELD(symval, sdw_device_id, part_id); DEF_FIELD(symval, sdw_device_id, sdw_version); DEF_FIELD(symval, sdw_device_id, class_id); - strcpy(alias, "sdw:"); ADD(alias, "m", mfg_id != 0, mfg_id); ADD(alias, "p", part_id != 0, part_id); ADD(alias, "v", sdw_version != 0, sdw_version); ADD(alias, "c", class_id != 0, class_id); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "sdw:%s", alias); } /* Looks like: fsl-mc:vNdN */ -static int do_fsl_mc_entry(const char *filename, void *symval, - char *alias) +static void do_fsl_mc_entry(struct module *mod, void *symval) { DEF_FIELD(symval, fsl_mc_device_id, vendor); DEF_FIELD_ADDR(symval, fsl_mc_device_id, obj_type); - sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type); - return 1; + module_alias_printf(mod, false, "fsl-mc:v%08Xd%s", vendor, *obj_type); } /* Looks like: tbsvc:kSpNvNrN */ -static int do_tbsvc_entry(const char *filename, void *symval, char *alias) +static void do_tbsvc_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, tb_service_id, match_flags); DEF_FIELD_ADDR(symval, tb_service_id, protocol_key); DEF_FIELD(symval, tb_service_id, protocol_id); DEF_FIELD(symval, tb_service_id, protocol_version); DEF_FIELD(symval, tb_service_id, protocol_revision); - strcpy(alias, "tbsvc:"); if (match_flags & TBSVC_MATCH_PROTOCOL_KEY) sprintf(alias + strlen(alias), "k%s", *protocol_key); else @@ -1339,93 +1218,80 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias) ADD(alias, "r", match_flags & TBSVC_MATCH_PROTOCOL_REVISION, protocol_revision); - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "tbsvc:%s", alias); } /* Looks like: typec:idNmN */ -static int do_typec_entry(const char *filename, void *symval, char *alias) +static void do_typec_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, typec_device_id, svid); DEF_FIELD(symval, typec_device_id, mode); - sprintf(alias, "typec:id%04X", svid); ADD(alias, "m", mode != TYPEC_ANY_MODE, mode); - return 1; + module_alias_printf(mod, false, "typec:id%04X%s", svid, alias); } /* Looks like: tee:uuid */ -static int do_tee_entry(const char *filename, void *symval, char *alias) +static void do_tee_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); - sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + module_alias_printf(mod, true, + "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], uuid->b[15]); - - add_wildcard(alias); - return 1; } /* Looks like: wmi:guid */ -static int do_wmi_entry(const char *filename, void *symval, char *alias) +static void do_wmi_entry(struct module *mod, void *symval) { - int len; DEF_FIELD_ADDR(symval, wmi_device_id, guid_string); if (strlen(*guid_string) != UUID_STRING_LEN) { warn("Invalid WMI device id 'wmi:%s' in '%s'\n", - *guid_string, filename); - return 0; + *guid_string, mod->name); + return; } - len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string); - if (len < 0 || len >= ALIAS_SIZE) { - warn("Could not generate all MODULE_ALIAS's in '%s'\n", - filename); - return 0; - } - return 1; + module_alias_printf(mod, false, WMI_MODULE_PREFIX "%s", *guid_string); } /* Looks like: mhi:S */ -static int do_mhi_entry(const char *filename, void *symval, char *alias) +static void do_mhi_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); - sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); - return 1; + module_alias_printf(mod, false, MHI_DEVICE_MODALIAS_FMT, *chan); } /* Looks like: mhi_ep:S */ -static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) +static void do_mhi_ep_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, mhi_device_id, chan); - sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); - return 1; + module_alias_printf(mod, false, MHI_EP_DEVICE_MODALIAS_FMT, *chan); } /* Looks like: ishtp:{guid} */ -static int do_ishtp_entry(const char *filename, void *symval, char *alias) +static void do_ishtp_entry(struct module *mod, void *symval) { + char alias[256] = {}; DEF_FIELD_ADDR(symval, ishtp_device_id, guid); - strcpy(alias, ISHTP_MODULE_PREFIX "{"); add_guid(alias, *guid); - strcat(alias, "}"); - return 1; + module_alias_printf(mod, false, ISHTP_MODULE_PREFIX "{%s}", alias); } -static int do_auxiliary_entry(const char *filename, void *symval, char *alias) +static void do_auxiliary_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, auxiliary_device_id, name); - sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); - return 1; + module_alias_printf(mod, false, AUXILIARY_MODULE_PREFIX "%s", *name); } /* @@ -1433,8 +1299,10 @@ static int do_auxiliary_entry(const char *filename, void *symval, char *alias) * * N is exactly 2 digits, where each is an upper-case hex digit. */ -static int do_ssam_entry(const char *filename, void *symval, char *alias) +static void do_ssam_entry(struct module *mod, void *symval) { + char alias[256] = {}; + DEF_FIELD(symval, ssam_device_id, match_flags); DEF_FIELD(symval, ssam_device_id, domain); DEF_FIELD(symval, ssam_device_id, category); @@ -1442,30 +1310,28 @@ static int do_ssam_entry(const char *filename, void *symval, char *alias) DEF_FIELD(symval, ssam_device_id, instance); DEF_FIELD(symval, ssam_device_id, function); - sprintf(alias, "ssam:d%02Xc%02X", domain, category); ADD(alias, "t", match_flags & SSAM_MATCH_TARGET, target); ADD(alias, "i", match_flags & SSAM_MATCH_INSTANCE, instance); ADD(alias, "f", match_flags & SSAM_MATCH_FUNCTION, function); - return 1; + module_alias_printf(mod, false, "ssam:d%02Xc%02X%s", + domain, category, alias); } /* Looks like: dfl:tNfN */ -static int do_dfl_entry(const char *filename, void *symval, char *alias) +static void do_dfl_entry(struct module *mod, void *symval) { DEF_FIELD(symval, dfl_device_id, type); DEF_FIELD(symval, dfl_device_id, feature_id); - sprintf(alias, "dfl:t%04Xf%04X", type, feature_id); - - add_wildcard(alias); - return 1; + module_alias_printf(mod, true, "dfl:t%04Xf%04X", type, feature_id); } /* Looks like: cdx:vNdN */ -static int do_cdx_entry(const char *filename, void *symval, - char *alias) +static void do_cdx_entry(struct module *mod, void *symval) { + char alias[256]; + DEF_FIELD(symval, cdx_device_id, vendor); DEF_FIELD(symval, cdx_device_id, device); DEF_FIELD(symval, cdx_device_id, subvendor); @@ -1484,7 +1350,7 @@ static int do_cdx_entry(const char *filename, void *symval, default: warn("Unknown CDX driver_override alias %08X\n", override_only); - return 0; + return; } ADD(alias, "v", vendor != CDX_ANY_ID, vendor); @@ -1493,24 +1359,22 @@ static int do_cdx_entry(const char *filename, void *symval, ADD(alias, "sd", subdevice != CDX_ANY_ID, subdevice); ADD(alias, "c", class_mask == 0xFFFFFF, class); - return 1; + module_alias_printf(mod, false, "%s", alias); } -static int do_vchiq_entry(const char *filename, void *symval, char *alias) +static void do_vchiq_entry(struct module *mod, void *symval) { DEF_FIELD_ADDR(symval, vchiq_device_id, name); - sprintf(alias, "vchiq:%s", *name); - return 1; + module_alias_printf(mod, false, "vchiq:%s", *name); } /* Looks like: coreboot:tN */ -static int do_coreboot_entry(const char *filename, void *symval, char *alias) +static void do_coreboot_entry(struct module *mod, void *symval) { DEF_FIELD(symval, coreboot_device_id, tag); - sprintf(alias, "coreboot:t%08X", tag); - return 1; + module_alias_printf(mod, false, "coreboot:t%08X", tag); } /* Does namelen bytes of name exactly match the symbol? */ @@ -1522,25 +1386,34 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol) return memcmp(name, symbol, namelen) == 0; } -static void do_table(void *symval, unsigned long size, +static void do_table(const char *name, void *symval, unsigned long size, unsigned long id_size, const char *device_id, - int (*do_entry)(const char *filename, void *symval, char *alias), + void (*do_entry)(struct module *mod, void *symval), struct module *mod) { unsigned int i; - char alias[ALIAS_SIZE]; - device_id_check(mod->name, device_id, size, id_size, symval); - /* Leave last one: it's the terminator. */ - size -= id_size; + if (size % id_size || size < id_size) { + error("%s: type mismatch between %s[] and MODULE_DEVICE_TABLE(%s, ...)\n", + mod->name, name, device_id); + return; + } - for (i = 0; i < size; i += id_size) { - if (do_entry(mod->name, symval+i, alias)) { - buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"%s\");\n", alias); + /* Verify the last entry is a terminator */ + for (i = size - id_size; i < size; i++) { + if (*(uint8_t *)(symval + i)) { + error("%s: %s[] is not terminated with a NULL entry\n", + mod->name, name); + return; } } + + /* Leave last one: it's the terminator. */ + size -= id_size; + + for (i = 0; i < size; i += id_size) + do_entry(mod, symval + i); } static const struct devtable devtable[] = { @@ -1596,6 +1469,10 @@ static const struct devtable devtable[] = { {"cdx", SIZE_cdx_device_id, do_cdx_entry}, {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, + {"of", SIZE_of_device_id, do_of_entry}, + {"usb", SIZE_usb_device_id, do_usb_entry_multi}, + {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, + {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, }; /* Create MODULE_ALIAS() statements. @@ -1606,8 +1483,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, { void *symval; char *zeros = NULL; - const char *name, *identifier; - unsigned int namelen; + const char *type, *name; + size_t typelen; + static const char *prefix = "__mod_device_table__"; /* We're looking for a section relative symbol */ if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) @@ -1617,19 +1495,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) return; - /* All our symbols are of form __mod____device_table. */ - if (strncmp(symname, "__mod_", strlen("__mod_"))) - return; - name = symname + strlen("__mod_"); - namelen = strlen(name); - if (namelen < strlen("_device_table")) - return; - if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) + /* All our symbols are of form __mod_device_table____. */ + if (!strstarts(symname, prefix)) return; - identifier = strstr(name, "__"); - if (!identifier) + type = symname + strlen(prefix); + + name = strstr(type, "__"); + if (!name) return; - namelen = identifier - name; + typelen = name - type; + name += strlen("__"); /* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { @@ -1639,35 +1514,15 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, symval = sym_get_data(info, sym); } - /* First handle the "special" cases */ - if (sym_is(name, namelen, "usb")) - do_usb_table(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "of")) - do_of_table(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "pnp")) - do_pnp_device_entry(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "pnp_card")) - do_pnp_card_entries(symval, sym->st_size, mod); - else { - int i; - - for (i = 0; i < ARRAY_SIZE(devtable); i++) { - const struct devtable *p = &devtable[i]; + for (int i = 0; i < ARRAY_SIZE(devtable); i++) { + const struct devtable *p = &devtable[i]; - if (sym_is(name, namelen, p->device_id)) { - do_table(symval, sym->st_size, p->id_size, - p->device_id, p->do_entry, mod); - break; - } + if (sym_is(type, typelen, p->device_id)) { + do_table(name, symval, sym->st_size, p->id_size, + p->device_id, p->do_entry, mod); + break; } } - free(zeros); -} -/* Now add out buffered information to the generated C source */ -void add_moddevtable(struct buffer *buf, struct module *mod) -{ - buf_printf(buf, "\n"); - buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos); - free(mod->dev_table_buf.p); + free(zeros); } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 107393a8c48a5993dbe456702fec0652a967ee86..0584cbcdbd2d65d0c80932af35f2ae518125a022 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -176,6 +177,7 @@ static struct module *new_module(const char *name, size_t namelen) INIT_LIST_HEAD(&mod->unresolved_symbols); INIT_LIST_HEAD(&mod->missing_namespaces); INIT_LIST_HEAD(&mod->imported_namespaces); + INIT_LIST_HEAD(&mod->aliases); memcpy(mod->name, name, namelen); mod->name[namelen] = '\0'; @@ -209,19 +211,6 @@ struct symbol { static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10); -/* This is based on the hash algorithm from gdbm, via tdb */ -static inline unsigned int tdb_hash(const char *name) -{ - unsigned value; /* Used to compute the hash value. */ - unsigned i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) - value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - /** * Allocate a new symbols for use in the hash of exported symbols or * the list of unresolved symbols per module @@ -239,7 +228,7 @@ static struct symbol *alloc_symbol(const char *name) /* For the hash of exported symbols */ static void hash_add_symbol(struct symbol *sym) { - hash_add(symbol_hashtable, &sym->hnode, tdb_hash(sym->name)); + hash_add(symbol_hashtable, &sym->hnode, hash_str(sym->name)); } static void sym_add_unresolved(const char *name, struct module *mod, bool weak) @@ -260,7 +249,7 @@ static struct symbol *sym_find_with_module(const char *name, struct module *mod) if (name[0] == '.') name++; - hash_for_each_possible(symbol_hashtable, s, hnode, tdb_hash(name)) { + hash_for_each_possible(symbol_hashtable, s, hnode, hash_str(name)) { if (strcmp(s->name, name) == 0 && (!mod || s->module == mod)) return s; } @@ -340,8 +329,6 @@ static const char *sec_name(const struct elf_info *info, unsigned int secindex) return sech_name(info, &info->sechdrs[secindex]); } -#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) - static struct symbol *sym_add_exported(const char *name, struct module *mod, bool gpl_only, const char *namespace) { @@ -1966,6 +1953,7 @@ static void write_vmlinux_export_c_file(struct module *mod) static void write_mod_c_file(struct module *mod) { struct buffer buf = { }; + struct module_alias *alias, *next; char fname[PATH_MAX]; int ret; @@ -1973,7 +1961,14 @@ static void write_mod_c_file(struct module *mod) add_exported_symbols(&buf, mod); add_versions(&buf, mod); add_depends(&buf, mod); - add_moddevtable(&buf, mod); + + buf_printf(&buf, "\n"); + list_for_each_entry_safe(alias, next, &mod->aliases, node) { + buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str); + list_del(&alias->node); + free(alias); + } + add_srcversion(&buf, mod); ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index ada3a36cc4bc9388d761400f7df2239a9d66a976..49848fcbe2a1250adfcda52a9869986d500809aa 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -67,6 +67,8 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) + struct buffer { char *p; int pos; @@ -79,6 +81,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...); void buf_write(struct buffer *buf, const char *s, int len); +/** + * struct module_alias - auto-generated MODULE_ALIAS() + * + * @node: linked to module::aliases + * @str: a string for MODULE_ALIAS() + */ +struct module_alias { + struct list_head node; + char str[]; +}; + +/** + * struct module - represent a module (vmlinux or *.ko) + * + * @aliases: list head for module_aliases + */ struct module { struct list_head list; struct list_head exported_symbols; @@ -89,12 +107,12 @@ struct module { bool seen; bool has_init; bool has_cleanup; - struct buffer dev_table_buf; char srcversion[25]; // Missing namespace dependencies struct list_head missing_namespaces; // Actual imported namespaces struct list_head imported_namespaces; + struct list_head aliases; char name[]; }; @@ -170,7 +188,6 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, /* file2alias.c */ void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); -void add_moddevtable(struct buffer *buf, struct module *mod); /* sumversion.c */ void get_src_version(const char *modname, char sum[], unsigned sumlen); diff --git a/scripts/nsdeps b/scripts/nsdeps index f1718cc0d700bb9db486383efe4036633d3691c2..a3372166ac01b91a8f8d654e187edcfe7e566415 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -19,22 +19,16 @@ if ! { echo "$SPATCH_REQ_VERSION"; echo "$SPATCH_VERSION"; } | sort -CV ; then exit 1 fi -if [ "$KBUILD_EXTMOD" ]; then - src_prefix= -else - src_prefix=$srctree/ -fi - generate_deps_for_ns() { $SPATCH --very-quiet --in-place --sp-file \ - $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2 + $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=\"$1\" $2 } generate_deps() { local mod=${1%.ko:} shift local namespaces="$*" - local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod) + local mod_source_files=$(sed "s|^\(.*\)\.o$|${srcroot}/\1.c|" $mod.mod) for ns in $namespaces; do echo "Adding namespace $ns to module $mod.ko." @@ -57,4 +51,4 @@ generate_deps() { while read line do generate_deps $line -done < $MODULES_NSDEPS +done < modules.nsdeps diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 441b0bb66e0d0c66362ece081f5a2d314708db87..fb686fd3266f01207f422f0988a857c915160c27 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -96,16 +96,18 @@ install_linux_image_dbg () { # Parse modules.order directly because 'make modules_install' may sign, # compress modules, and then run unneeded depmod. - while read -r mod; do - mod="${mod%.o}.ko" - dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}" - buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') - link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug" - - mkdir -p "${dbg%/*}" "${link%/*}" - "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}" - ln -sf --relative "${dbg}" "${link}" - done < modules.order + if is_enabled CONFIG_MODULES; then + while read -r mod; do + mod="${mod%.o}.ko" + dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}" + buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') + link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug" + + mkdir -p "${dbg%/*}" "${link%/*}" + "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}" + ln -sf --relative "${dbg}" "${link}" + done < modules.order + fi # Build debug package # Different tools want the image in different locations diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build index 7ec1f061a519c70ad33a5434608d1060b26b089a..64d958ee45f38623b027bf19162d76583c6594fc 100755 --- a/scripts/package/install-extmod-build +++ b/scripts/package/install-extmod-build @@ -51,6 +51,13 @@ mkdir -p "${destdir}" if [ "${CC}" != "${HOSTCC}" ]; then echo "Rebuilding host programs with ${CC}..." + # This leverages external module building. + # - Clear sub_make_done to allow the top-level Makefile to redo sub-make. + # - Filter out --no-print-directory to print "Entering directory" logs + # when Make changes the working directory. + unset sub_make_done + MAKEFLAGS=$(echo "${MAKEFLAGS}" | sed s/--no-print-directory//) + cat <<-'EOF' > "${destdir}/Kbuild" subdir-y := scripts EOF diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index fc3b7fa709fcf2610bed22ff2953a4e4fc0d217a..4ffcc70f8e319c88439ab80c020f9da8087eac23 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -202,7 +202,7 @@ Build-Depends-Arch: bc, bison, cpio, flex, gcc-${host_gnu} , kmod, libelf-dev:native, libssl-dev:native, libssl-dev , - rsync + python3:native, rsync Homepage: https://www.kernel.org/ Package: $packagename-$version diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 38b96c6797f4080ee07fc40e074638994d5ba3d0..28169d7e143b6999d93a0471f5d20927a53522fb 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -10,6 +10,8 @@ # # +set -e + usage() { echo "Usage: $0 [--no-local] [srctree]" >&2 exit 1 @@ -30,6 +32,29 @@ if test $# -gt 0 -o ! -d "$srctree"; then usage fi +try_tag() { + tag="$1" + + # Is $tag an annotated tag? + if [ "$(git cat-file -t "$tag" 2> /dev/null)" != tag ]; then + return + fi + + # Is it an ancestor of HEAD, and if so, how many commits are in $tag..HEAD? + # shellcheck disable=SC2046 # word splitting is the point here + set -- $(git rev-list --count --left-right "$tag"...HEAD 2> /dev/null) + + # $1 is 0 if and only if $tag is an ancestor of HEAD. Use + # string comparison, because $1 is empty if the 'git rev-list' + # command somehow failed. + if [ "$1" != 0 ]; then + return + fi + + # $2 is the number of commits in the range $tag..HEAD, possibly 0. + count="$2" +} + scm_version() { local short=false @@ -61,33 +86,33 @@ scm_version() # stable kernel: 6.1.7 -> v6.1.7 version_tag=v$(echo "${KERNELVERSION}" | sed -E 's/^([0-9]+\.[0-9]+)\.0(.*)$/\1\2/') + # try_tag initializes count if the tag is usable. + count= + # If a localversion* file exists, and the corresponding # annotated tag exists and is an ancestor of HEAD, use # it. This is the case in linux-next. - tag=${file_localversion#-} - desc= - if [ -n "${tag}" ]; then - desc=$(git describe --match=$tag 2>/dev/null) + if [ -n "${file_localversion#-}" ] ; then + try_tag "${file_localversion#-}" fi # Otherwise, if a localversion* file exists, and the tag # obtained by appending it to the tag derived from # KERNELVERSION exists and is an ancestor of HEAD, use # it. This is e.g. the case in linux-rt. - if [ -z "${desc}" ] && [ -n "${file_localversion}" ]; then - tag="${version_tag}${file_localversion}" - desc=$(git describe --match=$tag 2>/dev/null) + if [ -z "${count}" ] && [ -n "${file_localversion}" ]; then + try_tag "${version_tag}${file_localversion}" fi # Otherwise, default to the annotated tag derived from KERNELVERSION. - if [ -z "${desc}" ]; then - tag="${version_tag}" - desc=$(git describe --match=$tag 2>/dev/null) + if [ -z "${count}" ]; then + try_tag "${version_tag}" fi - # If we are at the tagged commit, we ignore it because the version is - # well-defined. - if [ "${tag}" != "${desc}" ]; then + # If we are at the tagged commit, we ignore it because the + # version is well-defined. If none of the attempted tags exist + # or were usable, $count is still empty. + if [ -z "${count}" ] || [ "${count}" -gt 0 ]; then # If only the short version is requested, don't bother # running further git commands @@ -95,14 +120,15 @@ scm_version() echo "+" return fi + # If we are past the tagged commit, we pretty print it. # (like 6.1.0-14595-g292a089d78d3) - if [ -n "${desc}" ]; then - echo "${desc}" | awk -F- '{printf("-%05d", $(NF-1))}' + if [ -n "${count}" ]; then + printf "%s%05d" "-" "${count}" fi # Add -g and exactly 12 hex chars. - printf '%s%s' -g "$(echo $head | cut -c1-12)" + printf '%s%.12s' -g "$head" fi if ${no_dirty}; then diff --git a/scripts/tags.sh b/scripts/tags.sh index 0d01c1cafb709e12971d1f9f20ad4ba7d75048c1..b21236377998027678325fe26c547d7281c1cfe5 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -189,7 +189,7 @@ regex_c=( '/\ #include #include +#include #include "include/apparmor.h" #include "include/capability.h" @@ -30,8 +31,9 @@ struct aa_sfs_entry aa_sfs_entry_caps[] = { }; struct audit_cache { - struct aa_profile *profile; - kernel_cap_t caps; + const struct cred *ad_subj_cred; + /* Capabilities go from 0 to CAP_LAST_CAP */ + u64 ktime_ns_expiration[CAP_LAST_CAP+1]; }; static DEFINE_PER_CPU(struct audit_cache, audit_cache); @@ -64,6 +66,8 @@ static void audit_cb(struct audit_buffer *ab, void *va) static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile, int cap, int error) { + const u64 AUDIT_CACHE_TIMEOUT_NS = 1000*1000*1000; /* 1 second */ + struct aa_ruleset *rules = list_first_entry(&profile->rules, typeof(*rules), list); struct audit_cache *ent; @@ -89,15 +93,16 @@ static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile /* Do simple duplicate message elimination */ ent = &get_cpu_var(audit_cache); - if (profile == ent->profile && cap_raised(ent->caps, cap)) { + /* If the capability was never raised the timestamp check would also catch that */ + if (ad->subj_cred == ent->ad_subj_cred && ktime_get_ns() <= ent->ktime_ns_expiration[cap]) { put_cpu_var(audit_cache); if (COMPLAIN_MODE(profile)) return complain_error(error); return error; } else { - aa_put_profile(ent->profile); - ent->profile = aa_get_profile(profile); - cap_raise(ent->caps, cap); + put_cred(ent->ad_subj_cred); + ent->ad_subj_cred = get_cred(ad->subj_cred); + ent->ktime_ns_expiration[cap] = ktime_get_ns() + AUDIT_CACHE_TIMEOUT_NS; } put_cpu_var(audit_cache); @@ -109,7 +114,7 @@ static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile * @profile: profile being enforced (NOT NULL, NOT unconfined) * @cap: capability to test if allowed * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated - * @ad: audit data (MAY BE NULL indicating no auditing) + * @ad: audit data (NOT NULL) * * Returns: 0 if allowed else -EPERM */ diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 2bc34dce9a4688206216ab0ec775d0c20b6b025b..5939bd9a9b9bb049a4202767775b0dd11a43d997 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -636,6 +636,7 @@ static struct aa_label *profile_transition(const struct cred *subj_cred, struct aa_ruleset *rules = list_first_entry(&profile->rules, typeof(*rules), list); struct aa_label *new = NULL; + struct aa_profile *new_profile = NULL; const char *info = NULL, *name = NULL, *target = NULL; aa_state_t state = rules->file->start[AA_CLASS_FILE]; struct aa_perms perms = {}; @@ -680,15 +681,18 @@ static struct aa_label *profile_transition(const struct cred *subj_cred, /* hack ix fallback - improve how this is detected */ goto audit; } else if (!new) { - error = -EACCES; info = "profile transition not found"; - /* remove MAY_EXEC to audit as failure */ + /* remove MAY_EXEC to audit as failure or complaint */ perms.allow &= ~MAY_EXEC; + if (COMPLAIN_MODE(profile)) { + /* create null profile instead of failing */ + goto create_learning_profile; + } + error = -EACCES; } } else if (COMPLAIN_MODE(profile)) { +create_learning_profile: /* no exec permission - learning mode */ - struct aa_profile *new_profile = NULL; - new_profile = aa_new_learning_profile(profile, false, name, GFP_KERNEL); if (!new_profile) { @@ -709,8 +713,8 @@ static struct aa_label *profile_transition(const struct cred *subj_cred, if (!(perms.xindex & AA_X_UNSAFE)) { if (DEBUG_ON) { - dbg_printk("apparmor: scrubbing environment variables" - " for %s profile=", name); + dbg_printk("apparmor: setting AT_SECURE for %s profile=", + name); aa_label_printk(new, GFP_KERNEL); dbg_printk("\n"); } @@ -789,8 +793,8 @@ static int profile_onexec(const struct cred *subj_cred, if (!(perms.xindex & AA_X_UNSAFE)) { if (DEBUG_ON) { - dbg_printk("apparmor: scrubbing environment " - "variables for %s label=", xname); + dbg_printk("apparmor: setting AT_SECURE for %s label=", + xname); aa_label_printk(onexec, GFP_KERNEL); dbg_printk("\n"); } @@ -821,33 +825,19 @@ static struct aa_label *handle_onexec(const struct cred *subj_cred, AA_BUG(!bprm); AA_BUG(!buffer); - if (!stack) { - error = fn_for_each_in_ns(label, profile, - profile_onexec(subj_cred, profile, onexec, stack, - bprm, buffer, cond, unsafe)); - if (error) - return ERR_PTR(error); - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, - aa_get_newest_label(onexec), - profile_transition(subj_cred, profile, bprm, - buffer, - cond, unsafe)); - - } else { - /* TODO: determine how much we want to loosen this */ - error = fn_for_each_in_ns(label, profile, - profile_onexec(subj_cred, profile, onexec, stack, bprm, - buffer, cond, unsafe)); - if (error) - return ERR_PTR(error); - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, - aa_label_merge(&profile->label, onexec, - GFP_KERNEL), - profile_transition(subj_cred, profile, bprm, - buffer, - cond, unsafe)); - } + /* TODO: determine how much we want to loosen this */ + error = fn_for_each_in_ns(label, profile, + profile_onexec(subj_cred, profile, onexec, stack, + bprm, buffer, cond, unsafe)); + if (error) + return ERR_PTR(error); + new = fn_label_build_in_ns(label, profile, GFP_KERNEL, + stack ? aa_label_merge(&profile->label, onexec, + GFP_KERNEL) + : aa_get_newest_label(onexec), + profile_transition(subj_cred, profile, bprm, + buffer, cond, unsafe)); if (new) return new; @@ -960,8 +950,8 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) if (unsafe) { if (DEBUG_ON) { - dbg_printk("scrubbing environment variables for %s " - "label=", bprm->filename); + dbg_printk("setting AT_SECURE for %s label=", + bprm->filename); aa_label_printk(new, GFP_KERNEL); dbg_printk("\n"); } @@ -971,8 +961,8 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) if (label->proxy != new->proxy) { /* when transitioning clear unsafe personality bits */ if (DEBUG_ON) { - dbg_printk("apparmor: clearing unsafe personality " - "bits. %s label=", bprm->filename); + dbg_printk("apparmor: clearing unsafe personality bits. %s label=", + bprm->filename); aa_label_printk(new, GFP_KERNEL); dbg_printk("\n"); } diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h index 2a72e6b17d68bc7affb6f13b553ea2c17a6cc90c..93290ae300bb2e4dc4acd64e64c083f9130565cd 100644 --- a/security/apparmor/include/label.h +++ b/security/apparmor/include/label.h @@ -160,31 +160,7 @@ int aa_label_next_confined(struct aa_label *l, int i); #define label_for_each_cont(I, L, P) \ for (++((I).i); ((P) = (L)->vec[(I).i]); ++((I).i)) -#define next_comb(I, L1, L2) \ -do { \ - (I).j++; \ - if ((I).j >= (L2)->size) { \ - (I).i++; \ - (I).j = 0; \ - } \ -} while (0) - -/* for each combination of P1 in L1, and P2 in L2 */ -#define label_for_each_comb(I, L1, L2, P1, P2) \ -for ((I).i = (I).j = 0; \ - ((P1) = (L1)->vec[(I).i]) && ((P2) = (L2)->vec[(I).j]); \ - (I) = next_comb(I, L1, L2)) - -#define fn_for_each_comb(L1, L2, P1, P2, FN) \ -({ \ - struct label_it i; \ - int __E = 0; \ - label_for_each_comb(i, (L1), (L2), (P1), (P2)) { \ - last_error(__E, (FN)); \ - } \ - __E; \ -}) /* for each profile that is enforcing confinement in a label */ #define label_for_each_confined(I, L, P) \ @@ -291,8 +267,6 @@ bool aa_label_replace(struct aa_label *old, struct aa_label *new); bool aa_label_make_newest(struct aa_labelset *ls, struct aa_label *old, struct aa_label *new); -struct aa_label *aa_label_find(struct aa_label *l); - struct aa_profile *aa_label_next_in_merge(struct label_it *I, struct aa_label *a, struct aa_label *b); @@ -320,8 +294,6 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns, struct aa_label *label, int flags, gfp_t gfp); void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags, gfp_t gfp); -void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp); -void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp); void aa_label_printk(struct aa_label *label, gfp_t gfp); struct aa_label *aa_label_strn_parse(struct aa_label *base, const char *str, diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h index d7a894b1031ffd0c6584b291d8a50273275eaf90..f11a0db7f51da4b84045dc082839bd66cda21016 100644 --- a/security/apparmor/include/lib.h +++ b/security/apparmor/include/lib.h @@ -59,7 +59,6 @@ extern int apparmor_initialized; /* fn's in lib */ const char *skipn_spaces(const char *str, size_t n); -char *aa_split_fqname(char *args, char **ns_name); const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, size_t *ns_len); void aa_info_message(const char *str); diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h index 4bb0405c91908a6adec2e48ca36a35a3d5bd9a98..536ce3abd5986a598ef1f6f4de5e04e0fd5662f1 100644 --- a/security/apparmor/include/match.h +++ b/security/apparmor/include/match.h @@ -87,10 +87,12 @@ struct table_header { char td_data[]; }; -#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF]->td_data)) +#define TABLE_DATAU16(TABLE) ((u16 *)((TABLE)->td_data)) +#define TABLE_DATAU32(TABLE) ((u32 *)((TABLE)->td_data)) +#define DEFAULT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_DEF]->td_data)) #define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE]->td_data)) -#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT]->td_data)) -#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK]->td_data)) +#define NEXT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_NXT]->td_data)) +#define CHECK_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_CHK]->td_data)) #define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC]->td_data)) #define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT]->td_data)) #define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2]->td_data)) diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h index 0f7e913c3fc21428afeeb73f5551cf85ebaea55a..bbaa7d39a39acefbbd163a1ecf2f6ff735c0e9bd 100644 --- a/security/apparmor/include/perms.h +++ b/security/apparmor/include/perms.h @@ -213,9 +213,6 @@ void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend); void aa_profile_match_label(struct aa_profile *profile, struct aa_ruleset *rules, struct aa_label *label, int type, u32 request, struct aa_perms *perms); -int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, - u32 request, int type, u32 *deny, - struct apparmor_audit_data *ad); int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms, u32 request, struct apparmor_audit_data *ad, void (*cb)(struct audit_buffer *, void *)); diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 75088cc310b677f7fddf95215965049fa9ee12bf..757e3c232c571697d0abc68933d6adf124963ef6 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -264,7 +264,6 @@ void aa_free_profile(struct aa_profile *profile); struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name); struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname, size_t n); -struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name); struct aa_profile *aa_fqlookupn_profile(struct aa_label *base, const char *fqname, size_t n); diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h index cc6d1c9f4a472c4ec1ab23593756d3e7ee44ec6b..f6a515640950ffee5b8ed911ab318805d90b179d 100644 --- a/security/apparmor/include/secid.h +++ b/security/apparmor/include/secid.h @@ -34,6 +34,5 @@ void apparmor_release_secctx(char *secdata, u32 seclen); int aa_alloc_secid(struct aa_label *label, gfp_t gfp); void aa_free_secid(u32 secid); -void aa_secid_update(u32 secid, struct aa_label *label); #endif /* __AA_SECID_H */ diff --git a/security/apparmor/label.c b/security/apparmor/label.c index c71e4615dd460bb2bd113f70d41b257cb708d665..91483ecacc16acc33b432a040512a415a9d83d80 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c @@ -899,23 +899,6 @@ struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len, return vec_create_and_insert_label(vec, len, gfp); } -/** - * aa_label_find - find label @label in label set - * @label: label to find (NOT NULL) - * - * Requires: caller to hold a valid ref on l - * - * Returns: refcounted @label if @label is in tree - * refcounted label that is equiv to @label in tree - * else NULL if @label or equiv is not in tree - */ -struct aa_label *aa_label_find(struct aa_label *label) -{ - AA_BUG(!label); - - return vec_find(label->vec, label->size); -} - /** * aa_label_insert - insert label @label into @ls or return existing label @@ -1811,22 +1794,6 @@ void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags, pr_info("%s", label->hname); } -void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp) -{ - struct aa_ns *ns = aa_get_current_ns(); - - aa_label_xaudit(ab, ns, label, FLAG_VIEW_SUBNS, gfp); - aa_put_ns(ns); -} - -void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp) -{ - struct aa_ns *ns = aa_get_current_ns(); - - aa_label_seq_xprint(f, ns, label, FLAG_VIEW_SUBNS, gfp); - aa_put_ns(ns); -} - void aa_label_printk(struct aa_label *label, gfp_t gfp) { struct aa_ns *ns = aa_get_current_ns(); diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index cd569fbbfe36d29a741c9fe8eb449a82dfdf160f..7db62213e352e6e396e33c0531d130d344c65292 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c @@ -45,44 +45,6 @@ void aa_free_str_table(struct aa_str_table *t) } } -/** - * aa_split_fqname - split a fqname into a profile and namespace name - * @fqname: a full qualified name in namespace profile format (NOT NULL) - * @ns_name: pointer to portion of the string containing the ns name (NOT NULL) - * - * Returns: profile name or NULL if one is not specified - * - * Split a namespace name from a profile name (see policy.c for naming - * description). If a portion of the name is missing it returns NULL for - * that portion. - * - * NOTE: may modify the @fqname string. The pointers returned point - * into the @fqname string. - */ -char *aa_split_fqname(char *fqname, char **ns_name) -{ - char *name = strim(fqname); - - *ns_name = NULL; - if (name[0] == ':') { - char *split = strchr(&name[1], ':'); - *ns_name = skip_spaces(&name[1]); - if (split) { - /* overwrite ':' with \0 */ - *split++ = 0; - if (strncmp(split, "//", 2) == 0) - split += 2; - name = skip_spaces(split); - } else - /* a ns name without a following profile is allowed */ - name = NULL; - } - if (name && *name == 0) - name = NULL; - - return name; -} - /** * skipn_spaces - Removes leading whitespace from @str. * @str: The string to be stripped. @@ -275,33 +237,6 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, audit_log_format(ab, "\""); } -/** - * aa_audit_perms_cb - generic callback fn for auditing perms - * @ab: audit buffer (NOT NULL) - * @va: audit struct to audit values of (NOT NULL) - */ -static void aa_audit_perms_cb(struct audit_buffer *ab, void *va) -{ - struct common_audit_data *sa = va; - struct apparmor_audit_data *ad = aad(sa); - - if (ad->request) { - audit_log_format(ab, " requested_mask="); - aa_audit_perm_mask(ab, ad->request, aa_file_perm_chrs, - PERMS_CHRS_MASK, aa_file_perm_names, - PERMS_NAMES_MASK); - } - if (ad->denied) { - audit_log_format(ab, "denied_mask="); - aa_audit_perm_mask(ab, ad->denied, aa_file_perm_chrs, - PERMS_CHRS_MASK, aa_file_perm_names, - PERMS_NAMES_MASK); - } - audit_log_format(ab, " peer="); - aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, - FLAGS_NONE, GFP_ATOMIC); -} - /** * aa_apply_modes_to_perms - apply namespace and profile flags to perms * @profile: that perms where computed from @@ -349,25 +284,6 @@ void aa_profile_match_label(struct aa_profile *profile, } -/* currently unused */ -int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, - u32 request, int type, u32 *deny, - struct apparmor_audit_data *ad) -{ - struct aa_ruleset *rules = list_first_entry(&profile->rules, - typeof(*rules), list); - struct aa_perms perms; - - ad->peer = &target->label; - ad->request = request; - - aa_profile_match_label(profile, rules, &target->label, type, request, - &perms); - aa_apply_modes_to_perms(profile, &perms); - *deny |= request & perms.deny; - return aa_check_perms(profile, &perms, request, ad, aa_audit_perms_cb); -} - /** * aa_check_perms - do audit mode selection based on perms set * @profile: profile being checked diff --git a/security/apparmor/match.c b/security/apparmor/match.c index 517d77d3c34cc908ad1f85843cc28c8f509c8837..f2d9c57f879439a7fd2bee16a8cf3d5506e8bcf0 100644 --- a/security/apparmor/match.c +++ b/security/apparmor/match.c @@ -247,6 +247,42 @@ void aa_dfa_free_kref(struct kref *kref) dfa_free(dfa); } + + +/** + * remap_data16_to_data32 - remap u16 @old table to a u32 based table + * @old: table to remap + * + * Returns: new table with u32 entries instead of u16. + * + * Note: will free @old so caller does not have to + */ +static struct table_header *remap_data16_to_data32(struct table_header *old) +{ + struct table_header *new; + size_t tsize; + u32 i; + + tsize = table_size(old->td_lolen, YYTD_DATA32); + new = kvzalloc(tsize, GFP_KERNEL); + if (!new) { + kvfree(old); + return NULL; + } + new->td_id = old->td_id; + new->td_flags = YYTD_DATA32; + new->td_lolen = old->td_lolen; + + for (i = 0; i < old->td_lolen; i++) + TABLE_DATAU32(new)[i] = (u32) TABLE_DATAU16(old)[i]; + + kvfree(old); + if (is_vmalloc_addr(new)) + vm_unmap_aliases(); + + return new; +} + /** * aa_dfa_unpack - unpack the binary tables of a serialized dfa * @blob: aligned serialized stream of data to unpack (NOT NULL) @@ -326,8 +362,10 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) case YYTD_ID_DEF: case YYTD_ID_NXT: case YYTD_ID_CHK: - if (table->td_flags != YYTD_DATA16) + if (!(table->td_flags == YYTD_DATA16 || + table->td_flags == YYTD_DATA32)) { goto fail; + } break; case YYTD_ID_EC: if (table->td_flags != YYTD_DATA8) @@ -342,6 +380,23 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) dfa->tables[table->td_id] = table; data += table_size(table->td_lolen, table->td_flags); size -= table_size(table->td_lolen, table->td_flags); + + /* + * this remapping has to be done after incrementing data above + * for now straight remap, later have dfa support both + */ + switch (table->td_id) { + case YYTD_ID_DEF: + case YYTD_ID_NXT: + case YYTD_ID_CHK: + if (table->td_flags == YYTD_DATA16) { + table = remap_data16_to_data32(table); + if (!table) + goto fail; + } + dfa->tables[table->td_id] = table; + break; + } table = NULL; } error = verify_table_headers(dfa->tables, flags); @@ -395,10 +450,10 @@ do { \ aa_state_t aa_dfa_match_len(struct aa_dfa *dfa, aa_state_t start, const char *str, int len) { - u16 *def = DEFAULT_TABLE(dfa); + u32 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); + u32 *next = NEXT_TABLE(dfa); + u32 *check = CHECK_TABLE(dfa); aa_state_t state = start; if (state == DFA_NOMATCH) @@ -434,10 +489,10 @@ aa_state_t aa_dfa_match_len(struct aa_dfa *dfa, aa_state_t start, */ aa_state_t aa_dfa_match(struct aa_dfa *dfa, aa_state_t start, const char *str) { - u16 *def = DEFAULT_TABLE(dfa); + u32 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); + u32 *next = NEXT_TABLE(dfa); + u32 *check = CHECK_TABLE(dfa); aa_state_t state = start; if (state == DFA_NOMATCH) @@ -472,10 +527,10 @@ aa_state_t aa_dfa_match(struct aa_dfa *dfa, aa_state_t start, const char *str) */ aa_state_t aa_dfa_next(struct aa_dfa *dfa, aa_state_t state, const char c) { - u16 *def = DEFAULT_TABLE(dfa); + u32 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); + u32 *next = NEXT_TABLE(dfa); + u32 *check = CHECK_TABLE(dfa); /* current state is , matching character *str */ if (dfa->tables[YYTD_ID_EC]) { @@ -490,10 +545,10 @@ aa_state_t aa_dfa_next(struct aa_dfa *dfa, aa_state_t state, const char c) aa_state_t aa_dfa_outofband_transition(struct aa_dfa *dfa, aa_state_t state) { - u16 *def = DEFAULT_TABLE(dfa); + u32 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); + u32 *next = NEXT_TABLE(dfa); + u32 *check = CHECK_TABLE(dfa); u32 b = (base)[(state)]; if (!(b & MATCH_FLAG_OOB_TRANSITION)) @@ -521,10 +576,10 @@ aa_state_t aa_dfa_outofband_transition(struct aa_dfa *dfa, aa_state_t state) aa_state_t aa_dfa_match_until(struct aa_dfa *dfa, aa_state_t start, const char *str, const char **retpos) { - u16 *def = DEFAULT_TABLE(dfa); + u32 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); + u32 *next = NEXT_TABLE(dfa); + u32 *check = CHECK_TABLE(dfa); u32 *accept = ACCEPT_TABLE(dfa); aa_state_t state = start, pos; @@ -582,10 +637,10 @@ aa_state_t aa_dfa_match_until(struct aa_dfa *dfa, aa_state_t start, aa_state_t aa_dfa_matchn_until(struct aa_dfa *dfa, aa_state_t start, const char *str, int n, const char **retpos) { - u16 *def = DEFAULT_TABLE(dfa); + u32 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); + u32 *next = NEXT_TABLE(dfa); + u32 *check = CHECK_TABLE(dfa); u32 *accept = ACCEPT_TABLE(dfa); aa_state_t state = start, pos; @@ -658,10 +713,10 @@ static aa_state_t leftmatch_fb(struct aa_dfa *dfa, aa_state_t start, const char *str, struct match_workbuf *wb, unsigned int *count) { - u16 *def = DEFAULT_TABLE(dfa); + u32 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); + u32 *next = NEXT_TABLE(dfa); + u32 *check = CHECK_TABLE(dfa); aa_state_t state = start, pos; AA_BUG(!dfa); diff --git a/security/apparmor/path.c b/security/apparmor/path.c index 45ec994b558d7b1d6149ba7f1b68ae16d5942058..d6c74c357ffd595e2cba63818a26ee6048e9a552 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -130,7 +130,7 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, /* handle error conditions - and still allow a partial path to * be returned. */ - if (!res || IS_ERR(res)) { + if (IS_ERR_OR_NULL(res)) { if (PTR_ERR(res) == -ENAMETOOLONG) { error = -ENAMETOOLONG; *name = buf; diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 14df15e3569525fb16fd16360b6cfe2a78688c55..d0244fab065308eccbc54522dfbf43a6afaa4bdf 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -103,8 +103,7 @@ static void aa_free_pdb(struct aa_policydb *pdb) { if (pdb) { aa_put_dfa(pdb->dfa); - if (pdb->perms) - kvfree(pdb->perms); + kvfree(pdb->perms); aa_free_str_table(&pdb->trans); kfree(pdb); } @@ -580,11 +579,6 @@ struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname, return profile; } -struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *hname) -{ - return aa_lookupn_profile(ns, hname, strlen(hname)); -} - struct aa_profile *aa_fqlookupn_profile(struct aa_label *base, const char *fqname, size_t n) { @@ -626,6 +620,7 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name, /* TODO: ideally we should inherit abi from parent */ profile->label.flags |= FLAG_NULL; + profile->attach.xmatch = aa_get_pdb(nullpdb); rules = list_first_entry(&profile->rules, typeof(*rules), list); rules->file = aa_get_pdb(nullpdb); rules->policy = aa_get_pdb(nullpdb); diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 3483c595f999fc55f71b6b179044f809f12a6c45..992b74c50d641e697138a640bb19b14620d51c2b 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -645,10 +645,13 @@ fail: static bool unpack_perm(struct aa_ext *e, u32 version, struct aa_perms *perm) { + u32 reserved; + if (version != 1) return false; - return aa_unpack_u32(e, &perm->allow, NULL) && + /* reserved entry is for later expansion, discard for now */ + return aa_unpack_u32(e, &reserved, NULL) && aa_unpack_u32(e, &perm->allow, NULL) && aa_unpack_u32(e, &perm->deny, NULL) && aa_unpack_u32(e, &perm->subtree, NULL) && diff --git a/security/apparmor/policy_unpack_test.c b/security/apparmor/policy_unpack_test.c index c64733d6c98fbb9d701f6270be9adc3d9b7d3b02..5b2ba88ae9e24bc8cc9e996d63b09b6c831cea20 100644 --- a/security/apparmor/policy_unpack_test.c +++ b/security/apparmor/policy_unpack_test.c @@ -44,7 +44,7 @@ #define TEST_ARRAY_BUF_OFFSET \ (TEST_NAMED_ARRAY_BUF_OFFSET + 3 + strlen(TEST_ARRAY_NAME) + 1) -MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); struct policy_unpack_fixture { struct aa_ext *e; @@ -281,6 +281,8 @@ static void policy_unpack_test_unpack_strdup_with_null_name(struct kunit *test) ((uintptr_t)puf->e->start <= (uintptr_t)string) && ((uintptr_t)string <= (uintptr_t)puf->e->end)); KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA); + + kfree(string); } static void policy_unpack_test_unpack_strdup_with_name(struct kunit *test) @@ -296,6 +298,8 @@ static void policy_unpack_test_unpack_strdup_with_name(struct kunit *test) ((uintptr_t)puf->e->start <= (uintptr_t)string) && ((uintptr_t)string <= (uintptr_t)puf->e->end)); KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA); + + kfree(string); } static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test) @@ -313,6 +317,8 @@ static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test) KUNIT_EXPECT_EQ(test, size, 0); KUNIT_EXPECT_NULL(test, string); KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start); + + kfree(string); } static void policy_unpack_test_unpack_nameX_with_null_name(struct kunit *test) diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c index 6350d107013a4ba9be54a55399dbfcca1eaca560..47dc08fc583e9ac486909c0bf3f31dcef5600370 100644 --- a/security/apparmor/secid.c +++ b/security/apparmor/secid.c @@ -39,20 +39,6 @@ int apparmor_display_secid_mode; * TODO: use secid_update in label replace */ -/** - * aa_secid_update - update a secid mapping to a new label - * @secid: secid to update - * @label: label the secid will now map to - */ -void aa_secid_update(u32 secid, struct aa_label *label) -{ - unsigned long flags; - - xa_lock_irqsave(&aa_secids, flags); - __xa_store(&aa_secids, secid, label, 0); - xa_unlock_irqrestore(&aa_secids, flags); -} - /* * see label for inverse aa_label_to_secid */ diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index dbfd554b4624e7fd231abc3b0c6c463a8ada23f3..21a8e54c383f08a9fc9e478f726cb9d1ab7f34a5 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -635,7 +635,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, return false; for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; - struct lsm_prop prop = { }; + struct lsm_prop inode_prop = { }; if (!lsm_rule->lsm[i].rule) { if (!lsm_rule->lsm[i].args_p) @@ -649,15 +649,16 @@ retry: case LSM_OBJ_USER: case LSM_OBJ_ROLE: case LSM_OBJ_TYPE: - security_inode_getlsmprop(inode, &prop); - rc = ima_filter_rule_match(&prop, lsm_rule->lsm[i].type, + security_inode_getlsmprop(inode, &inode_prop); + rc = ima_filter_rule_match(&inode_prop, + lsm_rule->lsm[i].type, Audit_equal, lsm_rule->lsm[i].rule); break; case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: - rc = ima_filter_rule_match(&prop, lsm_rule->lsm[i].type, + rc = ima_filter_rule_match(prop, lsm_rule->lsm[i].type, Audit_equal, lsm_rule->lsm[i].rule); break; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f5a08f94e09402b6b0b1538fae1a7a3f5af19fe6..366c87a40bd15707f6da4f25e8de4ddce3d281fc 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5738,7 +5738,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb, /* we do this in the LOCAL_OUT path and not the POST_ROUTING path * because we want to make sure we apply the necessary labeling * before IPsec is applied so we can leverage AH protection */ - sk = skb->sk; + sk = sk_to_full_sk(skb->sk); if (sk) { struct sk_security_struct *sksec; diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c index 96d4d7eb879f3a7765c767d99ac80c9e071efdd3..8dfffdc101a2565869a0dc56d5d366f8d0f2c6d0 100644 --- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -180,7 +180,7 @@ static int ac97_bus_reset(struct ac97_controller *ac97_ctrl) /** * snd_ac97_codec_driver_register - register an AC97 codec driver - * @dev: AC97 driver codec to register + * @drv: AC97 driver codec to register * * Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital * controller. @@ -196,7 +196,7 @@ EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_register); /** * snd_ac97_codec_driver_unregister - unregister an AC97 codec driver - * @dev: AC97 codec driver to unregister + * @drv: AC97 codec driver to unregister * * Unregister a previously registered ac97 codec driver. */ @@ -338,6 +338,7 @@ static int ac97_add_adapter(struct ac97_controller *ac97_ctrl) * @dev: the device providing the ac97 DC function * @slots_available: mask of the ac97 codecs that can be scanned and probed * bit0 => codec 0, bit1 => codec 1 ... bit 3 => codec 3 + * @codecs_pdata: codec platform data * * Register a digital controller which can control up to 4 ac97 codecs. This is * the controller side of the AC97 AC-link, while the slave side are the codecs. diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index b44d205cc838e6e4e248e7b85e440668fa722d43..8a3384342e8db083e31d0fa896352146e80fb121 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3813,9 +3813,11 @@ static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf) return VM_FAULT_SIGBUS; if (substream->ops->page) page = substream->ops->page(substream, offset); - else if (!snd_pcm_get_dma_buf(substream)) + else if (!snd_pcm_get_dma_buf(substream)) { + if (WARN_ON_ONCE(!runtime->dma_area)) + return VM_FAULT_SIGBUS; page = virt_to_page(runtime->dma_area + offset); - else + } else page = snd_sgbuf_get_page(snd_pcm_get_dma_buf(substream), offset); if (!page) return VM_FAULT_SIGBUS; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 03306be5fa02452ac9f05fb0a4338d2ed20e6f19..348ce1b7725ea22124afc3146972f556c88c14e9 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -724,8 +724,9 @@ static int resize_runtime_buffer(struct snd_rawmidi_substream *substream, newbuf = kvzalloc(params->buffer_size, GFP_KERNEL); if (!newbuf) return -ENOMEM; - guard(spinlock_irq)(&substream->lock); + spin_lock_irq(&substream->lock); if (runtime->buffer_ref) { + spin_unlock_irq(&substream->lock); kvfree(newbuf); return -EBUSY; } @@ -733,6 +734,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_substream *substream, runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; __reset_runtime_ptrs(runtime, is_input); + spin_unlock_irq(&substream->lock); kvfree(oldbuf); } runtime->avail_min = params->avail_min; diff --git a/sound/core/sound_kunit.c b/sound/core/sound_kunit.c index bfed1a25fc8f744ff30843c1fe38d5b82bde5665..84e337ecbddd0a7182a245adb8c7f4e6741aed1f 100644 --- a/sound/core/sound_kunit.c +++ b/sound/core/sound_kunit.c @@ -172,6 +172,7 @@ static void test_format_fill_silence(struct kunit *test) u32 i, j; buffer = kunit_kzalloc(test, SILENCE_BUFFER_SIZE, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer); for (i = 0; i < ARRAY_SIZE(buf_samples); i++) { for (j = 0; j < ARRAY_SIZE(valid_fmt); j++) @@ -208,8 +209,12 @@ static void test_playback_avail(struct kunit *test) struct snd_pcm_runtime *r = kunit_kzalloc(test, sizeof(*r), GFP_KERNEL); u32 i; + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r); + r->status = kunit_kzalloc(test, sizeof(*r->status), GFP_KERNEL); r->control = kunit_kzalloc(test, sizeof(*r->control), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->status); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->control); for (i = 0; i < ARRAY_SIZE(p_avail_data); i++) { r->buffer_size = p_avail_data[i].buffer_size; @@ -232,8 +237,12 @@ static void test_capture_avail(struct kunit *test) struct snd_pcm_runtime *r = kunit_kzalloc(test, sizeof(*r), GFP_KERNEL); u32 i; + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r); + r->status = kunit_kzalloc(test, sizeof(*r->status), GFP_KERNEL); r->control = kunit_kzalloc(test, sizeof(*r->control), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->status); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->control); for (i = 0; i < ARRAY_SIZE(c_avail_data); i++) { r->buffer_size = c_avail_data[i].buffer_size; @@ -247,6 +256,7 @@ static void test_capture_avail(struct kunit *test) static void test_card_set_id(struct kunit *test) { struct snd_card *card = kunit_kzalloc(test, sizeof(*card), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, card); snd_card_set_id(card, VALID_NAME); KUNIT_EXPECT_STREQ(test, card->id, VALID_NAME); @@ -280,6 +290,7 @@ static void test_pcm_format_name(struct kunit *test) static void test_card_add_component(struct kunit *test) { struct snd_card *card = kunit_kzalloc(test, sizeof(*card), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, card); snd_component_add(card, TEST_FIRST_COMPONENT); KUNIT_ASSERT_STREQ(test, card->components, TEST_FIRST_COMPONENT); diff --git a/sound/core/ump.c b/sound/core/ump.c index 5d4dd207e5ab260b4ff3affaebd28f42ac1c221d..6d0aac6c763fe7f90b6ae6c0f9dde2993ffaef9c 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -788,7 +788,10 @@ static void fill_fb_info(struct snd_ump_endpoint *ump, info->ui_hint = buf->fb_info.ui_hint; info->first_group = buf->fb_info.first_group; info->num_groups = buf->fb_info.num_groups; - info->flags = buf->fb_info.midi_10; + if (buf->fb_info.midi_10 < 2) + info->flags = buf->fb_info.midi_10; + else + info->flags = SNDRV_UMP_BLOCK_IS_MIDI1 | SNDRV_UMP_BLOCK_IS_LOWSPEED; info->active = buf->fb_info.active; info->midi_ci_version = buf->fb_info.midi_ci_version; info->sysex8_streams = buf->fb_info.sysex8_streams; diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c index 9f849e05ce79f8fa073893fd6f5295dd8a57b284..f564ec7af1940566d5c82c8c4a72fe3492221a07 100644 --- a/sound/hda/intel-dsp-config.c +++ b/sound/hda/intel-dsp-config.c @@ -801,4 +801,4 @@ EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Intel DSP config driver"); -MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI); +MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI"); diff --git a/sound/hda/intel-sdw-acpi.c b/sound/hda/intel-sdw-acpi.c index ed530e0dd4ddcc9dc3ebe107a823835b414e6150..49d3e0e300735005574c587644abce2afec5c7ed 100644 --- a/sound/hda/intel-sdw-acpi.c +++ b/sound/hda/intel-sdw-acpi.c @@ -198,7 +198,7 @@ int sdw_intel_acpi_scan(acpi_handle *parent_handle, return sdw_intel_scan_controller(info); } -EXPORT_SYMBOL_NS(sdw_intel_acpi_scan, SND_INTEL_SOUNDWIRE_ACPI); +EXPORT_SYMBOL_NS(sdw_intel_acpi_scan, "SND_INTEL_SOUNDWIRE_ACPI"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Intel Soundwire ACPI helpers"); diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index fdd4fe16225fcb87fad4be1341893deec66fe733..5a84591b13fc2b4c94380b4079d1fc33851d3c8f 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -464,7 +464,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, return -ENOMEM; } - err = hpi_stream_get_info_ex(dpcm->h_stream, NULL, + hpi_stream_get_info_ex(dpcm->h_stream, NULL, &dpcm->hpi_buffer_attached, NULL, NULL, NULL); } bytes_per_sec = params_rate(params) * params_channels(params); diff --git a/sound/pci/hda/cirrus_scodec.c b/sound/pci/hda/cirrus_scodec.c index 8de3bc7448fa52a37af86483d478423071076338..3c670207ba30e04909ae4bed22321533ac33a358 100644 --- a/sound/pci/hda/cirrus_scodec.c +++ b/sound/pci/hda/cirrus_scodec.c @@ -66,7 +66,7 @@ int cirrus_scodec_get_speaker_id(struct device *dev, int amp_index, return speaker_id; } -EXPORT_SYMBOL_NS_GPL(cirrus_scodec_get_speaker_id, SND_HDA_CIRRUS_SCODEC); +EXPORT_SYMBOL_NS_GPL(cirrus_scodec_get_speaker_id, "SND_HDA_CIRRUS_SCODEC"); MODULE_DESCRIPTION("HDA Cirrus side-codec library"); MODULE_AUTHOR("Richard Fitzgerald "); diff --git a/sound/pci/hda/cirrus_scodec_test.c b/sound/pci/hda/cirrus_scodec_test.c index e925ebe21ccbaeacb1be0d28eee0207554f55988..f5d6241daee47c7b095967f51f648900bd794b12 100644 --- a/sound/pci/hda/cirrus_scodec_test.c +++ b/sound/pci/hda/cirrus_scodec_test.c @@ -365,7 +365,7 @@ static struct kunit_suite cirrus_scodec_test_suite = { kunit_test_suite(cirrus_scodec_test_suite); -MODULE_IMPORT_NS(SND_HDA_CIRRUS_SCODEC); +MODULE_IMPORT_NS("SND_HDA_CIRRUS_SCODEC"); MODULE_DESCRIPTION("KUnit test for the Cirrus side-codec library"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index d68bf7591d90c19a601499d9c20612d8c1a12603..5dc021976c790579e9e8b15364c7cd9e64d1d262 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -2019,7 +2019,7 @@ err: return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l41_hda_probe, SND_HDA_SCODEC_CS35L41); +EXPORT_SYMBOL_NS_GPL(cs35l41_hda_probe, "SND_HDA_SCODEC_CS35L41"); void cs35l41_hda_remove(struct device *dev) { @@ -2044,7 +2044,7 @@ void cs35l41_hda_remove(struct device *dev) gpiod_put(cs35l41->cs_gpio); kfree(cs35l41->acpi_subsystem_id); } -EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); +EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, "SND_HDA_SCODEC_CS35L41"); const struct dev_pm_ops cs35l41_hda_pm_ops = { RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, @@ -2052,11 +2052,11 @@ const struct dev_pm_ops cs35l41_hda_pm_ops = { .prepare = cs35l41_system_suspend_prep, SYSTEM_SLEEP_PM_OPS(cs35l41_system_suspend, cs35l41_system_resume) }; -EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41); +EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, "SND_HDA_SCODEC_CS35L41"); MODULE_DESCRIPTION("CS35L41 HDA Driver"); -MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); -MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB); +MODULE_IMPORT_NS("SND_HDA_CS_DSP_CONTROLS"); +MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(FW_CS_DSP); +MODULE_IMPORT_NS("FW_CS_DSP"); diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c index bb84740c852076a7cd589c48e890177971f53b43..e77495413c214df3fc5efb6f34cb014f91a0e917 100644 --- a/sound/pci/hda/cs35l41_hda_i2c.c +++ b/sound/pci/hda/cs35l41_hda_i2c.c @@ -64,6 +64,6 @@ static struct i2c_driver cs35l41_i2c_driver = { module_i2c_driver(cs35l41_i2c_driver); MODULE_DESCRIPTION("HDA CS35L41 driver"); -MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L41); +MODULE_IMPORT_NS("SND_HDA_SCODEC_CS35L41"); MODULE_AUTHOR("Lucas Tanure "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c index f8c356ad0d340f1a64ab46b30c1f943788025d7e..2acbaf8467a09f70b683a2b0f2ef22c727f8b342 100644 --- a/sound/pci/hda/cs35l41_hda_spi.c +++ b/sound/pci/hda/cs35l41_hda_spi.c @@ -59,6 +59,6 @@ static struct spi_driver cs35l41_spi_driver = { module_spi_driver(cs35l41_spi_driver); MODULE_DESCRIPTION("HDA CS35L41 driver"); -MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L41); +MODULE_IMPORT_NS("SND_HDA_SCODEC_CS35L41"); MODULE_AUTHOR("Lucas Tanure "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/cs35l56_hda.c b/sound/pci/hda/cs35l56_hda.c index e3ac0e23ae321100befac7490a85fac8b3556e56..d96266c8cb38e85b3592538b222193c272285de0 100644 --- a/sound/pci/hda/cs35l56_hda.c +++ b/sound/pci/hda/cs35l56_hda.c @@ -1094,7 +1094,7 @@ err: return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_hda_common_probe, SND_HDA_SCODEC_CS35L56); +EXPORT_SYMBOL_NS_GPL(cs35l56_hda_common_probe, "SND_HDA_SCODEC_CS35L56"); void cs35l56_hda_remove(struct device *dev) { @@ -1113,7 +1113,7 @@ void cs35l56_hda_remove(struct device *dev) gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); } -EXPORT_SYMBOL_NS_GPL(cs35l56_hda_remove, SND_HDA_SCODEC_CS35L56); +EXPORT_SYMBOL_NS_GPL(cs35l56_hda_remove, "SND_HDA_SCODEC_CS35L56"); const struct dev_pm_ops cs35l56_hda_pm_ops = { RUNTIME_PM_OPS(cs35l56_hda_runtime_suspend, cs35l56_hda_runtime_resume, NULL) @@ -1123,14 +1123,14 @@ const struct dev_pm_ops cs35l56_hda_pm_ops = { NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend_no_irq, cs35l56_hda_system_resume_no_irq) }; -EXPORT_SYMBOL_NS_GPL(cs35l56_hda_pm_ops, SND_HDA_SCODEC_CS35L56); +EXPORT_SYMBOL_NS_GPL(cs35l56_hda_pm_ops, "SND_HDA_SCODEC_CS35L56"); MODULE_DESCRIPTION("CS35L56 HDA Driver"); -MODULE_IMPORT_NS(FW_CS_DSP); -MODULE_IMPORT_NS(SND_HDA_CIRRUS_SCODEC); -MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); -MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); -MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB); +MODULE_IMPORT_NS("FW_CS_DSP"); +MODULE_IMPORT_NS("SND_HDA_CIRRUS_SCODEC"); +MODULE_IMPORT_NS("SND_HDA_CS_DSP_CONTROLS"); +MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); +MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/cs35l56_hda_i2c.c b/sound/pci/hda/cs35l56_hda_i2c.c index 40f2f97944d54c916d58279a94f84e6be69b5bba..c7b83661314984ad8a0f505bb0ecc7dba59c3543 100644 --- a/sound/pci/hda/cs35l56_hda_i2c.c +++ b/sound/pci/hda/cs35l56_hda_i2c.c @@ -77,8 +77,8 @@ static struct i2c_driver cs35l56_hda_i2c_driver = { module_i2c_driver(cs35l56_hda_i2c_driver); MODULE_DESCRIPTION("HDA CS35L56 I2C driver"); -MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L56); -MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); +MODULE_IMPORT_NS("SND_HDA_SCODEC_CS35L56"); +MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/cs35l56_hda_spi.c b/sound/pci/hda/cs35l56_hda_spi.c index 7f02155fe61e3cd529e4c688bf6d734848baf45d..d4ee5bb7c48660d7717e33f44d0534380785d424 100644 --- a/sound/pci/hda/cs35l56_hda_spi.c +++ b/sound/pci/hda/cs35l56_hda_spi.c @@ -77,8 +77,8 @@ static struct spi_driver cs35l56_hda_spi_driver = { module_spi_driver(cs35l56_hda_spi_driver); MODULE_DESCRIPTION("HDA CS35L56 SPI driver"); -MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L56); -MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); +MODULE_IMPORT_NS("SND_HDA_SCODEC_CS35L56"); +MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 8e74be038b0faded87fc13a182cf60abcafb47e3..84393f4f429dff9e26e04d0e69f52c457dd04345 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -933,6 +933,7 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec, bool match_all_pins) { const struct snd_hda_pin_quirk *pq; + const char *name = NULL; if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET) return; @@ -946,9 +947,10 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec, codec->fixup_id = pq->value; #ifdef CONFIG_SND_DEBUG_VERBOSE codec->fixup_name = pq->name; - codec_dbg(codec, "%s: picked fixup %s (pin match)\n", - codec->core.chip_name, codec->fixup_name); + name = pq->name; #endif + codec_info(codec, "%s: picked fixup %s (pin match)\n", + codec->core.chip_name, name ? name : ""); codec->fixup_list = fixlist; return; } @@ -1015,8 +1017,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec, if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { id = HDA_FIXUP_ID_NO_FIXUP; fixlist = NULL; - codec_dbg(codec, "%s: picked no fixup (nofixup specified)\n", - codec->core.chip_name); + codec_info(codec, "%s: picked no fixup (nofixup specified)\n", + codec->core.chip_name); goto found; } @@ -1026,8 +1028,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec, if (!strcmp(codec->modelname, models->name)) { id = models->id; name = models->name; - codec_dbg(codec, "%s: picked fixup %s (model specified)\n", - codec->core.chip_name, codec->fixup_name); + codec_info(codec, "%s: picked fixup %s (model specified)\n", + codec->core.chip_name, name); goto found; } models++; @@ -1085,9 +1087,9 @@ void snd_hda_pick_fixup(struct hda_codec *codec, #ifdef CONFIG_SND_DEBUG_VERBOSE name = q->name; #endif - codec_dbg(codec, "%s: picked fixup %s for %s %04x:%04x\n", - codec->core.chip_name, name ? name : "", - type, q->subvendor, q->subdevice); + codec_info(codec, "%s: picked fixup %s for %s %04x:%04x\n", + codec->core.chip_name, name ? name : "", + type, q->subvendor, q->subdevice); found: codec->fixup_id = id; codec->fixup_list = fixlist; diff --git a/sound/pci/hda/hda_component.c b/sound/pci/hda/hda_component.c index 2d6b7b0b355d2a86fbb7bf8b7c821d70cad8015d..71860e2d637716147b7b8e29c67273150d2a4523 100644 --- a/sound/pci/hda/hda_component.c +++ b/sound/pci/hda/hda_component.c @@ -29,7 +29,7 @@ void hda_component_acpi_device_notify(struct hda_component_parent *parent, } mutex_unlock(&parent->mutex); } -EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, SND_HDA_SCODEC_COMPONENT); +EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, "SND_HDA_SCODEC_COMPONENT"); int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc, struct hda_component_parent *parent, @@ -64,7 +64,7 @@ int hda_component_manager_bind_acpi_notifications(struct hda_codec *cdc, return 0; } -EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind_acpi_notifications, SND_HDA_SCODEC_COMPONENT); +EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind_acpi_notifications, "SND_HDA_SCODEC_COMPONENT"); void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc, struct hda_component_parent *parent, @@ -81,7 +81,7 @@ void hda_component_manager_unbind_acpi_notifications(struct hda_codec *cdc, if (ret < 0) codec_warn(cdc, "Failed to uninstall notify handler: %d\n", ret); } -EXPORT_SYMBOL_NS_GPL(hda_component_manager_unbind_acpi_notifications, SND_HDA_SCODEC_COMPONENT); +EXPORT_SYMBOL_NS_GPL(hda_component_manager_unbind_acpi_notifications, "SND_HDA_SCODEC_COMPONENT"); #endif /* ifdef CONFIG_ACPI */ void hda_component_manager_playback_hook(struct hda_component_parent *parent, int action) @@ -107,7 +107,7 @@ void hda_component_manager_playback_hook(struct hda_component_parent *parent, in } mutex_unlock(&parent->mutex); } -EXPORT_SYMBOL_NS_GPL(hda_component_manager_playback_hook, SND_HDA_SCODEC_COMPONENT); +EXPORT_SYMBOL_NS_GPL(hda_component_manager_playback_hook, "SND_HDA_SCODEC_COMPONENT"); struct hda_scodec_match { const char *bus; @@ -149,7 +149,7 @@ int hda_component_manager_bind(struct hda_codec *cdc, return ret; } -EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, SND_HDA_SCODEC_COMPONENT); +EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, "SND_HDA_SCODEC_COMPONENT"); int hda_component_manager_init(struct hda_codec *cdc, struct hda_component_parent *parent, int count, @@ -189,7 +189,7 @@ int hda_component_manager_init(struct hda_codec *cdc, return ret; } -EXPORT_SYMBOL_NS_GPL(hda_component_manager_init, SND_HDA_SCODEC_COMPONENT); +EXPORT_SYMBOL_NS_GPL(hda_component_manager_init, "SND_HDA_SCODEC_COMPONENT"); void hda_component_manager_free(struct hda_component_parent *parent, const struct component_master_ops *ops) @@ -205,7 +205,7 @@ void hda_component_manager_free(struct hda_component_parent *parent, parent->codec = NULL; } -EXPORT_SYMBOL_NS_GPL(hda_component_manager_free, SND_HDA_SCODEC_COMPONENT); +EXPORT_SYMBOL_NS_GPL(hda_component_manager_free, "SND_HDA_SCODEC_COMPONENT"); MODULE_DESCRIPTION("HD Audio component binding library"); MODULE_AUTHOR("Richard Fitzgerald "); diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c index deb74c2470829ff6014fcef26be56e8b292bd620..18fa6e7edb497cb698a12a8b5269bf4a37a2f9b2 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.c +++ b/sound/pci/hda/hda_cs_dsp_ctl.c @@ -34,7 +34,7 @@ const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW] = { [HDA_CS_DSP_FW_SPK_DIAG] = "spk-diag", [HDA_CS_DSP_FW_MISC] = "misc", }; -EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_fw_ids, SND_HDA_CS_DSP_CONTROLS); +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_fw_ids, "SND_HDA_CS_DSP_CONTROLS"); static int hda_cs_dsp_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) { @@ -200,7 +200,7 @@ void hda_cs_dsp_add_controls(struct cs_dsp *dsp, const struct hda_cs_dsp_ctl_inf hda_cs_dsp_control_add(cs_ctl, info); } } -EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_add_controls, SND_HDA_CS_DSP_CONTROLS); +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_add_controls, "SND_HDA_CS_DSP_CONTROLS"); void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) { @@ -210,7 +210,7 @@ void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) if (ctl) snd_ctl_remove(ctl->card, ctl->kctl); } -EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, "SND_HDA_CS_DSP_CONTROLS"); int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, unsigned int alg, const void *buf, size_t len) @@ -227,7 +227,7 @@ int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, return 0; } -EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, SND_HDA_CS_DSP_CONTROLS); +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, "SND_HDA_CS_DSP_CONTROLS"); int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) @@ -241,9 +241,9 @@ int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, return ret; } -EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_read_ctl, SND_HDA_CS_DSP_CONTROLS); +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_read_ctl, "SND_HDA_CS_DSP_CONTROLS"); MODULE_DESCRIPTION("CS_DSP ALSA Control HDA Library"); MODULE_AUTHOR("Stefan Binding, "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(FW_CS_DSP); +MODULE_IMPORT_NS("FW_CS_DSP"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 56a3622ca2c1e24530280d6e278a7650ae310579..4ba9e647250b371eebcad07b27d1c9ef64b9a322 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -473,6 +473,8 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) break; case 0x10ec0234: case 0x10ec0274: + alc_write_coef_idx(codec, 0x6e, 0x0c25); + fallthrough; case 0x10ec0294: case 0x10ec0700: case 0x10ec0701: @@ -3613,25 +3615,22 @@ static void alc256_init(struct hda_codec *codec) hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); - if (hp_pin_sense) + if (hp_pin_sense) { msleep(2); + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ - alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ - - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - - if (hp_pin_sense || spec->ultra_low_power) - msleep(85); - - snd_hda_codec_write(codec, hp_pin, 0, + snd_hda_codec_write(codec, hp_pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - if (hp_pin_sense || spec->ultra_low_power) - msleep(100); + msleep(75); + + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + msleep(75); + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ + } alc_update_coef_idx(codec, 0x46, 3 << 12, 0); - alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */ alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15); /* @@ -3655,29 +3654,28 @@ static void alc256_shutup(struct hda_codec *codec) alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); - if (hp_pin_sense) + if (hp_pin_sense) { msleep(2); - snd_hda_codec_write(codec, hp_pin, 0, + snd_hda_codec_write(codec, hp_pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - if (hp_pin_sense || spec->ultra_low_power) - msleep(85); + msleep(75); /* 3k pull low control for Headset jack. */ /* NOTE: call this before clearing the pin, otherwise codec stalls */ /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly * when booting with headset plugged. So skip setting it for the codec alc257 */ - if (spec->en_3kpull_low) - alc_update_coef_idx(codec, 0x46, 0, 3 << 12); + if (spec->en_3kpull_low) + alc_update_coef_idx(codec, 0x46, 0, 3 << 12); - if (!spec->no_shutup_pins) - snd_hda_codec_write(codec, hp_pin, 0, + if (!spec->no_shutup_pins) + snd_hda_codec_write(codec, hp_pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); - if (hp_pin_sense || spec->ultra_low_power) - msleep(100); + msleep(75); + } alc_auto_setup_eapd(codec, false); alc_shutup_pins(codec); @@ -3772,33 +3770,28 @@ static void alc225_init(struct hda_codec *codec) hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); - if (hp1_pin_sense || hp2_pin_sense) + if (hp1_pin_sense || hp2_pin_sense) { msleep(2); + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ - alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ - - if (hp1_pin_sense || spec->ultra_low_power) - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - if (hp2_pin_sense) - snd_hda_codec_write(codec, 0x16, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - - if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) - msleep(85); - - if (hp1_pin_sense || spec->ultra_low_power) - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - if (hp2_pin_sense) - snd_hda_codec_write(codec, 0x16, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + msleep(75); - if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) - msleep(100); + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); - alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); - alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ + msleep(75); + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ + } } static void alc225_shutup(struct hda_codec *codec) @@ -3810,36 +3803,35 @@ static void alc225_shutup(struct hda_codec *codec) if (!hp_pin) hp_pin = 0x21; - alc_disable_headset_jack_key(codec); - /* 3k pull low control for Headset jack. */ - alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); - hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); - if (hp1_pin_sense || hp2_pin_sense) + if (hp1_pin_sense || hp2_pin_sense) { + alc_disable_headset_jack_key(codec); + /* 3k pull low control for Headset jack. */ + alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); msleep(2); - if (hp1_pin_sense || spec->ultra_low_power) - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - if (hp2_pin_sense) - snd_hda_codec_write(codec, 0x16, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - - if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) - msleep(85); + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - if (hp1_pin_sense || spec->ultra_low_power) - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); - if (hp2_pin_sense) - snd_hda_codec_write(codec, 0x16, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + msleep(75); - if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) - msleep(100); + if (hp1_pin_sense) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + if (hp2_pin_sense) + snd_hda_codec_write(codec, 0x16, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + msleep(75); + alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); + alc_enable_headset_jack_key(codec); + } alc_auto_setup_eapd(codec, false); alc_shutup_pins(codec); if (spec->ultra_low_power) { @@ -3850,9 +3842,6 @@ static void alc225_shutup(struct hda_codec *codec) alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4); msleep(30); } - - alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); - alc_enable_headset_jack_key(codec); } static void alc_default_init(struct hda_codec *codec) @@ -6502,6 +6491,16 @@ static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec, } } +/* disable DAC3 (0x06) selection on NID 0x15 - share Speaker/Bass Speaker DAC 0x03 */ +static void alc294_fixup_bass_speaker_15(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + static const hda_nid_t conn[] = { 0x02, 0x03 }; + snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn); + } +} + /* Hook to update amp GPIO4 for automute */ static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec, struct hda_jack_callback *jack) @@ -7559,6 +7558,7 @@ enum { ALC269_FIXUP_THINKPAD_ACPI, ALC269_FIXUP_DMIC_THINKPAD_ACPI, ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13, + ALC269VC_FIXUP_INFINIX_Y4_MAX, ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO, ALC255_FIXUP_ACER_MIC_NO_PRESENCE, ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, @@ -7782,6 +7782,8 @@ enum { ALC256_FIXUP_CHROME_BOOK, ALC245_FIXUP_CLEVO_NOISY_MIC, ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE, + ALC233_FIXUP_MEDION_MTL_SPK, + ALC294_FIXUP_BASS_SPEAKER_15, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -7945,6 +7947,15 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST }, + [ALC269VC_FIXUP_INFINIX_Y4_MAX] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1b, 0x90170150 }, /* use as internal speaker */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST + }, [ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -10074,6 +10085,17 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST }, + [ALC233_FIXUP_MEDION_MTL_SPK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1b, 0x90170110 }, + { } + }, + }, + [ALC294_FIXUP_BASS_SPEAKER_15] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc294_fixup_bass_speaker_15, + }, }; static const struct hda_quirk alc269_fixup_tbl[] = { @@ -10499,6 +10521,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8cdf, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ce0, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d84, "HP EliteBook X G1i", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), @@ -10582,6 +10605,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1df3, "ASUS UM5606WA", ALC294_FIXUP_BASS_SPEAKER_15), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), @@ -10943,7 +10967,10 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13), SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), + SND_PCI_QUIRK(0x2782, 0x1701, "Infinix Y4 Max", ALC269VC_FIXUP_INFINIX_Y4_MAX), + SND_PCI_QUIRK(0x2782, 0x1705, "MEDION E15433", ALC269VC_FIXUP_INFINIX_Y4_MAX), SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME), + SND_PCI_QUIRK(0x2782, 0x4900, "MEDION E15443", ALC233_FIXUP_MEDION_MTL_SPK), SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), @@ -13266,7 +13293,7 @@ MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Realtek HD-audio codec"); -MODULE_IMPORT_NS(SND_HDA_SCODEC_COMPONENT); +MODULE_IMPORT_NS("SND_HDA_SCODEC_COMPONENT"); static struct hda_codec_driver realtek_driver = { .id = snd_hda_id_realtek, diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index 370d847517f9ab4b9ec6c773f73c82bf7aca564c..db05659c0af8c18fa1320830094df6b3cc570185 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -110,10 +111,20 @@ static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data) return 1; } +static const struct acpi_gpio_params speakerid_gpios = { 0, 0, false }; + +static const struct acpi_gpio_mapping tas2781_speaker_id_gpios[] = { + { "speakerid-gpios", &speakerid_gpios, 1 }, + { } +}; + static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid) { struct acpi_device *adev; + struct device *physdev; LIST_HEAD(resources); + const char *sub; + uint32_t subid; int ret; adev = acpi_dev_get_first_match_dev(hid, NULL, -1); @@ -123,18 +134,45 @@ static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid) return -ENODEV; } + physdev = get_device(acpi_get_first_physical_node(adev)); ret = acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p); - if (ret < 0) + if (ret < 0) { + dev_err(p->dev, "Failed to get ACPI resource.\n"); + goto err; + } + sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev)); + if (IS_ERR(sub)) { + dev_err(p->dev, "Failed to get SUBSYS ID.\n"); goto err; + } + /* Speaker id was needed for ASUS projects. */ + ret = kstrtou32(sub, 16, &subid); + if (!ret && upper_16_bits(subid) == PCI_VENDOR_ID_ASUSTEK) { + ret = devm_acpi_dev_add_driver_gpios(p->dev, + tas2781_speaker_id_gpios); + if (ret < 0) + dev_err(p->dev, "Failed to add driver gpio %d.\n", + ret); + p->speaker_id = devm_gpiod_get(p->dev, "speakerid", GPIOD_IN); + if (IS_ERR(p->speaker_id)) { + dev_err(p->dev, "Failed to get Speaker id.\n"); + ret = PTR_ERR(p->speaker_id); + goto err; + } + } else { + p->speaker_id = NULL; + } acpi_dev_free_resource_list(&resources); strscpy(p->dev_name, hid, sizeof(p->dev_name)); + put_device(physdev); acpi_dev_put(adev); return 0; err: dev_err(p->dev, "read acpi error, ret: %d\n", ret); + put_device(physdev); acpi_dev_put(adev); return ret; @@ -615,7 +653,7 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) struct tasdevice_priv *tas_priv = context; struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev); struct hda_codec *codec = tas_priv->codec; - int i, ret; + int i, ret, spk_id; pm_runtime_get_sync(tas_priv->dev); mutex_lock(&tas_priv->codec_lock); @@ -648,8 +686,25 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) tasdevice_dsp_remove(tas_priv); tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING; - scnprintf(tas_priv->coef_binaryname, 64, "TAS2XXX%04X.bin", - codec->core.subsystem_id & 0xffff); + if (tas_priv->speaker_id != NULL) { + // Speaker id need to be checked for ASUS only. + spk_id = gpiod_get_value(tas_priv->speaker_id); + if (spk_id < 0) { + // Speaker id is not valid, use default. + dev_dbg(tas_priv->dev, "Wrong spk_id = %d\n", spk_id); + spk_id = 0; + } + snprintf(tas_priv->coef_binaryname, + sizeof(tas_priv->coef_binaryname), + "TAS2XXX%04X%d.bin", + lower_16_bits(codec->core.subsystem_id), + spk_id); + } else { + snprintf(tas_priv->coef_binaryname, + sizeof(tas_priv->coef_binaryname), + "TAS2XXX%04X.bin", + lower_16_bits(codec->core.subsystem_id)); + } ret = tasdevice_dsp_parser(tas_priv); if (ret) { dev_err(tas_priv->dev, "dspfw load %s error\n", @@ -977,4 +1032,4 @@ module_i2c_driver(tas2781_hda_i2c_driver); MODULE_DESCRIPTION("TAS2781 HDA Driver"); MODULE_AUTHOR("Shenghao Ding, TI, "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_TAS2781_FMWLIB); +MODULE_IMPORT_NS("SND_SOC_TAS2781_FMWLIB"); diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 6dec44f516c13f2df0377906a7ca30ba50a1bb3e..c7590d4989bba5335e3afe8368e91de2bd089391 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -163,6 +163,7 @@ config SND_SOC_AMD_SOUNDWIRE config SND_SOC_AMD_PS tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support" select SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE + select SND_SOC_ACPI_AMD_MATCH depends on X86 && PCI && ACPI help This option enables Audio Coprocessor i.e ACP v6.3 support on diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c index 515bf862deb56bf11fc229bdc98dc432aa1b0ab2..1f59ee248771cc73283d6e5be0b67a345cc13c49 100644 --- a/sound/soc/amd/acp/acp-i2s.c +++ b/sound/soc/amd/acp/acp-i2s.c @@ -694,7 +694,7 @@ const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = { .set_fmt = acp_i2s_set_fmt, .set_tdm_slot = acp_i2s_set_tdm_slot, }; -EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, "SND_SOC_ACP_COMMON"); MODULE_DESCRIPTION("AMD ACP Audio I2S controller"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 3f76d1f0a9e70742d7980e3deb98c67b81027f02..7acc7ed2e8cc90d403a123f4c261a0dc50ffa0bc 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -31,7 +31,7 @@ void acp_enable_interrupts(struct acp_dev_data *adata) ext_intr_ctrl |= ACP_ERROR_MASK; writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); } -EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, "SND_SOC_ACP_COMMON"); void acp_disable_interrupts(struct acp_dev_data *adata) { @@ -40,7 +40,7 @@ void acp_disable_interrupts(struct acp_dev_data *adata) writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); writel(0x00, ACP_EXTERNAL_INTR_ENB(adata)); } -EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, "SND_SOC_ACP_COMMON"); static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) @@ -97,7 +97,7 @@ void restore_acp_pdm_params(struct snd_pcm_substream *substream, writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); set_acp_pdm_clk(substream, dai); } -EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, "SND_SOC_ACP_COMMON"); static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) @@ -248,7 +248,7 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, } return set_acp_i2s_dma_fifo(substream, dai); } -EXPORT_SYMBOL_NS_GPL(restore_acp_i2s_params, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(restore_acp_i2s_params, "SND_SOC_ACP_COMMON"); static int acp_power_on(struct acp_chip_info *chip) { @@ -326,7 +326,7 @@ int acp_init(struct acp_chip_info *chip) writel(0, chip->base + ACP_ZSC_DSP_CTRL); return 0; } -EXPORT_SYMBOL_NS_GPL(acp_init, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_init, "SND_SOC_ACP_COMMON"); int acp_deinit(struct acp_chip_info *chip) { @@ -343,7 +343,7 @@ int acp_deinit(struct acp_chip_info *chip) writel(0x01, chip->base + ACP_ZSC_DSP_CTRL); return 0; } -EXPORT_SYMBOL_NS_GPL(acp_deinit, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_deinit, "SND_SOC_ACP_COMMON"); int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data) { @@ -351,7 +351,7 @@ int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data) pci_write_config_dword(dev, 0x64, data); return 0; } -EXPORT_SYMBOL_NS_GPL(smn_write, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(smn_write, "SND_SOC_ACP_COMMON"); int smn_read(struct pci_dev *dev, u32 smn_addr) { @@ -361,7 +361,7 @@ int smn_read(struct pci_dev *dev, u32 smn_addr) pci_read_config_dword(dev, 0x64, &data); return data; } -EXPORT_SYMBOL_NS_GPL(smn_read, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(smn_read, "SND_SOC_ACP_COMMON"); static void check_acp3x_config(struct acp_chip_info *chip) { @@ -479,7 +479,7 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip) } } } -EXPORT_SYMBOL_NS_GPL(check_acp_config, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(check_acp_config, "SND_SOC_ACP_COMMON"); MODULE_DESCRIPTION("AMD ACP legacy common features"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/amd/acp/acp-legacy-mach.c b/sound/soc/amd/acp/acp-legacy-mach.c index 45613a865d2ba7fbd3c0c9f9ea87f17ee39b5c77..a7a551366a4097d7f1410c1980ecb3a8eea4e775 100644 --- a/sound/soc/amd/acp/acp-legacy-mach.c +++ b/sound/soc/amd/acp/acp-legacy-mach.c @@ -240,6 +240,6 @@ static struct platform_driver acp_asoc_audio = { module_platform_driver(acp_asoc_audio); -MODULE_IMPORT_NS(SND_SOC_AMD_MACH); +MODULE_IMPORT_NS("SND_SOC_AMD_MACH"); MODULE_DESCRIPTION("ACP chrome audio support"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index d314253207d5c3edf3d4ff88fd25d0c9979ef800..f7602c1769bf4f04a1dffc6ec113c99ec8e1dc97 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -1579,7 +1579,7 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) return 0; } -EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, SND_SOC_AMD_MACH); +EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, "SND_SOC_AMD_MACH"); int acp_legacy_dai_links_create(struct snd_soc_card *card) { @@ -1790,7 +1790,7 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card) return 0; } -EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH); +EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, "SND_SOC_AMD_MACH"); MODULE_DESCRIPTION("AMD ACP Common Machine driver"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 4b6ad7abc3bad0b77521b9b4fc91131e32c3c9cb..e0fc42d939d3ed90ded74f39dcfe8083608f36a5 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -250,5 +250,5 @@ module_pci_driver(snd_amd_acp_pci_driver); MODULE_DESCRIPTION("AMD ACP common PCI support"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_IMPORT_NS(SND_SOC_ACP_COMMON); +MODULE_IMPORT_NS("SND_SOC_ACP_COMMON"); MODULE_ALIAS(DRV_NAME); diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index 48faafe724ed2c0009b405095737badf9e4a59d2..d4855da05b6ae4295dc3d1c36ce80a2b811b858e 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -181,7 +181,7 @@ const struct snd_soc_dai_ops acp_dmic_dai_ops = { .startup = acp_dmic_dai_startup, .shutdown = acp_dmic_dai_shutdown, }; -EXPORT_SYMBOL_NS_GPL(acp_dmic_dai_ops, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_dmic_dai_ops, "SND_SOC_ACP_COMMON"); MODULE_DESCRIPTION("AMD ACP Audio PDM controller"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 1f352b2b300231c710c1f49986d329c33836c223..aa330aeeb3012c03c97eddfaa6b6e9ce929138bc 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -133,7 +133,7 @@ int acp_machine_select(struct acp_dev_data *adata) dev_warn(adata->dev, "Unable to register Machine device\n"); return 0; } -EXPORT_SYMBOL_NS_GPL(acp_machine_select, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); static irqreturn_t i2s_irq_handler(int irq, void *data) { @@ -191,7 +191,7 @@ void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); } -EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, "SND_SOC_ACP_COMMON"); void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size) { @@ -250,7 +250,7 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s addr += PAGE_SIZE; } } -EXPORT_SYMBOL_NS_GPL(config_acp_dma, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(config_acp_dma, "SND_SOC_ACP_COMMON"); static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { @@ -414,7 +414,7 @@ int acp_platform_register(struct device *dev) return 0; } -EXPORT_SYMBOL_NS_GPL(acp_platform_register, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_platform_register, "SND_SOC_ACP_COMMON"); int acp_platform_unregister(struct device *dev) { @@ -424,7 +424,7 @@ int acp_platform_unregister(struct device *dev) platform_device_unregister(adata->mach_dev); return 0; } -EXPORT_SYMBOL_NS_GPL(acp_platform_unregister, SND_SOC_ACP_COMMON); +EXPORT_SYMBOL_NS_GPL(acp_platform_unregister, "SND_SOC_ACP_COMMON"); MODULE_DESCRIPTION("AMD ACP PCM Driver"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index 008d97598b629f0c6a39d945ca6b368e57200ccf..2648256fa129ceebe4eec5b9fcf7c46d2d82a9bc 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -305,6 +305,6 @@ static struct platform_driver rembrandt_driver = { module_platform_driver(rembrandt_driver); MODULE_DESCRIPTION("AMD ACP Rembrandt Driver"); -MODULE_IMPORT_NS(SND_SOC_ACP_COMMON); +MODULE_IMPORT_NS("SND_SOC_ACP_COMMON"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 166f1efacf1d88412e37625c8ae109fb31ab9283..ca2b74283d8fbcaf50ff5dbc4593a970f22436f3 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -254,6 +254,6 @@ static struct platform_driver renoir_driver = { module_platform_driver(renoir_driver); MODULE_DESCRIPTION("AMD ACP Renoir Driver"); -MODULE_IMPORT_NS(SND_SOC_ACP_COMMON); +MODULE_IMPORT_NS("SND_SOC_ACP_COMMON"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c index 48952a238946a5454ca8d4aef9439051506a399a..9280cd30d19cf2ac454f91b7efeae53fad3bd598 100644 --- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c +++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c @@ -482,5 +482,5 @@ module_platform_driver(soc_sdw_driver); MODULE_DESCRIPTION("ASoC AMD SoundWire Legacy Generic Machine driver"); MODULE_AUTHOR("Vijendar Mukunda "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_SDW_UTILS); -MODULE_IMPORT_NS(SND_SOC_AMD_SDW_MACH); +MODULE_IMPORT_NS("SND_SOC_SDW_UTILS"); +MODULE_IMPORT_NS("SND_SOC_AMD_SDW_MACH"); diff --git a/sound/soc/amd/acp/acp-sdw-mach-common.c b/sound/soc/amd/acp/acp-sdw-mach-common.c index d9393cc4a302385e621bd715aa9cbaf8cdd31b93..6f5c39ed1a18d4fd8befd2539b02d644429714de 100644 --- a/sound/soc/amd/acp/acp-sdw-mach-common.c +++ b/sound/soc/amd/acp/acp-sdw-mach-common.c @@ -57,7 +57,7 @@ int get_acp63_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct dev } return 0; } -EXPORT_SYMBOL_NS_GPL(get_acp63_cpu_pin_id, SND_SOC_AMD_SDW_MACH); +EXPORT_SYMBOL_NS_GPL(get_acp63_cpu_pin_id, "SND_SOC_AMD_SDW_MACH"); MODULE_DESCRIPTION("AMD SoundWire Common Machine driver"); MODULE_AUTHOR("Vijendar Mukunda "); diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c index 0d256c0749c9c798503e62614fcea73887e96c07..c09b1f118a6cc1d0626fcb7542c6ea437aeeb275 100644 --- a/sound/soc/amd/acp/acp-sdw-sof-mach.c +++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c @@ -442,5 +442,5 @@ module_platform_driver(sof_sdw_driver); MODULE_DESCRIPTION("ASoC AMD SoundWire Generic Machine driver"); MODULE_AUTHOR("Vijendar Mukunda link_mask = sdw_bitmap; return 0; } -EXPORT_SYMBOL_NS(amd_sdw_scan_controller, SND_AMD_SOUNDWIRE_ACPI); +EXPORT_SYMBOL_NS(amd_sdw_scan_controller, "SND_AMD_SOUNDWIRE_ACPI"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("AMD SoundWire ACPI helpers"); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index aef73ec6f7ef4ecdd7005176f895b986189a92f2..823a69bf778b9c5d6651ea75f59e0f5b7c7e8072 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -753,6 +753,6 @@ module_pci_driver(ps_acp63_driver); MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); MODULE_AUTHOR("Syed.SabaKareem@amd.com"); MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver"); -MODULE_IMPORT_NS(SOUNDWIRE_AMD_INIT); -MODULE_IMPORT_NS(SND_AMD_SOUNDWIRE_ACPI); +MODULE_IMPORT_NS("SOUNDWIRE_AMD_INIT"); +MODULE_IMPORT_NS("SND_AMD_SOUNDWIRE_ACPI"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 2436e8deb2be485aea43b201493f7409ef36e744..e38c5885dadfbc33a41723a96a656bbc622a7c65 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -220,6 +220,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "21J6"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21M1"), + } + }, { .driver_data = &acp6x_card, .matches = { @@ -241,6 +248,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "21M5"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21ME"), + } + }, { .driver_data = &acp6x_card, .matches = { @@ -409,6 +423,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Xiaomi Book Pro 14 2022"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"), + DMI_MATCH(DMI_PRODUCT_NAME, "Redmi G 2022"), + } + }, { .driver_data = &acp6x_card, .matches = { @@ -537,8 +558,14 @@ static int acp6x_probe(struct platform_device *pdev) struct acp6x_pdm *machine = NULL; struct snd_soc_card *card; struct acpi_device *adev; + acpi_handle handle; + acpi_integer dmic_status; int ret; + bool is_dmic_enable, wov_en; + /* IF WOV entry not found, enable dmic based on AcpDmicConnected entry*/ + is_dmic_enable = false; + wov_en = true; /* check the parent device's firmware node has _DSD or not */ adev = ACPI_COMPANION(pdev->dev.parent); if (adev) { @@ -546,9 +573,19 @@ static int acp6x_probe(struct platform_device *pdev) if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) && obj->integer.value == 1) - platform_set_drvdata(pdev, &acp6x_card); + is_dmic_enable = true; } + handle = ACPI_HANDLE(pdev->dev.parent); + ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status); + if (!ACPI_FAILURE(ret)) + wov_en = dmic_status; + + if (is_dmic_enable && wov_en) + platform_set_drvdata(pdev, &acp6x_card); + else + return 0; + /* check for any DMI overrides */ dmi_id = dmi_first_match(yc_acp_quirk_table); if (dmi_id) diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c index c9e7d40c47cc1c26eabc11e57e4d09cb3b97f628..b4f4696809dd231a64229114c5550bb5f237607f 100644 --- a/sound/soc/apple/mca.c +++ b/sound/soc/apple/mca.c @@ -616,7 +616,7 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream, tdm_slot_width = 32; if (tdm_slot_width < params_width(params)) { - dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n", + dev_err(dev, "TDM slots too narrow (tdm=%u params=%d)\n", tdm_slot_width, params_width(params)); return -EINVAL; } diff --git a/sound/soc/codecs/cs-amp-lib-test.c b/sound/soc/codecs/cs-amp-lib-test.c index a6e8348a1bd5378017fbf4647b0b17e38df664f0..45626f99a4175e7c0725943643e2bbd1b317eae9 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -756,7 +756,7 @@ static struct kunit_suite cs_amp_lib_test_suite = { kunit_test_suite(cs_amp_lib_test_suite); -MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB); +MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB"); MODULE_DESCRIPTION("KUnit test for Cirrus Logic amplifier library"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index 51b128c8067188d23aa27cfe05664b7ef45bd04a..c677868c5d5f7ba171d56bf28336a3c2e96211b4 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -97,7 +97,7 @@ int cs_amp_write_cal_coeffs(struct cs_dsp *dsp, else return -ENODEV; } -EXPORT_SYMBOL_NS_GPL(cs_amp_write_cal_coeffs, SND_SOC_CS_AMP_LIB); +EXPORT_SYMBOL_NS_GPL(cs_amp_write_cal_coeffs, "SND_SOC_CS_AMP_LIB"); static efi_status_t cs_amp_get_efi_variable(efi_char16_t *name, efi_guid_t *guid, @@ -270,7 +270,7 @@ int cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, int amp_ else return -ENOENT; } -EXPORT_SYMBOL_NS_GPL(cs_amp_get_efi_calibration_data, SND_SOC_CS_AMP_LIB); +EXPORT_SYMBOL_NS_GPL(cs_amp_get_efi_calibration_data, "SND_SOC_CS_AMP_LIB"); static const struct cs_amp_test_hooks cs_amp_test_hook_ptrs = { .get_efi_variable = cs_amp_get_efi_variable, @@ -279,9 +279,9 @@ static const struct cs_amp_test_hooks cs_amp_test_hook_ptrs = { const struct cs_amp_test_hooks * const cs_amp_test_hooks = PTR_IF(IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST), &cs_amp_test_hook_ptrs); -EXPORT_SYMBOL_NS_GPL(cs_amp_test_hooks, SND_SOC_CS_AMP_LIB); +EXPORT_SYMBOL_NS_GPL(cs_amp_test_hooks, "SND_SOC_CS_AMP_LIB"); MODULE_DESCRIPTION("Cirrus Logic amplifier library"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(FW_CS_DSP); +MODULE_IMPORT_NS("FW_CS_DSP"); diff --git a/sound/soc/codecs/cs35l45-i2c.c b/sound/soc/codecs/cs35l45-i2c.c index f5fc42dcc8c70c50dd1dbc9c64e21dfb7dedb295..a09aa3b92ae15776653f831022f582619799c016 100644 --- a/sound/soc/codecs/cs35l45-i2c.c +++ b/sound/soc/codecs/cs35l45-i2c.c @@ -73,4 +73,4 @@ module_i2c_driver(cs35l45_i2c_driver); MODULE_DESCRIPTION("I2C CS35L45 driver"); MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_CS35L45); +MODULE_IMPORT_NS("SND_SOC_CS35L45"); diff --git a/sound/soc/codecs/cs35l45-spi.c b/sound/soc/codecs/cs35l45-spi.c index 39e203a5f060c6987ad55d6d8115eee4c507813a..5f91472c3fd291a94e63ecd01bbe8f1ef8f81389 100644 --- a/sound/soc/codecs/cs35l45-spi.c +++ b/sound/soc/codecs/cs35l45-spi.c @@ -75,4 +75,4 @@ module_spi_driver(cs35l45_spi_driver); MODULE_DESCRIPTION("SPI CS35L45 driver"); MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_CS35L45); +MODULE_IMPORT_NS("SND_SOC_CS35L45"); diff --git a/sound/soc/codecs/cs35l45-tables.c b/sound/soc/codecs/cs35l45-tables.c index 405dab137b3b092425ce3fcfe7dc335c2a05db52..d2ecc7b3f61938a77edf4d89fc6bb6de6ccf48c7 100644 --- a/sound/soc/codecs/cs35l45-tables.c +++ b/sound/soc/codecs/cs35l45-tables.c @@ -38,7 +38,7 @@ int cs35l45_apply_patch(struct cs35l45_private *cs35l45) return regmap_register_patch(cs35l45->regmap, cs35l45_patch, ARRAY_SIZE(cs35l45_patch)); } -EXPORT_SYMBOL_NS_GPL(cs35l45_apply_patch, SND_SOC_CS35L45); +EXPORT_SYMBOL_NS_GPL(cs35l45_apply_patch, "SND_SOC_CS35L45"); static const struct reg_default cs35l45_defaults[] = { { CS35L45_BLOCK_ENABLES, 0x00003323 }, @@ -260,7 +260,7 @@ const struct regmap_config cs35l45_i2c_regmap = { .readable_reg = cs35l45_readable_reg, .cache_type = REGCACHE_MAPLE, }; -EXPORT_SYMBOL_NS_GPL(cs35l45_i2c_regmap, SND_SOC_CS35L45); +EXPORT_SYMBOL_NS_GPL(cs35l45_i2c_regmap, "SND_SOC_CS35L45"); const struct regmap_config cs35l45_spi_regmap = { .reg_bits = 32, @@ -276,7 +276,7 @@ const struct regmap_config cs35l45_spi_regmap = { .readable_reg = cs35l45_readable_reg, .cache_type = REGCACHE_MAPLE, }; -EXPORT_SYMBOL_NS_GPL(cs35l45_spi_regmap, SND_SOC_CS35L45); +EXPORT_SYMBOL_NS_GPL(cs35l45_spi_regmap, "SND_SOC_CS35L45"); static const struct { u8 cfg_id; @@ -329,4 +329,4 @@ int cs35l45_get_clk_freq_id(unsigned int freq) return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(cs35l45_get_clk_freq_id, SND_SOC_CS35L45); +EXPORT_SYMBOL_NS_GPL(cs35l45_get_clk_freq_id, "SND_SOC_CS35L45"); diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index fa1d9d9151f96ef2bb9c9e13719cf48026a02d5e..432a19f4de2b4b64d99419bece01d4e15f7bab3c 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -1486,7 +1486,7 @@ err: return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45); +EXPORT_SYMBOL_NS_GPL(cs35l45_probe, "SND_SOC_CS35L45"); void cs35l45_remove(struct cs35l45_private *cs35l45) { @@ -1501,7 +1501,7 @@ void cs35l45_remove(struct cs35l45_private *cs35l45) /* VDD_BATT must be the last to power-off */ regulator_disable(cs35l45->vdd_batt); } -EXPORT_SYMBOL_NS_GPL(cs35l45_remove, SND_SOC_CS35L45); +EXPORT_SYMBOL_NS_GPL(cs35l45_remove, "SND_SOC_CS35L45"); EXPORT_GPL_DEV_PM_OPS(cs35l45_pm_ops) = { RUNTIME_PM_OPS(cs35l45_runtime_suspend, cs35l45_runtime_resume, NULL) diff --git a/sound/soc/codecs/cs35l56-i2c.c b/sound/soc/codecs/cs35l56-i2c.c index 2bd2ff75cd5047a087a95bc62ffbfa82ab3c2881..8a518df1e16e8327bfcdb7b97d6591848a0a65d6 100644 --- a/sound/soc/codecs/cs35l56-i2c.c +++ b/sound/soc/codecs/cs35l56-i2c.c @@ -84,8 +84,8 @@ static struct i2c_driver cs35l56_i2c_driver = { module_i2c_driver(cs35l56_i2c_driver); MODULE_DESCRIPTION("ASoC CS35L56 I2C driver"); -MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE); -MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); +MODULE_IMPORT_NS("SND_SOC_CS35L56_CORE"); +MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c index 7c9a17fe2195ccc6011f4bc5ee09f594860b456e..3f91cb3f9ae70fe720bb04b87e3c86fba157a7e4 100644 --- a/sound/soc/codecs/cs35l56-sdw.c +++ b/sound/soc/codecs/cs35l56-sdw.c @@ -582,8 +582,8 @@ static struct sdw_driver cs35l56_sdw_driver = { module_sdw_driver(cs35l56_sdw_driver); MODULE_DESCRIPTION("ASoC CS35L56 SoundWire driver"); -MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE); -MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); +MODULE_IMPORT_NS("SND_SOC_CS35L56_CORE"); +MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c index e45e9ae01bc668dac03e31dab1eabd34084f11a9..e0ed4fc11155a57f16a4d45939920b83ab326ce5 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -49,7 +49,7 @@ int cs35l56_set_patch(struct cs35l56_base *cs35l56_base) return regmap_register_patch(cs35l56_base->regmap, cs35l56_patch, ARRAY_SIZE(cs35l56_patch)); } -EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, "SND_SOC_CS35L56_SHARED"); static const struct reg_default cs35l56_reg_defaults[] = { /* no defaults for OTP_MEM - first read populates cache */ @@ -241,7 +241,7 @@ int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command) return 0; } -EXPORT_SYMBOL_NS_GPL(cs35l56_mbox_send, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_mbox_send, "SND_SOC_CS35L56_SHARED"); int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base) { @@ -261,7 +261,7 @@ int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base) val, ret); return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_firmware_shutdown, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_firmware_shutdown, "SND_SOC_CS35L56_SHARED"); int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base) { @@ -287,21 +287,21 @@ int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base) return 0; } -EXPORT_SYMBOL_NS_GPL(cs35l56_wait_for_firmware_boot, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_wait_for_firmware_boot, "SND_SOC_CS35L56_SHARED"); void cs35l56_wait_control_port_ready(void) { /* Wait for control port to be ready (datasheet tIRS). */ usleep_range(CS35L56_CONTROL_PORT_READY_US, 2 * CS35L56_CONTROL_PORT_READY_US); } -EXPORT_SYMBOL_NS_GPL(cs35l56_wait_control_port_ready, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_wait_control_port_ready, "SND_SOC_CS35L56_SHARED"); void cs35l56_wait_min_reset_pulse(void) { /* Satisfy minimum reset pulse width spec */ usleep_range(CS35L56_RESET_PULSE_MIN_US, 2 * CS35L56_RESET_PULSE_MIN_US); } -EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse, "SND_SOC_CS35L56_SHARED"); static const struct reg_sequence cs35l56_system_reset_seq[] = { REG_SEQ0(CS35L56_DSP1_HALO_STATE, 0), @@ -327,7 +327,7 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire) /* Leave in cache-only. This will be revoked when the chip has rebooted. */ } -EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, "SND_SOC_CS35L56_SHARED"); int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq) { @@ -346,7 +346,7 @@ int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq) return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, "SND_SOC_CS35L56_SHARED"); irqreturn_t cs35l56_irq(int irq, void *data) { @@ -413,7 +413,7 @@ err_unlock: return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_irq, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_irq, "SND_SOC_CS35L56_SHARED"); int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base) { @@ -444,7 +444,7 @@ int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base) return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_is_fw_reload_needed, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_is_fw_reload_needed, "SND_SOC_CS35L56_SHARED"); static const struct reg_sequence cs35l56_hibernate_seq[] = { /* This must be the last register access */ @@ -513,7 +513,7 @@ int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base) return 0; } -EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend_common, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend_common, "SND_SOC_CS35L56_SHARED"); int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire) { @@ -565,7 +565,7 @@ err: return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common, "SND_SOC_CS35L56_SHARED"); static const struct cs_dsp_region cs35l56_dsp1_regions[] = { { .type = WMFW_HALO_PM_PACKED, .base = CS35L56_DSP1_PMEM_0 }, @@ -588,7 +588,7 @@ void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_ds cs_dsp->num_mems = ARRAY_SIZE(cs35l56_dsp1_regions); cs_dsp->no_core_startstop = true; } -EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, "SND_SOC_CS35L56_SHARED"); struct cs35l56_pte { u8 x; @@ -634,7 +634,7 @@ const struct cirrus_amp_cal_controls cs35l56_calibration_controls = { .status = "CAL_STATUS", .checksum = "CAL_CHECKSUM", }; -EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, "SND_SOC_CS35L56_SHARED"); int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base) { @@ -664,7 +664,7 @@ int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base) return 0; } -EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration, "SND_SOC_CS35L56_SHARED"); int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, bool *fw_missing, unsigned int *fw_version) @@ -688,7 +688,7 @@ int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, return 0; } -EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, "SND_SOC_CS35L56_SHARED"); int cs35l56_hw_init(struct cs35l56_base *cs35l56_base) { @@ -774,7 +774,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base) return 0; } -EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, "SND_SOC_CS35L56_SHARED"); int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base) { @@ -816,7 +816,7 @@ err: return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id, "SND_SOC_CS35L56_SHARED"); static const u32 cs35l56_bclk_valid_for_pll_freq_table[] = { [0x0C] = 128000, @@ -865,7 +865,7 @@ int cs35l56_get_bclk_freq_id(unsigned int freq) return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, "SND_SOC_CS35L56_SHARED"); static const char * const cs35l56_supplies[/* auto-sized */] = { "VDD_P", @@ -881,7 +881,7 @@ void cs35l56_fill_supply_names(struct regulator_bulk_data *data) for (i = 0; i < ARRAY_SIZE(cs35l56_supplies); i++) data[i].supply = cs35l56_supplies[i]; } -EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, "SND_SOC_CS35L56_SHARED"); const char * const cs35l56_tx_input_texts[] = { "None", "ASP1RX1", "ASP1RX2", "VMON", "IMON", "ERRVOL", "CLASSH", @@ -889,7 +889,7 @@ const char * const cs35l56_tx_input_texts[] = { "DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1TX8", "TEMPMON", "INTERPOLATOR", "SDW1RX1", "SDW1RX2", }; -EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, "SND_SOC_CS35L56_SHARED"); const unsigned int cs35l56_tx_input_values[] = { CS35L56_INPUT_SRC_NONE, @@ -914,7 +914,7 @@ const unsigned int cs35l56_tx_input_values[] = { CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1, CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2, }; -EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, "SND_SOC_CS35L56_SHARED"); const struct regmap_config cs35l56_regmap_i2c = { .reg_bits = 32, @@ -930,7 +930,7 @@ const struct regmap_config cs35l56_regmap_i2c = { .precious_reg = cs35l56_precious_reg, .cache_type = REGCACHE_MAPLE, }; -EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, "SND_SOC_CS35L56_SHARED"); const struct regmap_config cs35l56_regmap_spi = { .reg_bits = 32, @@ -947,7 +947,7 @@ const struct regmap_config cs35l56_regmap_spi = { .precious_reg = cs35l56_precious_reg, .cache_type = REGCACHE_MAPLE, }; -EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, "SND_SOC_CS35L56_SHARED"); const struct regmap_config cs35l56_regmap_sdw = { .reg_bits = 32, @@ -963,10 +963,10 @@ const struct regmap_config cs35l56_regmap_sdw = { .precious_reg = cs35l56_precious_reg, .cache_type = REGCACHE_MAPLE, }; -EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, SND_SOC_CS35L56_SHARED); +EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, "SND_SOC_CS35L56_SHARED"); MODULE_DESCRIPTION("ASoC CS35L56 Shared"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB); +MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB"); diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c index b07b798b0b45d667f2d1aba6a27cd153da818332..c101134e85328e973944100879a226b939ce068e 100644 --- a/sound/soc/codecs/cs35l56-spi.c +++ b/sound/soc/codecs/cs35l56-spi.c @@ -82,8 +82,8 @@ static struct spi_driver cs35l56_spi_driver = { module_spi_driver(cs35l56_spi_driver); MODULE_DESCRIPTION("ASoC CS35L56 SPI driver"); -MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE); -MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); +MODULE_IMPORT_NS("SND_SOC_CS35L56_CORE"); +MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 757ade6373ede393496e9cbc0ee76b2c3d9d3b1f..ae045c88c48d272fd8819f68a048e8b7c2081ea9 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -1341,7 +1341,7 @@ err: return ret; } -EXPORT_SYMBOL_NS_GPL(cs35l56_common_probe, SND_SOC_CS35L56_CORE); +EXPORT_SYMBOL_NS_GPL(cs35l56_common_probe, "SND_SOC_CS35L56_CORE"); int cs35l56_init(struct cs35l56_private *cs35l56) { @@ -1422,7 +1422,7 @@ post_soft_reset: return 0; } -EXPORT_SYMBOL_NS_GPL(cs35l56_init, SND_SOC_CS35L56_CORE); +EXPORT_SYMBOL_NS_GPL(cs35l56_init, "SND_SOC_CS35L56_CORE"); void cs35l56_remove(struct cs35l56_private *cs35l56) { @@ -1447,7 +1447,7 @@ void cs35l56_remove(struct cs35l56_private *cs35l56) gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); } -EXPORT_SYMBOL_NS_GPL(cs35l56_remove, SND_SOC_CS35L56_CORE); +EXPORT_SYMBOL_NS_GPL(cs35l56_remove, "SND_SOC_CS35L56_CORE"); #if IS_ENABLED(CONFIG_SND_SOC_CS35L56_I2C) || IS_ENABLED(CONFIG_SND_SOC_CS35L56_SPI) EXPORT_NS_GPL_DEV_PM_OPS(cs35l56_pm_ops_i2c_spi, SND_SOC_CS35L56_CORE) = { @@ -1459,8 +1459,8 @@ EXPORT_NS_GPL_DEV_PM_OPS(cs35l56_pm_ops_i2c_spi, SND_SOC_CS35L56_CORE) = { #endif MODULE_DESCRIPTION("ASoC CS35L56 driver"); -MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); -MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB); +MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED"); +MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l42-i2c.c b/sound/soc/codecs/cs42l42-i2c.c index 8d10f9328e02d0a3f484bff22b6075a82c9fd989..8a1d5c7a61d7fe1f232de3173cfdbdd19231e800 100644 --- a/sound/soc/codecs/cs42l42-i2c.c +++ b/sound/soc/codecs/cs42l42-i2c.c @@ -101,4 +101,4 @@ module_i2c_driver(cs42l42_i2c_driver); MODULE_DESCRIPTION("ASoC CS42L42 I2C driver"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_CS42L42_CORE); +MODULE_IMPORT_NS("SND_SOC_CS42L42_CORE"); diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c index 29891c1f6bece53c8df0d5c025b2cfbe5a31be19..ae1401b250a307d2616f6748db08efc48dbe0cc9 100644 --- a/sound/soc/codecs/cs42l42-sdw.c +++ b/sound/soc/codecs/cs42l42-sdw.c @@ -622,4 +622,4 @@ module_sdw_driver(cs42l42_sdw_driver); MODULE_DESCRIPTION("ASoC CS42L42 SoundWire driver"); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_CS42L42_CORE); +MODULE_IMPORT_NS("SND_SOC_CS42L42_CORE"); diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 6400ac875e6f6ca6ab5f1ac3cb2acc53f99b85fd..501c951cc327c5a2e0ba092fa41f90385f570f66 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -329,7 +329,7 @@ bool cs42l42_readable_register(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(cs42l42_readable_register, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_readable_register, "SND_SOC_CS42L42_CORE"); bool cs42l42_volatile_register(struct device *dev, unsigned int reg) { @@ -363,7 +363,7 @@ bool cs42l42_volatile_register(struct device *dev, unsigned int reg) return false; } } -EXPORT_SYMBOL_NS_GPL(cs42l42_volatile_register, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_volatile_register, "SND_SOC_CS42L42_CORE"); const struct regmap_range_cfg cs42l42_page_range = { .name = "Pages", @@ -375,7 +375,7 @@ const struct regmap_range_cfg cs42l42_page_range = { .window_start = 0, .window_len = 256, }; -EXPORT_SYMBOL_NS_GPL(cs42l42_page_range, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_page_range, "SND_SOC_CS42L42_CORE"); const struct regmap_config cs42l42_regmap = { .reg_bits = 8, @@ -395,7 +395,7 @@ const struct regmap_config cs42l42_regmap = { .use_single_read = true, .use_single_write = true, }; -EXPORT_SYMBOL_NS_GPL(cs42l42_regmap, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_regmap, "SND_SOC_CS42L42_CORE"); static DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 100, true); static DECLARE_TLV_DB_SCALE(mixer_tlv, -6300, 100, true); @@ -596,7 +596,7 @@ const struct snd_soc_component_driver cs42l42_soc_component = { .num_controls = ARRAY_SIZE(cs42l42_snd_controls), .endianness = 1, }; -EXPORT_SYMBOL_NS_GPL(cs42l42_soc_component, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_soc_component, "SND_SOC_CS42L42_CORE"); /* Switch to SCLK. Atomic delay after the write to allow the switch to complete. */ static const struct reg_sequence cs42l42_to_sclk_seq[] = { @@ -748,7 +748,7 @@ int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk, return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(cs42l42_pll_config, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_pll_config, "SND_SOC_CS42L42_CORE"); void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample_rate) { @@ -782,7 +782,7 @@ void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample CS42L42_CLK_OASRC_SEL_MASK, fs << CS42L42_CLK_OASRC_SEL_SHIFT); } -EXPORT_SYMBOL_NS_GPL(cs42l42_src_config, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_src_config, "SND_SOC_CS42L42_CORE"); static int cs42l42_asp_config(struct snd_soc_component *component, unsigned int sclk, unsigned int sample_rate) @@ -1116,7 +1116,7 @@ int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) return 0; } -EXPORT_SYMBOL_NS_GPL(cs42l42_mute_stream, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_mute_stream, "SND_SOC_CS42L42_CORE"); #define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE |\ @@ -1151,7 +1151,7 @@ struct snd_soc_dai_driver cs42l42_dai = { .symmetric_sample_bits = 1, .ops = &cs42l42_ops, }; -EXPORT_SYMBOL_NS_GPL(cs42l42_dai, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_dai, "SND_SOC_CS42L42_CORE"); static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) { @@ -1780,7 +1780,7 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS_GPL(cs42l42_irq_thread, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_irq_thread, "SND_SOC_CS42L42_CORE"); static void cs42l42_set_interrupt_masks(struct cs42l42_private *cs42l42) { @@ -2211,7 +2211,7 @@ int cs42l42_suspend(struct device *dev) return 0; } -EXPORT_SYMBOL_NS_GPL(cs42l42_suspend, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_suspend, "SND_SOC_CS42L42_CORE"); int cs42l42_resume(struct device *dev) { @@ -2242,7 +2242,7 @@ int cs42l42_resume(struct device *dev) return 0; } -EXPORT_SYMBOL_NS_GPL(cs42l42_resume, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_resume, "SND_SOC_CS42L42_CORE"); void cs42l42_resume_restore(struct device *dev) { @@ -2261,7 +2261,7 @@ void cs42l42_resume_restore(struct device *dev) dev_dbg(dev, "System resumed\n"); } -EXPORT_SYMBOL_NS_GPL(cs42l42_resume_restore, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_resume_restore, "SND_SOC_CS42L42_CORE"); static int __maybe_unused cs42l42_i2c_resume(struct device *dev) { @@ -2370,7 +2370,7 @@ err_disable_noreset: return ret; } -EXPORT_SYMBOL_NS_GPL(cs42l42_common_probe, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_common_probe, "SND_SOC_CS42L42_CORE"); int cs42l42_init(struct cs42l42_private *cs42l42) { @@ -2464,7 +2464,7 @@ err_disable: cs42l42->supplies); return ret; } -EXPORT_SYMBOL_NS_GPL(cs42l42_init, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_init, "SND_SOC_CS42L42_CORE"); void cs42l42_common_remove(struct cs42l42_private *cs42l42) { @@ -2484,7 +2484,7 @@ void cs42l42_common_remove(struct cs42l42_private *cs42l42) gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); } -EXPORT_SYMBOL_NS_GPL(cs42l42_common_remove, SND_SOC_CS42L42_CORE); +EXPORT_SYMBOL_NS_GPL(cs42l42_common_remove, "SND_SOC_CS42L42_CORE"); MODULE_DESCRIPTION("ASoC CS42L42 driver"); MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, "); diff --git a/sound/soc/codecs/cs42l43-sdw.c b/sound/soc/codecs/cs42l43-sdw.c index 60c00c05da055c8d9c258dd41b868c6127d7e421..336e88a7a987ce5edbc94590a59bddcf811ff880 100644 --- a/sound/soc/codecs/cs42l43-sdw.c +++ b/sound/soc/codecs/cs42l43-sdw.c @@ -42,7 +42,7 @@ int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream, return 0; } -EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_add_peripheral, SND_SOC_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_add_peripheral, "SND_SOC_CS42L43"); int cs42l43_sdw_remove_peripheral(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) @@ -56,7 +56,7 @@ int cs42l43_sdw_remove_peripheral(struct snd_pcm_substream *substream, return sdw_stream_remove_slave(sdw, sdw_stream); } -EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_remove_peripheral, SND_SOC_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_remove_peripheral, "SND_SOC_CS42L43"); int cs42l43_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stream, int direction) { @@ -64,7 +64,7 @@ int cs42l43_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stream, int direct return 0; } -EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_set_stream, SND_SOC_CS42L43); +EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_set_stream, "SND_SOC_CS42L43"); MODULE_DESCRIPTION("CS42L43 CODEC SoundWire Driver"); MODULE_AUTHOR("Charles Keepax "); diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c index 3ede0e3110f3471b4c28d349af35347aa5ac0270..4236f78beec069239021ff1da28277b7e6e927a0 100644 --- a/sound/soc/codecs/cs42l43.c +++ b/sound/soc/codecs/cs42l43.c @@ -2424,7 +2424,7 @@ static struct platform_driver cs42l43_codec_driver = { }; module_platform_driver(cs42l43_codec_driver); -MODULE_IMPORT_NS(SND_SOC_CS42L43); +MODULE_IMPORT_NS("SND_SOC_CS42L43"); MODULE_DESCRIPTION("CS42L43 CODEC Driver"); MODULE_AUTHOR("Charles Keepax "); diff --git a/sound/soc/codecs/cs42l83-i2c.c b/sound/soc/codecs/cs42l83-i2c.c index f482b6a4f5c3a311d17404a3c641be021ce2cafb..42c3e1efdc0867b4532dfdf9980508de48afe4da 100644 --- a/sound/soc/codecs/cs42l83-i2c.c +++ b/sound/soc/codecs/cs42l83-i2c.c @@ -237,4 +237,4 @@ module_i2c_driver(cs42l83_i2c_driver); MODULE_DESCRIPTION("ASoC CS42L83 I2C driver"); MODULE_AUTHOR("Martin Povišer "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_CS42L42_CORE); +MODULE_IMPORT_NS("SND_SOC_CS42L42_CORE"); diff --git a/sound/soc/codecs/cs530x-i2c.c b/sound/soc/codecs/cs530x-i2c.c index 56659bf735db7c91a99a4bcd56e2caa005ceead9..22b1a4d6b61cfb7680dc25d83635ab7e260b2939 100644 --- a/sound/soc/codecs/cs530x-i2c.c +++ b/sound/soc/codecs/cs530x-i2c.c @@ -67,6 +67,6 @@ static struct i2c_driver cs530x_i2c_driver = { module_i2c_driver(cs530x_i2c_driver); MODULE_DESCRIPTION("I2C CS530X driver"); -MODULE_IMPORT_NS(SND_SOC_CS530X); +MODULE_IMPORT_NS("SND_SOC_CS530X"); MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs530x.c b/sound/soc/codecs/cs530x.c index da52afe56c3c625aed26212dac6094e099a3d8e1..252e66c8449ecd5cf9c6bcb42abd78dbd1ec50d3 100644 --- a/sound/soc/codecs/cs530x.c +++ b/sound/soc/codecs/cs530x.c @@ -821,7 +821,7 @@ const struct regmap_config cs530x_regmap = { .reg_defaults = cs530x_reg_defaults, .num_reg_defaults = ARRAY_SIZE(cs530x_reg_defaults), }; -EXPORT_SYMBOL_NS_GPL(cs530x_regmap, SND_SOC_CS530X); +EXPORT_SYMBOL_NS_GPL(cs530x_regmap, "SND_SOC_CS530X"); static int cs530x_check_device_id(struct cs530x_priv *cs530x) { @@ -964,7 +964,7 @@ err_regulator: return ret; } -EXPORT_SYMBOL_NS_GPL(cs530x_probe, SND_SOC_CS530X); +EXPORT_SYMBOL_NS_GPL(cs530x_probe, "SND_SOC_CS530X"); MODULE_DESCRIPTION("CS530X CODEC Driver"); MODULE_AUTHOR("Paul Handrigan "); diff --git a/sound/soc/codecs/rt712-sdca-sdw.c b/sound/soc/codecs/rt712-sdca-sdw.c index 549aa31faed428da60914b2fe474a52437bfa2b1..b584a3f854b8530de26646444906d8e70cc340d0 100644 --- a/sound/soc/codecs/rt712-sdca-sdw.c +++ b/sound/soc/codecs/rt712-sdca-sdw.c @@ -507,4 +507,4 @@ module_sdw_driver(rt712_sdca_sdw_driver); MODULE_DESCRIPTION("ASoC RT712 SDCA SDW driver"); MODULE_AUTHOR("Shuming Fan "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_SDCA); +MODULE_IMPORT_NS("SND_SOC_SDCA"); diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 0aeb88abbf52f161a43477c5e17dcde1624972b9..61d9c220b6a4c0f8c188ba1d97a4e3ee8ff6bbc1 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -374,7 +374,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) out: return ret; } -EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser, SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser, "SND_SOC_TAS2781_FMWLIB"); /* fixed m68k compiling issue: mapping table can save code field */ static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw, @@ -862,7 +862,7 @@ void tasdevice_select_cfg_blk(void *pContext, int conf_no, __func__, length, blk_data[j]->block_size); } } -EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, "SND_SOC_TAS2781_FMWLIB"); static int tasdevice_load_block_kernel( struct tasdevice_priv *tasdevice, struct tasdev_blk *block) @@ -1943,7 +1943,7 @@ out: return ret; } -EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration, SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration, "SND_SOC_TAS2781_FMWLIB"); static int tasdevice_dspfw_ready(const struct firmware *fmw, void *context) @@ -2051,7 +2051,7 @@ int tasdevice_dsp_parser(void *context) out: return ret; } -EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser, SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser, "SND_SOC_TAS2781_FMWLIB"); static void tas2781_clear_calfirmware(struct tasdevice_fw *tas_fmw) { @@ -2104,7 +2104,7 @@ void tasdevice_calbin_remove(void *context) tasdev->cali_data_fmw = NULL; } } -EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove, SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove, "SND_SOC_TAS2781_FMWLIB"); void tasdevice_config_info_remove(void *context) { @@ -2131,7 +2131,7 @@ void tasdevice_config_info_remove(void *context) } kfree(ci); } -EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, "SND_SOC_TAS2781_FMWLIB"); static int tasdevice_load_data(struct tasdevice_priv *tas_priv, struct tasdevice_data *dev_data) @@ -2311,8 +2311,7 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no, out: return prog_status; } -EXPORT_SYMBOL_NS_GPL(tasdevice_select_tuningprm_cfg, - SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_select_tuningprm_cfg, "SND_SOC_TAS2781_FMWLIB"); int tasdevice_prmg_load(void *context, int prm_no) { @@ -2357,7 +2356,7 @@ int tasdevice_prmg_load(void *context, int prm_no) out: return prog_status; } -EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load, SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load, "SND_SOC_TAS2781_FMWLIB"); void tasdevice_tuning_switch(void *context, int state) { @@ -2393,8 +2392,7 @@ void tasdevice_tuning_switch(void *context, int state) TASDEVICE_BIN_BLK_PRE_SHUTDOWN); } } -EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch, - SND_SOC_TAS2781_FMWLIB); +EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch, "SND_SOC_TAS2781_FMWLIB"); MODULE_DESCRIPTION("Texas Firmware Support"); MODULE_AUTHOR("Shenghao Ding, TI, "); diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index e41f81eb8d16cb9e957fb701e99879372d41aa68..be2ca5eb6c9386f27479990cdd6bcb00c80a7902 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -1746,4 +1746,4 @@ MODULE_AUTHOR("Shenghao Ding "); MODULE_AUTHOR("Kevin Lu "); MODULE_DESCRIPTION("ASoC TAS2781 Driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_TAS2781_FMWLIB); +MODULE_IMPORT_NS("SND_SOC_TAS2781_FMWLIB"); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index e69283195f362ffd928eb006a987ad57dae0b49a..91c8697c29c321176f93aa6316f891c6ec6ea181 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -2098,4 +2098,4 @@ static const struct cs_dsp_client_ops wm_adsp2_client_ops = { MODULE_DESCRIPTION("Cirrus Logic ASoC DSP Support"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(FW_CS_DSP); +MODULE_IMPORT_NS("FW_CS_DSP"); diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c index dcf770b55c4bd42f4d8f5a3b9b2c7bb4aa5f6973..231400661c90600e9b2a184d8db6636941f041db 100644 --- a/sound/soc/fsl/imx-audmix.c +++ b/sound/soc/fsl/imx-audmix.c @@ -274,6 +274,9 @@ static int imx_audmix_probe(struct platform_device *pdev) /* Add AUDMIX Backend */ be_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "audmix-%d", i); + if (!be_name) + return -ENOMEM; + priv->dai[num_dai + i].cpus = &dlc[1]; priv->dai[num_dai + i].codecs = &snd_soc_dummy_dlc; diff --git a/sound/soc/intel/boards/ehl_rt5660.c b/sound/soc/intel/boards/ehl_rt5660.c index ebc417c04a500c6219917a47d7a83b44a3c5ba7c..5c7b218f22b72fa36493f9b0e09e3c512ba6e123 100644 --- a/sound/soc/intel/boards/ehl_rt5660.c +++ b/sound/soc/intel/boards/ehl_rt5660.c @@ -313,4 +313,4 @@ module_platform_driver(snd_ehl_rt5660_driver); MODULE_DESCRIPTION("ASoC Intel(R) Elkhartlake + rt5660 Machine driver"); MODULE_AUTHOR("libin.yang@intel.com"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); diff --git a/sound/soc/intel/boards/hda_dsp_common.c b/sound/soc/intel/boards/hda_dsp_common.c index fda5a92b00063615fcdfe36defff7e8c6b59ef46..86e541a2c204d412999a74975c5c3cc4c0ca3aaa 100644 --- a/sound/soc/intel/boards/hda_dsp_common.c +++ b/sound/soc/intel/boards/hda_dsp_common.c @@ -83,7 +83,7 @@ int hda_dsp_hdmi_build_controls(struct snd_soc_card *card, return err; } -EXPORT_SYMBOL_NS(hda_dsp_hdmi_build_controls, SND_SOC_INTEL_HDA_DSP_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_hdmi_build_controls, "SND_SOC_INTEL_HDA_DSP_COMMON"); #endif diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index 9edd6d985cf1efcb2c4ba96e3ebaf4ee3db496ff..22668bac74a1fc09f4ba99a1f1bc15c0fad5b82d 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -164,4 +164,4 @@ MODULE_DESCRIPTION("SKL/KBL/BXT/APL HDA Generic Machine driver"); MODULE_AUTHOR("Rakesh Ughreja "); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:skl_hda_dsp_generic"); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c index 50e846d67c194e3f5d0b65bad8e1032d4904049a..2ea1dda446ec2ccf01d371871d0385f510922ff2 100644 --- a/sound/soc/intel/boards/sof_board_helpers.c +++ b/sound/soc/intel/boards/sof_board_helpers.c @@ -35,7 +35,7 @@ int sof_intel_board_card_late_probe(struct snd_soc_card *card) return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); } -EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, SND_SOC_INTEL_SOF_BOARD_HELPERS); +EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, "SND_SOC_INTEL_SOF_BOARD_HELPERS"); /* * DMIC DAI Link @@ -731,7 +731,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(sof_intel_board_set_dai_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); +EXPORT_SYMBOL_NS(sof_intel_board_set_dai_link, "SND_SOC_INTEL_SOF_BOARD_HELPERS"); struct sof_card_private * sof_intel_board_get_ctx(struct device *dev, unsigned long board_quirk) @@ -774,10 +774,10 @@ sof_intel_board_get_ctx(struct device *dev, unsigned long board_quirk) return ctx; } -EXPORT_SYMBOL_NS(sof_intel_board_get_ctx, SND_SOC_INTEL_SOF_BOARD_HELPERS); +EXPORT_SYMBOL_NS(sof_intel_board_get_ctx, "SND_SOC_INTEL_SOF_BOARD_HELPERS"); MODULE_DESCRIPTION("ASoC Intel SOF Machine Driver Board Helpers"); MODULE_AUTHOR("Brent Lu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); -MODULE_IMPORT_NS(SND_SOC_ACPI_INTEL_MATCH); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); +MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_MATCH"); diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index e71e09124b34e3e8168f8dbb1ccdd85087499714..8db7695b974764fdd6a4042242e8282e1552757b 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -193,14 +193,14 @@ void cs35l41_set_dai_link(struct snd_soc_dai_link *link) link->init = cs35l41_init; link->ops = &cs35l41_ops; } -EXPORT_SYMBOL_NS(cs35l41_set_dai_link, SND_SOC_INTEL_SOF_CIRRUS_COMMON); +EXPORT_SYMBOL_NS(cs35l41_set_dai_link, "SND_SOC_INTEL_SOF_CIRRUS_COMMON"); void cs35l41_set_codec_conf(struct snd_soc_card *card) { card->codec_conf = cs35l41_codec_conf; card->num_configs = ARRAY_SIZE(cs35l41_codec_conf); } -EXPORT_SYMBOL_NS(cs35l41_set_codec_conf, SND_SOC_INTEL_SOF_CIRRUS_COMMON); +EXPORT_SYMBOL_NS(cs35l41_set_codec_conf, "SND_SOC_INTEL_SOF_CIRRUS_COMMON"); MODULE_DESCRIPTION("ASoC Intel SOF Cirrus Logic helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index f4fee2ee0d63b3efdef4978f7210d5fe6ad769d3..455c5bc8c6342360b8dc51ca1631384270d2a285 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -303,5 +303,5 @@ module_platform_driver(sof_audio) MODULE_DESCRIPTION("SOF Audio Machine driver for CS42L42"); MODULE_AUTHOR("Brent Lu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_MAXIM_COMMON"); diff --git a/sound/soc/intel/boards/sof_da7219.c b/sound/soc/intel/boards/sof_da7219.c index fa1f7d2d82787ea4f6beca1f3767b2f2b38100a4..9b7082b239c16d18618869c63f013ff101d20923 100644 --- a/sound/soc/intel/boards/sof_da7219.c +++ b/sound/soc/intel/boards/sof_da7219.c @@ -487,5 +487,5 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF Machine driver for Dialog codec"); MODULE_AUTHOR("Yong Zhi "); MODULE_AUTHOR("Brent Lu "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_MAXIM_COMMON"); diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index a927078768519505d97c2ef7bc0ad193b36e9a22..a0b3679b17b423482b259212e37ff70c63208e4c 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -843,4 +843,4 @@ module_platform_driver(sof_es8336_driver); MODULE_DESCRIPTION("ASoC Intel(R) SOF + ES8336 Machine driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index fcc3b95e57a4f3a1f59eb9608efc9b1705774a7f..c98a67ae5e6626da860cb0ddd11e6052380250ca 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -283,14 +283,14 @@ void max_98373_dai_link(struct device *dev, struct snd_soc_dai_link *link) link->init = max_98373_spk_codec_init; link->ops = &max_98373_ops; } -EXPORT_SYMBOL_NS(max_98373_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98373_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); void max_98373_set_codec_conf(struct snd_soc_card *card) { card->codec_conf = max_98373_codec_conf; card->num_configs = ARRAY_SIZE(max_98373_codec_conf); } -EXPORT_SYMBOL_NS(max_98373_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98373_set_codec_conf, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); /* * Maxim MAX98390 @@ -506,7 +506,7 @@ void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link) link->init = max_98390_init; link->ops = &max_98390_ops; } -EXPORT_SYMBOL_NS(max_98390_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98390_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) { @@ -529,7 +529,7 @@ void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) break; } } -EXPORT_SYMBOL_NS(max_98390_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98390_set_codec_conf, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); /* * Maxim MAX98357A/MAX98360A @@ -596,7 +596,7 @@ void max_98357a_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(max_98357a_components); link->init = max_98357a_init; } -EXPORT_SYMBOL_NS(max_98357a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98357a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); void max_98360a_dai_link(struct snd_soc_dai_link *link) { @@ -604,7 +604,7 @@ void max_98360a_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(max_98360a_components); link->init = max_98357a_init; } -EXPORT_SYMBOL_NS(max_98360a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98360a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index bfe17acbc161f7fab277b635c9ca2b11fae698ef..72ce32e2cd57d9ff75ad763ec8dc9ad0ed7deef8 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -339,7 +339,7 @@ MODULE_AUTHOR("David Lin "); MODULE_AUTHOR("Mac Chiang "); MODULE_AUTHOR("Brent Lu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_NUVOTON_COMMON); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_MAXIM_COMMON"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_NUVOTON_COMMON"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_REALTEK_COMMON"); diff --git a/sound/soc/intel/boards/sof_nuvoton_common.c b/sound/soc/intel/boards/sof_nuvoton_common.c index 549a412f5d531a234f8919076900b7f3e5ec4116..ed41cb6f7fa594cd8fad1588a3ef4ebae47ee544 100644 --- a/sound/soc/intel/boards/sof_nuvoton_common.c +++ b/sound/soc/intel/boards/sof_nuvoton_common.c @@ -67,7 +67,7 @@ void nau8318_set_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(nau8318_components); link->init = nau8318_init; } -EXPORT_SYMBOL_NS(nau8318_set_dai_link, SND_SOC_INTEL_SOF_NUVOTON_COMMON); +EXPORT_SYMBOL_NS(nau8318_set_dai_link, "SND_SOC_INTEL_SOF_NUVOTON_COMMON"); MODULE_DESCRIPTION("ASoC Intel SOF Nuvoton helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index 68380b738d8832da673ed99911236ca3bb2cb9b0..2f43710c1baedad610d46016e2ff83556dc9df86 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -440,4 +440,4 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF + PCM512x Machine driver"); MODULE_AUTHOR("Pierre-Louis Bossart"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:sof_pcm512x"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index f52e25083905882fc8f1f424d497173e290cfed0..600707d403b9d53cf0434117675c710ec52ea424 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -276,7 +276,7 @@ void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link) link->init = rt1011_init; link->ops = &rt1011_ops; } -EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1011_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card) { @@ -306,7 +306,7 @@ void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card) } } -EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * rt1015: i2c mode driver for ALC1015 and ALC1015Q @@ -374,12 +374,12 @@ void sof_rt1015p_dai_link(struct snd_soc_dai_link *link) link->init = rt1015p_init; link->ops = &rt1015p_ops; } -EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); void sof_rt1015p_codec_conf(struct snd_soc_card *card) { } -EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * RT1015 audio amplifier @@ -523,7 +523,7 @@ void sof_rt1015_codec_conf(struct snd_soc_card *card) card->codec_conf = rt1015_amp_conf; card->num_configs = ARRAY_SIZE(rt1015_amp_conf); } -EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); void sof_rt1015_dai_link(struct snd_soc_dai_link *link) { @@ -532,7 +532,7 @@ void sof_rt1015_dai_link(struct snd_soc_dai_link *link) link->init = speaker_codec_init_lr; link->ops = &rt1015_ops; } -EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * RT1308 audio amplifier @@ -628,7 +628,7 @@ void sof_rt1308_dai_link(struct snd_soc_dai_link *link) link->init = rt1308_init; link->ops = &rt1308_ops; } -EXPORT_SYMBOL_NS(sof_rt1308_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1308_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * 2-amp Configuration for RT1019 @@ -681,7 +681,7 @@ void sof_rt1019p_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(rt1019p_components); link->init = rt1019p_init; } -EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); MODULE_DESCRIPTION("ASoC Intel SOF Realtek helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 5ceb376d49249086bfacf60504de9fc464a5ca73..f5925bd0a3fc67abb120da41ab8b4435fa6ee2d1 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -913,6 +913,6 @@ MODULE_AUTHOR("Sathya Prakash M R "); MODULE_AUTHOR("Brent Lu "); MODULE_AUTHOR("Mac Chiang "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_MAXIM_COMMON"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_REALTEK_COMMON"); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ea5249df8ac3c51460f46f6ce117e62bd6ba4438..810be7c949a5cea04a56dbb13507d80a6540678d 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1325,5 +1325,5 @@ MODULE_AUTHOR("Bard Liao "); MODULE_AUTHOR("Rander Wang "); MODULE_AUTHOR("Pierre-Louis Bossart "); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); -MODULE_IMPORT_NS(SND_SOC_SDW_UTILS); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SDW_UTILS"); diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index 6ff8895a294a93c8a4840663b983bf1e0822de20..48ee5353bdf1c480a09561995475c5968991c2a1 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -234,6 +234,6 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF Amplifier Machine driver"); MODULE_AUTHOR("Balamurugan C "); MODULE_AUTHOR("Brent Lu "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_CIRRUS_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_REALTEK_COMMON"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_CIRRUS_COMMON"); diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c index 0b37465b6c53fce49249fedd20728b16c505f4d2..03fc5a1870123f14e09ab5a3588c5682066e7588 100644 --- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -893,4 +893,4 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines); -MODULE_IMPORT_NS(SND_SOC_ACPI_INTEL_SDCA_QUIRKS); +MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_SDCA_QUIRKS"); diff --git a/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c index 0b7076606d66976ba06600477dcee64d0643dcf4..3eaa058f846085f1019ba70068412d6ca2ba0bd6 100644 --- a/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c +++ b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c @@ -35,8 +35,8 @@ bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg) return false; } -EXPORT_SYMBOL_NS(snd_soc_acpi_intel_sdca_is_device_rt712_vb, SND_SOC_ACPI_INTEL_SDCA_QUIRKS); +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_sdca_is_device_rt712_vb, "SND_SOC_ACPI_INTEL_SDCA_QUIRKS"); MODULE_DESCRIPTION("ASoC ACPI Intel SDCA quirks"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_SDCA); +MODULE_IMPORT_NS("SND_SOC_SDCA"); diff --git a/sound/soc/intel/common/soc-acpi-intel-ssp-common.c b/sound/soc/intel/common/soc-acpi-intel-ssp-common.c index de7a3f7f47f104029723e941131663ae6fdc49a8..f56f4bfa518718ab8ee6c03405e031143ffd9e17 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ssp-common.c +++ b/sound/soc/intel/common/soc-acpi-intel-ssp-common.c @@ -90,7 +90,7 @@ snd_soc_acpi_intel_detect_codec_type(struct device *dev) return CODEC_NONE; } -EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_codec_type, SND_SOC_ACPI_INTEL_MATCH); +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_codec_type, "SND_SOC_ACPI_INTEL_MATCH"); enum snd_soc_acpi_intel_codec snd_soc_acpi_intel_detect_amp_type(struct device *dev) @@ -107,7 +107,7 @@ snd_soc_acpi_intel_detect_amp_type(struct device *dev) return CODEC_NONE; } -EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_amp_type, SND_SOC_ACPI_INTEL_MATCH); +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_amp_type, "SND_SOC_ACPI_INTEL_MATCH"); const char * snd_soc_acpi_intel_get_codec_name(enum snd_soc_acpi_intel_codec codec_type) @@ -129,7 +129,7 @@ snd_soc_acpi_intel_get_codec_name(enum snd_soc_acpi_intel_codec codec_type) return NULL; } -EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_name, SND_SOC_ACPI_INTEL_MATCH); +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_name, "SND_SOC_ACPI_INTEL_MATCH"); const char * snd_soc_acpi_intel_get_codec_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type) @@ -145,7 +145,7 @@ snd_soc_acpi_intel_get_codec_tplg_suffix(enum snd_soc_acpi_intel_codec codec_typ return NULL; } -EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_tplg_suffix, SND_SOC_ACPI_INTEL_MATCH); +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH"); const char * snd_soc_acpi_intel_get_amp_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type) @@ -161,7 +161,7 @@ snd_soc_acpi_intel_get_amp_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type) return NULL; } -EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_amp_tplg_suffix, SND_SOC_ACPI_INTEL_MATCH); +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_amp_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH"); MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers"); MODULE_AUTHOR("Brent Lu "); diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index 84abdba9ddb6d67127d10a8784d0e1d5c0de5639..e04b88a57535ce00977f8cb7b19eb67f7382f474 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -1277,10 +1277,12 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "DPTX_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_dptx_codec_init; } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8188_hdmi_codec_init; } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC_BE") == 0) { @@ -1292,6 +1294,9 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 || strcmp(dai_link->name, "ETDM1_IN_BE") == 0 || strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { + if (!dai_link->num_codecs) + continue; + if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) { /* * The TDM protocol settings with fixed 4 slots are defined in diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index 1aba9c75594eb663914e6d7a8e8409c316c21f46..b1598cc5587e3057f01566639594cb9dbd13cfcc 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -1091,7 +1091,7 @@ static int mt8192_mt6359_legacy_probe(struct mtk_soc_card_data *soc_card_data) dai_link->ignore = 0; } - if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + if (dai_link->num_codecs && strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; } @@ -1119,7 +1119,7 @@ static int mt8192_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, int i; for_each_card_prelinks(card, i, dai_link) - if (dai_link->num_codecs && dai_link->codecs[0].dai_name && + if (dai_link->num_codecs && strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0) dai_link->ops = &mt8192_rt1015_i2s_ops; } diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c index 56b9d2433a1eb1f3f60e657c7308027956177bbc..2b9cb3248795b817a68cd998b90d52c1dd6c66a0 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c @@ -1378,10 +1378,12 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, for_each_card_prelinks(card, i, dai_link) { if (strcmp(dai_link->name, "DPTX_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8195_dptx_codec_init; } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { - if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) dai_link->init = mt8195_hdmi_codec_init; } else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 || strcmp(dai_link->name, "UL_SRC1_BE") == 0 || @@ -1394,6 +1396,9 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 || strcmp(dai_link->name, "ETDM1_IN_BE") == 0 || strcmp(dai_link->name, "ETDM2_IN_BE") == 0) { + if (!dai_link->num_codecs) + continue; + if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) { if (!(codec_init & MAX98390_CODEC_INIT)) { dai_link->init = mt8195_max98390_init; diff --git a/sound/soc/sdca/sdca_device.c b/sound/soc/sdca/sdca_device.c index c44dc21cb63497a0ef01b229519f618bd4fdd695..80d663777eb53a575f378071b48cda46c8651b79 100644 --- a/sound/soc/sdca/sdca_device.c +++ b/sound/soc/sdca/sdca_device.c @@ -22,7 +22,7 @@ void sdca_lookup_interface_revision(struct sdw_slave *slave) fwnode_property_read_u32(fwnode, "mipi-sdw-sdca-interface-revision", &slave->sdca_data.interface_revision); } -EXPORT_SYMBOL_NS(sdca_lookup_interface_revision, SND_SOC_SDCA); +EXPORT_SYMBOL_NS(sdca_lookup_interface_revision, "SND_SOC_SDCA"); static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave) { @@ -64,4 +64,4 @@ bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk) } return false; } -EXPORT_SYMBOL_NS(sdca_device_quirk_match, SND_SOC_SDCA); +EXPORT_SYMBOL_NS(sdca_device_quirk_match, "SND_SOC_SDCA"); diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index e6e5629c7054e81056cc2f9fb00d04355ac19254..652865329968685bae50f2ea43af5615ab58f5ad 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -171,7 +171,7 @@ void sdca_lookup_functions(struct sdw_slave *slave) } acpi_dev_for_each_child(adev, find_sdca_function, &slave->sdca_data); } -EXPORT_SYMBOL_NS(sdca_lookup_functions, SND_SOC_SDCA); +EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SDCA library"); diff --git a/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c b/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c index fcc3ef685af7d394db5a3fab51c29c63e2002db5..246e5c2e0af55fe1c2ec15db742fc7d1212d417e 100644 --- a/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c +++ b/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c @@ -112,7 +112,7 @@ int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_count_sidecar, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_count_sidecar, "SND_SOC_SDW_UTILS"); int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card, struct snd_soc_dai_link **dai_links, @@ -134,7 +134,7 @@ int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_add_sidecar, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_add_sidecar, "SND_SOC_SDW_UTILS"); int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, @@ -148,4 +148,4 @@ int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_spk_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_spk_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_cs42l42.c b/sound/soc/sdw_utils/soc_sdw_cs42l42.c index 78a6cb059ac06b655efbe9c18d55ad2ab13296e9..f37c1793991a4c9265cb0f09daa80809a1de7a11 100644 --- a/sound/soc/sdw_utils/soc_sdw_cs42l42.c +++ b/sound/soc/sdw_utils/soc_sdw_cs42l42.c @@ -88,4 +88,4 @@ int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_cs42l42_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_cs42l42_rtd_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_cs42l43.c b/sound/soc/sdw_utils/soc_sdw_cs42l43.c index adb1c008e871d508a5d838196592c5b52c197a9c..668c9d28a1c12d214fb7547cccaaddfc74eabbe5 100644 --- a/sound/soc/sdw_utils/soc_sdw_cs42l43.c +++ b/sound/soc/sdw_utils/soc_sdw_cs42l43.c @@ -100,7 +100,7 @@ int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_hs_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_hs_rtd_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { @@ -124,7 +124,7 @@ int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_so return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_spk_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_spk_rtd_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_cs42l43_spk_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, @@ -139,7 +139,7 @@ int asoc_sdw_cs42l43_spk_init(struct snd_soc_card *card, return asoc_sdw_bridge_cs35l56_spk_init(card, dai_links, info, playback); } -EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_spk_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_spk_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { @@ -158,4 +158,4 @@ int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_s return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_dmic_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_dmic_rtd_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_cs_amp.c b/sound/soc/sdw_utils/soc_sdw_cs_amp.c index 58b059b68016b80b69e4d646b59905d10f327fbd..a0bb626c5cb8c47be9d16a3d9f64c4275dd24b01 100644 --- a/sound/soc/sdw_utils/soc_sdw_cs_amp.c +++ b/sound/soc/sdw_utils/soc_sdw_cs_amp.c @@ -46,7 +46,7 @@ int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_cs_spk_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_cs_spk_rtd_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_cs_amp_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, @@ -61,4 +61,4 @@ int asoc_sdw_cs_amp_init(struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_cs_amp_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_cs_amp_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_dmic.c b/sound/soc/sdw_utils/soc_sdw_dmic.c index fc2aae985084b6d589b53ea2475c66eed75b2fbd..0d8fce7234a7373865c8a5db574312065498711e 100644 --- a/sound/soc/sdw_utils/soc_sdw_dmic.c +++ b/sound/soc/sdw_utils/soc_sdw_dmic.c @@ -42,4 +42,4 @@ int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd) return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_dmic_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_dmic_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_maxim.c b/sound/soc/sdw_utils/soc_sdw_maxim.c index cdcd8df37e1d3c00a82a393cf8cc65eb9fe47a79..5df8d9cae60c3e6674ab7443e1729b45374026d9 100644 --- a/sound/soc/sdw_utils/soc_sdw_maxim.c +++ b/sound/soc/sdw_utils/soc_sdw_maxim.c @@ -43,7 +43,7 @@ int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_ return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_maxim_spk_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_maxim_spk_rtd_init, "SND_SOC_SDW_UTILS"); static int asoc_sdw_mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable) { @@ -145,4 +145,4 @@ int asoc_sdw_maxim_init(struct snd_soc_card *card, } return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_maxim_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_maxim_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt5682.c b/sound/soc/sdw_utils/soc_sdw_rt5682.c index 80b4caa926670fb1a58c7db4017e7e8274335b8d..8c86254cbaf640051a0afbeefabe1b3021d84f0e 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt5682.c +++ b/sound/soc/sdw_utils/soc_sdw_rt5682.c @@ -88,4 +88,4 @@ int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_rt5682_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt5682_rtd_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt700.c b/sound/soc/sdw_utils/soc_sdw_rt700.c index 4dbeeeca343441962ec5237ed2a9a07308f182d9..e6468e4ac6e7262dd6281fd04a5986494753f941 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt700.c +++ b/sound/soc/sdw_utils/soc_sdw_rt700.c @@ -85,4 +85,4 @@ int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_rt700_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt700_rtd_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt711.c b/sound/soc/sdw_utils/soc_sdw_rt711.c index 38b4126dd45f16c366a47f052eda13d870cd29f2..4aa93fdefef63a9e2f57499f0088f2f80cb891aa 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt711.c +++ b/sound/soc/sdw_utils/soc_sdw_rt711.c @@ -112,7 +112,7 @@ int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_rt711_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt711_rtd_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { @@ -126,7 +126,7 @@ int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_ return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rt711_exit, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt711_exit, "SND_SOC_SDW_UTILS"); int asoc_sdw_rt711_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, @@ -157,4 +157,4 @@ int asoc_sdw_rt711_init(struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rt711_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt711_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt_amp.c b/sound/soc/sdw_utils/soc_sdw_rt_amp.c index 6951dfb565263229a6019af81ea14b9f6bee253d..0538c252ba69b1f5a24ba2de2a610b22d0c0665f 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt_amp.c +++ b/sound/soc/sdw_utils/soc_sdw_rt_amp.c @@ -210,7 +210,7 @@ int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_spk_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_spk_rtd_init, "SND_SOC_SDW_UTILS"); static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -248,7 +248,7 @@ static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, const struct snd_soc_ops soc_sdw_rt1308_i2s_ops = { .hw_params = rt1308_i2s_hw_params, }; -EXPORT_SYMBOL_NS(soc_sdw_rt1308_i2s_ops, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(soc_sdw_rt1308_i2s_ops, "SND_SOC_SDW_UTILS"); int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { @@ -266,7 +266,7 @@ int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_exit, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_exit, "SND_SOC_SDW_UTILS"); int asoc_sdw_rt_amp_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, @@ -309,4 +309,4 @@ int asoc_sdw_rt_amp_init(struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c index 7f24806d809d9d38355e4e93cd1d3f085fbfd4e7..46d917a99c51dab90d28b12c4646ed7862dc0044 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt_dmic.c +++ b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c @@ -40,4 +40,4 @@ int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_dmic_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_dmic_rtd_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c b/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c index 81e43319876e775c1663ff3e708588d82f02e925..0161b14297d5a1e030730aa47406c0912694fc84 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c +++ b/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c @@ -87,4 +87,4 @@ int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_mf_sdca_spk_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_mf_sdca_spk_rtd_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c b/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c index af43efbb8f79c98e276d1d74b5539e0137bf1360..6279faf6edd48880615d80dbba850c4fcea08008 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c +++ b/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c @@ -170,7 +170,7 @@ int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_s return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_rtd_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { @@ -188,7 +188,7 @@ int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_lin return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_exit, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_exit, "SND_SOC_SDW_UTILS"); int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, @@ -219,4 +219,4 @@ int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c index 19bd02e2cd6d67186aeb0c7a37cc62253907ae63..937fa3ce59dfd675035e1cc980197789153af445 100644 --- a/sound/soc/sdw_utils/soc_sdw_utils.c +++ b/sound/soc/sdw_utils/soc_sdw_utils.c @@ -622,13 +622,13 @@ struct asoc_sdw_codec_info codec_info_list[] = { .dai_num = 1, }, }; -EXPORT_SYMBOL_NS(codec_info_list, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(codec_info_list, "SND_SOC_SDW_UTILS"); int asoc_sdw_get_codec_info_list_count(void) { return ARRAY_SIZE(codec_info_list); }; -EXPORT_SYMBOL_NS(asoc_sdw_get_codec_info_list_count, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_get_codec_info_list_count, "SND_SOC_SDW_UTILS"); struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr) { @@ -649,7 +649,7 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr) return NULL; } -EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, "SND_SOC_SDW_UTILS"); struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id) { @@ -664,7 +664,7 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id) return NULL; } -EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_acpi, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_acpi, "SND_SOC_SDW_UTILS"); struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, int *dai_index) { @@ -681,7 +681,7 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, i return NULL; } -EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, "SND_SOC_SDW_UTILS"); int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) { @@ -745,14 +745,14 @@ skip_add_controls_widgets: return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_rtd_init, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_rtd_init, "SND_SOC_SDW_UTILS"); /* these wrappers are only needed to avoid typecast compilation errors */ int asoc_sdw_startup(struct snd_pcm_substream *substream) { return sdw_startup_stream(substream); } -EXPORT_SYMBOL_NS(asoc_sdw_startup, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_startup, "SND_SOC_SDW_UTILS"); int asoc_sdw_prepare(struct snd_pcm_substream *substream) { @@ -771,7 +771,7 @@ int asoc_sdw_prepare(struct snd_pcm_substream *substream) return sdw_prepare_stream(sdw_stream); } -EXPORT_SYMBOL_NS(asoc_sdw_prepare, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_prepare, "SND_SOC_SDW_UTILS"); int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd) { @@ -811,7 +811,7 @@ int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_trigger, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_trigger, "SND_SOC_SDW_UTILS"); int asoc_sdw_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -854,7 +854,7 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream, return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_hw_params, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_hw_params, "SND_SOC_SDW_UTILS"); int asoc_sdw_hw_free(struct snd_pcm_substream *substream) { @@ -873,13 +873,13 @@ int asoc_sdw_hw_free(struct snd_pcm_substream *substream) return sdw_deprepare_stream(sdw_stream); } -EXPORT_SYMBOL_NS(asoc_sdw_hw_free, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_hw_free, "SND_SOC_SDW_UTILS"); void asoc_sdw_shutdown(struct snd_pcm_substream *substream) { sdw_shutdown_stream(substream); } -EXPORT_SYMBOL_NS(asoc_sdw_shutdown, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_shutdown, "SND_SOC_SDW_UTILS"); static bool asoc_sdw_is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, unsigned int sdw_version, @@ -940,7 +940,7 @@ const char *asoc_sdw_get_codec_name(struct device *dev, return NULL; } -EXPORT_SYMBOL_NS(asoc_sdw_get_codec_name, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_get_codec_name, "SND_SOC_SDW_UTILS"); /* helper to get the link that the codec DAI is used */ struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card, @@ -959,7 +959,7 @@ struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *ca } return NULL; } -EXPORT_SYMBOL_NS(asoc_sdw_mc_find_codec_dai_used, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_mc_find_codec_dai_used, "SND_SOC_SDW_UTILS"); void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card) { @@ -992,7 +992,7 @@ void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card) } } } -EXPORT_SYMBOL_NS(asoc_sdw_mc_dailink_exit_loop, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_mc_dailink_exit_loop, "SND_SOC_SDW_UTILS"); int asoc_sdw_card_late_probe(struct snd_soc_card *card) { @@ -1008,7 +1008,7 @@ int asoc_sdw_card_late_probe(struct snd_soc_card *card) } return ret; } -EXPORT_SYMBOL_NS(asoc_sdw_card_late_probe, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_card_late_probe, "SND_SOC_SDW_UTILS"); void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, int *be_id, char *name, int playback, int capture, @@ -1035,7 +1035,7 @@ void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_lin dai_links->init = init; dai_links->ops = ops; } -EXPORT_SYMBOL_NS(asoc_sdw_init_dai_link, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_init_dai_link, "SND_SOC_SDW_UTILS"); int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, int *be_id, char *name, int playback, int capture, @@ -1064,7 +1064,7 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_init_simple_dai_link, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_init_simple_dai_link, "SND_SOC_SDW_UTILS"); int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends) { @@ -1085,7 +1085,7 @@ int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int * return 0; } -EXPORT_SYMBOL_NS(asoc_sdw_count_sdw_endpoints, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_count_sdw_endpoints, "SND_SOC_SDW_UTILS"); struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks, const struct snd_soc_acpi_endpoint *new) @@ -1103,7 +1103,7 @@ struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks return dailinks; } -EXPORT_SYMBOL_NS(asoc_sdw_find_dailink, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_find_dailink, "SND_SOC_SDW_UTILS"); int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card, struct asoc_sdw_dailink *soc_dais, @@ -1226,7 +1226,7 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card, return num_dais; } -EXPORT_SYMBOL_NS(asoc_sdw_parse_sdw_endpoints, SND_SOC_SDW_UTILS); +EXPORT_SYMBOL_NS(asoc_sdw_parse_sdw_endpoints, "SND_SOC_SDW_UTILS"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SoundWire ASoC helpers"); diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c index fc792956bb97626af68f1456f6e2b8fdb8df773b..0c3a92f5f942d05167146cd8e938c226f5ca5175 100644 --- a/sound/soc/sof/amd/acp-common.c +++ b/sound/soc/sof/amd/acp-common.c @@ -258,10 +258,10 @@ const struct snd_sof_dsp_ops sof_acp_common_ops = { .register_ipc_clients = acp_probes_register, .unregister_ipc_clients = acp_probes_unregister, }; -EXPORT_SYMBOL_NS(sof_acp_common_ops, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(sof_acp_common_ops, "SND_SOC_SOF_AMD_COMMON"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("ACP SOF COMMON Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); -MODULE_IMPORT_NS(SOUNDWIRE_AMD_INIT); +MODULE_IMPORT_NS("SND_SOC_SOF_AMD_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SOUNDWIRE_AMD_INIT"); diff --git a/sound/soc/sof/amd/acp-ipc.c b/sound/soc/sof/amd/acp-ipc.c index b44b1b1adb6ed9e913c857168902f00949abcb86..5f371d9263f3bad507236ace95b7ef323c369187 100644 --- a/sound/soc/sof/amd/acp-ipc.c +++ b/sound/soc/sof/amd/acp-ipc.c @@ -19,13 +19,13 @@ void acp_mailbox_write(struct snd_sof_dev *sdev, u32 offset, void *message, size { memcpy_to_scratch(sdev, offset, message, bytes); } -EXPORT_SYMBOL_NS(acp_mailbox_write, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_mailbox_write, "SND_SOC_SOF_AMD_COMMON"); void acp_mailbox_read(struct snd_sof_dev *sdev, u32 offset, void *message, size_t bytes) { memcpy_from_scratch(sdev, offset, message, bytes); } -EXPORT_SYMBOL_NS(acp_mailbox_read, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_mailbox_read, "SND_SOC_SOF_AMD_COMMON"); static void acpbus_trigger_host_to_dsp_swintr(struct acp_dev_data *adata) { @@ -91,7 +91,7 @@ int acp_sof_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(acp_sof_ipc_send_msg, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_ipc_send_msg, "SND_SOC_SOF_AMD_COMMON"); static void acp_dsp_ipc_get_reply(struct snd_sof_dev *sdev) { @@ -235,7 +235,7 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(acp_sof_ipc_irq_thread, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_ipc_irq_thread, "SND_SOC_SOF_AMD_COMMON"); int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *sps, void *p, size_t sz) @@ -261,7 +261,7 @@ int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *sp return 0; } -EXPORT_SYMBOL_NS(acp_sof_ipc_msg_data, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_ipc_msg_data, "SND_SOC_SOF_AMD_COMMON"); int acp_set_stream_data_offset(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *sps, @@ -282,7 +282,7 @@ int acp_set_stream_data_offset(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(acp_set_stream_data_offset, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_set_stream_data_offset, "SND_SOC_SOF_AMD_COMMON"); int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) { @@ -290,12 +290,12 @@ int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) return desc->sram_pte_offset; } -EXPORT_SYMBOL_NS(acp_sof_ipc_get_mailbox_offset, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_ipc_get_mailbox_offset, "SND_SOC_SOF_AMD_COMMON"); int acp_sof_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id) { return 0; } -EXPORT_SYMBOL_NS(acp_sof_ipc_get_window_offset, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_ipc_get_window_offset, "SND_SOC_SOF_AMD_COMMON"); MODULE_DESCRIPTION("AMD ACP sof-ipc driver"); diff --git a/sound/soc/sof/amd/acp-loader.c b/sound/soc/sof/amd/acp-loader.c index 077af9e2af8d09be9927627b78a86854b31245f3..ea105227227dc41fb49f4f43793c6cbaf2eb77e3 100644 --- a/sound/soc/sof/amd/acp-loader.c +++ b/sound/soc/sof/amd/acp-loader.c @@ -44,7 +44,7 @@ int acp_dsp_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_ty return 0; } -EXPORT_SYMBOL_NS(acp_dsp_block_read, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_dsp_block_read, "SND_SOC_SOF_AMD_COMMON"); int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, u32 offset, void *src, size_t size) @@ -106,13 +106,13 @@ int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_t memcpy(dest, src, size); return 0; } -EXPORT_SYMBOL_NS(acp_dsp_block_write, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_dsp_block_write, "SND_SOC_SOF_AMD_COMMON"); int acp_get_bar_index(struct snd_sof_dev *sdev, u32 type) { return type; } -EXPORT_SYMBOL_NS(acp_get_bar_index, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_get_bar_index, "SND_SOC_SOF_AMD_COMMON"); static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev_data *adata) { @@ -244,7 +244,7 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev) } return ret; } -EXPORT_SYMBOL_NS(acp_dsp_pre_fw_run, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_dsp_pre_fw_run, "SND_SOC_SOF_AMD_COMMON"); int acp_sof_dsp_run(struct snd_sof_dev *sdev) { @@ -264,7 +264,7 @@ int acp_sof_dsp_run(struct snd_sof_dev *sdev) } return 0; } -EXPORT_SYMBOL_NS(acp_sof_dsp_run, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_dsp_run, "SND_SOC_SOF_AMD_COMMON"); int acp_sof_load_signed_firmware(struct snd_sof_dev *sdev) { @@ -317,4 +317,4 @@ int acp_sof_load_signed_firmware(struct snd_sof_dev *sdev) adata->fw_dbin->size); return ret; } -EXPORT_SYMBOL_NS(acp_sof_load_signed_firmware, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_load_signed_firmware, "SND_SOC_SOF_AMD_COMMON"); diff --git a/sound/soc/sof/amd/acp-pcm.c b/sound/soc/sof/amd/acp-pcm.c index cee0b1154874285df63d03a414cb082211dba4c1..2802684f26de17736e4c90be5d0350ba820d76a8 100644 --- a/sound/soc/sof/amd/acp-pcm.c +++ b/sound/soc/sof/amd/acp-pcm.c @@ -52,7 +52,7 @@ int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substr return 0; } -EXPORT_SYMBOL_NS(acp_pcm_hw_params, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_pcm_hw_params, "SND_SOC_SOF_AMD_COMMON"); int acp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { @@ -67,7 +67,7 @@ int acp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) return 0; } -EXPORT_SYMBOL_NS(acp_pcm_open, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_pcm_open, "SND_SOC_SOF_AMD_COMMON"); int acp_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { @@ -84,7 +84,7 @@ int acp_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) return acp_dsp_stream_put(sdev, stream); } -EXPORT_SYMBOL_NS(acp_pcm_close, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_pcm_close, "SND_SOC_SOF_AMD_COMMON"); snd_pcm_uframes_t acp_pcm_pointer(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) @@ -117,4 +117,4 @@ snd_pcm_uframes_t acp_pcm_pointer(struct snd_sof_dev *sdev, return pos; } -EXPORT_SYMBOL_NS(acp_pcm_pointer, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_pcm_pointer, "SND_SOC_SOF_AMD_COMMON"); diff --git a/sound/soc/sof/amd/acp-probes.c b/sound/soc/sof/amd/acp-probes.c index 778cf1a8b610521eac4b3231e7c15ebf70ff466f..0d0f8ec4aed838b1fbde652126e9e653d7b952f9 100644 --- a/sound/soc/sof/amd/acp-probes.c +++ b/sound/soc/sof/amd/acp-probes.c @@ -135,13 +135,13 @@ int acp_probes_register(struct snd_sof_dev *sdev) return sof_client_dev_register(sdev, "acp-probes", 0, &acp_probes_ops, sizeof(acp_probes_ops)); } -EXPORT_SYMBOL_NS(acp_probes_register, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_probes_register, "SND_SOC_SOF_AMD_COMMON"); void acp_probes_unregister(struct snd_sof_dev *sdev) { sof_client_dev_unregister(sdev, "acp-probes", 0); } -EXPORT_SYMBOL_NS(acp_probes_unregister, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_probes_unregister, "SND_SOC_SOF_AMD_COMMON"); -MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); +MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/amd/acp-stream.c b/sound/soc/sof/amd/acp-stream.c index 6f40ef7ba85ec26330e2ccb0a66c35e5776d3e68..9212a3137cfd2b87713f7ac17d95961fd47522d1 100644 --- a/sound/soc/sof/amd/acp-stream.c +++ b/sound/soc/sof/amd/acp-stream.c @@ -150,7 +150,7 @@ struct acp_dsp_stream *acp_dsp_stream_get(struct snd_sof_dev *sdev, int tag) dev_err(sdev->dev, "stream %d active or no inactive stream\n", tag); return NULL; } -EXPORT_SYMBOL_NS(acp_dsp_stream_get, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_dsp_stream_get, "SND_SOC_SOF_AMD_COMMON"); int acp_dsp_stream_put(struct snd_sof_dev *sdev, struct acp_dsp_stream *acp_stream) @@ -170,7 +170,7 @@ int acp_dsp_stream_put(struct snd_sof_dev *sdev, dev_err(sdev->dev, "Cannot find active stream tag %d\n", acp_stream->stream_tag); return -EINVAL; } -EXPORT_SYMBOL_NS(acp_dsp_stream_put, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_dsp_stream_put, "SND_SOC_SOF_AMD_COMMON"); int acp_dsp_stream_init(struct snd_sof_dev *sdev) { @@ -184,4 +184,4 @@ int acp_dsp_stream_init(struct snd_sof_dev *sdev) } return 0; } -EXPORT_SYMBOL_NS(acp_dsp_stream_init, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_dsp_stream_init, "SND_SOC_SOF_AMD_COMMON"); diff --git a/sound/soc/sof/amd/acp-trace.c b/sound/soc/sof/amd/acp-trace.c index c9482b27cbe39359e2b5ac01837c6de8c62ac820..0bd1f5990e8cd70baede5d379bc223d8f3761f8b 100644 --- a/sound/soc/sof/amd/acp-trace.c +++ b/sound/soc/sof/amd/acp-trace.c @@ -32,7 +32,7 @@ int acp_sof_trace_release(struct snd_sof_dev *sdev) adata->dtrace_stream = NULL; return 0; } -EXPORT_SYMBOL_NS(acp_sof_trace_release, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_trace_release, "SND_SOC_SOF_AMD_COMMON"); int acp_sof_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, struct sof_ipc_dma_trace_params_ext *dtrace_params) @@ -61,4 +61,4 @@ int acp_sof_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, return 0; } -EXPORT_SYMBOL_NS(acp_sof_trace_init, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(acp_sof_trace_init, "SND_SOC_SOF_AMD_COMMON"); diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index f7814dadf3bace4609f1e216a230fe6dc3913f5e..33648ff8b83365e76d7d90e52c2cb8f884a2fe72 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -633,7 +633,7 @@ int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state) return 0; } -EXPORT_SYMBOL_NS(amd_sof_acp_suspend, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(amd_sof_acp_suspend, "SND_SOC_SOF_AMD_COMMON"); int amd_sof_acp_resume(struct snd_sof_dev *sdev) { @@ -652,7 +652,7 @@ int amd_sof_acp_resume(struct snd_sof_dev *sdev) return acp_dsp_reset(sdev); } } -EXPORT_SYMBOL_NS(amd_sof_acp_resume, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(amd_sof_acp_resume, "SND_SOC_SOF_AMD_COMMON"); #if IS_ENABLED(CONFIG_SND_SOC_SOF_AMD_SOUNDWIRE) static int acp_sof_scan_sdw_devices(struct snd_sof_dev *sdev, u64 addr) @@ -852,7 +852,7 @@ unregister_dev: platform_device_unregister(adata->dmic_dev); return ret; } -EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(amd_sof_acp_probe, "SND_SOC_SOF_AMD_COMMON"); void amd_sof_acp_remove(struct snd_sof_dev *sdev) { @@ -872,9 +872,9 @@ void amd_sof_acp_remove(struct snd_sof_dev *sdev) acp_reset(sdev); } -EXPORT_SYMBOL_NS(amd_sof_acp_remove, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(amd_sof_acp_remove, "SND_SOC_SOF_AMD_COMMON"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("AMD ACP sof driver"); -MODULE_IMPORT_NS(SOUNDWIRE_AMD_INIT); -MODULE_IMPORT_NS(SND_AMD_SOUNDWIRE_ACPI); +MODULE_IMPORT_NS("SOUNDWIRE_AMD_INIT"); +MODULE_IMPORT_NS("SND_AMD_SOUNDWIRE_ACPI"); diff --git a/sound/soc/sof/amd/acp63.c b/sound/soc/sof/amd/acp63.c index 9e6eb4bfc805b21e9b0607d8ea26843307338d57..a686620b13588bc3d82d35701d20a6cab38e7f28 100644 --- a/sound/soc/sof/amd/acp63.c +++ b/sound/soc/sof/amd/acp63.c @@ -128,7 +128,7 @@ static struct snd_soc_dai_driver acp63_sof_dai[] = { /* Phoenix ops */ struct snd_sof_dsp_ops sof_acp63_ops; -EXPORT_SYMBOL_NS(sof_acp63_ops, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(sof_acp63_ops, "SND_SOC_SOF_AMD_COMMON"); int sof_acp63_ops_init(struct snd_sof_dev *sdev) { diff --git a/sound/soc/sof/amd/acp70.c b/sound/soc/sof/amd/acp70.c index 7d1842f42c90c0652e05503d374c13e8afa0c532..8314ac4008dae157632194b58da90aa1ed51ca61 100644 --- a/sound/soc/sof/amd/acp70.c +++ b/sound/soc/sof/amd/acp70.c @@ -128,7 +128,7 @@ static struct snd_soc_dai_driver acp70_sof_dai[] = { /* Phoenix ops */ struct snd_sof_dsp_ops sof_acp70_ops; -EXPORT_SYMBOL_NS(sof_acp70_ops, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(sof_acp70_ops, "SND_SOC_SOF_AMD_COMMON"); int sof_acp70_ops_init(struct snd_sof_dev *sdev) { diff --git a/sound/soc/sof/amd/pci-acp63.c b/sound/soc/sof/amd/pci-acp63.c index b54ed61b79edd26c5c9956021468b7cc38de1469..ffe7c755d655e63763f3c345cfddaf5cb0be7106 100644 --- a/sound/soc/sof/amd/pci-acp63.c +++ b/sound/soc/sof/amd/pci-acp63.c @@ -112,5 +112,5 @@ module_pci_driver(snd_sof_pci_amd_acp63_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("ACP63 SOF Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_AMD_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/amd/pci-acp70.c b/sound/soc/sof/amd/pci-acp70.c index a5d8b6a95a2226f094430b2b3146c7a576c182ee..3647ec992e95f66a7cfdb43091c6890812fa8a97 100644 --- a/sound/soc/sof/amd/pci-acp70.c +++ b/sound/soc/sof/amd/pci-acp70.c @@ -108,5 +108,5 @@ module_pci_driver(snd_sof_pci_amd_acp70_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("ACP70 SOF Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_AMD_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c index c45256bf4fda62267efa4983931a25af8ca2bede..cbb4d528266442f6481a9fea5c7074f75820fc50 100644 --- a/sound/soc/sof/amd/pci-rmb.c +++ b/sound/soc/sof/amd/pci-rmb.c @@ -101,5 +101,5 @@ module_pci_driver(snd_sof_pci_amd_rmb_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("REMBRANDT SOF Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_AMD_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c index 386a0f1e7ee01484c103290e7da0581382416627..b7d558cb1fd7a7fd2f071b9394588f1a9100e9c5 100644 --- a/sound/soc/sof/amd/pci-rn.c +++ b/sound/soc/sof/amd/pci-rn.c @@ -105,5 +105,5 @@ module_pci_driver(snd_sof_pci_amd_rn_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("RENOIR SOF Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_AMD_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/amd/pci-vangogh.c b/sound/soc/sof/amd/pci-vangogh.c index cb845f81795e5578ffd10b279517388453d8874f..53f64d6bc91bae9e2ec506384a83b209a296860f 100644 --- a/sound/soc/sof/amd/pci-vangogh.c +++ b/sound/soc/sof/amd/pci-vangogh.c @@ -100,5 +100,5 @@ module_pci_driver(snd_sof_pci_amd_vgh_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("VANGOGH SOF Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_AMD_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/amd/rembrandt.c b/sound/soc/sof/amd/rembrandt.c index 076f2f05a95c2066055dffa26f5ad372cfe6b1c1..86ef59743fc875ef4965dcced9ff18e289b75dcb 100644 --- a/sound/soc/sof/amd/rembrandt.c +++ b/sound/soc/sof/amd/rembrandt.c @@ -128,7 +128,7 @@ static struct snd_soc_dai_driver rembrandt_sof_dai[] = { /* Rembrandt ops */ struct snd_sof_dsp_ops sof_rembrandt_ops; -EXPORT_SYMBOL_NS(sof_rembrandt_ops, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(sof_rembrandt_ops, "SND_SOC_SOF_AMD_COMMON"); int sof_rembrandt_ops_init(struct snd_sof_dev *sdev) { diff --git a/sound/soc/sof/amd/renoir.c b/sound/soc/sof/amd/renoir.c index aa2d24dac6f5d5f6a3c3367de868157c2bd49073..b3b4639abf506554a6140bfa47ab8ef8096aaf8e 100644 --- a/sound/soc/sof/amd/renoir.c +++ b/sound/soc/sof/amd/renoir.c @@ -103,7 +103,7 @@ static struct snd_soc_dai_driver renoir_sof_dai[] = { /* Renoir ops */ struct snd_sof_dsp_ops sof_renoir_ops; -EXPORT_SYMBOL_NS(sof_renoir_ops, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(sof_renoir_ops, "SND_SOC_SOF_AMD_COMMON"); int sof_renoir_ops_init(struct snd_sof_dev *sdev) { diff --git a/sound/soc/sof/amd/vangogh.c b/sound/soc/sof/amd/vangogh.c index 61372958c09dc8c19343484e1155d986b067a17a..8e2672106ac60a22824836a944503a05616f8661 100644 --- a/sound/soc/sof/amd/vangogh.c +++ b/sound/soc/sof/amd/vangogh.c @@ -138,7 +138,7 @@ static struct snd_soc_dai_driver vangogh_sof_dai[] = { /* Vangogh ops */ struct snd_sof_dsp_ops sof_vangogh_ops; -EXPORT_SYMBOL_NS(sof_vangogh_ops, SND_SOC_SOF_AMD_COMMON); +EXPORT_SYMBOL_NS(sof_vangogh_ops, "SND_SOC_SOF_AMD_COMMON"); int sof_vangogh_ops_init(struct snd_sof_dev *sdev) { diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 24e779e8d650711ee6461a907be17f887e47afdb..aed834d03e1086ba83980d77382e207863ed35c3 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -836,4 +836,4 @@ MODULE_AUTHOR("Liam Girdwood"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core"); MODULE_ALIAS("platform:sof-audio"); -MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); +MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index f09ee0dea2ccd515c4029a9c449cb5f49bc52549..0b85b29d1067f65f398bd725948e4d0296d380a6 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -669,4 +669,4 @@ module_platform_driver(snd_sof_of_imx8_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for IMX8 platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index 01d3ad3314f3f26b8adeb7b7db51f0665cbbc387..ff42743efa79133428027b692be6631b3cc3ea81 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -516,4 +516,4 @@ module_platform_driver(snd_sof_of_imx8m_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for IMX8M platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); diff --git a/sound/soc/sof/imx/imx8ulp.c b/sound/soc/sof/imx/imx8ulp.c index e5eee1c9f6da460ae92e935fa127506fd9b4b4b7..6965791ab6ef64a577358fcf1ff0e5a9288e34f0 100644 --- a/sound/soc/sof/imx/imx8ulp.c +++ b/sound/soc/sof/imx/imx8ulp.c @@ -518,4 +518,4 @@ module_platform_driver(snd_sof_of_imx8ulp_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for IMX8ULP platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); diff --git a/sound/soc/sof/intel/atom.c b/sound/soc/sof/intel/atom.c index 3505ac3a1b143fcd0586a2782224508afca47357..30e981c558c649e2aab6a7db59fbf2df3462b3d7 100644 --- a/sound/soc/sof/intel/atom.c +++ b/sound/soc/sof/intel/atom.c @@ -94,7 +94,7 @@ void atom_dump(struct snd_sof_dev *sdev, u32 flags) (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd); } -EXPORT_SYMBOL_NS(atom_dump, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_dump, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); /* * IPC Doorbell IRQ handler and thread. @@ -131,7 +131,7 @@ irqreturn_t atom_irq_handler(int irq, void *context) return ret; } -EXPORT_SYMBOL_NS(atom_irq_handler, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_irq_handler, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); irqreturn_t atom_irq_thread(int irq, void *context) { @@ -176,7 +176,7 @@ irqreturn_t atom_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(atom_irq_thread, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_irq_thread, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); int atom_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { @@ -191,19 +191,19 @@ int atom_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(atom_send_msg, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_send_msg, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); int atom_get_mailbox_offset(struct snd_sof_dev *sdev) { return MBOX_OFFSET; } -EXPORT_SYMBOL_NS(atom_get_mailbox_offset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_get_mailbox_offset, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); int atom_get_window_offset(struct snd_sof_dev *sdev, u32 id) { return MBOX_OFFSET; } -EXPORT_SYMBOL_NS(atom_get_window_offset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_get_window_offset, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); static void atom_host_done(struct snd_sof_dev *sdev) { @@ -248,7 +248,7 @@ int atom_run(struct snd_sof_dev *sdev) /* return init core mask */ return 1; } -EXPORT_SYMBOL_NS(atom_run, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_run, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); int atom_reset(struct snd_sof_dev *sdev) { @@ -267,7 +267,7 @@ int atom_reset(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(atom_reset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_reset, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); static const char *fixup_tplg_name(struct snd_sof_dev *sdev, const char *sof_tplg_filename, @@ -330,7 +330,7 @@ struct snd_soc_acpi_mach *atom_machine_select(struct snd_sof_dev *sdev) return mach; } -EXPORT_SYMBOL_NS(atom_machine_select, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_machine_select, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); /* Atom DAIs */ struct snd_soc_dai_driver atom_dai[] = { @@ -401,7 +401,7 @@ struct snd_soc_dai_driver atom_dai[] = { }, }, }; -EXPORT_SYMBOL_NS(atom_dai, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_dai, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); void atom_set_mach_params(struct snd_soc_acpi_mach *mach, struct snd_sof_dev *sdev) @@ -415,7 +415,7 @@ void atom_set_mach_params(struct snd_soc_acpi_mach *mach, mach_params->num_dai_drivers = desc->ops->num_drv; mach_params->dai_drivers = desc->ops->drv; } -EXPORT_SYMBOL_NS(atom_set_mach_params, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +EXPORT_SYMBOL_NS(atom_set_mach_params, "SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for Atom platforms"); diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 322ff118f0f68b9705438604cf344b8b90eab015..c4d92f3508b6c57fd87ad7add2555f66a04721f9 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -695,6 +695,6 @@ module_platform_driver(snd_sof_acpi_intel_bdw_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for Broadwell platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); -MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HIFI_EP_IPC"); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SND_SOC_SOF_ACPI_DEV"); diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index f531710cf94ec20abb4b0edd421bc6c5c85e15ba..536d4c89d2f02c4ee9ec2595ae1f5164cd8bfa8f 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -476,7 +476,7 @@ module_platform_driver(snd_sof_acpi_intel_byt_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for Baytrail/Cherrytrail"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); -MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HIFI_EP_IPC"); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SND_SOC_SOF_ACPI_DEV"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 6a8c7a108ef05d5044db4d6ce293e2b7211a0b52..385e5339f0a4b7a26ac5677cc3c4d7f74c8a511a 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -110,7 +110,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(cnl_ipc4_irq_thread, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(cnl_ipc4_irq_thread, "SND_SOC_SOF_INTEL_CNL"); irqreturn_t cnl_ipc_irq_thread(int irq, void *context) { @@ -203,7 +203,7 @@ irqreturn_t cnl_ipc_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(cnl_ipc_irq_thread, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(cnl_ipc_irq_thread, "SND_SOC_SOF_INTEL_CNL"); static void cnl_ipc_host_done(struct snd_sof_dev *sdev) { @@ -286,7 +286,7 @@ int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(cnl_ipc4_send_msg, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(cnl_ipc4_send_msg, "SND_SOC_SOF_INTEL_CNL"); int cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { @@ -334,7 +334,7 @@ int cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(cnl_ipc_send_msg, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(cnl_ipc_send_msg, "SND_SOC_SOF_INTEL_CNL"); void cnl_ipc_dump(struct snd_sof_dev *sdev) { @@ -355,7 +355,7 @@ void cnl_ipc_dump(struct snd_sof_dev *sdev) "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n", hipcida, hipctdr, hipcctl); } -EXPORT_SYMBOL_NS(cnl_ipc_dump, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(cnl_ipc_dump, "SND_SOC_SOF_INTEL_CNL"); void cnl_ipc4_dump(struct snd_sof_dev *sdev) { @@ -377,11 +377,11 @@ void cnl_ipc4_dump(struct snd_sof_dev *sdev) "Host IPC initiator: %#x|%#x|%#x, target: %#x|%#x|%#x, ctl: %#x\n", hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl); } -EXPORT_SYMBOL_NS(cnl_ipc4_dump, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(cnl_ipc4_dump, "SND_SOC_SOF_INTEL_CNL"); /* cannonlake ops */ struct snd_sof_dsp_ops sof_cnl_ops; -EXPORT_SYMBOL_NS(sof_cnl_ops, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(sof_cnl_ops, "SND_SOC_SOF_INTEL_CNL"); int sof_cnl_ops_init(struct snd_sof_dev *sdev) { @@ -450,7 +450,7 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev) return 0; }; -EXPORT_SYMBOL_NS(sof_cnl_ops_init, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(sof_cnl_ops_init, "SND_SOC_SOF_INTEL_CNL"); const struct sof_intel_dsp_desc cnl_chip_info = { /* Cannonlake */ @@ -516,4 +516,4 @@ const struct sof_intel_dsp_desc jsl_chip_info = { .disable_interrupts = hda_dsp_disable_interrupts, .hw_ip_version = SOF_INTEL_CAVS_2_0, }; -EXPORT_SYMBOL_NS(jsl_chip_info, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(jsl_chip_info, "SND_SOC_SOF_INTEL_CNL"); diff --git a/sound/soc/sof/intel/hda-bus.c b/sound/soc/sof/intel/hda-bus.c index 1989147aa6a46320c3d2d5a1c298840ccbbfdfc2..b1be03011d7e1592396d0db4a127da647e2bcdb1 100644 --- a/sound/soc/sof/intel/hda-bus.c +++ b/sound/soc/sof/intel/hda-bus.c @@ -99,7 +99,7 @@ void sof_hda_bus_init(struct snd_sof_dev *sdev, struct device *dev) spin_lock_init(&bus->reg_lock); #endif /* CONFIG_SND_SOC_SOF_HDA_LINK */ } -EXPORT_SYMBOL_NS(sof_hda_bus_init, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sof_hda_bus_init, "SND_SOC_SOF_INTEL_HDA_COMMON"); void sof_hda_bus_exit(struct snd_sof_dev *sdev) { @@ -109,4 +109,4 @@ void sof_hda_bus_exit(struct snd_sof_dev *sdev) snd_hdac_ext_bus_exit(bus); #endif } -EXPORT_SYMBOL_NS(sof_hda_bus_exit, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sof_hda_bus_exit, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index dc46888faa0dc9c3fd3a826615bdeb5b66057b56..568f3dfe822f572654a543439ceba6d0aaf1368a 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -101,7 +101,7 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) snd_hdac_chip_updatew(bus, WAKEEN, mask & STATESTS_INT_MASK, val); } -EXPORT_SYMBOL_NS_GPL(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_jack_wake_enable, "SND_SOC_SOF_HDA_AUDIO_CODEC"); /* check jack status after resuming from suspend mode */ void hda_codec_jack_check(struct snd_sof_dev *sdev) @@ -121,7 +121,7 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev) if (codec->jacktbl.used) pm_request_resume(&codec->core.dev); } -EXPORT_SYMBOL_NS_GPL(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_jack_check, "SND_SOC_SOF_HDA_AUDIO_CODEC"); #if IS_ENABLED(CONFIG_SND_HDA_GENERIC) #define is_generic_config(bus) \ @@ -237,7 +237,7 @@ void hda_codec_probe_bus(struct snd_sof_dev *sdev) } } } -EXPORT_SYMBOL_NS_GPL(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_probe_bus, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_check_for_state_change(struct snd_sof_dev *sdev) { @@ -250,7 +250,7 @@ void hda_codec_check_for_state_change(struct snd_sof_dev *sdev) snd_hdac_chip_writew(bus, STATESTS, codec_mask); } } -EXPORT_SYMBOL_NS_GPL(hda_codec_check_for_state_change, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_check_for_state_change, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_detect_mask(struct snd_sof_dev *sdev) { @@ -275,7 +275,7 @@ void hda_codec_detect_mask(struct snd_sof_dev *sdev) bus->codec_mask); } } -EXPORT_SYMBOL_NS_GPL(hda_codec_detect_mask, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_detect_mask, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_init_cmd_io(struct snd_sof_dev *sdev) { @@ -288,7 +288,7 @@ void hda_codec_init_cmd_io(struct snd_sof_dev *sdev) /* initialize the codec command I/O */ snd_hdac_bus_init_cmd_io(bus); } -EXPORT_SYMBOL_NS_GPL(hda_codec_init_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_init_cmd_io, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_resume_cmd_io(struct snd_sof_dev *sdev) { @@ -302,7 +302,7 @@ void hda_codec_resume_cmd_io(struct snd_sof_dev *sdev) if (bus->cmd_dma_state) snd_hdac_bus_init_cmd_io(bus); } -EXPORT_SYMBOL_NS_GPL(hda_codec_resume_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_resume_cmd_io, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_stop_cmd_io(struct snd_sof_dev *sdev) { @@ -315,7 +315,7 @@ void hda_codec_stop_cmd_io(struct snd_sof_dev *sdev) /* initialize the codec command I/O */ snd_hdac_bus_stop_cmd_io(bus); } -EXPORT_SYMBOL_NS_GPL(hda_codec_stop_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_stop_cmd_io, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_suspend_cmd_io(struct snd_sof_dev *sdev) { @@ -330,7 +330,7 @@ void hda_codec_suspend_cmd_io(struct snd_sof_dev *sdev) snd_hdac_bus_stop_cmd_io(bus); } -EXPORT_SYMBOL_NS_GPL(hda_codec_suspend_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_suspend_cmd_io, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_rirb_status_clear(struct snd_sof_dev *sdev) { @@ -343,7 +343,7 @@ void hda_codec_rirb_status_clear(struct snd_sof_dev *sdev) /* clear rirb status */ snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK); } -EXPORT_SYMBOL_NS_GPL(hda_codec_rirb_status_clear, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_rirb_status_clear, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_set_codec_wakeup(struct snd_sof_dev *sdev, bool status) { @@ -354,7 +354,7 @@ void hda_codec_set_codec_wakeup(struct snd_sof_dev *sdev, bool status) snd_hdac_set_codec_wakeup(bus, status); } -EXPORT_SYMBOL_NS_GPL(hda_codec_set_codec_wakeup, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_set_codec_wakeup, "SND_SOC_SOF_HDA_AUDIO_CODEC"); bool hda_codec_check_rirb_status(struct snd_sof_dev *sdev) { @@ -381,7 +381,7 @@ bool hda_codec_check_rirb_status(struct snd_sof_dev *sdev) } return active; } -EXPORT_SYMBOL_NS_GPL(hda_codec_check_rirb_status, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_check_rirb_status, "SND_SOC_SOF_HDA_AUDIO_CODEC"); void hda_codec_device_remove(struct snd_sof_dev *sdev) { @@ -394,7 +394,7 @@ void hda_codec_device_remove(struct snd_sof_dev *sdev) /* codec removal, invoke bus_device_remove */ snd_hdac_ext_bus_device_remove(bus); } -EXPORT_SYMBOL_NS_GPL(hda_codec_device_remove, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_device_remove, "SND_SOC_SOF_HDA_AUDIO_CODEC"); #endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ @@ -413,7 +413,7 @@ void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable) snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable); } } -EXPORT_SYMBOL_NS_GPL(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); +EXPORT_SYMBOL_NS_GPL(hda_codec_i915_display_power, "SND_SOC_SOF_HDA_AUDIO_CODEC_I915"); int hda_codec_i915_init(struct snd_sof_dev *sdev) { @@ -434,7 +434,7 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS_GPL(hda_codec_i915_init, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); +EXPORT_SYMBOL_NS_GPL(hda_codec_i915_init, "SND_SOC_SOF_HDA_AUDIO_CODEC_I915"); int hda_codec_i915_exit(struct snd_sof_dev *sdev) { @@ -452,7 +452,7 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev) return snd_hdac_i915_exit(bus); } -EXPORT_SYMBOL_NS_GPL(hda_codec_i915_exit, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); +EXPORT_SYMBOL_NS_GPL(hda_codec_i915_exit, "SND_SOC_SOF_HDA_AUDIO_CODEC_I915"); #endif diff --git a/sound/soc/sof/intel/hda-common-ops.c b/sound/soc/sof/intel/hda-common-ops.c index 5fc28039a8e82567b81dbdf79c054da25b3b2057..746b426b1329b0ce122578f9fa41e08013c31a98 100644 --- a/sound/soc/sof/intel/hda-common-ops.c +++ b/sound/soc/sof/intel/hda-common-ops.c @@ -105,4 +105,4 @@ const struct snd_sof_dsp_ops sof_hda_common_ops = { .dsp_arch_ops = &sof_xtensa_arch_ops, }; -EXPORT_SYMBOL_NS(sof_hda_common_ops, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(sof_hda_common_ops, "SND_SOC_SOF_INTEL_HDA_GENERIC"); diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c index b9a02750ce61311aff49a5674bf5f0cabe7a883e..4f34fd919a00aac09f35c74faab6e87f6e352867 100644 --- a/sound/soc/sof/intel/hda-ctrl.c +++ b/sound/soc/sof/intel/hda-ctrl.c @@ -128,7 +128,7 @@ int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_dsp_ctrl_get_caps, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ctrl_get_caps, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_ctrl_ppcap_enable(struct snd_sof_dev *sdev, bool enable) { @@ -137,7 +137,7 @@ void hda_dsp_ctrl_ppcap_enable(struct snd_sof_dev *sdev, bool enable) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, SOF_HDA_PPCTL_GPROCEN, val); } -EXPORT_SYMBOL_NS(hda_dsp_ctrl_ppcap_enable, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ctrl_ppcap_enable, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev *sdev, bool enable) { @@ -146,7 +146,7 @@ void hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev *sdev, bool enable) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, SOF_HDA_PPCTL_PIE, val); } -EXPORT_SYMBOL_NS(hda_dsp_ctrl_ppcap_int_enable, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ctrl_ppcap_int_enable, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable) { @@ -181,7 +181,7 @@ int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable) return 0; } -EXPORT_SYMBOL_NS(hda_dsp_ctrl_clock_power_gating, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ctrl_clock_power_gating, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev) { @@ -266,7 +266,7 @@ err: return ret; } -EXPORT_SYMBOL_NS(hda_dsp_ctrl_init_chip, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ctrl_init_chip, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev) { @@ -329,6 +329,6 @@ void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev) MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF helpers for HDaudio platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC_I915); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_AUDIO_CODEC"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_AUDIO_CODEC_I915"); diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index ee274d445515b469c752b9d7dcfeca42b013bf45..c13f89b7065ec62d90e741ee5a1b44732ffbfed2 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -54,7 +54,7 @@ int hda_dai_config(struct snd_soc_dapm_widget *w, unsigned int flags, return 0; } -EXPORT_SYMBOL_NS(hda_dai_config, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dai_config, "SND_SOC_SOF_INTEL_HDA_COMMON"); #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_LINK) @@ -574,7 +574,7 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream, } return 0; } -EXPORT_SYMBOL_NS(sdw_hda_dai_hw_params, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sdw_hda_dai_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON"); int sdw_hda_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai, @@ -603,14 +603,14 @@ int sdw_hda_dai_hw_free(struct snd_pcm_substream *substream, return 0; } -EXPORT_SYMBOL_NS(sdw_hda_dai_hw_free, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sdw_hda_dai_hw_free, "SND_SOC_SOF_INTEL_HDA_COMMON"); int sdw_hda_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { return hda_dai_trigger(substream, cmd, cpu_dai); } -EXPORT_SYMBOL_NS(sdw_hda_dai_trigger, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sdw_hda_dai_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON"); static int hda_dai_suspend(struct hdac_bus *bus) { @@ -729,7 +729,7 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) ipc4_data->nhlt = intel_nhlt_init(sdev->dev); } } -EXPORT_SYMBOL_NS(hda_set_dai_drv_ops, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_set_dai_drv_ops, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_ops_free(struct snd_sof_dev *sdev) { @@ -743,7 +743,7 @@ void hda_ops_free(struct snd_sof_dev *sdev) sdev->private = NULL; } } -EXPORT_SYMBOL_NS(hda_ops_free, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_ops_free, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* * common dai driver for skl+ platforms. @@ -895,7 +895,7 @@ struct snd_soc_dai_driver skl_dai[] = { }, #endif }; -EXPORT_SYMBOL_NS(skl_dai, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(skl_dai, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_dais_suspend(struct snd_sof_dev *sdev) { diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 6028a80418bbcc66e17e3e0f3af89ae1db28523e..ccf8eefdca707ca87d561d4a69c171453e6d8974 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -90,7 +90,7 @@ u32 hda_get_interface_mask(struct snd_sof_dev *sdev) return interface_mask[sdev->dspless_mode_selected]; } -EXPORT_SYMBOL_NS(hda_get_interface_mask, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_get_interface_mask, "SND_SOC_SOF_INTEL_HDA_COMMON"); bool hda_is_chain_dma_supported(struct snd_sof_dev *sdev, u32 dai_type) { @@ -120,7 +120,7 @@ bool hda_is_chain_dma_supported(struct snd_sof_dev *sdev, u32 dai_type) return false; } } -EXPORT_SYMBOL_NS(hda_is_chain_dma_supported, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_is_chain_dma_supported, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* * DSP Core control. @@ -216,7 +216,7 @@ int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask) /* set reset state */ return hda_dsp_core_reset_enter(sdev, core_mask); } -EXPORT_SYMBOL_NS(hda_dsp_core_stall_reset, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_core_stall_reset, "SND_SOC_SOF_INTEL_HDA_COMMON"); bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, unsigned int core_mask) { @@ -242,7 +242,7 @@ bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, unsigned int core_mask) return is_enable; } -EXPORT_SYMBOL_NS(hda_dsp_core_is_enabled, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_core_is_enabled, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask) { @@ -270,7 +270,7 @@ int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask) return ret; } -EXPORT_SYMBOL_NS(hda_dsp_core_run, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_core_run, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* * Power Management. @@ -322,7 +322,7 @@ int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask) return ret; } -EXPORT_SYMBOL_NS(hda_dsp_core_power_up, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_core_power_up, "SND_SOC_SOF_INTEL_HDA_COMMON"); static int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask) { @@ -370,7 +370,7 @@ int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask) return hda_dsp_core_run(sdev, core_mask); } -EXPORT_SYMBOL_NS(hda_dsp_enable_core, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_enable_core, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev, unsigned int core_mask) @@ -411,7 +411,7 @@ int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev, return ret; } -EXPORT_SYMBOL_NS(hda_dsp_core_reset_power_down, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_core_reset_power_down, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev) { @@ -430,7 +430,7 @@ void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev) snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC, HDA_DSP_ADSPIC_IPC, HDA_DSP_ADSPIC_IPC); } -EXPORT_SYMBOL_NS(hda_dsp_ipc_int_enable, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc_int_enable, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev) { @@ -448,7 +448,7 @@ void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev) snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl, HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0); } -EXPORT_SYMBOL_NS(hda_dsp_ipc_int_disable, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc_int_disable, "SND_SOC_SOF_INTEL_HDA_COMMON"); static int hda_dsp_wait_d0i3c_done(struct snd_sof_dev *sdev) { @@ -732,7 +732,7 @@ int hda_dsp_set_power_state_ipc3(struct snd_sof_dev *sdev, return hda_dsp_set_power_state(sdev, target_state); } -EXPORT_SYMBOL_NS(hda_dsp_set_power_state_ipc3, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_set_power_state_ipc3, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_set_power_state_ipc4(struct snd_sof_dev *sdev, const struct sof_dsp_power_state *target_state) @@ -744,7 +744,7 @@ int hda_dsp_set_power_state_ipc4(struct snd_sof_dev *sdev, return hda_dsp_set_power_state(sdev, target_state); } -EXPORT_SYMBOL_NS(hda_dsp_set_power_state_ipc4, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_set_power_state_ipc4, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* * Audio DSP states may transform as below:- @@ -948,7 +948,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev) return snd_sof_dsp_set_power_state(sdev, &target_state); } -EXPORT_SYMBOL_NS(hda_dsp_resume, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_resume, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev) { @@ -964,7 +964,7 @@ int hda_dsp_runtime_resume(struct snd_sof_dev *sdev) return snd_sof_dsp_set_power_state(sdev, &target_state); } -EXPORT_SYMBOL_NS(hda_dsp_runtime_resume, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_runtime_resume, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_runtime_idle(struct snd_sof_dev *sdev) { @@ -978,7 +978,7 @@ int hda_dsp_runtime_idle(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_dsp_runtime_idle, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_runtime_idle, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev) { @@ -1000,7 +1000,7 @@ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev) return snd_sof_dsp_set_power_state(sdev, &target_state); } -EXPORT_SYMBOL_NS(hda_dsp_runtime_suspend, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_runtime_suspend, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) { @@ -1061,7 +1061,7 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); } -EXPORT_SYMBOL_NS(hda_dsp_suspend, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_suspend, "SND_SOC_SOF_INTEL_HDA_COMMON"); static unsigned int hda_dsp_check_for_dma_streams(struct snd_sof_dev *sdev) { @@ -1134,14 +1134,14 @@ int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev) return ret; } -EXPORT_SYMBOL_NS(hda_dsp_shutdown_dma_flush, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_shutdown_dma_flush, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_shutdown(struct snd_sof_dev *sdev) { sdev->system_suspend_target = SOF_SUSPEND_S3; return snd_sof_suspend(sdev->dev); } -EXPORT_SYMBOL_NS(hda_dsp_shutdown, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_shutdown, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev) { @@ -1154,7 +1154,7 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev) return ret; } -EXPORT_SYMBOL_NS(hda_dsp_set_hw_params_upon_resume, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_set_hw_params_upon_resume, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_d0i3_work(struct work_struct *work) { @@ -1181,7 +1181,7 @@ void hda_dsp_d0i3_work(struct work_struct *work) "error: failed to set DSP state %d substate %d\n", target_state.state, target_state.substate); } -EXPORT_SYMBOL_NS(hda_dsp_d0i3_work, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_d0i3_work, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_core_get(struct snd_sof_dev *sdev, int core) { @@ -1222,7 +1222,7 @@ power_down: return ret; } -EXPORT_SYMBOL_NS(hda_dsp_core_get, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_core_get, "SND_SOC_SOF_INTEL_HDA_COMMON"); #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) @@ -1238,7 +1238,7 @@ void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) HDA_DSP_REG_ADSPIC2_SNDW, enable ? HDA_DSP_REG_ADSPIC2_SNDW : 0); } -EXPORT_SYMBOL_NS(hda_common_enable_sdw_irq, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_common_enable_sdw_irq, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) { @@ -1252,7 +1252,7 @@ void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) if (chip && chip->enable_sdw_irq) chip->enable_sdw_irq(sdev, enable); } -EXPORT_SYMBOL_NS(hda_sdw_int_enable, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_sdw_int_enable, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev) { @@ -1276,7 +1276,7 @@ int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_sdw_check_lcount_common, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_sdw_check_lcount_common, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_sdw_check_lcount_ext(struct snd_sof_dev *sdev) { @@ -1302,7 +1302,7 @@ int hda_sdw_check_lcount_ext(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_sdw_check_lcount_ext, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_sdw_check_lcount_ext, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_sdw_check_lcount(struct snd_sof_dev *sdev) { @@ -1314,7 +1314,7 @@ int hda_sdw_check_lcount(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_sdw_check_lcount, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_sdw_check_lcount, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_sdw_process_wakeen(struct snd_sof_dev *sdev) { @@ -1328,7 +1328,7 @@ void hda_sdw_process_wakeen(struct snd_sof_dev *sdev) if (chip && chip->sdw_process_wakeen) chip->sdw_process_wakeen(sdev); } -EXPORT_SYMBOL_NS(hda_sdw_process_wakeen, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_sdw_process_wakeen, "SND_SOC_SOF_INTEL_HDA_COMMON"); #endif @@ -1339,7 +1339,7 @@ int hda_dsp_disable_interrupts(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_dsp_disable_interrupts, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_disable_interrupts, "SND_SOC_SOF_INTEL_HDA_COMMON"); static const struct hda_dsp_msg_code hda_dsp_rom_fw_error_texts[] = { {HDA_DSP_ROM_CSE_ERROR, "error: cse error"}, @@ -1550,7 +1550,7 @@ void hda_dsp_get_state(struct snd_sof_dev *sdev, const char *level) dev_printk(level, sdev->dev, "error code: %#x (%s)\n", error_code, error_text); } -EXPORT_SYMBOL_NS(hda_dsp_get_state, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_get_state, "SND_SOC_SOF_INTEL_HDA_COMMON"); static void hda_dsp_get_registers(struct snd_sof_dev *sdev, struct sof_ipc_dsp_oops_xtensa *xoops, @@ -1623,4 +1623,4 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) hda_dsp_dump_ext_rom_status(sdev, level, flags); } } -EXPORT_SYMBOL_NS(hda_dsp_dump, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_dump, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index 9feaaa2d166acc80911e0c12ddf4bcec440140b3..f3fbf43a70c2bb573502f9e97b17df412733a9fc 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -72,7 +72,7 @@ int hda_dsp_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(hda_dsp_ipc_send_msg, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc_send_msg, "SND_SOC_SOF_INTEL_HDA_COMMON"); static inline bool hda_dsp_ipc4_pm_msg(u32 primary) { @@ -99,7 +99,7 @@ void hda_dsp_ipc4_schedule_d0i3_work(struct sof_intel_hda_dev *hdev, mod_delayed_work(system_wq, &hdev->d0i3_work, msecs_to_jiffies(SOF_HDA_D0I3_WORK_DELAY_MS)); } -EXPORT_SYMBOL_NS(hda_dsp_ipc4_schedule_d0i3_work, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc4_schedule_d0i3_work, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { @@ -126,7 +126,7 @@ int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(hda_dsp_ipc4_send_msg, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc4_send_msg, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_ipc_get_reply(struct snd_sof_dev *sdev) { @@ -162,7 +162,7 @@ void hda_dsp_ipc_get_reply(struct snd_sof_dev *sdev) snd_sof_ipc_get_reply(sdev); } } -EXPORT_SYMBOL_NS(hda_dsp_ipc_get_reply, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc_get_reply, "SND_SOC_SOF_INTEL_HDA_COMMON"); irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context) { @@ -245,7 +245,7 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(hda_dsp_ipc4_irq_thread, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc4_irq_thread, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* IPC handler thread */ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) @@ -358,7 +358,7 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(hda_dsp_ipc_irq_thread, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc_irq_thread, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* Check if an IPC IRQ occurred */ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev) @@ -392,19 +392,19 @@ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev) out: return ret; } -EXPORT_SYMBOL_NS(hda_dsp_check_ipc_irq, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_check_ipc_irq, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) { return HDA_DSP_MBOX_UPLINK_OFFSET; } -EXPORT_SYMBOL_NS(hda_dsp_ipc_get_mailbox_offset, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc_get_mailbox_offset, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id) { return SRAM_WINDOW_OFFSET(id); } -EXPORT_SYMBOL_NS(hda_dsp_ipc_get_window_offset, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc_get_window_offset, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *sps, @@ -430,7 +430,7 @@ int hda_ipc_msg_data(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(hda_ipc_msg_data, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_ipc_msg_data, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_set_stream_data_offset(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *sps, @@ -455,7 +455,7 @@ int hda_set_stream_data_offset(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(hda_set_stream_data_offset, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_set_stream_data_offset, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_ipc4_dsp_dump(struct snd_sof_dev *sdev, u32 flags) { @@ -469,7 +469,7 @@ void hda_ipc4_dsp_dump(struct snd_sof_dev *sdev, u32 flags) else hda_dsp_dump_ext_rom_status(sdev, level, flags); } -EXPORT_SYMBOL_NS(hda_ipc4_dsp_dump, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_ipc4_dsp_dump, "SND_SOC_SOF_INTEL_HDA_COMMON"); bool hda_check_ipc_irq(struct snd_sof_dev *sdev) { @@ -481,7 +481,7 @@ bool hda_check_ipc_irq(struct snd_sof_dev *sdev) return false; } -EXPORT_SYMBOL_NS(hda_check_ipc_irq, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_check_ipc_irq, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_ipc_irq_dump(struct snd_sof_dev *sdev) { @@ -502,7 +502,7 @@ void hda_ipc_irq_dump(struct snd_sof_dev *sdev) intsts, intctl, rirbsts); dev_err(sdev->dev, "dsp irq ppsts 0x%8.8x adspis 0x%8.8x\n", ppsts, adspis); } -EXPORT_SYMBOL_NS(hda_ipc_irq_dump, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_ipc_irq_dump, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_ipc_dump(struct snd_sof_dev *sdev) { @@ -522,7 +522,7 @@ void hda_ipc_dump(struct snd_sof_dev *sdev) dev_err(sdev->dev, "host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n", hipcie, hipct, hipcctl); } -EXPORT_SYMBOL_NS(hda_ipc_dump, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_ipc_dump, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_ipc4_dump(struct snd_sof_dev *sdev) { @@ -541,7 +541,7 @@ void hda_ipc4_dump(struct snd_sof_dev *sdev) dev_err(sdev->dev, "Host IPC initiator: %#x|%#x, target: %#x|%#x, ctl: %#x\n", hipci, hipcie, hipct, hipcte, hipcctl); } -EXPORT_SYMBOL_NS(hda_ipc4_dump, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_ipc4_dump, "SND_SOC_SOF_INTEL_HDA_COMMON"); bool hda_ipc4_tx_is_busy(struct snd_sof_dev *sdev) { @@ -553,4 +553,4 @@ bool hda_ipc4_tx_is_busy(struct snd_sof_dev *sdev) return !!(val & chip->ipc_req_mask); } -EXPORT_SYMBOL_NS(hda_ipc4_tx_is_busy, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_ipc4_tx_is_busy, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 76a03b6b27286ab37abf4cdf5d3cdff16dfeb889..49085ca7b46bf01b66bc74b837d0e2a3d305d146 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -113,7 +113,7 @@ out_put: hda_dsp_stream_put(sdev, direction, hstream->stream_tag); return ERR_PTR(ret); } -EXPORT_SYMBOL_NS(hda_cl_prepare, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_cl_prepare, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* * first boot sequence has some extra steps. @@ -237,7 +237,7 @@ err: kfree(dump_msg); return ret; } -EXPORT_SYMBOL_NS(cl_dsp_init, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(cl_dsp_init, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_cl_trigger(struct device *dev, struct hdac_ext_stream *hext_stream, int cmd) { @@ -270,7 +270,7 @@ int hda_cl_trigger(struct device *dev, struct hdac_ext_stream *hext_stream, int return hda_dsp_stream_trigger(sdev, hext_stream, cmd); } } -EXPORT_SYMBOL_NS(hda_cl_trigger, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_cl_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_cl_cleanup(struct device *dev, struct snd_dma_buffer *dmab, bool persistent_buffer, struct hdac_ext_stream *hext_stream) @@ -308,7 +308,7 @@ int hda_cl_cleanup(struct device *dev, struct snd_dma_buffer *dmab, return ret; } -EXPORT_SYMBOL_NS(hda_cl_cleanup, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_cl_cleanup, "SND_SOC_SOF_INTEL_HDA_COMMON"); #define HDA_CL_DMA_IOC_TIMEOUT_MS 500 @@ -405,7 +405,7 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev) return ret; } -EXPORT_SYMBOL_NS(hda_dsp_cl_boot_firmware_iccmax, SND_SOC_SOF_INTEL_CNL); +EXPORT_SYMBOL_NS(hda_dsp_cl_boot_firmware_iccmax, "SND_SOC_SOF_INTEL_CNL"); static int hda_dsp_boot_imr(struct snd_sof_dev *sdev) { @@ -567,7 +567,7 @@ cleanup: return ret; } -EXPORT_SYMBOL_NS(hda_dsp_cl_boot_firmware, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_cl_boot_firmware, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev, struct sof_ipc4_fw_library *fw_lib, bool reload) @@ -683,7 +683,7 @@ cleanup: return ret; } -EXPORT_SYMBOL_NS(hda_dsp_ipc4_load_library, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ipc4_load_library, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, const struct sof_ext_man_elem_header *hdr) @@ -722,4 +722,4 @@ int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(hda_dsp_ext_man_get_cavs_config_data, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_ext_man_get_cavs_config_data, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c index 46f89d6d06f8e7b4fa62f1d624f9a3ffdeab01c2..fe627bcb0531a064ead936fda55d84330f891324 100644 --- a/sound/soc/sof/intel/hda-mlink.c +++ b/sound/soc/sof/intel/hda-mlink.c @@ -434,7 +434,7 @@ int hda_bus_ml_init(struct hdac_bus *bus) } return 0; } -EXPORT_SYMBOL_NS(hda_bus_ml_init, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hda_bus_ml_init, "SND_SOC_SOF_HDA_MLINK"); void hda_bus_ml_free(struct hdac_bus *bus) { @@ -452,7 +452,7 @@ void hda_bus_ml_free(struct hdac_bus *bus) kfree(h2link); } } -EXPORT_SYMBOL_NS(hda_bus_ml_free, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hda_bus_ml_free, "SND_SOC_SOF_HDA_MLINK"); static struct hdac_ext2_link * find_ext2_link(struct hdac_bus *bus, bool alt, int elid) @@ -479,7 +479,7 @@ int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid) return h2link->slcount; } -EXPORT_SYMBOL_NS(hdac_bus_eml_get_count, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_get_count, "SND_SOC_SOF_HDA_MLINK"); void hdac_bus_eml_enable_interrupt_unlocked(struct hdac_bus *bus, bool alt, int elid, bool enable) { @@ -497,7 +497,7 @@ void hdac_bus_eml_enable_interrupt_unlocked(struct hdac_bus *bus, bool alt, int hdaml_link_enable_interrupt(hlink->ml_addr + AZX_REG_ML_LCTL, enable); } -EXPORT_SYMBOL_NS(hdac_bus_eml_enable_interrupt_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_enable_interrupt_unlocked, "SND_SOC_SOF_HDA_MLINK"); void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable) { @@ -519,7 +519,7 @@ void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, boo mutex_unlock(&h2link->eml_lock); } -EXPORT_SYMBOL_NS(hdac_bus_eml_enable_interrupt, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_enable_interrupt, "SND_SOC_SOF_HDA_MLINK"); bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid) { @@ -537,7 +537,7 @@ bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid) return hdaml_link_check_interrupt(hlink->ml_addr + AZX_REG_ML_LCTL); } -EXPORT_SYMBOL_NS(hdac_bus_eml_check_interrupt, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_check_interrupt, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd) { @@ -557,13 +557,13 @@ int hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, return 0; } -EXPORT_SYMBOL_NS(hdac_bus_eml_set_syncprd_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_set_syncprd_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd) { return hdac_bus_eml_set_syncprd_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, syncprd); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_syncprd_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_syncprd_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid) { @@ -581,13 +581,13 @@ int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid) return hdaml_link_wait_syncpu(hlink->ml_addr + AZX_REG_ML_LSYNC); } -EXPORT_SYMBOL_NS(hdac_bus_eml_wait_syncpu_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_wait_syncpu_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus) { return hdac_bus_eml_wait_syncpu_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_wait_syncpu_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_wait_syncpu_unlocked, "SND_SOC_SOF_HDA_MLINK"); void hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink) { @@ -605,13 +605,13 @@ void hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, in hdaml_link_sync_arm(hlink->ml_addr + AZX_REG_ML_LSYNC, sublink); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sync_arm_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sync_arm_unlocked, "SND_SOC_SOF_HDA_MLINK"); void hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink) { hdac_bus_eml_sync_arm_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, sublink); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_sync_arm_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_sync_arm_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid) { @@ -631,13 +631,13 @@ int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid) return 0; } -EXPORT_SYMBOL_NS(hdac_bus_eml_sync_go_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sync_go_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus) { return hdac_bus_eml_sync_go_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_sync_go_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_sync_go_unlocked, "SND_SOC_SOF_HDA_MLINK"); bool hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid) { @@ -660,13 +660,13 @@ bool hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int eli return hdaml_link_check_cmdsync(hlink->ml_addr + AZX_REG_ML_LSYNC, cmdsync_mask); } -EXPORT_SYMBOL_NS(hdac_bus_eml_check_cmdsync_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_check_cmdsync_unlocked, "SND_SOC_SOF_HDA_MLINK"); bool hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus) { return hdac_bus_eml_check_cmdsync_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_check_cmdsync_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_check_cmdsync_unlocked, "SND_SOC_SOF_HDA_MLINK"); static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink, bool eml_lock) @@ -708,13 +708,13 @@ int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink) { return hdac_bus_eml_power_up_base(bus, alt, elid, sublink, true); } -EXPORT_SYMBOL_NS(hdac_bus_eml_power_up, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_power_up, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink) { return hdac_bus_eml_power_up_base(bus, alt, elid, sublink, false); } -EXPORT_SYMBOL_NS(hdac_bus_eml_power_up_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_power_up_unlocked, "SND_SOC_SOF_HDA_MLINK"); static int hdac_bus_eml_power_down_base(struct hdac_bus *bus, bool alt, int elid, int sublink, bool eml_lock) @@ -755,25 +755,25 @@ int hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublin { return hdac_bus_eml_power_down_base(bus, alt, elid, sublink, true); } -EXPORT_SYMBOL_NS(hdac_bus_eml_power_down, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_power_down, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink) { return hdac_bus_eml_power_down_base(bus, alt, elid, sublink, false); } -EXPORT_SYMBOL_NS(hdac_bus_eml_power_down_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_power_down_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink) { return hdac_bus_eml_power_up_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, sublink); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_power_up_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_power_up_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return hdac_bus_eml_power_down_unlocked(bus, true, AZX_REG_ML_LEPTR_ID_SDW, sublink); } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_power_down_unlocked, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_power_down_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sdw_get_lsdiid_unlocked(struct hdac_bus *bus, int sublink, u16 *lsdiid) { @@ -789,7 +789,7 @@ int hdac_bus_eml_sdw_get_lsdiid_unlocked(struct hdac_bus *bus, int sublink, u16 *lsdiid = hdaml_link_get_lsdiid(hlink->ml_addr + AZX_REG_ML_LSDIID_OFFSET(sublink)); return 0; -} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_get_lsdiid_unlocked, SND_SOC_SOF_HDA_MLINK); +} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_get_lsdiid_unlocked, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { @@ -809,7 +809,7 @@ int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) mutex_unlock(&h2link->eml_lock); return 0; -} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_lsdiid, SND_SOC_SOF_HDA_MLINK); +} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_lsdiid, "SND_SOC_SOF_HDA_MLINK"); /* * the 'y' parameter comes from the PCMSyCM hardware register naming. 'y' refers to the @@ -853,7 +853,7 @@ int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y, sublink, channel_mask, stream_id, dir, val); return 0; -} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_map_stream_ch, SND_SOC_SOF_HDA_MLINK); +} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_map_stream_ch, "SND_SOC_SOF_HDA_MLINK"); void hda_bus_ml_put_all(struct hdac_bus *bus) { @@ -866,7 +866,7 @@ void hda_bus_ml_put_all(struct hdac_bus *bus) snd_hdac_ext_bus_link_put(bus, hlink); } } -EXPORT_SYMBOL_NS(hda_bus_ml_put_all, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hda_bus_ml_put_all, "SND_SOC_SOF_HDA_MLINK"); void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { @@ -876,7 +876,7 @@ void hda_bus_ml_reset_losidv(struct hdac_bus *bus) list_for_each_entry(hlink, &bus->hlink_list, list) writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); } -EXPORT_SYMBOL_NS(hda_bus_ml_reset_losidv, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hda_bus_ml_reset_losidv, "SND_SOC_SOF_HDA_MLINK"); int hda_bus_ml_resume(struct hdac_bus *bus) { @@ -895,7 +895,7 @@ int hda_bus_ml_resume(struct hdac_bus *bus) } return 0; } -EXPORT_SYMBOL_NS(hda_bus_ml_resume, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hda_bus_ml_resume, "SND_SOC_SOF_HDA_MLINK"); int hda_bus_ml_suspend(struct hdac_bus *bus) { @@ -913,7 +913,7 @@ int hda_bus_ml_suspend(struct hdac_bus *bus) } return 0; } -EXPORT_SYMBOL_NS(hda_bus_ml_suspend, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hda_bus_ml_suspend, "SND_SOC_SOF_HDA_MLINK"); struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid) { @@ -925,7 +925,7 @@ struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid) return &h2link->eml_lock; } -EXPORT_SYMBOL_NS(hdac_bus_eml_get_mutex, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_get_mutex, "SND_SOC_SOF_HDA_MLINK"); struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { @@ -937,7 +937,7 @@ struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) return &h2link->hext_link; } -EXPORT_SYMBOL_NS(hdac_bus_eml_ssp_get_hlink, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_ssp_get_hlink, "SND_SOC_SOF_HDA_MLINK"); struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) { @@ -949,7 +949,7 @@ struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) return &h2link->hext_link; } -EXPORT_SYMBOL_NS(hdac_bus_eml_dmic_get_hlink, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_dmic_get_hlink, "SND_SOC_SOF_HDA_MLINK"); struct hdac_ext_link *hdac_bus_eml_sdw_get_hlink(struct hdac_bus *bus) { @@ -961,7 +961,7 @@ struct hdac_ext_link *hdac_bus_eml_sdw_get_hlink(struct hdac_bus *bus) return &h2link->hext_link; } -EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_get_hlink, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_get_hlink, "SND_SOC_SOF_HDA_MLINK"); int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable) { @@ -985,7 +985,7 @@ int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool e return 0; } -EXPORT_SYMBOL_NS(hdac_bus_eml_enable_offload, SND_SOC_SOF_HDA_MLINK); +EXPORT_SYMBOL_NS(hdac_bus_eml_enable_offload, "SND_SOC_SOF_HDA_MLINK"); #endif diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index f6e24edd7adbe9b370b15e11af4b11585d363466..5b5e484f9acf1a5257d892d74ddf5e40c0418a93 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -142,7 +142,7 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(hda_dsp_pcm_hw_params, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_pcm_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON"); /* update SPIB register with appl position */ int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) @@ -165,7 +165,7 @@ int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substrea return 0; } -EXPORT_SYMBOL_NS(hda_dsp_pcm_ack, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_pcm_ack, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, int cmd) @@ -175,7 +175,7 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev, return hda_dsp_stream_trigger(sdev, hext_stream, cmd); } -EXPORT_SYMBOL_NS(hda_dsp_pcm_trigger, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_pcm_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON"); snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) @@ -207,7 +207,7 @@ found: trace_sof_intel_hda_dsp_pcm(sdev, hstream, substream, pos); return pos; } -EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) @@ -302,7 +302,7 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(hda_dsp_pcm_open, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_pcm_open, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) @@ -322,4 +322,4 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev, substream->runtime->private_data = NULL; return 0; } -EXPORT_SYMBOL_NS(hda_dsp_pcm_close, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_pcm_close, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/hda-probes.c b/sound/soc/sof/intel/hda-probes.c index 3e33101f052102d24ce7779dc70b0395277b35e4..c645346c2c847c437763c11b25732ee0173ee6aa 100644 --- a/sound/soc/sof/intel/hda-probes.c +++ b/sound/soc/sof/intel/hda-probes.c @@ -139,12 +139,12 @@ int hda_probes_register(struct snd_sof_dev *sdev) return sof_client_dev_register(sdev, "hda-probes", 0, &hda_probes_ops, sizeof(hda_probes_ops)); } -EXPORT_SYMBOL_NS(hda_probes_register, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_probes_register, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_probes_unregister(struct snd_sof_dev *sdev) { sof_client_dev_unregister(sdev, "hda-probes", 0); } -EXPORT_SYMBOL_NS(hda_probes_unregister, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_probes_unregister, "SND_SOC_SOF_INTEL_HDA_COMMON"); -MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); +MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 519bafd3b947bb510181c0010f8dff74910d02dc..aa6b0247d5c99e58771b3d8b16e271b7f92ac142 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -27,7 +27,7 @@ int sof_hda_position_quirk = SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS; module_param_named(position_quirk, sof_hda_position_quirk, int, 0444); MODULE_PARM_DESC(position_quirk, "SOF HDaudio position quirk"); -EXPORT_SYMBOL_NS(sof_hda_position_quirk, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sof_hda_position_quirk, "SND_SOC_SOF_INTEL_HDA_COMMON"); #define HDA_LTRP_GB_VALUE_US 95 @@ -738,7 +738,7 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(hda_dsp_stream_hw_free, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_stream_hw_free, "SND_SOC_SOF_INTEL_HDA_COMMON"); bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev) { @@ -761,7 +761,7 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev) return ret; } -EXPORT_SYMBOL_NS(hda_dsp_check_stream_irq, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_check_stream_irq, "SND_SOC_SOF_INTEL_HDA_COMMON"); static void hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction) @@ -858,7 +858,7 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(hda_dsp_stream_threaded_handler, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_stream_threaded_handler, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_stream_init(struct snd_sof_dev *sdev) { @@ -996,7 +996,7 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_dsp_stream_init, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_stream_init, "SND_SOC_SOF_INTEL_HDA_COMMON"); void hda_dsp_stream_free(struct snd_sof_dev *sdev) { @@ -1026,7 +1026,7 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev) devm_kfree(sdev->dev, hda_stream); } } -EXPORT_SYMBOL_NS(hda_dsp_stream_free, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_stream_free, "SND_SOC_SOF_INTEL_HDA_COMMON"); snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream, int direction, bool can_sleep) @@ -1113,7 +1113,7 @@ snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream, return pos; } -EXPORT_SYMBOL_NS(hda_dsp_stream_get_position, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_stream_get_position, "SND_SOC_SOF_INTEL_HDA_COMMON"); #define merge_u64(u32_u, u32_l) (((u64)(u32_u) << 32) | (u32_l)) @@ -1153,7 +1153,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev, return merge_u64(llp_u, llp_l); } -EXPORT_SYMBOL_NS(hda_dsp_get_stream_llp, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON"); /** * hda_dsp_get_stream_ldp - Retrieve the LDP (Linear DMA Position) of the stream @@ -1185,4 +1185,4 @@ u64 hda_dsp_get_stream_ldp(struct snd_sof_dev *sdev, return ((u64)ldp_u << 32) | ldp_l; } -EXPORT_SYMBOL_NS(hda_dsp_get_stream_ldp, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_get_stream_ldp, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c index 351eb2eb184bc159e950add66ec8a8af1d78b949..5da8188ffcfe1f89cddbd012c7f01b582bf7eedb 100644 --- a/sound/soc/sof/intel/hda-trace.c +++ b/sound/soc/sof/intel/hda-trace.c @@ -68,7 +68,7 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, return ret; } -EXPORT_SYMBOL_NS(hda_dsp_trace_init, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_trace_init, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_trace_release(struct snd_sof_dev *sdev) { @@ -87,7 +87,7 @@ int hda_dsp_trace_release(struct snd_sof_dev *sdev) dev_dbg(sdev->dev, "DMA trace stream is not opened!\n"); return -ENODEV; } -EXPORT_SYMBOL_NS(hda_dsp_trace_release, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_trace_release, "SND_SOC_SOF_INTEL_HDA_COMMON"); int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd) { @@ -95,4 +95,4 @@ int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd) return hda_dsp_stream_trigger(sdev, hda->dtrace_stream, cmd); } -EXPORT_SYMBOL_NS(hda_dsp_trace_trigger, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_trace_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 01b135068b1f808139d696a0b211865555611440..f991785f727e9e32abee8be43bba378fcbaec8b3 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -238,7 +238,7 @@ int hda_sdw_startup(struct snd_sof_dev *sdev) return sdw_intel_startup(hdev->sdw); } -EXPORT_SYMBOL_NS(hda_sdw_startup, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_sdw_startup, "SND_SOC_SOF_INTEL_HDA_GENERIC"); static int hda_sdw_exit(struct snd_sof_dev *sdev) { @@ -280,7 +280,7 @@ bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev) out: return ret; } -EXPORT_SYMBOL_NS(hda_common_check_sdw_irq, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_common_check_sdw_irq, "SND_SOC_SOF_INTEL_HDA_GENERIC"); static bool hda_dsp_check_sdw_irq(struct snd_sof_dev *sdev) { @@ -314,7 +314,7 @@ bool hda_sdw_check_wakeen_irq_common(struct snd_sof_dev *sdev) return false; } -EXPORT_SYMBOL_NS(hda_sdw_check_wakeen_irq_common, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_sdw_check_wakeen_irq_common, "SND_SOC_SOF_INTEL_HDA_GENERIC"); static bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) { @@ -345,7 +345,7 @@ void hda_sdw_process_wakeen_common(struct snd_sof_dev *sdev) sdw_intel_process_wakeen_event(hdev->sdw); } -EXPORT_SYMBOL_NS(hda_sdw_process_wakeen_common, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_sdw_process_wakeen_common, "SND_SOC_SOF_INTEL_HDA_GENERIC"); #else /* IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) */ static inline int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) @@ -418,7 +418,7 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev) /* re-enable clock gating and power gating */ return hda_dsp_ctrl_clock_power_gating(sdev, true); } -EXPORT_SYMBOL_NS(hda_dsp_post_fw_run, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_dsp_post_fw_run, "SND_SOC_SOF_INTEL_HDA_GENERIC"); /* * Debug @@ -739,7 +739,7 @@ int hda_dsp_probe_early(struct snd_sof_dev *sdev) err: return ret; } -EXPORT_SYMBOL_NS(hda_dsp_probe_early, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_dsp_probe_early, "SND_SOC_SOF_INTEL_HDA_GENERIC"); int hda_dsp_probe(struct snd_sof_dev *sdev) { @@ -894,7 +894,7 @@ hdac_bus_unmap: return ret; } -EXPORT_SYMBOL_NS(hda_dsp_probe, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_dsp_probe, "SND_SOC_SOF_INTEL_HDA_GENERIC"); void hda_dsp_remove(struct snd_sof_dev *sdev) { @@ -954,7 +954,7 @@ skip_disable_dsp: if (!sdev->dspless_mode_selected) iounmap(sdev->bar[HDA_DSP_BAR]); } -EXPORT_SYMBOL_NS(hda_dsp_remove, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_dsp_remove, "SND_SOC_SOF_INTEL_HDA_GENERIC"); void hda_dsp_remove_late(struct snd_sof_dev *sdev) { @@ -970,7 +970,7 @@ int hda_power_down_dsp(struct snd_sof_dev *sdev) return hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); } -EXPORT_SYMBOL_NS(hda_power_down_dsp, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_power_down_dsp, "SND_SOC_SOF_INTEL_HDA_GENERIC"); #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) static void hda_generic_machine_select(struct snd_sof_dev *sdev, @@ -1471,7 +1471,7 @@ int hda_pci_intel_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) return sof_pci_probe(pci, pci_id); } -EXPORT_SYMBOL_NS(hda_pci_intel_probe, SND_SOC_SOF_INTEL_HDA_GENERIC); +EXPORT_SYMBOL_NS(hda_pci_intel_probe, "SND_SOC_SOF_INTEL_HDA_GENERIC"); int hda_register_clients(struct snd_sof_dev *sdev) { @@ -1485,13 +1485,13 @@ void hda_unregister_clients(struct snd_sof_dev *sdev) MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for HDaudio platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC_I915); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); -MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI); -MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT); -MODULE_IMPORT_NS(SOUNDWIRE_INTEL); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_ACPI_INTEL_MATCH); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_AUDIO_CODEC"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_AUDIO_CODEC_I915"); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI"); +MODULE_IMPORT_NS("SOUNDWIRE_INTEL_INIT"); +MODULE_IMPORT_NS("SOUNDWIRE_INTEL"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_MATCH"); diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c index e3c4b4a0d705f2dc50c5e1f88c2a6d6f0f922a3f..793d8539821d4669d0802412ce1db6c50e469c8e 100644 --- a/sound/soc/sof/intel/lnl.c +++ b/sound/soc/sof/intel/lnl.c @@ -22,7 +22,7 @@ /* LunarLake ops */ struct snd_sof_dsp_ops sof_lnl_ops; -EXPORT_SYMBOL_NS(sof_lnl_ops, SND_SOC_SOF_INTEL_LNL); +EXPORT_SYMBOL_NS(sof_lnl_ops, "SND_SOC_SOF_INTEL_LNL"); static const struct snd_sof_debugfs_map lnl_dsp_debugfs[] = { {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS}, @@ -182,7 +182,7 @@ int sof_lnl_ops_init(struct snd_sof_dev *sdev) return 0; }; -EXPORT_SYMBOL_NS(sof_lnl_ops_init, SND_SOC_SOF_INTEL_LNL); +EXPORT_SYMBOL_NS(sof_lnl_ops_init, "SND_SOC_SOF_INTEL_LNL"); /* Check if an SDW IRQ occurred */ static bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) @@ -261,4 +261,4 @@ const struct sof_intel_dsp_desc ptl_chip_info = { .disable_interrupts = lnl_dsp_disable_interrupts, .hw_ip_version = SOF_INTEL_ACE_3_0, }; -EXPORT_SYMBOL_NS(ptl_chip_info, SND_SOC_SOF_INTEL_LNL); +EXPORT_SYMBOL_NS(ptl_chip_info, "SND_SOC_SOF_INTEL_LNL"); diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 2b9d22ccf345b86f5b5f9b2a991733d4ba08fe95..d07c68f431baf37dda9106ea434f3ffc1a8d8657 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -77,7 +77,7 @@ bool mtl_dsp_check_ipc_irq(struct snd_sof_dev *sdev) return false; } -EXPORT_SYMBOL_NS(mtl_dsp_check_ipc_irq, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_check_ipc_irq, "SND_SOC_SOF_INTEL_MTL"); /* Check if an SDW IRQ occurred */ static bool mtl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) @@ -121,7 +121,7 @@ int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(mtl_ipc_send_msg, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_ipc_send_msg, "SND_SOC_SOF_INTEL_MTL"); void mtl_enable_ipc_interrupts(struct snd_sof_dev *sdev) { @@ -149,7 +149,7 @@ void mtl_disable_ipc_interrupts(struct snd_sof_dev *sdev) snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl, MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, 0); } -EXPORT_SYMBOL_NS(mtl_disable_ipc_interrupts, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_disable_ipc_interrupts, "SND_SOC_SOF_INTEL_MTL"); static void mtl_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) { @@ -234,7 +234,7 @@ int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) return ret; } -EXPORT_SYMBOL_NS(mtl_enable_interrupts, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_enable_interrupts, "SND_SOC_SOF_INTEL_MTL"); /* pre fw run operations */ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) @@ -297,7 +297,7 @@ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) return ret; } -EXPORT_SYMBOL_NS(mtl_dsp_pre_fw_run, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_pre_fw_run, "SND_SOC_SOF_INTEL_MTL"); int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) { @@ -324,7 +324,7 @@ int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) hda_sdw_int_enable(sdev, true); return 0; } -EXPORT_SYMBOL_NS(mtl_dsp_post_fw_run, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_post_fw_run, "SND_SOC_SOF_INTEL_MTL"); void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags) { @@ -342,7 +342,7 @@ void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags) sof_ipc4_intel_dump_telemetry_state(sdev, flags); } -EXPORT_SYMBOL_NS(mtl_dsp_dump, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_dump, "SND_SOC_SOF_INTEL_MTL"); static bool mtl_dsp_primary_core_is_enabled(struct snd_sof_dev *sdev) { @@ -453,7 +453,7 @@ int mtl_power_down_dsp(struct snd_sof_dev *sdev) (dsphfdsscs & cpa) == 0, HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); } -EXPORT_SYMBOL_NS(mtl_power_down_dsp, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_power_down_dsp, "SND_SOC_SOF_INTEL_MTL"); int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) { @@ -556,7 +556,7 @@ err: kfree(dump_msg); return ret; } -EXPORT_SYMBOL_NS(mtl_dsp_cl_init, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_cl_init, "SND_SOC_SOF_INTEL_MTL"); irqreturn_t mtl_ipc_irq_thread(int irq, void *context) { @@ -640,19 +640,19 @@ irqreturn_t mtl_ipc_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(mtl_ipc_irq_thread, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_ipc_irq_thread, "SND_SOC_SOF_INTEL_MTL"); int mtl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) { return MTL_DSP_MBOX_UPLINK_OFFSET; } -EXPORT_SYMBOL_NS(mtl_dsp_ipc_get_mailbox_offset, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_ipc_get_mailbox_offset, "SND_SOC_SOF_INTEL_MTL"); int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id) { return MTL_SRAM_WINDOW_OFFSET(id); } -EXPORT_SYMBOL_NS(mtl_dsp_ipc_get_window_offset, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_ipc_get_window_offset, "SND_SOC_SOF_INTEL_MTL"); void mtl_ipc_dump(struct snd_sof_dev *sdev) { @@ -670,7 +670,7 @@ void mtl_ipc_dump(struct snd_sof_dev *sdev) "Host IPC initiator: %#x|%#x|%#x, target: %#x|%#x|%#x, ctl: %#x\n", hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl); } -EXPORT_SYMBOL_NS(mtl_ipc_dump, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_ipc_dump, "SND_SOC_SOF_INTEL_MTL"); static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev) { @@ -691,7 +691,7 @@ int mtl_dsp_core_get(struct snd_sof_dev *sdev, int core) return 0; } -EXPORT_SYMBOL_NS(mtl_dsp_core_get, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_core_get, "SND_SOC_SOF_INTEL_MTL"); int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core) { @@ -709,7 +709,7 @@ int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core) return 0; } -EXPORT_SYMBOL_NS(mtl_dsp_core_put, SND_SOC_SOF_INTEL_MTL); +EXPORT_SYMBOL_NS(mtl_dsp_core_put, "SND_SOC_SOF_INTEL_MTL"); /* Meteorlake ops */ struct snd_sof_dsp_ops sof_mtl_ops; diff --git a/sound/soc/sof/intel/pci-apl.c b/sound/soc/sof/intel/pci-apl.c index f006dcf5458aee93051a2ef24cb79266e2119fef..94ab3c61e3f7fedfd4fd5036237449475941dad3 100644 --- a/sound/soc/sof/intel/pci-apl.c +++ b/sound/soc/sof/intel/pci-apl.c @@ -106,6 +106,6 @@ module_pci_driver(snd_sof_pci_intel_apl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for ApolloLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-cnl.c b/sound/soc/sof/intel/pci-cnl.c index a8406342f08bdd8edf8bfeb7e5a2e90b80bf6c3a..739c352c3860fedd9472ce3be1d0a09a616cf2ac 100644 --- a/sound/soc/sof/intel/pci-cnl.c +++ b/sound/soc/sof/intel/pci-cnl.c @@ -144,6 +144,6 @@ module_pci_driver(snd_sof_pci_intel_cnl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for CannonLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-icl.c b/sound/soc/sof/intel/pci-icl.c index 25effca50d9fed1a819501717bb209e0217c7b68..8545ab95eac8b12111238f4dc5d185baa6393bba 100644 --- a/sound/soc/sof/intel/pci-icl.c +++ b/sound/soc/sof/intel/pci-icl.c @@ -109,7 +109,7 @@ module_pci_driver(snd_sof_pci_intel_icl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for IceLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_CNL); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_CNL"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-lnl.c b/sound/soc/sof/intel/pci-lnl.c index 602c574064eb5ca34978be1edd8b0987edef67e0..8d4d74ac4398b9fb3c25d0431e992b53bbc6c2d6 100644 --- a/sound/soc/sof/intel/pci-lnl.c +++ b/sound/soc/sof/intel/pci-lnl.c @@ -71,8 +71,8 @@ module_pci_driver(snd_sof_pci_intel_lnl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for LunarLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_MTL); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c index 8cb0333c033ef19756818c46998e329edc2fee2c..71f711cf85990e8d4245fc63edc5a92cf2df83ed 100644 --- a/sound/soc/sof/intel/pci-mtl.c +++ b/sound/soc/sof/intel/pci-mtl.c @@ -134,6 +134,6 @@ module_pci_driver(snd_sof_pci_intel_mtl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for MeteorLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-ptl.c b/sound/soc/sof/intel/pci-ptl.c index 69195b5e7b1a92f0172c7e73f9ca99e73d8db0f7..0aacdfac9fb4314abca37d36cfea41b55638643c 100644 --- a/sound/soc/sof/intel/pci-ptl.c +++ b/sound/soc/sof/intel/pci-ptl.c @@ -69,9 +69,9 @@ module_pci_driver(snd_sof_pci_intel_ptl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for PantherLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_LNL); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_MTL); -MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_LNL"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-skl.c b/sound/soc/sof/intel/pci-skl.c index 8ca0231d7e4f6e349d98fff90f0e4558920682cc..bd9daae51e4cc3e1105672a410a19166dd2107af 100644 --- a/sound/soc/sof/intel/pci-skl.c +++ b/sound/soc/sof/intel/pci-skl.c @@ -90,6 +90,6 @@ module_pci_driver(snd_sof_pci_intel_skl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for SkyLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c index 01db2e720b44ed614a55ce6644d7d45b54175fef..f76a7197f6caa46613c2df8706b0e0384512e552 100644 --- a/sound/soc/sof/intel/pci-tgl.c +++ b/sound/soc/sof/intel/pci-tgl.c @@ -318,7 +318,7 @@ module_pci_driver(snd_sof_pci_intel_tgl_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for TigerLake platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_CNL); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_CNL"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index 1375c393827e1167806a748cb4dab28b3b912791..b585ac4a85c2c7d09850995baac9b4c9da35f31e 100644 --- a/sound/soc/sof/intel/pci-tng.c +++ b/sound/soc/sof/intel/pci-tng.c @@ -245,7 +245,7 @@ module_pci_driver(snd_sof_pci_intel_tng_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for Tangier platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); -MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); -MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_ATOM_HIFI_EP); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HIFI_EP_IPC"); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index 9a002811e9ffde149bf6f3bb26cc1fe5e12f1a9f..0696bce65e33ef7f4708bf0411d88871e3cf8a87 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -50,7 +50,7 @@ static int skl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) /* skylake ops */ struct snd_sof_dsp_ops sof_skl_ops; -EXPORT_SYMBOL_NS(sof_skl_ops, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sof_skl_ops, "SND_SOC_SOF_INTEL_HDA_COMMON"); int sof_skl_ops_init(struct snd_sof_dev *sdev) { @@ -96,7 +96,7 @@ int sof_skl_ops_init(struct snd_sof_dev *sdev) return 0; }; -EXPORT_SYMBOL_NS(sof_skl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sof_skl_ops_init, "SND_SOC_SOF_INTEL_HDA_COMMON"); const struct sof_intel_dsp_desc skl_chip_info = { .cores_num = 2, @@ -114,4 +114,4 @@ const struct sof_intel_dsp_desc skl_chip_info = { .disable_interrupts = hda_dsp_disable_interrupts, .hw_ip_version = SOF_INTEL_CAVS_1_5, }; -EXPORT_SYMBOL_NS(skl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(skl_chip_info, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/intel/telemetry.c b/sound/soc/sof/intel/telemetry.c index 2d2f96548310a70623f088c0646d22be73c10dd7..dcaaf03599db2210c663a710915470925f8017c2 100644 --- a/sound/soc/sof/intel/telemetry.c +++ b/sound/soc/sof/intel/telemetry.c @@ -93,4 +93,4 @@ free_block: free_telemetry_data: kfree(telemetry_data); } -EXPORT_SYMBOL_NS(sof_ipc4_intel_dump_telemetry_state, SND_SOC_SOF_INTEL_HDA_COMMON); +EXPORT_SYMBOL_NS(sof_ipc4_intel_dump_telemetry_state, "SND_SOC_SOF_INTEL_HDA_COMMON"); diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index be61e377e59e03470e035bcd11500eb0745407d8..c2fce554a674bbd1f7092c493fa09bf7c99af8b7 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -20,6 +20,9 @@ /* size of tplg ABI in bytes */ #define SOF_IPC3_TPLG_ABI_SIZE 3 +/* Base of SOF_DAI_INTEL_ALH, this should be aligned with SOC_SDW_INTEL_BIDIR_PDI_BASE */ +#define INTEL_ALH_DAI_INDEX_BASE 2 + struct sof_widget_data { int ctrl_type; int ipc_cmd; @@ -1594,6 +1597,17 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) if (ret < 0) goto free; + /* Subtract the base to match the FW dai index. */ + if (comp_dai->type == SOF_DAI_INTEL_ALH) { + if (comp_dai->dai_index < INTEL_ALH_DAI_INDEX_BASE) { + dev_err(sdev->dev, + "Invalid ALH dai index %d, only Pin numbers >= %d can be used\n", + comp_dai->dai_index, INTEL_ALH_DAI_INDEX_BASE); + return -EINVAL; + } + comp_dai->dai_index -= INTEL_ALH_DAI_INDEX_BASE; + } + dev_dbg(scomp->dev, "dai %s: type %d index %d\n", swidget->widget->name, comp_dai->type, comp_dai->dai_index); sof_dbg_comp_config(scomp, &comp_dai->config); @@ -2167,8 +2181,16 @@ static int sof_ipc3_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget * case SOF_DAI_INTEL_ALH: if (data) { /* save the dai_index during hw_params and reuse it for hw_free */ - if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) - config->dai_index = data->dai_index; + if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) { + /* Subtract the base to match the FW dai index. */ + if (data->dai_index < INTEL_ALH_DAI_INDEX_BASE) { + dev_err(sdev->dev, + "Invalid ALH dai index %d, only Pin numbers >= %d can be used\n", + config->dai_index, INTEL_ALH_DAI_INDEX_BASE); + return -EINVAL; + } + config->dai_index = data->dai_index - INTEL_ALH_DAI_INDEX_BASE; + } config->alh.stream_id = data->dai_data; } break; diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c index 9466f7d2e5350363a084c3c48afeb62f36adb357..9955dfa520ae2f944884ce464379ed96adb2b9d4 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186.c @@ -668,5 +668,5 @@ module_platform_driver(snd_sof_of_mt8186_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for MT8186/MT8188 platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); -MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SND_SOC_SOF_MTK_COMMON"); diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 5b4423ed8023bdb61a2c2ddaa46e376deadb3da7..6032b566c6795833d2b3e432c7af5eaf436489ce 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -624,5 +624,5 @@ module_platform_driver(snd_sof_of_mt8195_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for MTL 8195 platforms"); -MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); -MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON); +MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); +MODULE_IMPORT_NS("SND_SOC_SOF_MTK_COMMON"); diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index 76ff798a4a1ea3675fad99ea7b1e1c26739018b0..58fd5f7c790540f1e9f491a5d4f7616127b7cba0 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -41,7 +41,7 @@ const struct dev_pm_ops sof_acpi_pm = { SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, snd_sof_runtime_idle) }; -EXPORT_SYMBOL_NS(sof_acpi_pm, SND_SOC_SOF_ACPI_DEV); +EXPORT_SYMBOL_NS(sof_acpi_pm, "SND_SOC_SOF_ACPI_DEV"); static void sof_acpi_probe_complete(struct device *dev) { @@ -85,7 +85,7 @@ int sof_acpi_probe(struct platform_device *pdev, const struct sof_dev_desc *desc /* call sof helper for DSP hardware probe */ return snd_sof_device_probe(dev, sof_pdata); } -EXPORT_SYMBOL_NS(sof_acpi_probe, SND_SOC_SOF_ACPI_DEV); +EXPORT_SYMBOL_NS(sof_acpi_probe, "SND_SOC_SOF_ACPI_DEV"); void sof_acpi_remove(struct platform_device *pdev) { @@ -97,7 +97,7 @@ void sof_acpi_remove(struct platform_device *pdev) /* call sof helper for DSP hardware remove */ snd_sof_device_remove(dev); } -EXPORT_SYMBOL_NS(sof_acpi_remove, SND_SOC_SOF_ACPI_DEV); +EXPORT_SYMBOL_NS(sof_acpi_remove, "SND_SOC_SOF_ACPI_DEV"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for ACPI platforms"); diff --git a/sound/soc/sof/sof-client-ipc-flood-test.c b/sound/soc/sof/sof-client-ipc-flood-test.c index e7d2001140e81a93e46d8d05d8f1ca45ef05ef14..b35c98896968140256e7349dd37c133bb2f9eefe 100644 --- a/sound/soc/sof/sof-client-ipc-flood-test.c +++ b/sound/soc/sof/sof-client-ipc-flood-test.c @@ -396,4 +396,4 @@ module_auxiliary_driver(sof_ipc_flood_client_drv); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SOF IPC Flood Test Client Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); +MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/sof-client-ipc-kernel-injector.c b/sound/soc/sof/sof-client-ipc-kernel-injector.c index d3f541069b24b8fc4dfaa8a1d4774e6e30db6cc5..8b28c3dc920cb0b02cb1d91b8492c51089add787 100644 --- a/sound/soc/sof/sof-client-ipc-kernel-injector.c +++ b/sound/soc/sof/sof-client-ipc-kernel-injector.c @@ -159,4 +159,4 @@ module_auxiliary_driver(sof_msg_inject_client_drv); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SOF IPC Kernel Injector Client Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); +MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c index d0f8beb9d0008d1ccfc1a9eadd13324108d5e1de..ba7ca1c5027ff0ad141d1cc6e024dd5fca346e05 100644 --- a/sound/soc/sof/sof-client-ipc-msg-injector.c +++ b/sound/soc/sof/sof-client-ipc-msg-injector.c @@ -337,4 +337,4 @@ module_auxiliary_driver(sof_msg_inject_client_drv); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SOF IPC Message Injector Client Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); +MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index ccc7d38ddc38340686c93282d83f4e427a5febc8..aff9ce9804295453ac955562e2550bb4913d9454 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -542,4 +542,4 @@ module_auxiliary_driver(sof_probes_client_drv); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("SOF Probes Client Driver"); -MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); +MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index 5d6005a88e798fd1a1022340d91ea71de5b0b0d6..4c7951338c66f6bd6613de627a40cc725b5520d8 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -259,7 +259,7 @@ err_dev_add_data: return ret; } -EXPORT_SYMBOL_NS_GPL(sof_client_dev_register, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_dev_register, "SND_SOC_SOF_CLIENT"); void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 id) { @@ -282,7 +282,7 @@ void sof_client_dev_unregister(struct snd_sof_dev *sdev, const char *name, u32 i mutex_unlock(&sdev->ipc_client_mutex); } -EXPORT_SYMBOL_NS_GPL(sof_client_dev_unregister, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_dev_unregister, "SND_SOC_SOF_CLIENT"); int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg, void *reply_data, size_t reply_bytes) @@ -301,7 +301,7 @@ int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg, return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, "SND_SOC_SOF_CLIENT"); int sof_client_ipc_rx_message(struct sof_client_dev *cdev, void *ipc_msg, void *msg_buf) { @@ -320,7 +320,7 @@ int sof_client_ipc_rx_message(struct sof_client_dev *cdev, void *ipc_msg, void * return -EOPNOTSUPP; } -EXPORT_SYMBOL_NS_GPL(sof_client_ipc_rx_message, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_ipc_rx_message, "SND_SOC_SOF_CLIENT"); int sof_client_ipc_set_get_data(struct sof_client_dev *cdev, void *ipc_msg, bool set) @@ -339,7 +339,7 @@ int sof_client_ipc_set_get_data(struct sof_client_dev *cdev, void *ipc_msg, return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(sof_client_ipc_set_get_data, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_ipc_set_get_data, "SND_SOC_SOF_CLIENT"); #ifdef CONFIG_SND_SOC_SOF_IPC4 struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c, const guid_t *uuid) @@ -352,7 +352,7 @@ struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c, return NULL; } -EXPORT_SYMBOL_NS_GPL(sof_client_ipc4_find_module, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_ipc4_find_module, "SND_SOC_SOF_CLIENT"); #endif int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state) @@ -376,7 +376,7 @@ int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state) return 0; } -EXPORT_SYMBOL_NS_GPL(sof_suspend_clients, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_suspend_clients, "SND_SOC_SOF_CLIENT"); int sof_resume_clients(struct snd_sof_dev *sdev) { @@ -399,20 +399,20 @@ int sof_resume_clients(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS_GPL(sof_resume_clients, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_resume_clients, "SND_SOC_SOF_CLIENT"); struct dentry *sof_client_get_debugfs_root(struct sof_client_dev *cdev) { return cdev->sdev->debugfs_root; } -EXPORT_SYMBOL_NS_GPL(sof_client_get_debugfs_root, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_get_debugfs_root, "SND_SOC_SOF_CLIENT"); /* DMA buffer allocation in client drivers must use the core SOF device */ struct device *sof_client_get_dma_dev(struct sof_client_dev *cdev) { return cdev->sdev->dev; } -EXPORT_SYMBOL_NS_GPL(sof_client_get_dma_dev, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_get_dma_dev, "SND_SOC_SOF_CLIENT"); const struct sof_ipc_fw_version *sof_client_get_fw_version(struct sof_client_dev *cdev) { @@ -420,7 +420,7 @@ const struct sof_ipc_fw_version *sof_client_get_fw_version(struct sof_client_dev return &sdev->fw_ready.version; } -EXPORT_SYMBOL_NS_GPL(sof_client_get_fw_version, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_get_fw_version, "SND_SOC_SOF_CLIENT"); size_t sof_client_get_ipc_max_payload_size(struct sof_client_dev *cdev) { @@ -428,7 +428,7 @@ size_t sof_client_get_ipc_max_payload_size(struct sof_client_dev *cdev) return sdev->ipc->max_payload_size; } -EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_max_payload_size, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_max_payload_size, "SND_SOC_SOF_CLIENT"); enum sof_ipc_type sof_client_get_ipc_type(struct sof_client_dev *cdev) { @@ -436,7 +436,7 @@ enum sof_ipc_type sof_client_get_ipc_type(struct sof_client_dev *cdev) return sdev->pdata->ipc_type; } -EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_type, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_get_ipc_type, "SND_SOC_SOF_CLIENT"); /* module refcount management of SOF core */ int sof_client_core_module_get(struct sof_client_dev *cdev) @@ -448,7 +448,7 @@ int sof_client_core_module_get(struct sof_client_dev *cdev) return 0; } -EXPORT_SYMBOL_NS_GPL(sof_client_core_module_get, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_core_module_get, "SND_SOC_SOF_CLIENT"); void sof_client_core_module_put(struct sof_client_dev *cdev) { @@ -456,7 +456,7 @@ void sof_client_core_module_put(struct sof_client_dev *cdev) module_put(sdev->dev->driver->owner); } -EXPORT_SYMBOL_NS_GPL(sof_client_core_module_put, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_core_module_put, "SND_SOC_SOF_CLIENT"); /* IPC event handling */ void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf) @@ -525,7 +525,7 @@ int sof_client_register_ipc_rx_handler(struct sof_client_dev *cdev, return 0; } -EXPORT_SYMBOL_NS_GPL(sof_client_register_ipc_rx_handler, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_register_ipc_rx_handler, "SND_SOC_SOF_CLIENT"); void sof_client_unregister_ipc_rx_handler(struct sof_client_dev *cdev, u32 ipc_msg_type) @@ -545,7 +545,7 @@ void sof_client_unregister_ipc_rx_handler(struct sof_client_dev *cdev, mutex_unlock(&sdev->client_event_handler_mutex); } -EXPORT_SYMBOL_NS_GPL(sof_client_unregister_ipc_rx_handler, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_unregister_ipc_rx_handler, "SND_SOC_SOF_CLIENT"); /*DSP state notification and query */ void sof_client_fw_state_dispatcher(struct snd_sof_dev *sdev) @@ -583,7 +583,7 @@ int sof_client_register_fw_state_handler(struct sof_client_dev *cdev, return 0; } -EXPORT_SYMBOL_NS_GPL(sof_client_register_fw_state_handler, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_register_fw_state_handler, "SND_SOC_SOF_CLIENT"); void sof_client_unregister_fw_state_handler(struct sof_client_dev *cdev) { @@ -602,7 +602,7 @@ void sof_client_unregister_fw_state_handler(struct sof_client_dev *cdev) mutex_unlock(&sdev->client_event_handler_mutex); } -EXPORT_SYMBOL_NS_GPL(sof_client_unregister_fw_state_handler, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_unregister_fw_state_handler, "SND_SOC_SOF_CLIENT"); enum sof_fw_state sof_client_get_fw_state(struct sof_client_dev *cdev) { @@ -610,4 +610,4 @@ enum sof_fw_state sof_client_get_fw_state(struct sof_client_dev *cdev) return sdev->fw_state; } -EXPORT_SYMBOL_NS_GPL(sof_client_get_fw_state, SND_SOC_SOF_CLIENT); +EXPORT_SYMBOL_NS_GPL(sof_client_get_fw_state, "SND_SOC_SOF_CLIENT"); diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index fe5650616573099e7b43f413d7f7afad8a6565a7..103377e2caaf82bb15661b935fa0fefc52c325fa 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -162,7 +162,7 @@ const struct dev_pm_ops sof_pci_pm = { SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, snd_sof_runtime_idle) }; -EXPORT_SYMBOL_NS(sof_pci_pm, SND_SOC_SOF_PCI_DEV); +EXPORT_SYMBOL_NS(sof_pci_pm, "SND_SOC_SOF_PCI_DEV"); static void sof_pci_probe_complete(struct device *dev) { @@ -280,7 +280,7 @@ out: return ret; } -EXPORT_SYMBOL_NS(sof_pci_probe, SND_SOC_SOF_PCI_DEV); +EXPORT_SYMBOL_NS(sof_pci_probe, "SND_SOC_SOF_PCI_DEV"); void sof_pci_remove(struct pci_dev *pci) { @@ -295,13 +295,13 @@ void sof_pci_remove(struct pci_dev *pci) /* release pci regions and disable device */ pci_release_regions(pci); } -EXPORT_SYMBOL_NS(sof_pci_remove, SND_SOC_SOF_PCI_DEV); +EXPORT_SYMBOL_NS(sof_pci_remove, "SND_SOC_SOF_PCI_DEV"); void sof_pci_shutdown(struct pci_dev *pci) { snd_sof_device_shutdown(&pci->dev); } -EXPORT_SYMBOL_NS(sof_pci_shutdown, SND_SOC_SOF_PCI_DEV); +EXPORT_SYMBOL_NS(sof_pci_shutdown, "SND_SOC_SOF_PCI_DEV"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for PCI platforms"); diff --git a/sound/soc/sof/xtensa/core.c b/sound/soc/sof/xtensa/core.c index 3cf8c84beff9570f559cc1fc027af9dc5766190d..50623e65fe1a514eca6ba12bb4fd0304d31c59f2 100644 --- a/sound/soc/sof/xtensa/core.c +++ b/sound/soc/sof/xtensa/core.c @@ -149,7 +149,7 @@ const struct dsp_arch_ops sof_xtensa_arch_ops = { .dsp_oops = xtensa_dsp_oops, .dsp_stack = xtensa_stack, }; -EXPORT_SYMBOL_NS(sof_xtensa_arch_ops, SND_SOC_SOF_XTENSA); +EXPORT_SYMBOL_NS(sof_xtensa_arch_ops, "SND_SOC_SOF_XTENSA"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF Xtensa DSP support"); diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 8f85200292f3ff35e2271736cabe33099a72e91c..842ba5b801eae83f29d5d41e47db6291f8e5f034 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -36,6 +36,12 @@ union uac23_clock_multiplier_desc { struct uac_clock_multiplier_descriptor v3; }; +/* check whether the descriptor bLength has the minimal length */ +#define DESC_LENGTH_CHECK(p, proto) \ + ((proto) == UAC_VERSION_3 ? \ + ((p)->v3.bLength >= sizeof((p)->v3)) : \ + ((p)->v2.bLength >= sizeof((p)->v2))) + #define GET_VAL(p, proto, field) \ ((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field) @@ -58,6 +64,8 @@ static bool validate_clock_source(void *p, int id, int proto) { union uac23_clock_source_desc *cs = p; + if (!DESC_LENGTH_CHECK(cs, proto)) + return false; return GET_VAL(cs, proto, bClockID) == id; } @@ -65,13 +73,27 @@ static bool validate_clock_selector(void *p, int id, int proto) { union uac23_clock_selector_desc *cs = p; - return GET_VAL(cs, proto, bClockID) == id; + if (!DESC_LENGTH_CHECK(cs, proto)) + return false; + if (GET_VAL(cs, proto, bClockID) != id) + return false; + /* additional length check for baCSourceID array (in bNrInPins size) + * and two more fields (which sizes depend on the protocol) + */ + if (proto == UAC_VERSION_3) + return cs->v3.bLength >= sizeof(cs->v3) + cs->v3.bNrInPins + + 4 /* bmControls */ + 2 /* wCSelectorDescrStr */; + else + return cs->v2.bLength >= sizeof(cs->v2) + cs->v2.bNrInPins + + 1 /* bmControls */ + 1 /* iClockSelector */; } static bool validate_clock_multiplier(void *p, int id, int proto) { union uac23_clock_multiplier_desc *cs = p; + if (!DESC_LENGTH_CHECK(cs, proto)) + return false; return GET_VAL(cs, proto, bClockID) == id; } diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index cbfbb064a9c23ea96078eb028822bbf7f51cda2d..8bc959b60be3b66b8045081e89a41fc5eb5f23bc 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -555,6 +555,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf) { struct usb_host_config *config = dev->actconfig; + struct usb_device_descriptor new_device_descriptor; int err; if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD || @@ -566,10 +567,14 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac if (err < 0) dev_dbg(&dev->dev, "error sending boot message: %d\n", err); err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - &dev->descriptor, sizeof(dev->descriptor)); - config = dev->actconfig; + &new_device_descriptor, sizeof(new_device_descriptor)); if (err < 0) dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); + if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) + dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n", + new_device_descriptor.bNumConfigurations); + else + memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); err = usb_reset_configuration(dev); if (err < 0) dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err); @@ -901,6 +906,7 @@ static void mbox2_setup_48_24_magic(struct usb_device *dev) static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) { struct usb_host_config *config = dev->actconfig; + struct usb_device_descriptor new_device_descriptor; int err; u8 bootresponse[0x12]; int fwsize; @@ -936,10 +942,14 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) dev_dbg(&dev->dev, "device initialised!\n"); err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - &dev->descriptor, sizeof(dev->descriptor)); - config = dev->actconfig; + &new_device_descriptor, sizeof(new_device_descriptor)); if (err < 0) dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); + if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) + dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n", + new_device_descriptor.bNumConfigurations); + else + memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); err = usb_reset_configuration(dev); if (err < 0) @@ -1249,6 +1259,7 @@ static void mbox3_setup_defaults(struct usb_device *dev) static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) { struct usb_host_config *config = dev->actconfig; + struct usb_device_descriptor new_device_descriptor; int err; int descriptor_size; @@ -1262,10 +1273,14 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) dev_dbg(&dev->dev, "MBOX3: device initialised!\n"); err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - &dev->descriptor, sizeof(dev->descriptor)); - config = dev->actconfig; + &new_device_descriptor, sizeof(new_device_descriptor)); if (err < 0) dev_dbg(&dev->dev, "MBOX3: error usb_get_descriptor: %d\n", err); + if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) + dev_dbg(&dev->dev, "MBOX3: error too large bNumConfigurations: %d\n", + new_device_descriptor.bNumConfigurations); + else + memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor)); err = usb_reset_configuration(dev); if (err < 0) diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index 8073c9e4fe46a03c64fdd08ca0f9e0f1b656479c..cccf62ea2b8f9b55a83a4960c1a60087c7b053f3 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -63,6 +63,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_DELTA_VELOCITY] = "deltavelocity", [IIO_COLORTEMP] = "colortemp", [IIO_CHROMATICITY] = "chromaticity", + [IIO_ATTENTION] = "attention", }; static const char * const iio_ev_type_text[] = { @@ -183,6 +184,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_DELTA_VELOCITY: case IIO_COLORTEMP: case IIO_CHROMATICITY: + case IIO_ATTENTION: break; default: return false; @@ -449,6 +451,7 @@ error_free_chrdev_name: enable_events(dev_dir_name, 0); free(chrdev_name); + free(dev_dir_name); return ret; } diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f7586f82b967ad6db1f607a594f72e459ee915aa..4ce176ad411fb12a10101bbedbb6180275941b4b 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4573,6 +4573,8 @@ static int validate_ibt(struct objtool_file *file) !strcmp(sec->name, "__jump_table") || !strcmp(sec->name, "__mcount_loc") || !strcmp(sec->name, ".kcfi_traps") || + !strcmp(sec->name, ".llvm.call-graph-profile") || + !strcmp(sec->name, ".llvm_bb_addr_map") || !strcmp(sec->name, "__tracepoints") || strstr(sec->name, "__patchable_function_entries")) continue; diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 3d27983dc908d848ca6ad79bc85515febce71323..6f64d611faea96f565705f2d06151ce59694990c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -224,12 +224,17 @@ int find_symbol_hole_containing(const struct section *sec, unsigned long offset) if (n) return 0; /* not a hole */ - /* didn't find a symbol for which @offset is after it */ - if (!hole.sym) - return 0; /* not a hole */ + /* + * @offset >= sym->offset + sym->len, find symbol after it. + * When hole.sym is empty, use the first node to compute the hole. + * If there is no symbol in the section, the first node will be NULL, + * in which case, -1 is returned to skip the whole section. + */ + if (hole.sym) + n = rb_next(&hole.sym->node); + else + n = rb_first_cached(&sec->symbol_tree); - /* @offset >= sym->offset + sym->len, find symbol after it */ - n = rb_next(&hole.sym->node); if (!n) return -1; /* until end of address space */ diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 067717bce1d4ab6ff21728e6765ce94446338f7c..a7f7ed01421c1494f53780da8f1ee0381191876c 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -33,6 +33,9 @@ name as necessary to disambiguate it from others is necessary. Note that option msr0xXXX is a hex offset, eg. msr0x10 /sys/path... is an absolute path to a sysfs attribute is a perf device from /sys/bus/event_source/devices/ eg. cstate_core + On Intel hybrid platforms, instead of one "cpu" perf device there are two, "cpu_core" and "cpu_atom" devices for P and E cores respectively. + Turbostat, in this case, allow user to use "cpu" device and will automatically detect the type of a CPU and translate it to "cpu_core" and "cpu_atom" accordingly. + For a complete example see "ADD PERF COUNTER EXAMPLE #2 (using virtual "cpu" device)". is a perf event for given device from /sys/bus/event_source/devices//events/ eg. c1-residency perf/cstate_core/c1-residency would then use /sys/bus/event_source/devices/cstate_core/events/c1-residency @@ -187,6 +190,8 @@ The system configuration dump (if --quiet is not used) is followed by statistics .PP \fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors. .PP +\fBSysWatt\fP Watts consumed by the whole platform (RAPL PSYS). Disabled by default. Enable with --enable SysWatt. +.PP \fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. Note that the system summary is the sum of the package throttling time, and thus may be higher than 100% on a multi-package system. Note that the meaning of this field is model specific. For example, some hardware increments this counter when RAPL responds to thermal limits, but does not increment this counter when RAPL responds to power limits. Comparing PkgWatt and PkgTmp to system limits is necessary. .PP \fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM. @@ -387,6 +392,28 @@ CPU pCPU%c1 CPU%c1 .fi +.SH ADD PERF COUNTER EXAMPLE #2 (using virtual cpu device) +Here we run on hybrid, Raptor Lake platform. +We limit turbostat to show output for just cpu0 (pcore) and cpu12 (ecore). +We add a counter showing number of L3 cache misses, using virtual "cpu" device, +labeling it with the column header, "VCMISS". +We add a counter showing number of L3 cache misses, using virtual "cpu_core" device, +labeling it with the column header, "PCMISS". This will fail on ecore cpu12. +We add a counter showing number of L3 cache misses, using virtual "cpu_atom" device, +labeling it with the column header, "ECMISS". This will fail on pcore cpu0. +We display it only once, after the conclusion of 0.1 second sleep. +.nf +sudo ./turbostat --quiet --cpu 0,12 --show CPU --add perf/cpu/cache-misses,cpu,delta,raw,VCMISS --add perf/cpu_core/cache-misses,cpu,delta,raw,PCMISS --add perf/cpu_atom/cache-misses,cpu,delta,raw,ECMISS sleep .1 +turbostat: added_perf_counters_init_: perf/cpu_atom/cache-misses: failed to open counter on cpu0 +turbostat: added_perf_counters_init_: perf/cpu_core/cache-misses: failed to open counter on cpu12 +0.104630 sec +CPU ECMISS PCMISS VCMISS +- 0x0000000000000000 0x0000000000000000 0x0000000000000000 +0 0x0000000000000000 0x0000000000007951 0x0000000000007796 +12 0x000000000001137a 0x0000000000000000 0x0000000000011392 + +.fi + .SH ADD PMT COUNTER EXAMPLE Here we limit turbostat to showing just the CPU number 0. We add two counters, showing crystal clock count and the DC6 residency. diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 089220aaa5c9291b5e0432ec1d0fa9b3f44b3e1a..58a487c225a73a5e671027dfdefa193284747f0d 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -31,6 +31,9 @@ ) // end copied section +#define CPUID_LEAF_MODEL_ID 0x1A +#define CPUID_LEAF_MODEL_ID_CORE_TYPE_SHIFT 24 + #define X86_VENDOR_INTEL 0 #include INTEL_FAMILY_HEADER @@ -89,6 +92,9 @@ #define PERF_DEV_NAME_BYTES 32 #define PERF_EVT_NAME_BYTES 32 +#define INTEL_ECORE_TYPE 0x20 +#define INTEL_PCORE_TYPE 0x40 + enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE }; enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC, COUNTER_K2M }; enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT, FORMAT_AVERAGE }; @@ -194,6 +200,8 @@ struct msr_counter bic[] = { { 0x0, "SAMMHz", NULL, 0, 0, 0, NULL, 0 }, { 0x0, "SAMAMHz", NULL, 0, 0, 0, NULL, 0 }, { 0x0, "Die%c6", NULL, 0, 0, 0, NULL, 0 }, + { 0x0, "SysWatt", NULL, 0, 0, 0, NULL, 0 }, + { 0x0, "Sys_J", NULL, 0, 0, 0, NULL, 0 }, }; #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) @@ -256,6 +264,8 @@ struct msr_counter bic[] = { #define BIC_SAMMHz (1ULL << 56) #define BIC_SAMACTMHz (1ULL << 57) #define BIC_Diec6 (1ULL << 58) +#define BIC_SysWatt (1ULL << 59) +#define BIC_Sys_J (1ULL << 60) #define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die ) #define BIC_THERMAL_PWR ( BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__) @@ -263,7 +273,7 @@ struct msr_counter bic[] = { #define BIC_IDLE (BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX | BIC_SAM_mc6 | BIC_Diec6) #define BIC_OTHER ( BIC_IRQ | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC) -#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC) +#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC | BIC_SysWatt | BIC_Sys_J) unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT); unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC; @@ -370,7 +380,6 @@ enum gfx_sysfs_idx { }; struct gfx_sysfs_info { - const char *path; FILE *fp; unsigned int val; unsigned long long val_ull; @@ -502,12 +511,15 @@ enum rapl_msrs { RAPL_AMD_PWR_UNIT = BIT(14), /* 0xc0010299 MSR_AMD_RAPL_POWER_UNIT */ RAPL_AMD_CORE_ENERGY_STAT = BIT(15), /* 0xc001029a MSR_AMD_CORE_ENERGY_STATUS */ RAPL_AMD_PKG_ENERGY_STAT = BIT(16), /* 0xc001029b MSR_AMD_PKG_ENERGY_STATUS */ + RAPL_PLATFORM_ENERGY_LIMIT = BIT(17), /* 0x64c MSR_PLATFORM_ENERGY_LIMIT */ + RAPL_PLATFORM_ENERGY_STATUS = BIT(18), /* 0x64d MSR_PLATFORM_ENERGY_STATUS */ }; #define RAPL_PKG (RAPL_PKG_ENERGY_STATUS | RAPL_PKG_POWER_LIMIT) #define RAPL_DRAM (RAPL_DRAM_ENERGY_STATUS | RAPL_DRAM_POWER_LIMIT) #define RAPL_CORE (RAPL_CORE_ENERGY_STATUS | RAPL_CORE_POWER_LIMIT) #define RAPL_GFX (RAPL_GFX_POWER_LIMIT | RAPL_GFX_ENERGY_STATUS) +#define RAPL_PSYS (RAPL_PLATFORM_ENERGY_STATUS | RAPL_PLATFORM_ENERGY_LIMIT) #define RAPL_PKG_ALL (RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO) #define RAPL_DRAM_ALL (RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_DRAM_POWER_INFO) @@ -708,7 +720,7 @@ static const struct platform_features skl_features = { .has_ext_cst_msrs = 1, .trl_msrs = TRL_BASE, .tcc_offset_bits = 6, - .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX, + .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX | RAPL_PSYS, .enable_tsc_tweak = 1, }; @@ -725,42 +737,44 @@ static const struct platform_features cnl_features = { .has_ext_cst_msrs = 1, .trl_msrs = TRL_BASE, .tcc_offset_bits = 6, - .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX, + .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX | RAPL_PSYS, .enable_tsc_tweak = 1, }; +/* Copied from cnl_features, with PC7/PC9 removed */ static const struct platform_features adl_features = { - .has_msr_misc_feature_control = 1, - .has_msr_misc_pwr_mgmt = 1, - .has_nhm_msrs = 1, - .has_config_tdp = 1, - .bclk_freq = BCLK_100MHZ, - .supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC8 | PC10, - .cst_limit = CST_LIMIT_HSW, - .has_irtl_msrs = 1, - .has_msr_core_c1_res = 1, - .has_ext_cst_msrs = 1, - .trl_msrs = TRL_BASE, - .tcc_offset_bits = 6, - .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX, - .enable_tsc_tweak = 1, + .has_msr_misc_feature_control = cnl_features.has_msr_misc_feature_control, + .has_msr_misc_pwr_mgmt = cnl_features.has_msr_misc_pwr_mgmt, + .has_nhm_msrs = cnl_features.has_nhm_msrs, + .has_config_tdp = cnl_features.has_config_tdp, + .bclk_freq = cnl_features.bclk_freq, + .supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC8 | PC10, + .cst_limit = cnl_features.cst_limit, + .has_irtl_msrs = cnl_features.has_irtl_msrs, + .has_msr_core_c1_res = cnl_features.has_msr_core_c1_res, + .has_ext_cst_msrs = cnl_features.has_ext_cst_msrs, + .trl_msrs = cnl_features.trl_msrs, + .tcc_offset_bits = cnl_features.tcc_offset_bits, + .rapl_msrs = cnl_features.rapl_msrs, + .enable_tsc_tweak = cnl_features.enable_tsc_tweak, }; -static const struct platform_features arl_features = { - .has_msr_misc_feature_control = 1, - .has_msr_misc_pwr_mgmt = 1, - .has_nhm_msrs = 1, - .has_config_tdp = 1, - .bclk_freq = BCLK_100MHZ, - .supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC10, - .cst_limit = CST_LIMIT_HSW, - .has_irtl_msrs = 1, - .has_msr_core_c1_res = 1, - .has_ext_cst_msrs = 1, - .trl_msrs = TRL_BASE, - .tcc_offset_bits = 6, - .rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX, - .enable_tsc_tweak = 1, +/* Copied from adl_features, with PC3/PC8 removed */ +static const struct platform_features lnl_features = { + .has_msr_misc_feature_control = adl_features.has_msr_misc_feature_control, + .has_msr_misc_pwr_mgmt = adl_features.has_msr_misc_pwr_mgmt, + .has_nhm_msrs = adl_features.has_nhm_msrs, + .has_config_tdp = adl_features.has_config_tdp, + .bclk_freq = adl_features.bclk_freq, + .supported_cstates = CC1 | CC6 | CC7 | PC2 | PC6 | PC10, + .cst_limit = adl_features.cst_limit, + .has_irtl_msrs = adl_features.has_irtl_msrs, + .has_msr_core_c1_res = adl_features.has_msr_core_c1_res, + .has_ext_cst_msrs = adl_features.has_ext_cst_msrs, + .trl_msrs = adl_features.trl_msrs, + .tcc_offset_bits = adl_features.tcc_offset_bits, + .rapl_msrs = adl_features.rapl_msrs, + .enable_tsc_tweak = adl_features.enable_tsc_tweak, }; static const struct platform_features skx_features = { @@ -790,7 +804,7 @@ static const struct platform_features icx_features = { .has_irtl_msrs = 1, .has_cst_prewake_bit = 1, .trl_msrs = TRL_BASE | TRL_CORECOUNT, - .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL, + .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS, .has_fixed_rapl_unit = 1, }; @@ -806,7 +820,7 @@ static const struct platform_features spr_features = { .has_irtl_msrs = 1, .has_cst_prewake_bit = 1, .trl_msrs = TRL_BASE | TRL_CORECOUNT, - .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL, + .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS, }; static const struct platform_features srf_features = { @@ -822,7 +836,7 @@ static const struct platform_features srf_features = { .has_irtl_msrs = 1, .has_cst_prewake_bit = 1, .trl_msrs = TRL_BASE | TRL_CORECOUNT, - .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL, + .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS, }; static const struct platform_features grr_features = { @@ -838,7 +852,7 @@ static const struct platform_features grr_features = { .has_irtl_msrs = 1, .has_cst_prewake_bit = 1, .trl_msrs = TRL_BASE | TRL_CORECOUNT, - .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL, + .rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS, }; static const struct platform_features slv_features = { @@ -997,18 +1011,19 @@ static const struct platform_data turbostat_pdata[] = { { INTEL_SAPPHIRERAPIDS_X, &spr_features }, { INTEL_EMERALDRAPIDS_X, &spr_features }, { INTEL_GRANITERAPIDS_X, &spr_features }, + { INTEL_GRANITERAPIDS_D, &spr_features }, { INTEL_LAKEFIELD, &cnl_features }, { INTEL_ALDERLAKE, &adl_features }, { INTEL_ALDERLAKE_L, &adl_features }, { INTEL_RAPTORLAKE, &adl_features }, { INTEL_RAPTORLAKE_P, &adl_features }, { INTEL_RAPTORLAKE_S, &adl_features }, - { INTEL_METEORLAKE, &cnl_features }, - { INTEL_METEORLAKE_L, &cnl_features }, - { INTEL_ARROWLAKE_H, &arl_features }, - { INTEL_ARROWLAKE_U, &arl_features }, - { INTEL_ARROWLAKE, &arl_features }, - { INTEL_LUNARLAKE_M, &arl_features }, + { INTEL_METEORLAKE, &adl_features }, + { INTEL_METEORLAKE_L, &adl_features }, + { INTEL_ARROWLAKE_H, &adl_features }, + { INTEL_ARROWLAKE_U, &adl_features }, + { INTEL_ARROWLAKE, &adl_features }, + { INTEL_LUNARLAKE_M, &lnl_features }, { INTEL_ATOM_SILVERMONT, &slv_features }, { INTEL_ATOM_SILVERMONT_D, &slvd_features }, { INTEL_ATOM_AIRMONT, &amt_features }, @@ -1100,6 +1115,7 @@ enum rapl_rci_index { RAPL_RCI_INDEX_PKG_PERF_STATUS = 4, RAPL_RCI_INDEX_DRAM_PERF_STATUS = 5, RAPL_RCI_INDEX_CORE_ENERGY = 6, + RAPL_RCI_INDEX_ENERGY_PLATFORM = 7, NUM_RAPL_COUNTERS, }; @@ -1126,6 +1142,7 @@ struct rapl_counter_info_t { struct rapl_counter_info_t *rapl_counter_info_perdomain; unsigned int rapl_counter_info_perdomain_size; +#define RAPL_COUNTER_FLAG_PLATFORM_COUNTER (1u << 0) #define RAPL_COUNTER_FLAG_USE_MSR_SUM (1u << 1) struct rapl_counter_arch_info { @@ -1247,6 +1264,19 @@ static const struct rapl_counter_arch_info rapl_counter_arch_infos[] = { .compat_scale = 1.0, .flags = 0, }, + { + .feature_mask = RAPL_PSYS, + .perf_subsys = "power", + .perf_name = "energy-psys", + .msr = MSR_PLATFORM_ENERGY_STATUS, + .msr_mask = 0x00000000FFFFFFFF, + .msr_shift = 0, + .platform_rapl_msr_scale = &rapl_energy_units, + .rci_index = RAPL_RCI_INDEX_ENERGY_PLATFORM, + .bic = BIC_SysWatt | BIC_Sys_J, + .compat_scale = 1.0, + .flags = RAPL_COUNTER_FLAG_PLATFORM_COUNTER | RAPL_COUNTER_FLAG_USE_MSR_SUM, + }, }; struct rapl_counter { @@ -1674,6 +1704,7 @@ enum { IDX_PP1_ENERGY, IDX_PKG_PERF, IDX_DRAM_PERF, + IDX_PSYS_ENERGY, IDX_COUNT, }; @@ -1718,6 +1749,9 @@ off_t idx_to_offset(int idx) case IDX_DRAM_PERF: offset = MSR_DRAM_PERF_STATUS; break; + case IDX_PSYS_ENERGY: + offset = MSR_PLATFORM_ENERGY_STATUS; + break; default: offset = -1; } @@ -1748,6 +1782,9 @@ int offset_to_idx(off_t offset) case MSR_DRAM_PERF_STATUS: idx = IDX_DRAM_PERF; break; + case MSR_PLATFORM_ENERGY_STATUS: + idx = IDX_PSYS_ENERGY; + break; default: idx = -1; } @@ -1769,6 +1806,8 @@ int idx_valid(int idx) return platform->rapl_msrs & RAPL_PKG_PERF_STATUS; case IDX_DRAM_PERF: return platform->rapl_msrs & RAPL_DRAM_PERF_STATUS; + case IDX_PSYS_ENERGY: + return platform->rapl_msrs & RAPL_PSYS; default: return 0; } @@ -1840,6 +1879,10 @@ struct system_summary { struct pkg_data packages; } average; +struct platform_counters { + struct rapl_counter energy_psys; /* MSR_PLATFORM_ENERGY_STATUS */ +} platform_counters_odd, platform_counters_even; + struct cpu_topology { int physical_package_id; int die_id; @@ -1848,6 +1891,7 @@ struct cpu_topology { int logical_node_id; /* 0-based count within the package */ int physical_core_id; int thread_id; + int type; cpu_set_t *put_ids; /* Processing Unit/Thread IDs */ } *cpus; @@ -2291,7 +2335,7 @@ void print_header(char *delim) break; case PMT_TYPE_XTAL_TIME: - outp += sprintf(outp, "%s%s", delim, ppmt->name); + outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), ppmt->name); break; } @@ -2365,7 +2409,7 @@ void print_header(char *delim) break; case PMT_TYPE_XTAL_TIME: - outp += sprintf(outp, "%s%s", delim, ppmt->name); + outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), ppmt->name); break; } @@ -2496,13 +2540,18 @@ void print_header(char *delim) break; case PMT_TYPE_XTAL_TIME: - outp += sprintf(outp, "%s%s", delim, ppmt->name); + outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), ppmt->name); break; } ppmt = ppmt->next; } + if (DO_BIC(BIC_SysWatt)) + outp += sprintf(outp, "%sSysWatt", (printed++ ? delim : "")); + if (DO_BIC(BIC_Sys_J)) + outp += sprintf(outp, "%sSys_J", (printed++ ? delim : "")); + outp += sprintf(outp, "\n"); } @@ -2510,6 +2559,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p { int i; struct msr_counter *mp; + struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even; outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p); @@ -2581,6 +2631,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores.raw_value); outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx.raw_value); outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram.raw_value); + outp += sprintf(outp, "Joules PSYS: %0llX\n", pplat_cnt->energy_psys.raw_value); outp += sprintf(outp, "Throttle PKG: %0llX\n", p->rapl_pkg_perf_status.raw_value); outp += sprintf(outp, "Throttle RAM: %0llX\n", p->rapl_dram_perf_status.raw_value); outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c); @@ -2619,6 +2670,9 @@ double rapl_counter_get_value(const struct rapl_counter *c, enum rapl_unit desir */ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) { + static int count; + + struct platform_counters *pplat_cnt = NULL; double interval_float, tsc; char *fmt8; int i; @@ -2628,6 +2682,11 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data char *delim = "\t"; int printed = 0; + if (t == &average.threads) { + pplat_cnt = count & 1 ? &platform_counters_odd : &platform_counters_even; + ++count; + } + /* if showing only 1st thread in core and this isn't one, bail out */ if (show_core_only && !is_cpu_first_thread_in_core(t, c, p)) return 0; @@ -2788,6 +2847,8 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data } for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) { + const unsigned long value_raw = t->pmt_counter[i]; + const double value_converted = 100.0 * value_raw / crystal_hz / interval_float; switch (ppmt->type) { case PMT_TYPE_RAW: if (pmt_counter_get_width(ppmt) <= 32) @@ -2799,9 +2860,6 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data break; case PMT_TYPE_XTAL_TIME: - const unsigned long value_raw = t->pmt_counter[i]; - const double value_converted = 100.0 * value_raw / crystal_hz / interval_float; - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); break; } @@ -2869,6 +2927,8 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data } for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) { + const unsigned long value_raw = c->pmt_counter[i]; + const double value_converted = 100.0 * value_raw / crystal_hz / interval_float; switch (ppmt->type) { case PMT_TYPE_RAW: if (pmt_counter_get_width(ppmt) <= 32) @@ -2880,9 +2940,6 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data break; case PMT_TYPE_XTAL_TIME: - const unsigned long value_raw = c->pmt_counter[i]; - const double value_converted = 100.0 * value_raw / crystal_hz / interval_float; - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); break; } @@ -3068,6 +3125,8 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data } for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) { + const unsigned long value_raw = p->pmt_counter[i]; + const double value_converted = 100.0 * value_raw / crystal_hz / interval_float; switch (ppmt->type) { case PMT_TYPE_RAW: if (pmt_counter_get_width(ppmt) <= 32) @@ -3079,14 +3138,18 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data break; case PMT_TYPE_XTAL_TIME: - const unsigned long value_raw = p->pmt_counter[i]; - const double value_converted = 100.0 * value_raw / crystal_hz / interval_float; - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); break; } } + if (DO_BIC(BIC_SysWatt) && (t == &average.threads)) + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), + rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_WATTS, interval_float)); + if (DO_BIC(BIC_Sys_J) && (t == &average.threads)) + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), + rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_JOULES, interval_float)); + done: if (*(outp - 1) != '\n') outp += sprintf(outp, "\n"); @@ -3394,6 +3457,11 @@ int delta_cpu(struct thread_data *t, struct core_data *c, return retval; } +void delta_platform(struct platform_counters *new, struct platform_counters *old) +{ + old->energy_psys.raw_value = new->energy_psys.raw_value - old->energy_psys.raw_value; +} + void rapl_counter_clear(struct rapl_counter *c) { c->raw_value = 0; @@ -4123,6 +4191,9 @@ static size_t cstate_counter_info_count_perf(const struct cstate_counter_info_t void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci, unsigned int idx) { + if (rci->source[idx] == COUNTER_SOURCE_NONE) + return; + rc->raw_value = rci->data[idx]; rc->unit = rci->unit[idx]; rc->scale = rci->scale[idx]; @@ -4130,6 +4201,7 @@ void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct pkg_data *p) { + struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even; unsigned long long perf_data[NUM_RAPL_COUNTERS + 1]; struct rapl_counter_info_t *rci; @@ -4157,6 +4229,7 @@ int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct for (unsigned int i = 0, pi = 1; i < NUM_RAPL_COUNTERS; ++i) { switch (rci->source[i]) { case COUNTER_SOURCE_NONE: + rci->data[i] = 0; break; case COUNTER_SOURCE_PERF: @@ -4195,7 +4268,7 @@ int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct } } - BUILD_BUG_ON(NUM_RAPL_COUNTERS != 7); + BUILD_BUG_ON(NUM_RAPL_COUNTERS != 8); write_rapl_counter(&p->energy_pkg, rci, RAPL_RCI_INDEX_ENERGY_PKG); write_rapl_counter(&p->energy_cores, rci, RAPL_RCI_INDEX_ENERGY_CORES); write_rapl_counter(&p->energy_dram, rci, RAPL_RCI_INDEX_DRAM); @@ -4203,6 +4276,7 @@ int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct write_rapl_counter(&p->rapl_pkg_perf_status, rci, RAPL_RCI_INDEX_PKG_PERF_STATUS); write_rapl_counter(&p->rapl_dram_perf_status, rci, RAPL_RCI_INDEX_DRAM_PERF_STATUS); write_rapl_counter(&c->core_energy, rci, RAPL_RCI_INDEX_CORE_ENERGY); + write_rapl_counter(&pplat_cnt->energy_psys, rci, RAPL_RCI_INDEX_ENERGY_PLATFORM); return 0; } @@ -5385,6 +5459,9 @@ static int parse_cpu_str(char *cpu_str, cpu_set_t *cpu_set, int cpu_set_size) if (*next == '-') /* no negative cpu numbers */ return 1; + if (*next == '\0' || *next == '\n') + break; + start = strtoul(next, &next, 10); if (start >= CPU_SUBSET_MAXCPUS) @@ -5656,6 +5733,32 @@ int init_thread_id(int cpu) return 0; } +int set_my_cpu_type(void) +{ + unsigned int eax, ebx, ecx, edx; + unsigned int max_level; + + __cpuid(0, max_level, ebx, ecx, edx); + + if (max_level < CPUID_LEAF_MODEL_ID) + return 0; + + __cpuid(CPUID_LEAF_MODEL_ID, eax, ebx, ecx, edx); + + return (eax >> CPUID_LEAF_MODEL_ID_CORE_TYPE_SHIFT); +} + +int set_cpu_hybrid_type(int cpu) +{ + if (cpu_migrate(cpu)) + return -1; + + int type = set_my_cpu_type(); + + cpus[cpu].type = type; + return 0; +} + /* * snapshot_proc_interrupts() * @@ -5728,28 +5831,21 @@ int snapshot_proc_interrupts(void) */ int snapshot_graphics(int idx) { - FILE *fp; int retval; + rewind(gfx_info[idx].fp); + switch (idx) { case GFX_rc6: case SAM_mc6: - fp = fopen_or_die(gfx_info[idx].path, "r"); - retval = fscanf(fp, "%lld", &gfx_info[idx].val_ull); + retval = fscanf(gfx_info[idx].fp, "%lld", &gfx_info[idx].val_ull); if (retval != 1) err(1, "rc6"); - fclose(fp); return 0; case GFX_MHz: case GFX_ACTMHz: case SAM_MHz: case SAM_ACTMHz: - if (gfx_info[idx].fp == NULL) { - gfx_info[idx].fp = fopen_or_die(gfx_info[idx].path, "r"); - } else { - rewind(gfx_info[idx].fp); - fflush(gfx_info[idx].fp); - } retval = fscanf(gfx_info[idx].fp, "%d", &gfx_info[idx].val); if (retval != 1) err(1, "MHz"); @@ -6116,6 +6212,7 @@ restart: re_initialize(); goto restart; } + delta_platform(&platform_counters_odd, &platform_counters_even); compute_average(EVEN_COUNTERS); format_all_counters(EVEN_COUNTERS); flush_output_stdout(); @@ -6139,6 +6236,7 @@ restart: re_initialize(); goto restart; } + delta_platform(&platform_counters_even, &platform_counters_odd); compute_average(ODD_COUNTERS); format_all_counters(ODD_COUNTERS); flush_output_stdout(); @@ -6442,14 +6540,25 @@ static void probe_intel_uncore_frequency(void) probe_intel_uncore_frequency_legacy(); } +static void set_graphics_fp(char *path, int idx) +{ + if (!access(path, R_OK)) + gfx_info[idx].fp = fopen_or_die(path, "r"); +} + +/* Enlarge this if there are /sys/class/drm/card2 ... */ +#define GFX_MAX_CARDS 2 + static void probe_graphics(void) { + char path[PATH_MAX]; + int i; + /* Xe graphics sysfs knobs */ if (!access("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", R_OK)) { FILE *fp; char buf[8]; bool gt0_is_gt; - int idx; fp = fopen("/sys/class/drm/card0/device/tile0/gt0/gtidle/name", "r"); if (!fp) @@ -6468,81 +6577,76 @@ static void probe_graphics(void) else goto next; - idx = gt0_is_gt ? GFX_rc6 : SAM_mc6; - gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms"; + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", gt0_is_gt ? GFX_rc6 : SAM_mc6); - idx = gt0_is_gt ? GFX_MHz : SAM_MHz; - if (!access("/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq", R_OK)) - gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq"; + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq", gt0_is_gt ? GFX_MHz : SAM_MHz); - idx = gt0_is_gt ? GFX_ACTMHz : SAM_ACTMHz; - if (!access("/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq", R_OK)) - gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq"; + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq", gt0_is_gt ? GFX_ACTMHz : SAM_ACTMHz); - idx = gt0_is_gt ? SAM_mc6 : GFX_rc6; - if (!access("/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms", R_OK)) - gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms"; + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms", gt0_is_gt ? SAM_mc6 : GFX_rc6); - idx = gt0_is_gt ? SAM_MHz : GFX_MHz; - if (!access("/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq", R_OK)) - gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq"; + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq", gt0_is_gt ? SAM_MHz : GFX_MHz); - idx = gt0_is_gt ? SAM_ACTMHz : GFX_ACTMHz; - if (!access("/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq", R_OK)) - gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq"; + set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq", gt0_is_gt ? SAM_ACTMHz : GFX_ACTMHz); goto end; } next: /* New i915 graphics sysfs knobs */ - if (!access("/sys/class/drm/card0/gt/gt0/rc6_residency_ms", R_OK)) { - gfx_info[GFX_rc6].path = "/sys/class/drm/card0/gt/gt0/rc6_residency_ms"; + for (i = 0; i < GFX_MAX_CARDS; i++) { + snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rc6_residency_ms", i); + if (!access(path, R_OK)) + break; + } - if (!access("/sys/class/drm/card0/gt/gt0/rps_cur_freq_mhz", R_OK)) - gfx_info[GFX_MHz].path = "/sys/class/drm/card0/gt/gt0/rps_cur_freq_mhz"; + if (i == GFX_MAX_CARDS) + goto legacy_i915; - if (!access("/sys/class/drm/card0/gt/gt0/rps_act_freq_mhz", R_OK)) - gfx_info[GFX_ACTMHz].path = "/sys/class/drm/card0/gt/gt0/rps_act_freq_mhz"; + snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rc6_residency_ms", i); + set_graphics_fp(path, GFX_rc6); - if (!access("/sys/class/drm/card0/gt/gt1/rc6_residency_ms", R_OK)) - gfx_info[SAM_mc6].path = "/sys/class/drm/card0/gt/gt1/rc6_residency_ms"; + snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rps_cur_freq_mhz", i); + set_graphics_fp(path, GFX_MHz); - if (!access("/sys/class/drm/card0/gt/gt1/rps_cur_freq_mhz", R_OK)) - gfx_info[SAM_MHz].path = "/sys/class/drm/card0/gt/gt1/rps_cur_freq_mhz"; + snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rps_act_freq_mhz", i); + set_graphics_fp(path, GFX_ACTMHz); - if (!access("/sys/class/drm/card0/gt/gt1/rps_act_freq_mhz", R_OK)) - gfx_info[SAM_ACTMHz].path = "/sys/class/drm/card0/gt/gt1/rps_act_freq_mhz"; + snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rc6_residency_ms", i); + set_graphics_fp(path, SAM_mc6); - goto end; - } + snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rps_cur_freq_mhz", i); + set_graphics_fp(path, SAM_MHz); + + snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rps_act_freq_mhz", i); + set_graphics_fp(path, SAM_ACTMHz); + goto end; + +legacy_i915: /* Fall back to traditional i915 graphics sysfs knobs */ - if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK)) - gfx_info[GFX_rc6].path = "/sys/class/drm/card0/power/rc6_residency_ms"; + set_graphics_fp("/sys/class/drm/card0/power/rc6_residency_ms", GFX_rc6); - if (!access("/sys/class/drm/card0/gt_cur_freq_mhz", R_OK)) - gfx_info[GFX_MHz].path = "/sys/class/drm/card0/gt_cur_freq_mhz"; - else if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK)) - gfx_info[GFX_MHz].path = "/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz"; + set_graphics_fp("/sys/class/drm/card0/gt_cur_freq_mhz", GFX_MHz); + if (!gfx_info[GFX_MHz].fp) + set_graphics_fp("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", GFX_MHz); - if (!access("/sys/class/drm/card0/gt_act_freq_mhz", R_OK)) - gfx_info[GFX_ACTMHz].path = "/sys/class/drm/card0/gt_act_freq_mhz"; - else if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", R_OK)) - gfx_info[GFX_ACTMHz].path = "/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz"; + set_graphics_fp("/sys/class/drm/card0/gt_act_freq_mhz", GFX_ACTMHz); + if (!gfx_info[GFX_ACTMHz].fp) + set_graphics_fp("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", GFX_ACTMHz); end: - if (gfx_info[GFX_rc6].path) + if (gfx_info[GFX_rc6].fp) BIC_PRESENT(BIC_GFX_rc6); - if (gfx_info[GFX_MHz].path) + if (gfx_info[GFX_MHz].fp) BIC_PRESENT(BIC_GFXMHz); - if (gfx_info[GFX_ACTMHz].path) + if (gfx_info[GFX_ACTMHz].fp) BIC_PRESENT(BIC_GFXACTMHz); - if (gfx_info[SAM_mc6].path) + if (gfx_info[SAM_mc6].fp) BIC_PRESENT(BIC_SAM_mc6); - if (gfx_info[SAM_MHz].path) + if (gfx_info[SAM_MHz].fp) BIC_PRESENT(BIC_SAMMHz); - if (gfx_info[SAM_ACTMHz].path) + if (gfx_info[SAM_ACTMHz].fp) BIC_PRESENT(BIC_SAMACTMHz); } @@ -6911,8 +7015,8 @@ void rapl_probe_intel(void) unsigned long long msr; unsigned int time_unit; double tdp; - const unsigned long long bic_watt_bits = BIC_PkgWatt | BIC_CorWatt | BIC_RAMWatt | BIC_GFXWatt; - const unsigned long long bic_joules_bits = BIC_Pkg_J | BIC_Cor_J | BIC_RAM_J | BIC_GFX_J; + const unsigned long long bic_watt_bits = BIC_SysWatt | BIC_PkgWatt | BIC_CorWatt | BIC_RAMWatt | BIC_GFXWatt; + const unsigned long long bic_joules_bits = BIC_Sys_J | BIC_Pkg_J | BIC_Cor_J | BIC_RAM_J | BIC_GFX_J; if (rapl_joules) bic_enabled &= ~bic_watt_bits; @@ -7572,6 +7676,9 @@ void rapl_perf_init(void) domain_visited[next_domain] = 1; + if ((cai->flags & RAPL_COUNTER_FLAG_PLATFORM_COUNTER) && (cpu != base_cpu)) + continue; + struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[next_domain]; /* Check if the counter is enabled and accessible */ @@ -8196,7 +8303,7 @@ void topology_probe(bool startup) set_max_cpu_num(); topo.num_cpus = 0; for_all_proc_cpus(count_cpus); - if (!summary_only && topo.num_cpus > 1) + if (!summary_only) BIC_PRESENT(BIC_CPU); if (debug > 1) @@ -8284,6 +8391,8 @@ void topology_probe(bool startup) for_all_proc_cpus(init_thread_id); + for_all_proc_cpus(set_cpu_hybrid_type); + /* * For online cpus * find max_core_id, max_package_id @@ -8332,7 +8441,7 @@ void topology_probe(bool startup) topo.cores_per_node = max_core_id + 1; if (debug > 1) fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_node); - if (!summary_only && topo.cores_per_node > 1) + if (!summary_only) BIC_PRESENT(BIC_Core); topo.num_die = topo.max_die_id + 1; @@ -8548,6 +8657,35 @@ void check_perf_access(void) bic_enabled &= ~BIC_IPC; } +bool perf_has_hybrid_devices(void) +{ + /* + * 0: unknown + * 1: has separate perf device for p and e core + * -1: doesn't have separate perf device for p and e core + */ + static int cached; + + if (cached > 0) + return true; + + if (cached < 0) + return false; + + if (access("/sys/bus/event_source/devices/cpu_core", F_OK)) { + cached = -1; + return false; + } + + if (access("/sys/bus/event_source/devices/cpu_atom", F_OK)) { + cached = -1; + return false; + } + + cached = 1; + return true; +} + int added_perf_counters_init_(struct perf_counter_info *pinfo) { size_t num_domains = 0; @@ -8604,29 +8742,56 @@ int added_perf_counters_init_(struct perf_counter_info *pinfo) if (domain_visited[next_domain]) continue; - perf_type = read_perf_type(pinfo->device); + /* + * Intel hybrid platforms expose different perf devices for P and E cores. + * Instead of one, "/sys/bus/event_source/devices/cpu" device, there are + * "/sys/bus/event_source/devices/{cpu_core,cpu_atom}". + * + * This makes it more complicated to the user, because most of the counters + * are available on both and have to be handled manually, otherwise. + * + * Code below, allow user to use the old "cpu" name, which is translated accordingly. + */ + const char *perf_device = pinfo->device; + + if (strcmp(perf_device, "cpu") == 0 && perf_has_hybrid_devices()) { + switch (cpus[cpu].type) { + case INTEL_PCORE_TYPE: + perf_device = "cpu_core"; + break; + + case INTEL_ECORE_TYPE: + perf_device = "cpu_atom"; + break; + + default: /* Don't change, we will probably fail and report a problem soon. */ + break; + } + } + + perf_type = read_perf_type(perf_device); if (perf_type == (unsigned int)-1) { warnx("%s: perf/%s/%s: failed to read %s", - __func__, pinfo->device, pinfo->event, "type"); + __func__, perf_device, pinfo->event, "type"); continue; } - perf_config = read_perf_config(pinfo->device, pinfo->event); + perf_config = read_perf_config(perf_device, pinfo->event); if (perf_config == (unsigned int)-1) { warnx("%s: perf/%s/%s: failed to read %s", - __func__, pinfo->device, pinfo->event, "config"); + __func__, perf_device, pinfo->event, "config"); continue; } /* Scale is not required, some counters just don't have it. */ - perf_scale = read_perf_scale(pinfo->device, pinfo->event); + perf_scale = read_perf_scale(perf_device, pinfo->event); if (perf_scale == 0.0) perf_scale = 1.0; fd_perf = open_perf_counter(cpu, perf_type, perf_config, -1, 0); if (fd_perf == -1) { warnx("%s: perf/%s/%s: failed to open counter on cpu%d", - __func__, pinfo->device, pinfo->event, cpu); + __func__, perf_device, pinfo->event, cpu); continue; } @@ -8636,7 +8801,7 @@ int added_perf_counters_init_(struct perf_counter_info *pinfo) if (debug) fprintf(stderr, "Add perf/%s/%s cpu%d: %d\n", - pinfo->device, pinfo->event, cpu, pinfo->fd_perf_per_domain[next_domain]); + perf_device, pinfo->event, cpu, pinfo->fd_perf_per_domain[next_domain]); } pinfo = pinfo->next; @@ -9071,7 +9236,7 @@ int get_and_dump_counters(void) void print_version() { - fprintf(outf, "turbostat version 2024.07.26 - Len Brown \n"); + fprintf(outf, "turbostat version 2024.11.30 - Len Brown \n"); } #define COMMAND_LINE_SIZE 2048 @@ -9781,7 +9946,7 @@ void cmdline(int argc, char **argv) * Parse some options early, because they may make other options invalid, * like adding the MSR counter with --add and at the same time using --no-msr. */ - while ((opt = getopt_long_only(argc, argv, "MPn:", long_options, &option_index)) != -1) { + while ((opt = getopt_long_only(argc, argv, "+MPn:", long_options, &option_index)) != -1) { switch (opt) { case 'M': no_msr = 1; @@ -9805,6 +9970,12 @@ void cmdline(int argc, char **argv) break; case 'D': dump_only++; + /* + * Force the no_perf early to prevent using it as a source. + * User asks for raw values, but perf returns them relative + * to the opening of the file descriptor. + */ + no_perf = 1; break; case 'e': /* --enable specified counter */ diff --git a/tools/testing/cxl/cxl_core_exports.c b/tools/testing/cxl/cxl_core_exports.c index 077e6883921df2ccd8e82dea6d75dc359d1daefd..f088792a8925f0c59ea3985a73b17c75301576ae 100644 --- a/tools/testing/cxl/cxl_core_exports.c +++ b/tools/testing/cxl/cxl_core_exports.c @@ -4,4 +4,4 @@ #include "cxl.h" /* Exporting of cxl_core symbols that are only used by cxl_test */ -EXPORT_SYMBOL_NS_GPL(cxl_num_decoders_committed, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_num_decoders_committed, "CXL"); diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c index 050725afa45d16202b8e92bf7d280d676592007e..d0337c11f9ee675b0c461c8ae28e50957dc644ce 100644 --- a/tools/testing/cxl/test/cxl.c +++ b/tools/testing/cxl/test/cxl.c @@ -1531,5 +1531,5 @@ MODULE_PARM_DESC(interleave_arithmetic, "Modulo:0, XOR:1"); module_init(cxl_test_init); module_exit(cxl_test_exit); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(ACPI); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("ACPI"); +MODULE_IMPORT_NS("CXL"); diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index 71916e0e1546e8f7e1034482e68b28c4edc5a2ea..347c1e7b37bdfa9c70c6b469ad987baa48ca35e4 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -1679,4 +1679,4 @@ static struct platform_driver cxl_mock_mem_driver = { module_platform_driver(cxl_mock_mem_driver); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("CXL"); diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c index f4ce96cc11d4b01689867c6b9c8c0b5efd5ec18b..450c7566c33f3633428f04d8b45815a826ae8b1c 100644 --- a/tools/testing/cxl/test/mock.c +++ b/tools/testing/cxl/test/mock.c @@ -76,7 +76,7 @@ int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id, return rc; } -EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI); +EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI"); acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle, acpi_string pathname, @@ -147,7 +147,7 @@ struct cxl_hdm *__wrap_devm_cxl_setup_hdm(struct cxl_port *port, return cxlhdm; } -EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, "CXL"); int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port) { @@ -162,7 +162,7 @@ int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port) return rc; } -EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, "CXL"); int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm, struct cxl_endpoint_dvsec_info *info) @@ -179,7 +179,7 @@ int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm, return rc; } -EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, "CXL"); int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port) { @@ -194,7 +194,7 @@ int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port) return rc; } -EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, "CXL"); int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds) { @@ -209,7 +209,7 @@ int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds) return rc; } -EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, "CXL"); int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm, @@ -226,7 +226,7 @@ int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds, return rc; } -EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, "CXL"); int __wrap_cxl_dvsec_rr_decode(struct device *dev, struct cxl_port *port, struct cxl_endpoint_dvsec_info *info) @@ -242,7 +242,7 @@ int __wrap_cxl_dvsec_rr_decode(struct device *dev, struct cxl_port *port, return rc; } -EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, "CXL"); struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port, struct device *dport_dev, @@ -266,7 +266,7 @@ struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port, return dport; } -EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, "CXL"); resource_size_t __wrap_cxl_rcd_component_reg_phys(struct device *dev, struct cxl_dport *dport) @@ -283,7 +283,7 @@ resource_size_t __wrap_cxl_rcd_component_reg_phys(struct device *dev, return component_reg_phys; } -EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcd_component_reg_phys, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcd_component_reg_phys, "CXL"); void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port) { @@ -297,7 +297,7 @@ void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port) cxl_endpoint_parse_cdat(port); put_cxl_mock_ops(index); } -EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL"); void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host) { @@ -309,8 +309,8 @@ void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device put_cxl_mock_ops(index); } -EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dport_init_ras_reporting, CXL); +EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dport_init_ras_reporting, "CXL"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(ACPI); -MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS("ACPI"); +MODULE_IMPORT_NS("CXL"); diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index 892e990c034ab76b74279d21fd09e30bb1924fba..68a064ce598c93b1156159de8b0ba38659908286 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -883,7 +883,7 @@ static const struct platform_device_id ndtest_id[] = { static struct platform_driver ndtest_driver = { .probe = ndtest_probe, - .remove_new = ndtest_remove, + .remove = ndtest_remove, .driver = { .name = KBUILD_MODNAME, }, diff --git a/tools/testing/selftests/alsa/.gitignore b/tools/testing/selftests/alsa/.gitignore index 12dc3fcd345645348ebac36d3ef95b7bc26f12fe..3dd8e1176b899f92cd31b9b97d971556eb51e703 100644 --- a/tools/testing/selftests/alsa/.gitignore +++ b/tools/testing/selftests/alsa/.gitignore @@ -1,3 +1,5 @@ +global-timer mixer-test pcm-test test-pcmtest-driver +utimer-test diff --git a/tools/testing/selftests/drivers/net/hw/rss_ctx.py b/tools/testing/selftests/drivers/net/hw/rss_ctx.py index 0b49ce7ae6784e634336a7bf5c6772ae6438e514..ca8a7edff3dda2f90b6ad3e08749207a8202263a 100755 --- a/tools/testing/selftests/drivers/net/hw/rss_ctx.py +++ b/tools/testing/selftests/drivers/net/hw/rss_ctx.py @@ -3,7 +3,8 @@ import datetime import random -from lib.py import ksft_run, ksft_pr, ksft_exit, ksft_eq, ksft_ne, ksft_ge, ksft_lt +import re +from lib.py import ksft_run, ksft_pr, ksft_exit, ksft_eq, ksft_ne, ksft_ge, ksft_lt, ksft_true from lib.py import NetDrvEpEnv from lib.py import EthtoolFamily, NetdevFamily from lib.py import KsftSkipEx, KsftFailEx @@ -96,6 +97,13 @@ def _send_traffic_check(cfg, port, name, params): f"traffic on inactive queues ({name}): " + str(cnts)) +def _ntuple_rule_check(cfg, rule_id, ctx_id): + """Check that ntuple rule references RSS context ID""" + text = ethtool(f"-n {cfg.ifname} rule {rule_id}").stdout + pattern = f"RSS Context (ID: )?{ctx_id}" + ksft_true(re.search(pattern, text), "RSS context not referenced in ntuple rule") + + def test_rss_key_indir(cfg): """Test basics like updating the main RSS key and indirection table.""" @@ -459,6 +467,8 @@ def test_rss_context(cfg, ctx_cnt=1, create_with_cfg=None): ntuple = ethtool_create(cfg, "-N", flow) defer(ethtool, f"-N {cfg.ifname} delete {ntuple}") + _ntuple_rule_check(cfg, ntuple, ctx_id) + for i in range(ctx_cnt): _send_traffic_check(cfg, ports[i], f"context {i}", { 'target': (2+i*2, 3+i*2), diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c index 319567f0fae140132f73a794624d42db45228bd9..81db85a5cc1641faa7d48967330559a3acc5a3fe 100644 --- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c +++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c @@ -57,7 +57,6 @@ static int __do_binderfs_test(struct __test_metadata *_metadata) { int fd, ret, saved_errno, result = 1; size_t len; - ssize_t wret; struct binderfs_device device = { 0 }; struct binder_version version = { 0 }; char binderfs_mntpt[] = P_tmpdir "/binderfs_XXXXXX", diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h index e5db897586bbfe010d8799f6f52fc5c418344e6b..531228b849daebcf40d994abb8bf35e760b3cc4e 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -22,6 +22,9 @@ #define HID_REQ_SET_IDLE HID_REQ_SET_IDLE___not_used #define HID_REQ_SET_PROTOCOL HID_REQ_SET_PROTOCOL___not_used +/* do not define kfunc through vmlinux.h as this messes up our custom hack */ +#define BPF_NO_KFUNC_PROTOTYPES + #include "vmlinux.h" #undef hid_bpf_ctx @@ -91,31 +94,31 @@ struct hid_bpf_ops { /* following are kfuncs exported by HID for HID-BPF */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, - const size_t __sz) __ksym; -extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym; -extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym; + const size_t __sz) __weak __ksym; +extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __weak __ksym; +extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __weak __ksym; extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *data, size_t buf__sz, enum hid_report_type type, - enum hid_class_request reqtype) __ksym; + enum hid_class_request reqtype) __weak __ksym; extern int hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, - __u8 *buf, size_t buf__sz) __ksym; + __u8 *buf, size_t buf__sz) __weak __ksym; extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, __u8 *data, - size_t buf__sz) __ksym; + size_t buf__sz) __weak __ksym; extern int hid_bpf_try_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, __u8 *data, - size_t buf__sz) __ksym; + size_t buf__sz) __weak __ksym; /* bpf_wq implementation */ extern int bpf_wq_init(struct bpf_wq *wq, void *p__map, unsigned int flags) __weak __ksym; extern int bpf_wq_start(struct bpf_wq *wq, unsigned int flags) __weak __ksym; extern int bpf_wq_set_callback_impl(struct bpf_wq *wq, int (callback_fn)(void *map, int *key, void *wq), - unsigned int flags__k, void *aux__ign) __ksym; + unsigned int flags__k, void *aux__ign) __weak __ksym; #define bpf_wq_set_callback(timer, cb, flags) \ bpf_wq_set_callback_impl(timer, cb, flags, NULL) diff --git a/tools/testing/selftests/hid/run-hid-tools-tests.sh b/tools/testing/selftests/hid/run-hid-tools-tests.sh index bdae8464da86566118d88b9e6ee6713982868df7..af1682a53c27e10a30d3299ef6def672a27b0847 100755 --- a/tools/testing/selftests/hid/run-hid-tools-tests.sh +++ b/tools/testing/selftests/hid/run-hid-tools-tests.sh @@ -2,24 +2,26 @@ # SPDX-License-Identifier: GPL-2.0 # Runs tests for the HID subsystem +KSELFTEST_SKIP_TEST=4 + if ! command -v python3 > /dev/null 2>&1; then echo "hid-tools: [SKIP] python3 not installed" - exit 77 + exit $KSELFTEST_SKIP_TEST fi if ! python3 -c "import pytest" > /dev/null 2>&1; then - echo "hid: [SKIP/ pytest module not installed" - exit 77 + echo "hid: [SKIP] pytest module not installed" + exit $KSELFTEST_SKIP_TEST fi if ! python3 -c "import pytest_tap" > /dev/null 2>&1; then - echo "hid: [SKIP/ pytest_tap module not installed" - exit 77 + echo "hid: [SKIP] pytest_tap module not installed" + exit $KSELFTEST_SKIP_TEST fi if ! python3 -c "import hidtools" > /dev/null 2>&1; then - echo "hid: [SKIP/ hid-tools module not installed" - exit 77 + echo "hid: [SKIP] hid-tools module not installed" + exit $KSELFTEST_SKIP_TEST fi TARGET=${TARGET:=.} diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index 54ab484d0000646ee526a6017d097ea728eb44ba..4bc1051848e58340199c8a01af8889803a4fe72d 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -47,6 +47,8 @@ bool filter_reg(__u64 reg) case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SSCOFPMF: case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SSNPM: case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SSTC: + case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVADE: + case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVADU: case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVINVAL: case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVNAPOT: case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVPBMT: @@ -422,6 +424,8 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off) KVM_ISA_EXT_ARR(SSCOFPMF), KVM_ISA_EXT_ARR(SSNPM), KVM_ISA_EXT_ARR(SSTC), + KVM_ISA_EXT_ARR(SVADE), + KVM_ISA_EXT_ARR(SVADU), KVM_ISA_EXT_ARR(SVINVAL), KVM_ISA_EXT_ARR(SVNAPOT), KVM_ISA_EXT_ARR(SVPBMT), @@ -955,6 +959,8 @@ KVM_ISA_EXT_SUBLIST_CONFIG(smstateen, SMSTATEEN); KVM_ISA_EXT_SIMPLE_CONFIG(sscofpmf, SSCOFPMF); KVM_ISA_EXT_SIMPLE_CONFIG(ssnpm, SSNPM); KVM_ISA_EXT_SIMPLE_CONFIG(sstc, SSTC); +KVM_ISA_EXT_SIMPLE_CONFIG(svade, SVADE); +KVM_ISA_EXT_SIMPLE_CONFIG(svadu, SVADU); KVM_ISA_EXT_SIMPLE_CONFIG(svinval, SVINVAL); KVM_ISA_EXT_SIMPLE_CONFIG(svnapot, SVNAPOT); KVM_ISA_EXT_SIMPLE_CONFIG(svpbmt, SVPBMT); @@ -1020,6 +1026,8 @@ struct vcpu_reg_list *vcpu_configs[] = { &config_sscofpmf, &config_ssnpm, &config_sstc, + &config_svade, + &config_svadu, &config_svinval, &config_svnapot, &config_svpbmt, diff --git a/tools/testing/selftests/module/find_symbol.sh b/tools/testing/selftests/module/find_symbol.sh index 140364d3c49fc912eb6846b512e65cb419f6c1ba..2c56805c9b6e6ea0c9a6899f80b8cdf08ba42526 100755 --- a/tools/testing/selftests/module/find_symbol.sh +++ b/tools/testing/selftests/module/find_symbol.sh @@ -44,10 +44,10 @@ load_mod() local ARCH="$(uname -m)" case "${ARCH}" in x86_64) - perf stat $STATS $MODPROBE test_kallsyms_b + perf stat $STATS $MODPROBE $MOD ;; *) - time $MODPROBE test_kallsyms_b + time $MODPROBE $MOD exit 1 ;; esac diff --git a/tools/testing/vsock/control.c b/tools/testing/vsock/control.c index d2deb4b15b943cb348ecc7c065fe8dc059ee4631..0066e0324d35c65dcce569d6f73394be075c9dbc 100644 --- a/tools/testing/vsock/control.c +++ b/tools/testing/vsock/control.c @@ -27,6 +27,7 @@ #include "timeout.h" #include "control.h" +#include "util.h" static int control_fd = -1; @@ -50,7 +51,6 @@ void control_init(const char *control_host, for (ai = result; ai; ai = ai->ai_next) { int fd; - int val = 1; fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) @@ -65,11 +65,8 @@ void control_init(const char *control_host, break; } - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - &val, sizeof(val)) < 0) { - perror("setsockopt"); - exit(EXIT_FAILURE); - } + setsockopt_int_check(fd, SOL_SOCKET, SO_REUSEADDR, 1, + "setsockopt SO_REUSEADDR"); if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) goto next; diff --git a/tools/testing/vsock/msg_zerocopy_common.c b/tools/testing/vsock/msg_zerocopy_common.c index 5a4bdf7b5132827e0d2094d88ad52a9a03e61a63..8622e5a0f8b77497c877af8659e9ea4ce091cc17 100644 --- a/tools/testing/vsock/msg_zerocopy_common.c +++ b/tools/testing/vsock/msg_zerocopy_common.c @@ -14,16 +14,6 @@ #include "msg_zerocopy_common.h" -void enable_so_zerocopy(int fd) -{ - int val = 1; - - if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) { - perror("setsockopt"); - exit(EXIT_FAILURE); - } -} - void vsock_recv_completion(int fd, const bool *zerocopied) { struct sock_extended_err *serr; diff --git a/tools/testing/vsock/msg_zerocopy_common.h b/tools/testing/vsock/msg_zerocopy_common.h index 3763c5ccedb95e1716b3c001ea0e40d532e2a9b3..ad14139e93ca39df96960207bd7ed7d2ed977c9c 100644 --- a/tools/testing/vsock/msg_zerocopy_common.h +++ b/tools/testing/vsock/msg_zerocopy_common.h @@ -12,7 +12,6 @@ #define VSOCK_RECVERR 1 #endif -void enable_so_zerocopy(int fd); void vsock_recv_completion(int fd, const bool *zerocopied); #endif /* MSG_ZEROCOPY_COMMON_H */ diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c index a3d448a075e3a529325129ea000cfd78c5483640..34e9dac0a105f8aeb8c9af379b080d5ce8cb2782 100644 --- a/tools/testing/vsock/util.c +++ b/tools/testing/vsock/util.c @@ -651,3 +651,145 @@ void free_test_iovec(const struct iovec *test_iovec, free(iovec); } + +/* Set "unsigned long long" socket option and check that it's indeed set */ +void setsockopt_ull_check(int fd, int level, int optname, + unsigned long long val, char const *errmsg) +{ + unsigned long long chkval; + socklen_t chklen; + int err; + + err = setsockopt(fd, level, optname, &val, sizeof(val)); + if (err) { + fprintf(stderr, "setsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + chkval = ~val; /* just make storage != val */ + chklen = sizeof(chkval); + + err = getsockopt(fd, level, optname, &chkval, &chklen); + if (err) { + fprintf(stderr, "getsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + if (chklen != sizeof(chkval)) { + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), + chklen); + goto fail; + } + + if (chkval != val) { + fprintf(stderr, "value mismatch: set %llu got %llu\n", val, + chkval); + goto fail; + } + return; +fail: + fprintf(stderr, "%s val %llu\n", errmsg, val); + exit(EXIT_FAILURE); +; +} + +/* Set "int" socket option and check that it's indeed set */ +void setsockopt_int_check(int fd, int level, int optname, int val, + char const *errmsg) +{ + int chkval; + socklen_t chklen; + int err; + + err = setsockopt(fd, level, optname, &val, sizeof(val)); + if (err) { + fprintf(stderr, "setsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + chkval = ~val; /* just make storage != val */ + chklen = sizeof(chkval); + + err = getsockopt(fd, level, optname, &chkval, &chklen); + if (err) { + fprintf(stderr, "getsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + if (chklen != sizeof(chkval)) { + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), + chklen); + goto fail; + } + + if (chkval != val) { + fprintf(stderr, "value mismatch: set %d got %d\n", val, chkval); + goto fail; + } + return; +fail: + fprintf(stderr, "%s val %d\n", errmsg, val); + exit(EXIT_FAILURE); +} + +static void mem_invert(unsigned char *mem, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + mem[i] = ~mem[i]; +} + +/* Set "timeval" socket option and check that it's indeed set */ +void setsockopt_timeval_check(int fd, int level, int optname, + struct timeval val, char const *errmsg) +{ + struct timeval chkval; + socklen_t chklen; + int err; + + err = setsockopt(fd, level, optname, &val, sizeof(val)); + if (err) { + fprintf(stderr, "setsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + /* just make storage != val */ + chkval = val; + mem_invert((unsigned char *)&chkval, sizeof(chkval)); + chklen = sizeof(chkval); + + err = getsockopt(fd, level, optname, &chkval, &chklen); + if (err) { + fprintf(stderr, "getsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + if (chklen != sizeof(chkval)) { + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), + chklen); + goto fail; + } + + if (memcmp(&chkval, &val, sizeof(val)) != 0) { + fprintf(stderr, "value mismatch: set %ld:%ld got %ld:%ld\n", + val.tv_sec, val.tv_usec, chkval.tv_sec, chkval.tv_usec); + goto fail; + } + return; +fail: + fprintf(stderr, "%s val %ld:%ld\n", errmsg, val.tv_sec, val.tv_usec); + exit(EXIT_FAILURE); +} + +void enable_so_zerocopy_check(int fd) +{ + setsockopt_int_check(fd, SOL_SOCKET, SO_ZEROCOPY, 1, + "setsockopt SO_ZEROCOPY"); +} diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h index fff22d4a14c0ff1ab11aab558572e8449ea7ee03..ba84d296d8b71e1bcba2abdad337e07aac45e75e 100644 --- a/tools/testing/vsock/util.h +++ b/tools/testing/vsock/util.h @@ -68,4 +68,11 @@ unsigned long iovec_hash_djb2(const struct iovec *iov, size_t iovnum); struct iovec *alloc_test_iovec(const struct iovec *test_iovec, int iovnum); void free_test_iovec(const struct iovec *test_iovec, struct iovec *iovec, int iovnum); +void setsockopt_ull_check(int fd, int level, int optname, + unsigned long long val, char const *errmsg); +void setsockopt_int_check(int fd, int level, int optname, int val, + char const *errmsg); +void setsockopt_timeval_check(int fd, int level, int optname, + struct timeval val, char const *errmsg); +void enable_so_zerocopy_check(int fd); #endif /* UTIL_H */ diff --git a/tools/testing/vsock/vsock_perf.c b/tools/testing/vsock/vsock_perf.c index 4e8578f815e08a55fc3d5e8691b23453e2c772fe..75971ac708c9a3df9d126c3c02ffda9c321680a5 100644 --- a/tools/testing/vsock/vsock_perf.c +++ b/tools/testing/vsock/vsock_perf.c @@ -33,7 +33,7 @@ static unsigned int port = DEFAULT_PORT; static unsigned long buf_size_bytes = DEFAULT_BUF_SIZE_BYTES; -static unsigned long vsock_buf_bytes = DEFAULT_VSOCK_BUF_BYTES; +static unsigned long long vsock_buf_bytes = DEFAULT_VSOCK_BUF_BYTES; static bool zerocopy; static void error(const char *s) @@ -133,7 +133,7 @@ static float get_gbps(unsigned long bits, time_t ns_delta) ((float)ns_delta / NSEC_PER_SEC); } -static void run_receiver(unsigned long rcvlowat_bytes) +static void run_receiver(int rcvlowat_bytes) { unsigned int read_cnt; time_t rx_begin_ns; @@ -162,8 +162,8 @@ static void run_receiver(unsigned long rcvlowat_bytes) printf("Run as receiver\n"); printf("Listen port %u\n", port); printf("RX buffer %lu bytes\n", buf_size_bytes); - printf("vsock buffer %lu bytes\n", vsock_buf_bytes); - printf("SO_RCVLOWAT %lu bytes\n", rcvlowat_bytes); + printf("vsock buffer %llu bytes\n", vsock_buf_bytes); + printf("SO_RCVLOWAT %d bytes\n", rcvlowat_bytes); fd = socket(AF_VSOCK, SOCK_STREAM, 0); @@ -251,6 +251,16 @@ static void run_receiver(unsigned long rcvlowat_bytes) close(fd); } +static void enable_so_zerocopy(int fd) +{ + int val = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) { + perror("setsockopt"); + exit(EXIT_FAILURE); + } +} + static void run_sender(int peer_cid, unsigned long to_send_bytes) { time_t tx_begin_ns; @@ -439,7 +449,7 @@ static long strtolx(const char *arg) int main(int argc, char **argv) { unsigned long to_send_bytes = DEFAULT_TO_SEND_BYTES; - unsigned long rcvlowat_bytes = DEFAULT_RCVLOWAT_BYTES; + int rcvlowat_bytes = DEFAULT_RCVLOWAT_BYTES; int peer_cid = -1; bool sender = false; diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index 8d38dbf8f41f04128aef5113ae0e4cf09fc2e631..48f17641ca504316d1199926149c9bd62eb2921d 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -429,7 +429,7 @@ static void test_seqpacket_msg_bounds_client(const struct test_opts *opts) static void test_seqpacket_msg_bounds_server(const struct test_opts *opts) { - unsigned long sock_buf_size; + unsigned long long sock_buf_size; unsigned long remote_hash; unsigned long curr_hash; int fd; @@ -444,17 +444,13 @@ static void test_seqpacket_msg_bounds_server(const struct test_opts *opts) sock_buf_size = SOCK_BUF_SIZE; - if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, - &sock_buf_size, sizeof(sock_buf_size))) { - perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); - exit(EXIT_FAILURE); - } + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, + sock_buf_size, + "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); - if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, - &sock_buf_size, sizeof(sock_buf_size))) { - perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); - exit(EXIT_FAILURE); - } + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, + sock_buf_size, + "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); /* Ready to receive data. */ control_writeln("SRVREADY"); @@ -586,10 +582,8 @@ static void test_seqpacket_timeout_client(const struct test_opts *opts) tv.tv_sec = RCVTIMEO_TIMEOUT_SEC; tv.tv_usec = 0; - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) { - perror("setsockopt(SO_RCVTIMEO)"); - exit(EXIT_FAILURE); - } + setsockopt_timeval_check(fd, SOL_SOCKET, SO_RCVTIMEO, tv, + "setsockopt(SO_RCVTIMEO)"); read_enter_ns = current_nsec(); @@ -634,7 +628,8 @@ static void test_seqpacket_timeout_server(const struct test_opts *opts) static void test_seqpacket_bigmsg_client(const struct test_opts *opts) { - unsigned long sock_buf_size; + unsigned long long sock_buf_size; + size_t buf_size; socklen_t len; void *data; int fd; @@ -655,13 +650,20 @@ static void test_seqpacket_bigmsg_client(const struct test_opts *opts) sock_buf_size++; - data = malloc(sock_buf_size); + /* size_t can be < unsigned long long */ + buf_size = (size_t)sock_buf_size; + if (buf_size != sock_buf_size) { + fprintf(stderr, "Returned BUFFER_SIZE too large\n"); + exit(EXIT_FAILURE); + } + + data = malloc(buf_size); if (!data) { perror("malloc"); exit(EXIT_FAILURE); } - send_buf(fd, data, sock_buf_size, 0, -EMSGSIZE); + send_buf(fd, data, buf_size, 0, -EMSGSIZE); control_writeln("CLISENT"); @@ -835,7 +837,7 @@ static void test_stream_poll_rcvlowat_server(const struct test_opts *opts) static void test_stream_poll_rcvlowat_client(const struct test_opts *opts) { - unsigned long lowat_val = RCVLOWAT_BUF_SIZE; + int lowat_val = RCVLOWAT_BUF_SIZE; char buf[RCVLOWAT_BUF_SIZE]; struct pollfd fds; short poll_flags; @@ -847,11 +849,8 @@ static void test_stream_poll_rcvlowat_client(const struct test_opts *opts) exit(EXIT_FAILURE); } - if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, - &lowat_val, sizeof(lowat_val))) { - perror("setsockopt(SO_RCVLOWAT)"); - exit(EXIT_FAILURE); - } + setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, + lowat_val, "setsockopt(SO_RCVLOWAT)"); control_expectln("SRVSENT"); @@ -1357,9 +1356,10 @@ static void test_stream_rcvlowat_def_cred_upd_client(const struct test_opts *opt static void test_stream_credit_update_test(const struct test_opts *opts, bool low_rx_bytes_test) { - size_t recv_buf_size; + int recv_buf_size; struct pollfd fds; size_t buf_size; + unsigned long long sock_buf_size; void *buf; int fd; @@ -1371,11 +1371,12 @@ static void test_stream_credit_update_test(const struct test_opts *opts, buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE; - if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, - &buf_size, sizeof(buf_size))) { - perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); - exit(EXIT_FAILURE); - } + /* size_t can be < unsigned long long */ + sock_buf_size = buf_size; + + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, + sock_buf_size, + "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); if (low_rx_bytes_test) { /* Set new SO_RCVLOWAT here. This enables sending credit @@ -1384,11 +1385,8 @@ static void test_stream_credit_update_test(const struct test_opts *opts, */ recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE; - if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, - &recv_buf_size, sizeof(recv_buf_size))) { - perror("setsockopt(SO_RCVLOWAT)"); - exit(EXIT_FAILURE); - } + setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, + recv_buf_size, "setsockopt(SO_RCVLOWAT)"); } /* Send one dummy byte here, because 'setsockopt()' above also @@ -1430,11 +1428,8 @@ static void test_stream_credit_update_test(const struct test_opts *opts, recv_buf_size++; /* Updating SO_RCVLOWAT will send credit update. */ - if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, - &recv_buf_size, sizeof(recv_buf_size))) { - perror("setsockopt(SO_RCVLOWAT)"); - exit(EXIT_FAILURE); - } + setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, + recv_buf_size, "setsockopt(SO_RCVLOWAT)"); } fds.fd = fd; diff --git a/tools/testing/vsock/vsock_test_zerocopy.c b/tools/testing/vsock/vsock_test_zerocopy.c index 04c376b6937f51bea284bbb3fed25eb61166297c..9d9a6cb9614ad850d6508cda0cf9f5a806becc55 100644 --- a/tools/testing/vsock/vsock_test_zerocopy.c +++ b/tools/testing/vsock/vsock_test_zerocopy.c @@ -162,7 +162,7 @@ static void test_client(const struct test_opts *opts, } if (test_data->so_zerocopy) - enable_so_zerocopy(fd); + enable_so_zerocopy_check(fd); iovec = alloc_test_iovec(test_data->vecs, test_data->vecs_cnt); diff --git a/tools/testing/vsock/vsock_uring_test.c b/tools/testing/vsock/vsock_uring_test.c index 6c3e6f70c457da2ab6c0b993e90e1a5b4f8ac439..5c3078969659ff0e898cea2b707daa8d5f6880c4 100644 --- a/tools/testing/vsock/vsock_uring_test.c +++ b/tools/testing/vsock/vsock_uring_test.c @@ -73,7 +73,7 @@ static void vsock_io_uring_client(const struct test_opts *opts, } if (msg_zerocopy) - enable_so_zerocopy(fd); + enable_so_zerocopy_check(fd); iovec = alloc_test_iovec(test_data->vecs, test_data->vecs_cnt);